#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
+#include "llvm/ParameterAttributes.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/ConstantRange.h"
+#include "llvm/Support/MathExtras.h"
using namespace llvm;
unsigned CallSite::getCallingConv() const {
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()->front() ||
+ if (IV->getParent() != &IV->getParent()->getParent()->getEntryBlock() ||
isa<InvokeInst>(IV))
return 0; // Cannot guarantee that InVal dominates this PHINode.
CallInst::~CallInst() {
delete [] OperandList;
+ if (ParamAttrs)
+ ParamAttrs->dropRef();
}
void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) {
+ ParamAttrs = 0;
NumOperands = NumParams+1;
Use *OL = OperandList = new Use[NumParams+1];
OL[0].init(Func, this);
}
void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) {
+ ParamAttrs = 0;
NumOperands = 3;
Use *OL = OperandList = new Use[3];
OL[0].init(Func, this);
}
void CallInst::init(Value *Func, Value *Actual) {
+ ParamAttrs = 0;
NumOperands = 2;
Use *OL = OperandList = new Use[2];
OL[0].init(Func, this);
}
void CallInst::init(Value *Func) {
+ ParamAttrs = 0;
NumOperands = 1;
Use *OL = OperandList = new Use[1];
OL[0].init(Func, this);
assert(FTy->getNumParams() == 0 && "Calling a function with bad signature");
}
+#if 0
+// Leave for llvm-gcc
CallInst::CallInst(Value *Func, Value* const *Args, unsigned NumArgs,
const std::string &Name, BasicBlock *InsertAtEnd)
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
- ->getElementType())->getReturnType(),
+ ->getElementType())->getReturnType(),
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) {
+ : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
+ ->getElementType())->getReturnType(),
+ Instruction::Call, 0, 0, InsertBefore) {
init(Func, Args, NumArgs);
setName(Name);
}
init(Func, Actual1, Actual2);
setName(Name);
}
-
+#endif
CallInst::CallInst(Value *Func, Value* Actual, const std::string &Name,
Instruction *InsertBefore)
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
init(Func, Actual);
setName(Name);
}
-
CallInst::CallInst(Value *Func, const std::string &Name,
Instruction *InsertBefore)
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
CallInst::CallInst(const CallInst &CI)
: Instruction(CI.getType(), Instruction::Call, new Use[CI.getNumOperands()],
CI.getNumOperands()) {
+ ParamAttrs = 0;
SubclassData = CI.SubclassData;
Use *OL = OperandList;
Use *InOL = CI.OperandList;
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;
+ if (ParamAttrs)
+ ParamAttrs->dropRef();
}
void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
Value* const *Args, unsigned NumArgs) {
+ ParamAttrs = 0;
NumOperands = 3+NumArgs;
Use *OL = OperandList = new Use[3+NumArgs];
OL[0].init(Fn, this);
InvokeInst::InvokeInst(const InvokeInst &II)
: TerminatorInst(II.getType(), Instruction::Invoke,
new Use[II.getNumOperands()], II.getNumOperands()) {
+ ParamAttrs = 0;
SubclassData = II.SubclassData;
Use *OL = OperandList, *InOL = II.OperandList;
for (unsigned i = 0, e = II.getNumOperands(); i != e; ++i)
return setSuccessor(idx, B);
}
+void InvokeInst::setParamAttrs(ParamAttrsList *newAttrs) {
+ if (ParamAttrs)
+ ParamAttrs->dropRef();
+
+ if (newAttrs)
+ newAttrs->addRef();
+
+ ParamAttrs = newAttrs;
+}
//===----------------------------------------------------------------------===//
// ReturnInst Implementation
}
bool AllocationInst::isArrayAllocation() const {
- if (ConstantInt *CUI = dyn_cast<ConstantInt>(getOperand(0)))
- return CUI->getZExtValue() != 1;
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(getOperand(0)))
+ return CI->getZExtValue() != 1;
return true;
}
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertBef) {
setVolatile(false);
+ setAlignment(0);
AssertOK();
setName(Name);
}
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertAE) {
setVolatile(false);
+ setAlignment(0);
AssertOK();
setName(Name);
}
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertBef) {
setVolatile(isVolatile);
+ 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);
+ AssertOK();
+ 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);
}
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertAE) {
setVolatile(isVolatile);
+ setAlignment(0);
AssertOK();
setName(Name);
}
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertBef) {
setVolatile(false);
+ setAlignment(0);
AssertOK();
if (Name && Name[0]) setName(Name);
}
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertAE) {
setVolatile(false);
+ setAlignment(0);
AssertOK();
if (Name && Name[0]) setName(Name);
}
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertBef) {
setVolatile(isVolatile);
+ setAlignment(0);
AssertOK();
if (Name && Name[0]) setName(Name);
}
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertAE) {
setVolatile(isVolatile);
+ setAlignment(0);
AssertOK();
if (Name && Name[0]) setName(Name);
}
+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
Ops[0].init(val, this);
Ops[1].init(addr, this);
setVolatile(false);
+ setAlignment(0);
AssertOK();
}
Ops[0].init(val, this);
Ops[1].init(addr, this);
setVolatile(false);
+ setAlignment(0);
AssertOK();
}
Ops[0].init(val, this);
Ops[1].init(addr, this);
setVolatile(isVolatile);
+ 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);
+ AssertOK();
+}
+
+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();
}
Ops[0].init(val, this);
Ops[1].init(addr, this);
setVolatile(isVolatile);
+ setAlignment(0);
AssertOK();
}
+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
//===----------------------------------------------------------------------===//
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
//===----------------------------------------------------------------------===//
return false; // First operand of insertelement must be vector type.
if (Elt->getType() != cast<VectorType>(Vec->getType())->getElementType())
- return false;// Second operand of insertelement must be packed element type.
+ return false;// Second operand of insertelement must be vector element type.
if (Index->getType() != Type::Int32Ty)
return false; // Third operand of insertelement must be uint.
// isConstantAllOnes - Helper function for several functions below
static inline bool isConstantAllOnes(const Value *V) {
- return isa<ConstantInt>(V) &&cast<ConstantInt>(V)->isAllOnesValue();
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
+ return CI->isAllOnesValue();
+ if (const ConstantVector *CV = dyn_cast<ConstantVector>(V))
+ return CV->isAllOnesValue();
+ return false;
}
bool BinaryOperator::isNeg(const Value *V) {
/// example, the following are all no-op casts:
/// # bitcast uint %X, int
/// # bitcast uint* %x, sbyte*
-/// # bitcast packed< 2 x int > %x, packed< 4 x short>
+/// # bitcast vector< 2 x int > %x, vector< 4 x short>
/// # ptrtoint uint* %x, uint ; on 32-bit plaforms only
/// @brief Determine if a cast is a no-op.
bool CastInst::isNoopCast(const Type *IntPtrTy) const {
const Value *Src, bool SrcIsSigned, const Type *DestTy, bool DestIsSigned) {
// Get the bit sizes, we'll need these
const Type *SrcTy = Src->getType();
- unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr/packed
- unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr/packed
+ unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr/vector
+ unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr/vector
// Run through the possibilities ...
if (DestTy->isInteger()) { // Casting to integral
return FPToUI; // FP -> uint
} else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
assert(DestBits == PTy->getBitWidth() &&
- "Casting packed to integer of different width");
+ "Casting vector to integer of different width");
return BitCast; // Same size, no-op cast
} else {
assert(isa<PointerType>(SrcTy) &&
}
} else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
assert(DestBits == PTy->getBitWidth() &&
- "Casting packed to floating point of different width");
+ "Casting vector to floating point of different width");
return BitCast; // same size, no-op cast
} else {
assert(0 && "Casting pointer or non-first class to float");
} else if (const VectorType *DestPTy = dyn_cast<VectorType>(DestTy)) {
if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) {
assert(DestPTy->getBitWidth() == SrcPTy->getBitWidth() &&
- "Casting packed to packed of different widths");
- return BitCast; // packed -> packed
+ "Casting vector to vector of different widths");
+ return BitCast; // vector -> vector
} else if (DestPTy->getBitWidth() == SrcBits) {
- return BitCast; // float/int -> packed
+ return BitCast; // float/int -> vector
} else {
- assert(!"Illegal cast to packed (wrong type or size)");
+ assert(!"Illegal cast to vector (wrong type or size)");
}
} else if (isa<PointerType>(DestTy)) {
if (isa<PointerType>(SrcTy)) {
Ops[0].init(LHS, this);
Ops[1].init(RHS, this);
SubclassData = predicate;
+ setName(Name);
if (op == Instruction::ICmp) {
assert(predicate >= ICmpInst::FIRST_ICMP_PREDICATE &&
predicate <= ICmpInst::LAST_ICMP_PREDICATE &&
// Check that the operands are the right type
assert(Op0Ty->isFloatingPoint() &&
"Invalid operand types for FCmp instruction");
- setName(Name);
}
CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS,
Ops[0].init(LHS, this);
Ops[1].init(RHS, this);
SubclassData = predicate;
+ setName(Name);
if (op == Instruction::ICmp) {
assert(predicate >= ICmpInst::FIRST_ICMP_PREDICATE &&
predicate <= ICmpInst::LAST_ICMP_PREDICATE &&
// Check that the operands are the right type
assert(Op0Ty->isFloatingPoint() &&
"Invalid operand types for FCmp instruction");
- setName(Name);
}
CmpInst *
return create(getOpcode(), Ops[0], Ops[1]);
}
-CmpInst* CmpInst::clone() const {
- return create(getOpcode(), getPredicate(), Ops[0], Ops[1]);
+FCmpInst* FCmpInst::clone() const {
+ return new FCmpInst(getPredicate(), Ops[0], Ops[1]);
+}
+ICmpInst* ICmpInst::clone() const {
+ return new ICmpInst(getPredicate(), Ops[0], Ops[1]);
}
MallocInst *MallocInst::clone() const { return new MallocInst(*this); }