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/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/Instructions.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 PAListPtr &CallSite::getParamAttrs() const {
if (CallInst *CI = dyn_cast<CallInst>(I))
return CI->getParamAttrs();
else
return cast<InvokeInst>(I)->getParamAttrs();
}
void CallSite::setParamAttrs(const PAListPtr &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);
}
bool CallSite::hasArgument(const Value *Arg) const {
Matthijs Kooijman
committed
for (arg_iterator AI = this->arg_begin(), E = this->arg_end(); AI != E; ++AI)
if (AI->get() == Arg)
return true;
return false;
}
//===----------------------------------------------------------------------===//
// TerminatorInst Class
//===----------------------------------------------------------------------===//
// Out of line virtual method, so the vtable, etc has a home.
TerminatorInst::~TerminatorInst() {
}
//===----------------------------------------------------------------------===//
// UnaryInstruction Class
//===----------------------------------------------------------------------===//
// 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,
allocHungoffUses(PN.getNumOperands()), PN.getNumOperands()),
ReservedSpace(PN.getNumOperands()) {
Use *OL = OperandList;
for (unsigned i = 0, e = PN.getNumOperands(); i != e; i+=2) {
OL[i] = PN.getOperand(i);
OL[i+1] = PN.getOperand(i+1);
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 < 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 *OldOps = OperandList;
Use *NewOps = allocHungoffUses(NumOps);
for (unsigned i = 0; i != e; ++i) {
NewOps[i] = OldOps[i];
if (OldOps) Use::zap(OldOps, OldOps + e, true);
/// 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
//===----------------------------------------------------------------------===//
void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) {
assert(NumOperands == NumParams+1 && "NumOperands not set up?");
Use *OL = OperandList;
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) {
assert(NumOperands == 3 && "NumOperands not set up?");
Use *OL = OperandList;
OL[0] = Func;
OL[1] = Actual1;
OL[2] = Actual2;
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) {
assert(NumOperands == 2 && "NumOperands not set up?");
Use *OL = OperandList;
OL[0] = Func;
OL[1] = Actual;
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!");
}
assert(NumOperands == 1 && "NumOperands not set up?");
Use *OL = OperandList;
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,
OperandTraits<CallInst>::op_end(this) - 2,
2, 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,
OperandTraits<CallInst>::op_end(this) - 2,
2, 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,
OperandTraits<CallInst>::op_end(this) - 1,
1, 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,
OperandTraits<CallInst>::op_end(this) - 1,
1, InsertAtEnd) {
init(Func);
setName(Name);
}
: Instruction(CI.getType(), Instruction::Call,
OperandTraits<CallInst>::op_end(this) - CI.getNumOperands(),
CI.getNumOperands()) {
setParamAttrs(CI.getParamAttrs());
SubclassData = CI.SubclassData;
Use *OL = OperandList;
Use *InOL = CI.OperandList;
for (unsigned i = 0, e = CI.getNumOperands(); i != e; ++i)
}
void CallInst::addParamAttr(unsigned i, ParameterAttributes attr) {
PAListPtr PAL = getParamAttrs();
PAL = PAL.addAttr(i, attr);
setParamAttrs(PAL);
}
bool CallInst::paramHasAttr(unsigned i, ParameterAttributes attr) const {
if (ParamAttrs.paramHasAttr(i, attr))
if (const Function *F = getCalledFunction())
return F->paramHasAttr(i, attr);
void CallInst::setDoesNotThrow(bool doesNotThrow) {
PAListPtr PAL = getParamAttrs();
PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
PAL = PAL.removeAttr(0, ParamAttr::NoUnwind);
setParamAttrs(PAL);
}
//===----------------------------------------------------------------------===//
// InvokeInst Implementation
//===----------------------------------------------------------------------===//
void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
Value* const *Args, unsigned NumArgs) {
assert(NumOperands == 3+NumArgs && "NumOperands not set up?");
Use *OL = OperandList;
OL[0] = Fn;
OL[1] = IfNormal;
OL[2] = IfException;
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!");
Chris Lattner
committed
}
}
: TerminatorInst(II.getType(), Instruction::Invoke,
Gabor Greif
committed
OperandTraits<InvokeInst>::op_end(this)
- II.getNumOperands(),
setParamAttrs(II.getParamAttrs());
SubclassData = II.SubclassData;
Use *OL = OperandList, *InOL = II.OperandList;
for (unsigned i = 0, e = II.getNumOperands(); i != e; ++i)
}
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);
}
bool InvokeInst::paramHasAttr(unsigned i, ParameterAttributes attr) const {
if (ParamAttrs.paramHasAttr(i, attr))
if (const Function *F = getCalledFunction())
return F->paramHasAttr(i, attr);
void InvokeInst::addParamAttr(unsigned i, ParameterAttributes attr) {
PAListPtr PAL = getParamAttrs();
PAL = PAL.addAttr(i, attr);
setParamAttrs(PAL);
}
void InvokeInst::setDoesNotThrow(bool doesNotThrow) {
PAListPtr PAL = getParamAttrs();
PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
PAL = PAL.removeAttr(0, ParamAttr::NoUnwind);
setParamAttrs(PAL);
}
//===----------------------------------------------------------------------===//
// ReturnInst Implementation
//===----------------------------------------------------------------------===//
ReturnInst::ReturnInst(const ReturnInst &RI)
: TerminatorInst(Type::VoidTy, Instruction::Ret,
Gabor Greif
committed
OperandTraits<ReturnInst>::op_end(this)
- RI.getNumOperands(),
unsigned N = RI.getNumOperands();
else if (N) {
for (unsigned i = 0; i < N; ++i)
OL[i] = RI.getOperand(i);
}
ReturnInst::ReturnInst(Value *retVal, Instruction *InsertBefore)
: TerminatorInst(Type::VoidTy, Instruction::Ret,
OperandTraits<ReturnInst>::op_end(this) - (retVal != 0),
retVal != 0, InsertBefore) {
}
ReturnInst::ReturnInst(Value *retVal, BasicBlock *InsertAtEnd)
: TerminatorInst(Type::VoidTy, Instruction::Ret,
OperandTraits<ReturnInst>::op_end(this) - (retVal != 0),
retVal != 0, InsertAtEnd) {
}
ReturnInst::ReturnInst(BasicBlock *InsertAtEnd)
: TerminatorInst(Type::VoidTy, Instruction::Ret,
OperandTraits<ReturnInst>::op_end(this),
0, InsertAtEnd) {
}
ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
Instruction *InsertBefore)
: TerminatorInst(Type::VoidTy, Instruction::Ret,
OperandTraits<ReturnInst>::op_end(this) - N,
N, InsertBefore) {
if (N != 0)
init(retVals, N);
}
ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
BasicBlock *InsertAtEnd)
: TerminatorInst(Type::VoidTy, Instruction::Ret,
OperandTraits<ReturnInst>::op_end(this) - N,
N, InsertAtEnd) {
if (N != 0)
init(retVals, N);
}
void ReturnInst::init(Value * const* retVals, unsigned N) {
if (NumOperands == 1) {
if (V->getType() == Type::VoidTy)
return;
}
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() {
}
//===----------------------------------------------------------------------===//
// 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!");
}
BranchInst::BranchInst(BasicBlock *IfTrue, Instruction *InsertBefore)
: TerminatorInst(Type::VoidTy, Instruction::Br,
OperandTraits<BranchInst>::op_end(this) - 1,
1, InsertBefore) {
assert(IfTrue != 0 && "Branch destination may not be null!");
Gabor Greif
committed
Op<0>() = IfTrue;
}
BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
Instruction *InsertBefore)
: TerminatorInst(Type::VoidTy, Instruction::Br,
OperandTraits<BranchInst>::op_end(this) - 3,
3, InsertBefore) {
Gabor Greif
committed
Op<0>() = IfTrue;
Op<1>() = IfFalse;
#ifndef NDEBUG
AssertOK();
#endif
}
BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd)
: TerminatorInst(Type::VoidTy, Instruction::Br,
OperandTraits<BranchInst>::op_end(this) - 1,
1, InsertAtEnd) {
assert(IfTrue != 0 && "Branch destination may not be null!");
Gabor Greif
committed
Op<0>() = IfTrue;
}
BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
BasicBlock *InsertAtEnd)
: TerminatorInst(Type::VoidTy, Instruction::Br,
OperandTraits<BranchInst>::op_end(this) - 3,
3, InsertAtEnd) {
Gabor Greif
committed
Op<0>() = IfTrue;
Op<1>() = IfFalse;
#ifndef NDEBUG
AssertOK();
#endif
}
BranchInst::BranchInst(const BranchInst &BI) :
TerminatorInst(Type::VoidTy, Instruction::Br,
OperandTraits<BranchInst>::op_end(this) - BI.getNumOperands(),
BI.getNumOperands()) {
OperandList[0] = BI.getOperand(0);
if (BI.getNumOperands() != 1) {
assert(BI.getNumOperands() == 3 && "BR can have 1 or 3 operands!");
OperandList[1] = BI.getOperand(1);
OperandList[2] = BI.getOperand(2);
}
}
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) {
setAlignment(Align);
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) {
setAlignment(Align);
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() {
}
void AllocationInst::setAlignment(unsigned Align) {
assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
SubclassData = Log2_32(Align) + 1;
assert(getAlignment() == Align && "Alignment representation error!");
}
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,
OperandTraits<StoreInst>::op_begin(this),
OperandTraits<StoreInst>::operands(this),
InsertBefore) {
Op<0>() = val;
Op<1>() = addr;
setVolatile(false);
Christopher Lamb
committed
setAlignment(0);
}
StoreInst::StoreInst(Value *val, Value *addr, BasicBlock *InsertAtEnd)
: Instruction(Type::VoidTy, Store,
OperandTraits<StoreInst>::op_begin(this),
OperandTraits<StoreInst>::operands(this),
InsertAtEnd) {
Op<0>() = val;
Op<1>() = addr;
setVolatile(false);
Christopher Lamb
committed
setAlignment(0);
}
StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
: Instruction(Type::VoidTy, Store,
OperandTraits<StoreInst>::op_begin(this),
OperandTraits<StoreInst>::operands(this),
InsertBefore) {
Op<0>() = val;
Op<1>() = addr;
setVolatile(isVolatile);
Christopher Lamb
committed
setAlignment(0);
AssertOK();
}
StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
unsigned Align, Instruction *InsertBefore)
: Instruction(Type::VoidTy, Store,
OperandTraits<StoreInst>::op_begin(this),
OperandTraits<StoreInst>::operands(this),
InsertBefore) {
Op<0>() = val;
Op<1>() = addr;
Christopher Lamb
committed
setVolatile(isVolatile);
setAlignment(Align);
StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
unsigned Align, BasicBlock *InsertAtEnd)
: Instruction(Type::VoidTy, Store,
OperandTraits<StoreInst>::op_begin(this),
OperandTraits<StoreInst>::operands(this),
InsertAtEnd) {
Op<0>() = val;
Op<1>() = addr;
setVolatile(isVolatile);
setAlignment(Align);
AssertOK();
}
StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
: Instruction(Type::VoidTy, Store,
OperandTraits<StoreInst>::op_begin(this),
OperandTraits<StoreInst>::operands(this),
InsertAtEnd) {
Op<0>() = val;
Op<1>() = addr;
setVolatile(isVolatile);
Christopher Lamb
committed
setAlignment(0);
}
Christopher Lamb
committed
void StoreInst::setAlignment(unsigned Align) {
assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
SubclassData = (SubclassData & 1) | ((Log2_32(Align)+1)<<1);
}
//===----------------------------------------------------------------------===//
// GetElementPtrInst Implementation
//===----------------------------------------------------------------------===//
Christopher Lamb
committed
static unsigned retrieveAddrSpace(const Value *Val) {
return cast<PointerType>(Val->getType())->getAddressSpace();