#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/ConstantRange.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Streams.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
// CallSite Class
//===----------------------------------------------------------------------===//
+#define CALLSITE_DELEGATE_GETTER(METHOD) \
+ Instruction *II(getInstruction()); \
+ return isCall() \
+ ? cast<CallInst>(II)->METHOD \
+ : cast<InvokeInst>(II)->METHOD
+
+#define CALLSITE_DELEGATE_SETTER(METHOD) \
+ Instruction *II(getInstruction()); \
+ if (isCall()) \
+ cast<CallInst>(II)->METHOD; \
+ else \
+ cast<InvokeInst>(II)->METHOD
+
CallSite::CallSite(Instruction *C) {
assert((isa<CallInst>(C) || isa<InvokeInst>(C)) && "Not a call!");
- I = C;
+ I.setPointer(C);
+ I.setInt(isa<CallInst>(C));
}
unsigned CallSite::getCallingConv() const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->getCallingConv();
- else
- return cast<InvokeInst>(I)->getCallingConv();
+ CALLSITE_DELEGATE_GETTER(getCallingConv());
}
void CallSite::setCallingConv(unsigned CC) {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- CI->setCallingConv(CC);
- else
- cast<InvokeInst>(I)->setCallingConv(CC);
+ CALLSITE_DELEGATE_SETTER(setCallingConv(CC));
}
const AttrListPtr &CallSite::getAttributes() const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->getAttributes();
- else
- return cast<InvokeInst>(I)->getAttributes();
+ CALLSITE_DELEGATE_GETTER(getAttributes());
}
void CallSite::setAttributes(const AttrListPtr &PAL) {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- CI->setAttributes(PAL);
- else
- cast<InvokeInst>(I)->setAttributes(PAL);
+ CALLSITE_DELEGATE_SETTER(setAttributes(PAL));
}
bool CallSite::paramHasAttr(uint16_t i, Attributes attr) const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->paramHasAttr(i, attr);
- else
- return cast<InvokeInst>(I)->paramHasAttr(i, attr);
+ CALLSITE_DELEGATE_GETTER(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);
+ CALLSITE_DELEGATE_GETTER(getParamAlignment(i));
}
-
bool CallSite::doesNotAccessMemory() const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->doesNotAccessMemory();
- else
- return cast<InvokeInst>(I)->doesNotAccessMemory();
+ CALLSITE_DELEGATE_GETTER(doesNotAccessMemory());
}
void CallSite::setDoesNotAccessMemory(bool doesNotAccessMemory) {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- CI->setDoesNotAccessMemory(doesNotAccessMemory);
- else
- cast<InvokeInst>(I)->setDoesNotAccessMemory(doesNotAccessMemory);
+ CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory(doesNotAccessMemory));
}
bool CallSite::onlyReadsMemory() const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->onlyReadsMemory();
- else
- return cast<InvokeInst>(I)->onlyReadsMemory();
+ CALLSITE_DELEGATE_GETTER(onlyReadsMemory());
}
void CallSite::setOnlyReadsMemory(bool onlyReadsMemory) {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- CI->setOnlyReadsMemory(onlyReadsMemory);
- else
- cast<InvokeInst>(I)->setOnlyReadsMemory(onlyReadsMemory);
+ CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory(onlyReadsMemory));
}
bool CallSite::doesNotReturn() const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->doesNotReturn();
- else
- return cast<InvokeInst>(I)->doesNotReturn();
+ CALLSITE_DELEGATE_GETTER(doesNotReturn());
}
void CallSite::setDoesNotReturn(bool doesNotReturn) {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- CI->setDoesNotReturn(doesNotReturn);
- else
- cast<InvokeInst>(I)->setDoesNotReturn(doesNotReturn);
+ CALLSITE_DELEGATE_SETTER(setDoesNotReturn(doesNotReturn));
}
bool CallSite::doesNotThrow() const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->doesNotThrow();
- else
- return cast<InvokeInst>(I)->doesNotThrow();
+ CALLSITE_DELEGATE_GETTER(doesNotThrow());
}
void CallSite::setDoesNotThrow(bool doesNotThrow) {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- CI->setDoesNotThrow(doesNotThrow);
- else
- cast<InvokeInst>(I)->setDoesNotThrow(doesNotThrow);
+ CALLSITE_DELEGATE_SETTER(setDoesNotThrow(doesNotThrow));
}
bool CallSite::hasArgument(const Value *Arg) const {
return false;
}
+#undef CALLSITE_DELEGATE_GETTER
+#undef CALLSITE_DELEGATE_SETTER
+
//===----------------------------------------------------------------------===//
// TerminatorInst Class
//===----------------------------------------------------------------------===//
UnaryInstruction::~UnaryInstruction() {
}
+//===----------------------------------------------------------------------===//
+// SelectInst Class
+//===----------------------------------------------------------------------===//
+
+/// areInvalidOperands - Return a string if the specified operands are invalid
+/// for a select operation, otherwise return null.
+const char *SelectInst::areInvalidOperands(Value *Op0, Value *Op1, Value *Op2) {
+ if (Op1->getType() != Op2->getType())
+ return "both values to select must have same type";
+
+ if (const VectorType *VT = dyn_cast<VectorType>(Op0->getType())) {
+ // Vector select.
+ if (VT->getElementType() != Type::Int1Ty)
+ return "vector select condition element type must be i1";
+ const VectorType *ET = dyn_cast<VectorType>(Op1->getType());
+ if (ET == 0)
+ return "selected values for vector select must be vectors";
+ if (ET->getNumElements() != VT->getNumElements())
+ return "vector select requires selected vectors to have "
+ "the same vector length as select condition";
+ } else if (Op0->getType() != Type::Int1Ty) {
+ return "select condition must be i1 or <n x i1>";
+ }
+ return 0;
+}
+
+
//===----------------------------------------------------------------------===//
// PHINode Class
//===----------------------------------------------------------------------===//
/// 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!");
+ LLVM_UNREACHABLE("ReturnInst has no successors!");
}
BasicBlock *ReturnInst::getSuccessorV(unsigned idx) const {
- assert(0 && "ReturnInst has no successors!");
- abort();
+ LLVM_UNREACHABLE("ReturnInst has no successors!");
return 0;
}
}
void UnwindInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) {
- assert(0 && "UnwindInst has no successors!");
+ LLVM_UNREACHABLE("UnwindInst has no successors!");
}
BasicBlock *UnwindInst::getSuccessorV(unsigned idx) const {
- assert(0 && "UnwindInst has no successors!");
- abort();
+ LLVM_UNREACHABLE("UnwindInst has no successors!");
return 0;
}
}
void UnreachableInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) {
- assert(0 && "UnwindInst has no successors!");
+ LLVM_UNREACHABLE("UnwindInst has no successors!");
}
BasicBlock *UnreachableInst::getSuccessorV(unsigned idx) const {
- assert(0 && "UnwindInst has no successors!");
- abort();
+ LLVM_UNREACHABLE("UnwindInst has no successors!");
return 0;
}
OperandTraits<BranchInst>::op_end(this) - 1,
1, InsertBefore) {
assert(IfTrue != 0 && "Branch destination may not be null!");
- Op<0>() = IfTrue;
+ Op<-1>() = IfTrue;
}
BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
Instruction *InsertBefore)
: TerminatorInst(Type::VoidTy, Instruction::Br,
OperandTraits<BranchInst>::op_end(this) - 3,
3, InsertBefore) {
- Op<0>() = IfTrue;
- Op<1>() = IfFalse;
- Op<2>() = Cond;
+ Op<-1>() = IfTrue;
+ Op<-2>() = IfFalse;
+ Op<-3>() = Cond;
#ifndef NDEBUG
AssertOK();
#endif
OperandTraits<BranchInst>::op_end(this) - 1,
1, InsertAtEnd) {
assert(IfTrue != 0 && "Branch destination may not be null!");
- Op<0>() = IfTrue;
+ Op<-1>() = IfTrue;
}
BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
: TerminatorInst(Type::VoidTy, Instruction::Br,
OperandTraits<BranchInst>::op_end(this) - 3,
3, InsertAtEnd) {
- Op<0>() = IfTrue;
- Op<1>() = IfFalse;
- Op<2>() = Cond;
+ Op<-1>() = IfTrue;
+ Op<-2>() = IfFalse;
+ Op<-3>() = Cond;
#ifndef NDEBUG
AssertOK();
#endif
TerminatorInst(Type::VoidTy, Instruction::Br,
OperandTraits<BranchInst>::op_end(this) - BI.getNumOperands(),
BI.getNumOperands()) {
- OperandList[0] = BI.getOperand(0);
+ Op<-1>() = BI.Op<-1>();
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);
+ Op<-3>() = BI.Op<-3>();
+ Op<-2>() = BI.Op<-2>();
}
}
+
+Use* Use::getPrefix() {
+ PointerIntPair<Use**, 2, PrevPtrTag> &PotentialPrefix(this[-1].Prev);
+ if (PotentialPrefix.getOpaqueValue())
+ return 0;
+
+ return reinterpret_cast<Use*>((char*)&PotentialPrefix + 1);
+}
+
+BranchInst::~BranchInst() {
+ if (NumOperands == 1) {
+ if (Use *Prefix = OperandList->getPrefix()) {
+ Op<-1>() = 0;
+ //
+ // mark OperandList to have a special value for scrutiny
+ // by baseclass destructors and operator delete
+ OperandList = Prefix;
+ } else {
+ NumOperands = 3;
+ OperandList = op_begin();
+ }
+ }
+}
+
+
BasicBlock *BranchInst::getSuccessorV(unsigned idx) const {
return getSuccessor(idx);
}
Instruction::Alloca, AI.getAlignment()) {
}
+/// isStaticAlloca - Return true if this alloca is in the entry block of the
+/// function and is a constant size. If so, the code generator will fold it
+/// into the prolog/epilog code, so it is basically free.
+bool AllocaInst::isStaticAlloca() const {
+ // Must be constant size.
+ if (!isa<ConstantInt>(getArraySize())) return false;
+
+ // Must be in the entry block.
+ const BasicBlock *Parent = getParent();
+ return Parent == &Parent->getParent()->front();
+}
+
MallocInst::MallocInst(const MallocInst &MI)
: AllocationInst(MI.getType()->getElementType(), (Value*)MI.getOperand(0),
Instruction::Malloc, MI.getAlignment()) {
init(Ptr, Idx, Name);
}
-// getIndexedType - Returns the type of the element that would be loaded with
-// a load instruction with the specified parameters.
-//
-// The Idxs pointer should point to a continuous piece of memory containing the
-// indices, either as Value* or uint64_t.
-//
-// A null type is returned if the indices are invalid for the specified
-// pointer type.
-//
+/// getIndexedType - Returns the type of the element that would be accessed with
+/// a gep instruction with the specified parameters.
+///
+/// The Idxs pointer should point to a continuous piece of memory containing the
+/// indices, either as Value* or uint64_t.
+///
+/// A null type is returned if the indices are invalid for the specified
+/// pointer type.
+///
template <typename IndexTy>
-static const Type* getIndexedTypeInternal(const Type *Ptr,
- IndexTy const *Idxs,
- unsigned NumIdx) {
+static const Type* getIndexedTypeInternal(const Type *Ptr, IndexTy const *Idxs,
+ unsigned NumIdx) {
const PointerType *PTy = dyn_cast<PointerType>(Ptr);
if (!PTy) return 0; // Type isn't a pointer type!
const Type *Agg = PTy->getElementType();
- // Handle the special case of the empty set index set...
+ // Handle the special case of the empty set index set, which is always valid.
if (NumIdx == 0)
return Agg;
+
+ // If there is at least one index, the top level type must be sized, otherwise
+ // it cannot be 'stepped over'. We explicitly allow abstract types (those
+ // that contain opaque types) under the assumption that it will be resolved to
+ // a sane type later.
+ if (!Agg->isSized() && !Agg->isAbstract())
+ return 0;
unsigned CurIdx = 1;
for (; CurIdx != NumIdx; ++CurIdx) {
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.
+ return false; // Third operand of insertelement must be i32.
return true;
}
//===----------------------------------------------------------------------===//
void ExtractValueInst::init(const unsigned *Idx, unsigned NumIdx,
- const std::string &Name) {
+ const std::string &Name) {
assert(NumOperands == 1 && "NumOperands not initialized?");
Indices.insert(Indices.end(), Idx, Idx + NumIdx);
// BinaryOperator Class
//===----------------------------------------------------------------------===//
+/// AdjustIType - Map Add, Sub, and Mul to FAdd, FSub, and FMul when the
+/// type is floating-point, to help provide compatibility with an older API.
+///
+static BinaryOperator::BinaryOps AdjustIType(BinaryOperator::BinaryOps iType,
+ const Type *Ty) {
+ // API compatibility: Adjust integer opcodes to floating-point opcodes.
+ if (Ty->isFPOrFPVector()) {
+ if (iType == BinaryOperator::Add) iType = BinaryOperator::FAdd;
+ else if (iType == BinaryOperator::Sub) iType = BinaryOperator::FSub;
+ else if (iType == BinaryOperator::Mul) iType = BinaryOperator::FMul;
+ }
+ return iType;
+}
+
BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2,
const Type *Ty, const std::string &Name,
Instruction *InsertBefore)
- : Instruction(Ty, iType,
+ : Instruction(Ty, AdjustIType(iType, Ty),
OperandTraits<BinaryOperator>::op_begin(this),
OperandTraits<BinaryOperator>::operands(this),
InsertBefore) {
Op<0>() = S1;
Op<1>() = S2;
- init(iType);
+ init(AdjustIType(iType, Ty));
setName(Name);
}
BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2,
const Type *Ty, const std::string &Name,
BasicBlock *InsertAtEnd)
- : Instruction(Ty, iType,
+ : Instruction(Ty, AdjustIType(iType, Ty),
OperandTraits<BinaryOperator>::op_begin(this),
OperandTraits<BinaryOperator>::operands(this),
InsertAtEnd) {
Op<0>() = S1;
Op<1>() = S2;
- init(iType);
+ init(AdjustIType(iType, Ty));
setName(Name);
}
#ifndef NDEBUG
switch (iType) {
case Add: case Sub:
- case Mul:
+ case Mul:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert((getType()->isInteger() || getType()->isFloatingPoint() ||
- isa<VectorType>(getType())) &&
- "Tried to create an arithmetic operation on a non-arithmetic type!");
+ assert(getType()->isIntOrIntVector() &&
+ "Tried to create an integer operation on a non-integer type!");
+ break;
+ case FAdd: case FSub:
+ case FMul:
+ assert(getType() == LHS->getType() &&
+ "Arithmetic operation should return same type as operands!");
+ assert(getType()->isFPOrFPVector() &&
+ "Tried to create a floating-point operation on a "
+ "non-floating-point type!");
break;
case UDiv:
case SDiv:
case FDiv:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert((getType()->isFloatingPoint() || (isa<VectorType>(getType()) &&
- cast<VectorType>(getType())->getElementType()->isFloatingPoint()))
- && "Incorrect operand type (not floating point) for FDIV");
+ assert(getType()->isFPOrFPVector() &&
+ "Incorrect operand type (not floating point) for FDIV");
break;
case URem:
case SRem:
case FRem:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert((getType()->isFloatingPoint() || (isa<VectorType>(getType()) &&
- cast<VectorType>(getType())->getElementType()->isFloatingPoint()))
- && "Incorrect operand type (not floating point) for FREM");
+ assert(getType()->isFPOrFPVector() &&
+ "Incorrect operand type (not floating point) for FREM");
break;
case Shl:
case LShr:
Op->getType(), Name, InsertAtEnd);
}
+BinaryOperator *BinaryOperator::CreateFNeg(Value *Op, const std::string &Name,
+ Instruction *InsertBefore) {
+ Value *zero = ConstantExpr::getZeroValueForNegationExpr(Op->getType());
+ return new BinaryOperator(Instruction::FSub,
+ zero, Op,
+ Op->getType(), Name, InsertBefore);
+}
+
+BinaryOperator *BinaryOperator::CreateFNeg(Value *Op, const std::string &Name,
+ BasicBlock *InsertAtEnd) {
+ Value *zero = ConstantExpr::getZeroValueForNegationExpr(Op->getType());
+ return new BinaryOperator(Instruction::FSub,
+ zero, Op,
+ Op->getType(), Name, InsertAtEnd);
+}
+
BinaryOperator *BinaryOperator::CreateNot(Value *Op, const std::string &Name,
Instruction *InsertBefore) {
Constant *C;
return false;
}
+bool BinaryOperator::isFNeg(const Value *V) {
+ if (const BinaryOperator *Bop = dyn_cast<BinaryOperator>(V))
+ if (Bop->getOpcode() == Instruction::FSub)
+ return Bop->getOperand(0) ==
+ ConstantExpr::getZeroValueForNegationExpr(Bop->getType());
+ return false;
+}
+
bool BinaryOperator::isNot(const Value *V) {
if (const BinaryOperator *Bop = dyn_cast<BinaryOperator>(V))
return (Bop->getOpcode() == Instruction::Xor &&
return getNegArgument(const_cast<Value*>(BinOp));
}
+Value *BinaryOperator::getFNegArgument(Value *BinOp) {
+ assert(isFNeg(BinOp) && "getFNegArgument from non-'fneg' instruction!");
+ return cast<BinaryOperator>(BinOp)->getOperand(1);
+}
+
+const Value *BinaryOperator::getFNegArgument(const Value *BinOp) {
+ return getFNegArgument(const_cast<Value*>(BinOp));
+}
+
Value *BinaryOperator::getNotArgument(Value *BinOp) {
assert(isNot(BinOp) && "getNotArgument on non-'not' instruction!");
BinaryOperator *BO = cast<BinaryOperator>(BinOp);
case Instruction::BitCast:
return true; // BitCast never modifies bits.
case Instruction::PtrToInt:
- return IntPtrTy->getPrimitiveSizeInBits() ==
- getType()->getPrimitiveSizeInBits();
+ return IntPtrTy->getScalarSizeInBits() ==
+ getType()->getScalarSizeInBits();
case Instruction::IntToPtr:
- return IntPtrTy->getPrimitiveSizeInBits() ==
- getOperand(0)->getType()->getPrimitiveSizeInBits();
+ return IntPtrTy->getScalarSizeInBits() ==
+ getOperand(0)->getType()->getScalarSizeInBits();
}
}
// BITCONVERT = FirstClass n/a FirstClass n/a
//
// NOTE: some transforms are safe, but we consider them to be non-profitable.
- // For example, we could merge "fptoui double to uint" + "zext uint to ulong",
- // into "fptoui double to ulong", but this loses information about the range
+ // For example, we could merge "fptoui double to i32" + "zext i32 to i64",
+ // into "fptoui double to i64", but this loses information about the range
// of the produced value (we no longer know the top-part is all zeros).
// Further this conversion is often much more expensive for typical hardware,
// and causes issues when building libgcc. We disallow fptosi+sext for the
return 0;
case 7: {
// ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size
- unsigned PtrSize = IntPtrTy->getPrimitiveSizeInBits();
- unsigned MidSize = MidTy->getPrimitiveSizeInBits();
+ unsigned PtrSize = IntPtrTy->getScalarSizeInBits();
+ unsigned MidSize = MidTy->getScalarSizeInBits();
if (MidSize >= PtrSize)
return Instruction::BitCast;
return 0;
// ext, trunc -> bitcast, if the SrcTy and DstTy are same size
// ext, trunc -> ext, if sizeof(SrcTy) < sizeof(DstTy)
// ext, trunc -> trunc, if sizeof(SrcTy) > sizeof(DstTy)
- unsigned SrcSize = SrcTy->getPrimitiveSizeInBits();
- unsigned DstSize = DstTy->getPrimitiveSizeInBits();
+ unsigned SrcSize = SrcTy->getScalarSizeInBits();
+ unsigned DstSize = DstTy->getScalarSizeInBits();
if (SrcSize == DstSize)
return Instruction::BitCast;
else if (SrcSize < DstSize)
return 0;
case 13: {
// inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize
- unsigned PtrSize = IntPtrTy->getPrimitiveSizeInBits();
- unsigned SrcSize = SrcTy->getPrimitiveSizeInBits();
- unsigned DstSize = DstTy->getPrimitiveSizeInBits();
+ unsigned PtrSize = IntPtrTy->getScalarSizeInBits();
+ unsigned SrcSize = SrcTy->getScalarSizeInBits();
+ unsigned DstSize = DstTy->getScalarSizeInBits();
if (SrcSize <= PtrSize && SrcSize == DstSize)
return Instruction::BitCast;
return 0;
CastInst *CastInst::CreateZExtOrBitCast(Value *S, const Type *Ty,
const std::string &Name,
Instruction *InsertBefore) {
- if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
return Create(Instruction::ZExt, S, Ty, Name, InsertBefore);
}
CastInst *CastInst::CreateZExtOrBitCast(Value *S, const Type *Ty,
const std::string &Name,
BasicBlock *InsertAtEnd) {
- if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
return Create(Instruction::ZExt, S, Ty, Name, InsertAtEnd);
}
CastInst *CastInst::CreateSExtOrBitCast(Value *S, const Type *Ty,
const std::string &Name,
Instruction *InsertBefore) {
- if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
return Create(Instruction::SExt, S, Ty, Name, InsertBefore);
}
CastInst *CastInst::CreateSExtOrBitCast(Value *S, const Type *Ty,
const std::string &Name,
BasicBlock *InsertAtEnd) {
- if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
return Create(Instruction::SExt, S, Ty, Name, InsertAtEnd);
}
CastInst *CastInst::CreateTruncOrBitCast(Value *S, const Type *Ty,
const std::string &Name,
Instruction *InsertBefore) {
- if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
return Create(Instruction::Trunc, S, Ty, Name, InsertBefore);
}
CastInst *CastInst::CreateTruncOrBitCast(Value *S, const Type *Ty,
const std::string &Name,
BasicBlock *InsertAtEnd) {
- if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
return Create(Instruction::Trunc, S, Ty, Name, InsertAtEnd);
}
bool isSigned, const std::string &Name,
Instruction *InsertBefore) {
assert(C->getType()->isInteger() && Ty->isInteger() && "Invalid cast");
- unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
- unsigned DstBits = Ty->getPrimitiveSizeInBits();
+ unsigned SrcBits = C->getType()->getScalarSizeInBits();
+ unsigned DstBits = Ty->getScalarSizeInBits();
Instruction::CastOps opcode =
(SrcBits == DstBits ? Instruction::BitCast :
(SrcBits > DstBits ? Instruction::Trunc :
CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty,
bool isSigned, const std::string &Name,
BasicBlock *InsertAtEnd) {
- assert(C->getType()->isInteger() && Ty->isInteger() && "Invalid cast");
- unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
- unsigned DstBits = Ty->getPrimitiveSizeInBits();
+ assert(C->getType()->isIntOrIntVector() && Ty->isIntOrIntVector() &&
+ "Invalid cast");
+ unsigned SrcBits = C->getType()->getScalarSizeInBits();
+ unsigned DstBits = Ty->getScalarSizeInBits();
Instruction::CastOps opcode =
(SrcBits == DstBits ? Instruction::BitCast :
(SrcBits > DstBits ? Instruction::Trunc :
CastInst *CastInst::CreateFPCast(Value *C, const Type *Ty,
const std::string &Name,
Instruction *InsertBefore) {
- assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() &&
+ assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
"Invalid cast");
- unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
- unsigned DstBits = Ty->getPrimitiveSizeInBits();
+ unsigned SrcBits = C->getType()->getScalarSizeInBits();
+ unsigned DstBits = Ty->getScalarSizeInBits();
Instruction::CastOps opcode =
(SrcBits == DstBits ? Instruction::BitCast :
(SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt));
CastInst *CastInst::CreateFPCast(Value *C, const Type *Ty,
const std::string &Name,
BasicBlock *InsertAtEnd) {
- assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() &&
+ assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
"Invalid cast");
- unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
- unsigned DstBits = Ty->getPrimitiveSizeInBits();
+ unsigned SrcBits = C->getType()->getScalarSizeInBits();
+ unsigned DstBits = Ty->getScalarSizeInBits();
Instruction::CastOps opcode =
(SrcBits == DstBits ? Instruction::BitCast :
(SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt));
return true;
// Get the bit sizes, we'll need these
- unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr/vector
- unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr/vector
+ unsigned SrcBits = SrcTy->getScalarSizeInBits(); // 0 for ptr
+ unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
// Run through the possibilities ...
if (DestTy->isInteger()) { // Casting to integral
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/vector
- unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr/vector
+ unsigned SrcBits = SrcTy->getScalarSizeInBits(); // 0 for ptr
+ unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
assert(SrcTy->isFirstClassType() && DestTy->isFirstClassType() &&
"Only first class types are castable!");
PTy = NULL;
return BitCast; // same size, no-op cast
} else {
- assert(0 && "Casting pointer or non-first class to float");
+ LLVM_UNREACHABLE("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)) {
return false;
// Get the size of the types in bits, we'll need this later
- unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
- unsigned DstBitSize = DstTy->getPrimitiveSizeInBits();
+ unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
+ unsigned DstBitSize = DstTy->getScalarSizeInBits();
// Switch on the opcode provided
switch (op) {
// Now we know we're not dealing with a pointer/non-pointer mismatch. In all
// these cases, the cast is okay if the source and destination bit widths
// are identical.
- return SrcBitSize == DstBitSize;
+ return SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits();
}
}
}
CmpInst *
-CmpInst::Create(OtherOps Op, unsigned short predicate, Value *S1, Value *S2,
+CmpInst::Create(LLVMContext &Context, OtherOps Op, unsigned short predicate,
+ Value *S1, Value *S2,
const std::string &Name, Instruction *InsertBefore) {
if (Op == Instruction::ICmp) {
- return new ICmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
- InsertBefore);
- }
- if (Op == Instruction::FCmp) {
- return new FCmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
- InsertBefore);
- }
- if (Op == Instruction::VICmp) {
- return new VICmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
- InsertBefore);
+ if (InsertBefore)
+ return new ICmpInst(InsertBefore, CmpInst::Predicate(predicate),
+ S1, S2, Name);
+ else
+ return new ICmpInst(Context, CmpInst::Predicate(predicate),
+ S1, S2, Name);
}
- return new VFCmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
- InsertBefore);
+
+ if (InsertBefore)
+ return new FCmpInst(InsertBefore, CmpInst::Predicate(predicate),
+ S1, S2, Name);
+ else
+ return new FCmpInst(Context, CmpInst::Predicate(predicate),
+ S1, S2, Name);
}
CmpInst *
CmpInst::Create(OtherOps Op, unsigned short predicate, Value *S1, Value *S2,
const std::string &Name, BasicBlock *InsertAtEnd) {
if (Op == Instruction::ICmp) {
- return new ICmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
- InsertAtEnd);
- }
- if (Op == Instruction::FCmp) {
- return new FCmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
- InsertAtEnd);
+ return new ICmpInst(*InsertAtEnd, CmpInst::Predicate(predicate),
+ S1, S2, Name);
}
- if (Op == Instruction::VICmp) {
- return new VICmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
- InsertAtEnd);
- }
- return new VFCmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
- InsertAtEnd);
+ return new FCmpInst(*InsertAtEnd, CmpInst::Predicate(predicate),
+ S1, S2, Name);
}
void CmpInst::swapOperands() {
// Define these methods here so vtables don't get emitted into every translation
// unit that uses these classes.
-GetElementPtrInst *GetElementPtrInst::clone() const {
+GetElementPtrInst *GetElementPtrInst::clone(LLVMContext&) const {
return new(getNumOperands()) GetElementPtrInst(*this);
}
-BinaryOperator *BinaryOperator::clone() const {
+BinaryOperator *BinaryOperator::clone(LLVMContext&) const {
return Create(getOpcode(), Op<0>(), Op<1>());
}
-FCmpInst* FCmpInst::clone() const {
- return new FCmpInst(getPredicate(), Op<0>(), Op<1>());
+FCmpInst* FCmpInst::clone(LLVMContext &Context) const {
+ return new FCmpInst(Context, getPredicate(), Op<0>(), Op<1>());
}
-ICmpInst* ICmpInst::clone() const {
- return new ICmpInst(getPredicate(), Op<0>(), Op<1>());
+ICmpInst* ICmpInst::clone(LLVMContext &Context) const {
+ return new ICmpInst(Context, getPredicate(), Op<0>(), Op<1>());
}
-VFCmpInst* VFCmpInst::clone() const {
- return new VFCmpInst(getPredicate(), Op<0>(), Op<1>());
+ExtractValueInst *ExtractValueInst::clone(LLVMContext&) const {
+ return new ExtractValueInst(*this);
}
-VICmpInst* VICmpInst::clone() const {
- return new VICmpInst(getPredicate(), Op<0>(), Op<1>());
+InsertValueInst *InsertValueInst::clone(LLVMContext&) const {
+ return new InsertValueInst(*this);
}
-ExtractValueInst *ExtractValueInst::clone() const {
- return new ExtractValueInst(*this);
+MallocInst *MallocInst::clone(LLVMContext&) const {
+ return new MallocInst(*this);
}
-InsertValueInst *InsertValueInst::clone() const {
- return new InsertValueInst(*this);
+
+AllocaInst *AllocaInst::clone(LLVMContext&) const {
+ return new AllocaInst(*this);
+}
+
+FreeInst *FreeInst::clone(LLVMContext&) const {
+ return new FreeInst(getOperand(0));
+}
+
+LoadInst *LoadInst::clone(LLVMContext&) const {
+ return new LoadInst(*this);
+}
+
+StoreInst *StoreInst::clone(LLVMContext&) const {
+ return new StoreInst(*this);
+}
+
+CastInst *TruncInst::clone(LLVMContext&) const {
+ return new TruncInst(*this);
+}
+
+CastInst *ZExtInst::clone(LLVMContext&) const {
+ return new ZExtInst(*this);
+}
+
+CastInst *SExtInst::clone(LLVMContext&) const {
+ return new SExtInst(*this);
+}
+
+CastInst *FPTruncInst::clone(LLVMContext&) const {
+ return new FPTruncInst(*this);
+}
+
+CastInst *FPExtInst::clone(LLVMContext&) const {
+ return new FPExtInst(*this);
+}
+
+CastInst *UIToFPInst::clone(LLVMContext&) const {
+ return new UIToFPInst(*this);
+}
+
+CastInst *SIToFPInst::clone(LLVMContext&) const {
+ return new SIToFPInst(*this);
+}
+
+CastInst *FPToUIInst::clone(LLVMContext&) const {
+ return new FPToUIInst(*this);
+}
+
+CastInst *FPToSIInst::clone(LLVMContext&) const {
+ return new FPToSIInst(*this);
+}
+
+CastInst *PtrToIntInst::clone(LLVMContext&) const {
+ return new PtrToIntInst(*this);
+}
+
+CastInst *IntToPtrInst::clone(LLVMContext&) const {
+ return new IntToPtrInst(*this);
}
+CastInst *BitCastInst::clone(LLVMContext&) const {
+ return new BitCastInst(*this);
+}
-MallocInst *MallocInst::clone() const { return new MallocInst(*this); }
-AllocaInst *AllocaInst::clone() const { return new AllocaInst(*this); }
-FreeInst *FreeInst::clone() const { return new FreeInst(getOperand(0)); }
-LoadInst *LoadInst::clone() const { return new LoadInst(*this); }
-StoreInst *StoreInst::clone() const { return new StoreInst(*this); }
-CastInst *TruncInst::clone() const { return new TruncInst(*this); }
-CastInst *ZExtInst::clone() const { return new ZExtInst(*this); }
-CastInst *SExtInst::clone() const { return new SExtInst(*this); }
-CastInst *FPTruncInst::clone() const { return new FPTruncInst(*this); }
-CastInst *FPExtInst::clone() const { return new FPExtInst(*this); }
-CastInst *UIToFPInst::clone() const { return new UIToFPInst(*this); }
-CastInst *SIToFPInst::clone() const { return new SIToFPInst(*this); }
-CastInst *FPToUIInst::clone() const { return new FPToUIInst(*this); }
-CastInst *FPToSIInst::clone() const { return new FPToSIInst(*this); }
-CastInst *PtrToIntInst::clone() const { return new PtrToIntInst(*this); }
-CastInst *IntToPtrInst::clone() const { return new IntToPtrInst(*this); }
-CastInst *BitCastInst::clone() const { return new BitCastInst(*this); }
-CallInst *CallInst::clone() const {
+CallInst *CallInst::clone(LLVMContext&) const {
return new(getNumOperands()) CallInst(*this);
}
-SelectInst *SelectInst::clone() const {
+
+SelectInst *SelectInst::clone(LLVMContext&) const {
return new(getNumOperands()) SelectInst(*this);
}
-VAArgInst *VAArgInst::clone() const { return new VAArgInst(*this); }
-ExtractElementInst *ExtractElementInst::clone() const {
+VAArgInst *VAArgInst::clone(LLVMContext&) const {
+ return new VAArgInst(*this);
+}
+
+ExtractElementInst *ExtractElementInst::clone(LLVMContext&) const {
return new ExtractElementInst(*this);
}
-InsertElementInst *InsertElementInst::clone() const {
+
+InsertElementInst *InsertElementInst::clone(LLVMContext&) const {
return InsertElementInst::Create(*this);
}
-ShuffleVectorInst *ShuffleVectorInst::clone() const {
+
+ShuffleVectorInst *ShuffleVectorInst::clone(LLVMContext&) const {
return new ShuffleVectorInst(*this);
}
-PHINode *PHINode::clone() const { return new PHINode(*this); }
-ReturnInst *ReturnInst::clone() const {
+
+PHINode *PHINode::clone(LLVMContext&) const {
+ return new PHINode(*this);
+}
+
+ReturnInst *ReturnInst::clone(LLVMContext&) const {
return new(getNumOperands()) ReturnInst(*this);
}
-BranchInst *BranchInst::clone() const {
- return new(getNumOperands()) BranchInst(*this);
+
+BranchInst *BranchInst::clone(LLVMContext&) const {
+ unsigned Ops(getNumOperands());
+ return new(Ops, Ops == 1) BranchInst(*this);
+}
+
+SwitchInst *SwitchInst::clone(LLVMContext&) const {
+ return new SwitchInst(*this);
}
-SwitchInst *SwitchInst::clone() const { return new SwitchInst(*this); }
-InvokeInst *InvokeInst::clone() const {
+
+InvokeInst *InvokeInst::clone(LLVMContext&) const {
return new(getNumOperands()) InvokeInst(*this);
}
-UnwindInst *UnwindInst::clone() const { return new UnwindInst(); }
-UnreachableInst *UnreachableInst::clone() const { return new UnreachableInst();}
+
+UnwindInst *UnwindInst::clone(LLVMContext&) const {
+ return new UnwindInst();
+}
+
+UnreachableInst *UnreachableInst::clone(LLVMContext&) const {
+ return new UnreachableInst();
+}