//===-- Instructions.cpp - Implement the LLVM instructions ----------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements all of the non-inline methods for the LLVM instruction
// classes.
//
//===----------------------------------------------------------------------===//
#include "llvm/BasicBlock.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/Support/CallSite.h"
using namespace llvm;
unsigned CallSite::getCallingConv() const {
if (CallInst *CI = dyn_cast<CallInst>(I))
return CI->getCallingConv();
else
return cast<InvokeInst>(I)->getCallingConv();
}
void CallSite::setCallingConv(unsigned CC) {
if (CallInst *CI = dyn_cast<CallInst>(I))
CI->setCallingConv(CC);
else
cast<InvokeInst>(I)->setCallingConv(CC);
}
//===----------------------------------------------------------------------===//
// TerminatorInst Class
//===----------------------------------------------------------------------===//
TerminatorInst::TerminatorInst(Instruction::TermOps iType,
Use *Ops, unsigned NumOps, Instruction *IB)
: Instruction(Type::VoidTy, iType, Ops, NumOps, "", IB) {
}
TerminatorInst::TerminatorInst(Instruction::TermOps iType,
Use *Ops, unsigned NumOps, BasicBlock *IAE)
: Instruction(Type::VoidTy, iType, Ops, NumOps, "", IAE) {
}
//===----------------------------------------------------------------------===//
// PHINode Class
//===----------------------------------------------------------------------===//
PHINode::PHINode(const PHINode &PN)
: Instruction(PN.getType(), Instruction::PHI,
new Use[PN.getNumOperands()], PN.getNumOperands()),
ReservedSpace(PN.getNumOperands()) {
Use *OL = OperandList;
for (unsigned i = 0, e = PN.getNumOperands(); i != e; i+=2) {
OL[i].init(PN.getOperand(i), this);
OL[i+1].init(PN.getOperand(i+1), this);
}
}
PHINode::~PHINode() {
delete [] OperandList;
}
// removeIncomingValue - Remove an incoming value. This is useful if a
// predecessor basic block is deleted.
Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) {
unsigned NumOps = getNumOperands();
Use *OL = OperandList;
assert(Idx*2 < NumOps && "BB not in PHI node!");
Value *Removed = OL[Idx*2];
// Move everything after this operand down.
//
// FIXME: we could just swap with the end of the list, then erase. However,
// client might not expect this to happen. The code as it is thrashes the
// use/def lists, which is kinda lame.
for (unsigned i = (Idx+1)*2; i != NumOps; i += 2) {
OL[i-2] = OL[i];
OL[i-2+1] = OL[i+1];
}
// Nuke the last value.
OL[NumOps-2].set(0);
OL[NumOps-2+1].set(0);
NumOperands = NumOps-2;
// If the PHI node is dead, because it has zero entries, nuke it now.
if (NumOps == 2 && DeletePHIIfEmpty) {
// If anyone is using this PHI, make them use a dummy value instead...
replaceAllUsesWith(UndefValue::get(getType()));
eraseFromParent();
}
return Removed;
}
/// resizeOperands - resize operands - This adjusts the length of the operands
/// list accord