Newer
Older
//===-- Instructions.cpp - Implement the LLVM instructions ----------------===//
// The LLVM Compiler Infrastructure
//
// This file 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/ParamAttrsList.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/ConstantRange.h"
Christopher Lamb
committed
#include "llvm/Support/MathExtras.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
// CallSite Class
//===----------------------------------------------------------------------===//
CallSite::CallSite(Instruction *C) {
assert((isa<CallInst>(C) || isa<InvokeInst>(C)) && "Not a call!");
I = C;
}
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);
}
const ParamAttrsList* CallSite::getParamAttrs() const {
if (CallInst *CI = dyn_cast<CallInst>(I))
return CI->getParamAttrs();
else
return cast<InvokeInst>(I)->getParamAttrs();
}
void CallSite::setParamAttrs(const ParamAttrsList *PAL) {
if (CallInst *CI = dyn_cast<CallInst>(I))
CI->setParamAttrs(PAL);
else
cast<InvokeInst>(I)->setParamAttrs(PAL);
}
bool CallSite::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
if (CallInst *CI = dyn_cast<CallInst>(I))
return CI->paramHasAttr(i, attr);
return cast<InvokeInst>(I)->paramHasAttr(i, attr);
uint16_t CallSite::getParamAlignment(uint16_t i) const {
if (CallInst *CI = dyn_cast<CallInst>(I))
return CI->getParamAlignment(i);
else
return cast<InvokeInst>(I)->getParamAlignment(i);
}
bool CallSite::doesNotAccessMemory() const {
if (CallInst *CI = dyn_cast<CallInst>(I))
return CI->doesNotAccessMemory();
else
return cast<InvokeInst>(I)->doesNotAccessMemory();
}
bool CallSite::onlyReadsMemory() const {
if (CallInst *CI = dyn_cast<CallInst>(I))
return CI->onlyReadsMemory();
else
return cast<InvokeInst>(I)->onlyReadsMemory();
}
bool CallSite::doesNotThrow() const {
if (CallInst *CI = dyn_cast<CallInst>(I))
return CI->doesNotThrow();
return cast<InvokeInst>(I)->doesNotThrow();
void CallSite::setDoesNotThrow(bool doesNotThrow) {
if (CallInst *CI = dyn_cast<CallInst>(I))
CI->setDoesNotThrow(doesNotThrow);
else
cast<InvokeInst>(I)->setDoesNotThrow(doesNotThrow);
}
//===----------------------------------------------------------------------===//
// TerminatorInst Class
//===----------------------------------------------------------------------===//
// Out of line virtual method, so the vtable, etc has a home.
TerminatorInst::~TerminatorInst() {
}
// Out of line virtual method, so the vtable, etc has a home.
UnaryInstruction::~UnaryInstruction() {
}
//===----------------------------------------------------------------------===//
// 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;
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
}
// 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 according to the following behavior:
/// 1. If NumOps == 0, grow the operand list in response to a push_back style
/// of operation. This grows the number of ops by 1.5 times.
/// 2. If NumOps > NumOperands, reserve space for NumOps operands.
/// 3. If NumOps == NumOperands, trim the reserved space.
///
void PHINode::resizeOperands(unsigned NumOps) {
if (NumOps == 0) {
NumOps = (getNumOperands())*3/2;
if (NumOps < 4) NumOps = 4; // 4 op PHI nodes are VERY common.
} else if (NumOps*2 > NumOperands) {
// No resize needed.
if (ReservedSpace >= NumOps) return;
} else if (NumOps == NumOperands) {
if (ReservedSpace == NumOps) return;
} else {
}
ReservedSpace = NumOps;
Use *NewOps = new Use[NumOps];
Use *OldOps = OperandList;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
NewOps[i].init(OldOps[i], this);
OldOps[i].set(0);
}
delete [] OldOps;
OperandList = NewOps;
}
/// hasConstantValue - If the specified PHI node always merges together the same
/// value, return the value, otherwise return null.
///
Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const {
// If the PHI node only has one incoming value, eliminate the PHI node...
Anton Korobeynikov
committed
if (getNumIncomingValues() == 1) {
if (getIncomingValue(0) != this) // not X = phi X
return getIncomingValue(0);
else
return UndefValue::get(getType()); // Self cycle is dead.
Anton Korobeynikov
committed
}
// Otherwise if all of the incoming values are the same for the PHI, replace
// the PHI node with the incoming value.
//
Value *InVal = 0;
bool HasUndefInput = false;
for (unsigned i = 0, e = getNumIncomingValues(); i != e; ++i)
Anton Korobeynikov
committed
if (isa<UndefValue>(getIncomingValue(i))) {
HasUndefInput = true;
Anton Korobeynikov
committed
} else if (getIncomingValue(i) != this) { // Not the PHI node itself...
if (InVal && getIncomingValue(i) != InVal)
return 0; // Not the same, bail out.
else
InVal = getIncomingValue(i);
Anton Korobeynikov
committed
}
// The only case that could cause InVal to be null is if we have a PHI node
// that only has entries for itself. In this case, there is no entry into the
// loop, so kill the PHI.
//
if (InVal == 0) InVal = UndefValue::get(getType());
// If we have a PHI node like phi(X, undef, X), where X is defined by some
// instruction, we cannot always return X as the result of the PHI node. Only
// do this if X is not an instruction (thus it must dominate the PHI block),
// or if the client is prepared to deal with this possibility.
if (HasUndefInput && !AllowNonDominatingInstruction)
if (Instruction *IV = dyn_cast<Instruction>(InVal))
// If it's in the entry block, it dominates everything.
if (IV->getParent() != &IV->getParent()->getParent()->getEntryBlock() ||
return 0; // Cannot guarantee that InVal dominates this PHINode.
// All of the incoming values are the same, return the value now.
return InVal;
}
//===----------------------------------------------------------------------===//
// CallInst Implementation
//===----------------------------------------------------------------------===//
CallInst::~CallInst() {
delete [] OperandList;
if (ParamAttrs)
ParamAttrs->dropRef();
void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) {
NumOperands = NumParams+1;
Use *OL = OperandList = new Use[NumParams+1];
cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
FTy = FTy; // silence warning.
assert((NumParams == FTy->getNumParams() ||
(FTy->isVarArg() && NumParams > FTy->getNumParams())) &&
Chris Lattner
committed
"Calling a function with bad signature!");
Chris Lattner
committed
assert((i >= FTy->getNumParams() ||
FTy->getParamType(i) == Params[i]->getType()) &&
"Calling a function with a bad signature!");
Chris Lattner
committed
}
}
void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) {
NumOperands = 3;
Use *OL = OperandList = new Use[3];
OL[0].init(Func, this);
OL[1].init(Actual1, this);
OL[2].init(Actual2, this);
cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
FTy = FTy; // silence warning.
Chris Lattner
committed
(FTy->isVarArg() && FTy->getNumParams() < 2)) &&
"Calling a function with bad signature");
Chris Lattner
committed
assert((0 >= FTy->getNumParams() ||
FTy->getParamType(0) == Actual1->getType()) &&
"Calling a function with a bad signature!");
assert((1 >= FTy->getNumParams() ||
FTy->getParamType(1) == Actual2->getType()) &&
"Calling a function with a bad signature!");
}
void CallInst::init(Value *Func, Value *Actual) {
NumOperands = 2;
Use *OL = OperandList = new Use[2];
OL[0].init(Func, this);
OL[1].init(Actual, this);
cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
FTy = FTy; // silence warning.
assert((FTy->getNumParams() == 1 ||
(FTy->isVarArg() && FTy->getNumParams() == 0)) &&
"Calling a function with bad signature");
Chris Lattner
committed
assert((0 == FTy->getNumParams() ||
FTy->getParamType(0) == Actual->getType()) &&
"Calling a function with a bad signature!");
}
NumOperands = 1;
Use *OL = OperandList = new Use[1];
OL[0].init(Func, this);
const FunctionType *FTy =
cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
FTy = FTy; // silence warning.
assert(FTy->getNumParams() == 0 && "Calling a function with bad signature");
}
CallInst::CallInst(Value *Func, Value* Actual, const std::string &Name,
Instruction *InsertBefore)
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
->getElementType())->getReturnType(),
Instruction::Call, 0, 0, InsertBefore) {
init(Func, Actual);
setName(Name);
}
CallInst::CallInst(Value *Func, Value* Actual, const std::string &Name,
BasicBlock *InsertAtEnd)
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
->getElementType())->getReturnType(),
Instruction::Call, 0, 0, InsertAtEnd) {
init(Func, Actual);
setName(Name);
}
CallInst::CallInst(Value *Func, const std::string &Name,
Instruction *InsertBefore)
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
->getElementType())->getReturnType(),
Instruction::Call, 0, 0, InsertBefore) {
init(Func);
setName(Name);
}
CallInst::CallInst(Value *Func, const std::string &Name,
BasicBlock *InsertAtEnd)
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
->getElementType())->getReturnType(),
Instruction::Call, 0, 0, InsertAtEnd) {
init(Func);
setName(Name);
}
: Instruction(CI.getType(), Instruction::Call, new Use[CI.getNumOperands()],
CI.getNumOperands()),
ParamAttrs(0) {
setParamAttrs(CI.getParamAttrs());
SubclassData = CI.SubclassData;
Use *OL = OperandList;
Use *InOL = CI.OperandList;
for (unsigned i = 0, e = CI.getNumOperands(); i != e; ++i)
OL[i].init(InOL[i], this);
}
void CallInst::setParamAttrs(const ParamAttrsList *newAttrs) {
if (ParamAttrs == newAttrs)
return;
if (ParamAttrs)
ParamAttrs->dropRef();
if (newAttrs)
newAttrs->addRef();
ParamAttrs = newAttrs;
}
bool CallInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
if (ParamAttrs && ParamAttrs->paramHasAttr(i, attr))
if (const Function *F = getCalledFunction())
return F->paramHasAttr(i, attr);
uint16_t CallInst::getParamAlignment(uint16_t i) const {
if (ParamAttrs && ParamAttrs->getParamAlignment(i))
return ParamAttrs->getParamAlignment(i);
if (const Function *F = getCalledFunction())
return F->getParamAlignment(i);
return 0;
}
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
/// @brief Determine if the call does not access memory.
bool CallInst::doesNotAccessMemory() const {
return paramHasAttr(0, ParamAttr::ReadNone);
}
/// @brief Determine if the call does not access or only reads memory.
bool CallInst::onlyReadsMemory() const {
return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly);
}
/// @brief Determine if the call cannot return.
bool CallInst::doesNotReturn() const {
return paramHasAttr(0, ParamAttr::NoReturn);
}
/// @brief Determine if the call cannot unwind.
bool CallInst::doesNotThrow() const {
return paramHasAttr(0, ParamAttr::NoUnwind);
}
/// @brief Determine if the call returns a structure.
bool CallInst::isStructReturn() const {
// Be friendly and also check the callee.
return paramHasAttr(1, ParamAttr::StructRet);
}
/// @brief Determine if any call argument is an aggregate passed by value.
bool CallInst::hasByValArgument() const {
if (ParamAttrs && ParamAttrs->hasAttrSomewhere(ParamAttr::ByVal))
return true;
// Be consistent with other methods and check the callee too.
if (const Function *F = getCalledFunction())
if (const ParamAttrsList *PAL = F->getParamAttrs())
return PAL->hasAttrSomewhere(ParamAttr::ByVal);
return false;
}
void CallInst::setDoesNotThrow(bool doesNotThrow) {
const ParamAttrsList *PAL = getParamAttrs();
if (doesNotThrow)
PAL = ParamAttrsList::includeAttrs(PAL, 0, ParamAttr::NoUnwind);
else
PAL = ParamAttrsList::excludeAttrs(PAL, 0, ParamAttr::NoUnwind);
setParamAttrs(PAL);
}
//===----------------------------------------------------------------------===//
// InvokeInst Implementation
//===----------------------------------------------------------------------===//
InvokeInst::~InvokeInst() {
delete [] OperandList;
if (ParamAttrs)
ParamAttrs->dropRef();
void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
Value* const *Args, unsigned NumArgs) {
NumOperands = 3+NumArgs;
Use *OL = OperandList = new Use[3+NumArgs];
OL[0].init(Fn, this);
OL[1].init(IfNormal, this);
OL[2].init(IfException, this);
cast<FunctionType>(cast<PointerType>(Fn->getType())->getElementType());
FTy = FTy; // silence warning.
Anton Korobeynikov
committed
assert(((NumArgs == FTy->getNumParams()) ||
(FTy->isVarArg() && NumArgs > FTy->getNumParams())) &&
"Calling a function with bad signature");
for (unsigned i = 0, e = NumArgs; i != e; i++) {
Chris Lattner
committed
assert((i >= FTy->getNumParams() ||
FTy->getParamType(i) == Args[i]->getType()) &&
Chris Lattner
committed
"Invoking a function with a bad signature!");
OL[i+3].init(Args[i], this);
Chris Lattner
committed
}
}
: TerminatorInst(II.getType(), Instruction::Invoke,
new Use[II.getNumOperands()], II.getNumOperands()),
ParamAttrs(0) {
setParamAttrs(II.getParamAttrs());
SubclassData = II.SubclassData;
Use *OL = OperandList, *InOL = II.OperandList;
for (unsigned i = 0, e = II.getNumOperands(); i != e; ++i)
OL[i].init(InOL[i], this);
}
BasicBlock *InvokeInst::getSuccessorV(unsigned idx) const {
return getSuccessor(idx);
}
unsigned InvokeInst::getNumSuccessorsV() const {
return getNumSuccessors();
}
void InvokeInst::setSuccessorV(unsigned idx, BasicBlock *B) {
return setSuccessor(idx, B);
}
void InvokeInst::setParamAttrs(const ParamAttrsList *newAttrs) {
if (ParamAttrs == newAttrs)
return;
if (ParamAttrs)
ParamAttrs->dropRef();
if (newAttrs)
newAttrs->addRef();
ParamAttrs = newAttrs;
}
bool InvokeInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
if (ParamAttrs && ParamAttrs->paramHasAttr(i, attr))
if (const Function *F = getCalledFunction())
return F->paramHasAttr(i, attr);
uint16_t InvokeInst::getParamAlignment(uint16_t i) const {
if (ParamAttrs && ParamAttrs->getParamAlignment(i))
return ParamAttrs->getParamAlignment(i);
if (const Function *F = getCalledFunction())
return F->getParamAlignment(i);
return 0;
}
/// @brief Determine if the call does not access memory.
bool InvokeInst::doesNotAccessMemory() const {
return paramHasAttr(0, ParamAttr::ReadNone);
}
/// @brief Determine if the call does not access or only reads memory.
bool InvokeInst::onlyReadsMemory() const {
return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly);
}
/// @brief Determine if the call cannot return.
bool InvokeInst::doesNotReturn() const {
return paramHasAttr(0, ParamAttr::NoReturn);
}
/// @brief Determine if the call cannot unwind.
bool InvokeInst::doesNotThrow() const {
return paramHasAttr(0, ParamAttr::NoUnwind);
}
void InvokeInst::setDoesNotThrow(bool doesNotThrow) {
const ParamAttrsList *PAL = getParamAttrs();
if (doesNotThrow)
PAL = ParamAttrsList::includeAttrs(PAL, 0, ParamAttr::NoUnwind);
else
PAL = ParamAttrsList::excludeAttrs(PAL, 0, ParamAttr::NoUnwind);
setParamAttrs(PAL);
}
/// @brief Determine if the call returns a structure.
bool InvokeInst::isStructReturn() const {
// Be friendly and also check the callee.
return paramHasAttr(1, ParamAttr::StructRet);
}
//===----------------------------------------------------------------------===//
// ReturnInst Implementation
//===----------------------------------------------------------------------===//
ReturnInst::ReturnInst(const ReturnInst &RI)
: TerminatorInst(Type::VoidTy, Instruction::Ret,
&RetVal, RI.getNumOperands()) {
unsigned N = RI.getNumOperands();
if (N == 1)
RetVal.init(RI.RetVal, this);
else if (N) {
Use *OL = OperandList = new Use[N];
for (unsigned i = 0; i < N; ++i)
OL[i].init(RI.getOperand(i), this);
}
}
ReturnInst::ReturnInst(Value *retVal, Instruction *InsertBefore)
: TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertBefore) {
}
ReturnInst::ReturnInst(Value *retVal, BasicBlock *InsertAtEnd)
: TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
}
ReturnInst::ReturnInst(BasicBlock *InsertAtEnd)
: TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
}
ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
Instruction *InsertBefore)
: TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, N, InsertBefore) {
if (N != 0)
init(retVals, N);
}
ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
BasicBlock *InsertAtEnd)
: TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, N, InsertAtEnd) {
if (N != 0)
init(retVals, N);
}
ReturnInst::ReturnInst(Value * const* retVals, unsigned N)
: TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, N) {
if (N != 0)
init(retVals, N);
}
void ReturnInst::init(Value * const* retVals, unsigned N) {
if (NumOperands == 1) {
if (V->getType() == Type::VoidTy)
return;
}
Use *OL = OperandList = new Use[NumOperands];
for (unsigned i = 0; i < NumOperands; ++i) {
assert(!isa<BasicBlock>(V) &&
"Cannot return basic block. Probably using the incorrect ctor");
}
}
unsigned ReturnInst::getNumSuccessorsV() const {
return getNumSuccessors();
}
/// Out-of-line ReturnInst method, put here so the C++ compiler can choose to
/// emit the vtable for the class in this translation unit.
void ReturnInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) {
assert(0 && "ReturnInst has no successors!");
}
BasicBlock *ReturnInst::getSuccessorV(unsigned idx) const {
assert(0 && "ReturnInst has no successors!");
abort();
return 0;
}
ReturnInst::~ReturnInst() {
if (NumOperands > 1)
delete [] OperandList;
}
//===----------------------------------------------------------------------===//
// UnwindInst Implementation
//===----------------------------------------------------------------------===//
UnwindInst::UnwindInst(Instruction *InsertBefore)
: TerminatorInst(Type::VoidTy, Instruction::Unwind, 0, 0, InsertBefore) {
}
UnwindInst::UnwindInst(BasicBlock *InsertAtEnd)
: TerminatorInst(Type::VoidTy, Instruction::Unwind, 0, 0, InsertAtEnd) {
}
unsigned UnwindInst::getNumSuccessorsV() const {
return getNumSuccessors();
}
void UnwindInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) {
assert(0 && "UnwindInst has no successors!");
}
BasicBlock *UnwindInst::getSuccessorV(unsigned idx) const {
assert(0 && "UnwindInst has no successors!");
abort();
return 0;
}
//===----------------------------------------------------------------------===//
// UnreachableInst Implementation
//===----------------------------------------------------------------------===//
UnreachableInst::UnreachableInst(Instruction *InsertBefore)
: TerminatorInst(Type::VoidTy, Instruction::Unreachable, 0, 0, InsertBefore) {
}
UnreachableInst::UnreachableInst(BasicBlock *InsertAtEnd)
: TerminatorInst(Type::VoidTy, Instruction::Unreachable, 0, 0, InsertAtEnd) {
}
unsigned UnreachableInst::getNumSuccessorsV() const {
return getNumSuccessors();
}
void UnreachableInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) {
assert(0 && "UnwindInst has no successors!");
}
BasicBlock *UnreachableInst::getSuccessorV(unsigned idx) const {
assert(0 && "UnwindInst has no successors!");
abort();
return 0;
//===----------------------------------------------------------------------===//
// BranchInst Implementation
//===----------------------------------------------------------------------===//
void BranchInst::AssertOK() {
if (isConditional())
assert(getCondition()->getType() == Type::Int1Ty &&
"May only branch on boolean predicates!");
}
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
BranchInst::BranchInst(BasicBlock *IfTrue, Instruction *InsertBefore)
: TerminatorInst(Type::VoidTy, Instruction::Br, Ops, 1, InsertBefore) {
assert(IfTrue != 0 && "Branch destination may not be null!");
Ops[0].init(reinterpret_cast<Value*>(IfTrue), this);
}
BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
Instruction *InsertBefore)
: TerminatorInst(Type::VoidTy, Instruction::Br, Ops, 3, InsertBefore) {
Ops[0].init(reinterpret_cast<Value*>(IfTrue), this);
Ops[1].init(reinterpret_cast<Value*>(IfFalse), this);
Ops[2].init(Cond, this);
#ifndef NDEBUG
AssertOK();
#endif
}
BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd)
: TerminatorInst(Type::VoidTy, Instruction::Br, Ops, 1, InsertAtEnd) {
assert(IfTrue != 0 && "Branch destination may not be null!");
Ops[0].init(reinterpret_cast<Value*>(IfTrue), this);
}
BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
BasicBlock *InsertAtEnd)
: TerminatorInst(Type::VoidTy, Instruction::Br, Ops, 3, InsertAtEnd) {
Ops[0].init(reinterpret_cast<Value*>(IfTrue), this);
Ops[1].init(reinterpret_cast<Value*>(IfFalse), this);
Ops[2].init(Cond, this);
#ifndef NDEBUG
AssertOK();
#endif
}
BranchInst::BranchInst(const BranchInst &BI) :
TerminatorInst(Type::VoidTy, Instruction::Br, Ops, BI.getNumOperands()) {
OperandList[0].init(BI.getOperand(0), this);
if (BI.getNumOperands() != 1) {
assert(BI.getNumOperands() == 3 && "BR can have 1 or 3 operands!");
OperandList[1].init(BI.getOperand(1), this);
OperandList[2].init(BI.getOperand(2), this);
}
}
BasicBlock *BranchInst::getSuccessorV(unsigned idx) const {
return getSuccessor(idx);
}
unsigned BranchInst::getNumSuccessorsV() const {
return getNumSuccessors();
}
void BranchInst::setSuccessorV(unsigned idx, BasicBlock *B) {
setSuccessor(idx, B);
}
//===----------------------------------------------------------------------===//
// AllocationInst Implementation
//===----------------------------------------------------------------------===//
static Value *getAISize(Value *Amt) {
if (!Amt)
else {
assert(!isa<BasicBlock>(Amt) &&
"Passed basic block into allocation size parameter! Use other ctor");
"Malloc/Allocation array size is not a 32-bit integer!");
}
AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy,
unsigned Align, const std::string &Name,
Instruction *InsertBefore)
Christopher Lamb
committed
: UnaryInstruction(PointerType::getUnqual(Ty), iTy, getAISize(ArraySize),
InsertBefore), Alignment(Align) {
assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
assert(Ty != Type::VoidTy && "Cannot allocate void!");
Chris Lattner
committed
setName(Name);
}
AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy,
unsigned Align, const std::string &Name,
BasicBlock *InsertAtEnd)
Christopher Lamb
committed
: UnaryInstruction(PointerType::getUnqual(Ty), iTy, getAISize(ArraySize),
InsertAtEnd), Alignment(Align) {
assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
assert(Ty != Type::VoidTy && "Cannot allocate void!");
Chris Lattner
committed
setName(Name);
}
// Out of line virtual method, so the vtable, etc has a home.
AllocationInst::~AllocationInst() {
}
bool AllocationInst::isArrayAllocation() const {
if (ConstantInt *CI = dyn_cast<ConstantInt>(getOperand(0)))
return CI->getZExtValue() != 1;
}
const Type *AllocationInst::getAllocatedType() const {
return getType()->getElementType();
}
AllocaInst::AllocaInst(const AllocaInst &AI)
: AllocationInst(AI.getType()->getElementType(), (Value*)AI.getOperand(0),
Instruction::Alloca, AI.getAlignment()) {
}
MallocInst::MallocInst(const MallocInst &MI)
: AllocationInst(MI.getType()->getElementType(), (Value*)MI.getOperand(0),
Instruction::Malloc, MI.getAlignment()) {
}
//===----------------------------------------------------------------------===//
// FreeInst Implementation
//===----------------------------------------------------------------------===//
void FreeInst::AssertOK() {
assert(isa<PointerType>(getOperand(0)->getType()) &&
"Can not free something of nonpointer type!");
}
FreeInst::FreeInst(Value *Ptr, Instruction *InsertBefore)
: UnaryInstruction(Type::VoidTy, Free, Ptr, InsertBefore) {
}
FreeInst::FreeInst(Value *Ptr, BasicBlock *InsertAtEnd)
: UnaryInstruction(Type::VoidTy, Free, Ptr, InsertAtEnd) {
}
//===----------------------------------------------------------------------===//
// LoadInst Implementation
//===----------------------------------------------------------------------===//
assert(isa<PointerType>(getOperand(0)->getType()) &&
"Ptr must have pointer type.");
}
LoadInst::LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBef)
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertBef) {
setVolatile(false);
Christopher Lamb
committed
setAlignment(0);
Chris Lattner
committed
setName(Name);
}
LoadInst::LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAE)
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertAE) {
setVolatile(false);
Christopher Lamb
committed
setAlignment(0);
Chris Lattner
committed
setName(Name);
}
LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
Instruction *InsertBef)
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertBef) {
setVolatile(isVolatile);
Christopher Lamb
committed
setAlignment(0);
AssertOK();
setName(Name);
}
LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
unsigned Align, Instruction *InsertBef)
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertBef) {
setVolatile(isVolatile);
setAlignment(Align);
Chris Lattner
committed
setName(Name);
}
LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
unsigned Align, BasicBlock *InsertAE)
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertAE) {
setVolatile(isVolatile);
setAlignment(Align);
AssertOK();
setName(Name);
}
LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
BasicBlock *InsertAE)
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertAE) {
Chris Lattner
committed
setVolatile(isVolatile);
Christopher Lamb
committed
setAlignment(0);
Chris Lattner
committed
AssertOK();
setName(Name);
}
LoadInst::LoadInst(Value *Ptr, const char *Name, Instruction *InsertBef)
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertBef) {
Chris Lattner
committed
setVolatile(false);
Christopher Lamb
committed
setAlignment(0);
Chris Lattner
committed
AssertOK();
if (Name && Name[0]) setName(Name);
Chris Lattner
committed
}
LoadInst::LoadInst(Value *Ptr, const char *Name, BasicBlock *InsertAE)
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertAE) {
Chris Lattner
committed
setVolatile(false);
Christopher Lamb
committed
setAlignment(0);
Chris Lattner
committed
AssertOK();
if (Name && Name[0]) setName(Name);
Chris Lattner
committed
}
LoadInst::LoadInst(Value *Ptr, const char *Name, bool isVolatile,
Instruction *InsertBef)
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertBef) {
Chris Lattner
committed
setVolatile(isVolatile);
Christopher Lamb
committed
setAlignment(0);
Chris Lattner
committed
AssertOK();
if (Name && Name[0]) setName(Name);
Chris Lattner
committed
}
LoadInst::LoadInst(Value *Ptr, const char *Name, bool isVolatile,
BasicBlock *InsertAE)
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertAE) {
setVolatile(isVolatile);
Christopher Lamb
committed
setAlignment(0);
if (Name && Name[0]) setName(Name);
}
Christopher Lamb
committed
void LoadInst::setAlignment(unsigned Align) {
assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
SubclassData = (SubclassData & 1) | ((Log2_32(Align)+1)<<1);
}
//===----------------------------------------------------------------------===//
// StoreInst Implementation
//===----------------------------------------------------------------------===//
void StoreInst::AssertOK() {
assert(isa<PointerType>(getOperand(1)->getType()) &&
"Ptr must have pointer type!");
assert(getOperand(0)->getType() ==
cast<PointerType>(getOperand(1)->getType())->getElementType()
&& "Ptr must be a pointer to Val type!");
}
StoreInst::StoreInst(Value *val, Value *addr, Instruction *InsertBefore)
: Instruction(Type::VoidTy, Store, Ops, 2, InsertBefore) {
Ops[0].init(val, this);
Ops[1].init(addr, this);
setVolatile(false);
Christopher Lamb
committed
setAlignment(0);
}
StoreInst::StoreInst(Value *val, Value *addr, BasicBlock *InsertAtEnd)
: Instruction(Type::VoidTy, Store, Ops, 2, InsertAtEnd) {
Ops[0].init(val, this);
Ops[1].init(addr, this);
setVolatile(false);
Christopher Lamb
committed
setAlignment(0);