Newer
Older
//===-- 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"
#include "llvm/Support/ConstantRange.h"
Christopher Lamb
committed
#include "llvm/Support/MathExtras.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);
}
Chris Lattner
committed
//===----------------------------------------------------------------------===//
// TerminatorInst Class
//===----------------------------------------------------------------------===//
Chris Lattner
committed
// 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() {
}
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//===----------------------------------------------------------------------===//
// 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 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...
if (getNumIncomingValues() == 1)
if (getIncomingValue(0) != this) // not X = phi X
return getIncomingValue(0);
else
return UndefValue::get(getType()); // Self cycle is dead.
// 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)
if (isa<UndefValue>(getIncomingValue(i)))
HasUndefInput = true;
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);
// 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;
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* const *Args, unsigned NumArgs,
const std::string &Name, BasicBlock *InsertAtEnd)
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
Instruction::Call, 0, 0, InsertAtEnd) {
init(Func, Args, NumArgs);
setName(Name);
}
CallInst::CallInst(Value *Func, Value* const *Args, unsigned NumArgs,
const std::string &Name, Instruction *InsertBefore)
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
->getElementType())->getReturnType(),
Instruction::Call, 0, 0, InsertBefore) {
init(Func, Args, NumArgs);
setName(Name);
CallInst::CallInst(Value *Func, Value *Actual1, Value *Actual2,
const std::string &Name, Instruction *InsertBefore)
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
->getElementType())->getReturnType(),
Instruction::Call, 0, 0, InsertBefore) {
init(Func, Actual1, Actual2);
setName(Name);
}
CallInst::CallInst(Value *Func, Value *Actual1, Value *Actual2,
const std::string &Name, BasicBlock *InsertAtEnd)
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
->getElementType())->getReturnType(),
Instruction::Call, 0, 0, InsertAtEnd) {
init(Func, Actual1, Actual2);
setName(Name);
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()) {
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(ParamAttrsList *newAttrs) {
if (ParamAttrs)
ParamAttrs->dropRef();
if (newAttrs)
newAttrs->addRef();
ParamAttrs = newAttrs;
}
//===----------------------------------------------------------------------===//
// InvokeInst Implementation
//===----------------------------------------------------------------------===//
InvokeInst::~InvokeInst() {
delete [] OperandList;
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.
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()) {
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(ParamAttrsList *newAttrs) {
if (ParamAttrs)
ParamAttrs->dropRef();
if (newAttrs)
newAttrs->addRef();
ParamAttrs = newAttrs;
}
//===----------------------------------------------------------------------===//
// ReturnInst Implementation
//===----------------------------------------------------------------------===//
ReturnInst::ReturnInst(const ReturnInst &RI)
: TerminatorInst(Type::VoidTy, Instruction::Ret,
&RetVal, RI.getNumOperands()) {
if (RI.getNumOperands())
RetVal.init(RI.RetVal, this);
}
ReturnInst::ReturnInst(Value *retVal, Instruction *InsertBefore)
: TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertBefore) {
init(retVal);
}
ReturnInst::ReturnInst(Value *retVal, BasicBlock *InsertAtEnd)
: TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
init(retVal);
}
ReturnInst::ReturnInst(BasicBlock *InsertAtEnd)
: TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
}
void ReturnInst::init(Value *retVal) {
if (retVal && retVal->getType() != Type::VoidTy) {
"Cannot return basic block. Probably using the incorrect ctor");
NumOperands = 1;
RetVal.init(retVal, this);
}
}
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;
}
//===----------------------------------------------------------------------===//
// 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!");
}
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
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)
: UnaryInstruction(PointerType::get(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)
: UnaryInstruction(PointerType::get(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);
}
Chris Lattner
committed
// 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);
}
StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
: Instruction(Type::VoidTy, Store, Ops, 2, InsertBefore) {
Ops[0].init(val, this);
Ops[1].init(addr, this);
setVolatile(isVolatile);
Christopher Lamb
committed
setAlignment(0);
AssertOK();
}
StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
unsigned Align, Instruction *InsertBefore)
: Instruction(Type::VoidTy, Store, Ops, 2, InsertBefore) {
Ops[0].init(val, this);
Ops[1].init(addr, this);
setVolatile(isVolatile);
setAlignment(Align);
StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
unsigned Align, BasicBlock *InsertAtEnd)
: Instruction(Type::VoidTy, Store, Ops, 2, InsertAtEnd) {
Ops[0].init(val, this);
Ops[1].init(addr, this);
setVolatile(isVolatile);
setAlignment(Align);
AssertOK();
}
StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
: Instruction(Type::VoidTy, Store, Ops, 2, InsertAtEnd) {
Ops[0].init(val, this);
Ops[1].init(addr, this);
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
//===----------------------------------------------------------------------===//
void GetElementPtrInst::init(Value *Ptr, Value* const *Idx, unsigned NumIdx) {
NumOperands = 1+NumIdx;
Use *OL = OperandList = new Use[NumOperands];
OL[0].init(Ptr, this);
for (unsigned i = 0; i != NumIdx; ++i)
}
void GetElementPtrInst::init(Value *Ptr, Value *Idx) {
NumOperands = 2;
Use *OL = OperandList = new Use[2];
OL[0].init(Ptr, this);
OL[1].init(Idx, this);
}
GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx,
const std::string &Name, Instruction *InBe)
: Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),Idx))),
GetElementPtr, 0, 0, InBe) {
setName(Name);
}
GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx,
const std::string &Name, BasicBlock *IAE)
: Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),Idx))),
GetElementPtr, 0, 0, IAE) {
setName(Name);
GetElementPtrInst::~GetElementPtrInst() {
delete[] OperandList;
}
// getIndexedType - Returns the type of the element that would be loaded with
// a load instruction with the specified parameters.
//
// A null type is returned if the indices are invalid for the specified
// pointer type.
//
const Type* GetElementPtrInst::getIndexedType(const Type *Ptr,
Chris Lattner
committed
Value* const *Idxs,
unsigned NumIdx,
bool AllowCompositeLeaf) {
if (!isa<PointerType>(Ptr)) return 0; // Type isn't a pointer type!
// Handle the special case of the empty set index set...
Chris Lattner
committed
if (NumIdx == 0)
if (AllowCompositeLeaf ||
cast<PointerType>(Ptr)->getElementType()->isFirstClassType())
return cast<PointerType>(Ptr)->getElementType();
else
return 0;
unsigned CurIdx = 0;
while (const CompositeType *CT = dyn_cast<CompositeType>(Ptr)) {
Chris Lattner
committed
if (NumIdx == CurIdx) {
if (AllowCompositeLeaf || CT->isFirstClassType()) return Ptr;
return 0; // Can't load a whole structure or array!?!?
}
Chris Lattner
committed
Value *Index = Idxs[CurIdx++];
if (isa<PointerType>(CT) && CurIdx != 1)
return 0; // Can only index into pointer types at the first index!
if (!CT->indexValid(Index)) return 0;
Ptr = CT->getTypeAtIndex(Index);
// If the new type forwards to another type, then it is in the middle
// of being refined to another type (and hence, may have dropped all
// references to what it was using before). So, use the new forwarded
// type.
if (const Type * Ty = Ptr->getForwardedType()) {
Ptr = Ty;
}
}
Chris Lattner
committed
return CurIdx == NumIdx ? Ptr : 0;
}
const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, Value *Idx) {
const PointerType *PTy = dyn_cast<PointerType>(Ptr);
if (!PTy) return 0; // Type isn't a pointer type!
// Check the pointer index.
if (!PTy->indexValid(Idx)) return 0;
return PTy->getElementType();
/// hasAllZeroIndices - Return true if all of the indices of this GEP are
/// zeros. If so, the result pointer and the first operand have the same
/// value, just potentially different types.
bool GetElementPtrInst::hasAllZeroIndices() const {
for (unsigned i = 1, e = getNumOperands(); i != e; ++i) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(getOperand(i))) {
if (!CI->isZero()) return false;
} else {
return false;
}
}
return true;
}
/// hasAllConstantIndices - Return true if all of the indices of this GEP are
/// constant integers. If so, the result pointer and the first operand have
/// a constant offset between them.
bool GetElementPtrInst::hasAllConstantIndices() const {
for (unsigned i = 1, e = getNumOperands(); i != e; ++i) {
if (!isa<ConstantInt>(getOperand(i)))
return false;
}
return true;
}
//===----------------------------------------------------------------------===//
// ExtractElementInst Implementation
//===----------------------------------------------------------------------===//
ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
const std::string &Name,
Instruction *InsertBef)
: Instruction(cast<VectorType>(Val->getType())->getElementType(),
ExtractElement, Ops, 2, InsertBef) {
Chris Lattner
committed
assert(isValidOperands(Val, Index) &&
"Invalid extractelement instruction operands!");
Ops[0].init(Val, this);
Ops[1].init(Index, this);
setName(Name);
ExtractElementInst::ExtractElementInst(Value *Val, unsigned IndexV,