#include "llvm/IR/Instructions.h"
#include "LLVMContextImpl.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
-#include "llvm/Support/CallSite.h"
-#include "llvm/Support/ConstantRange.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
using namespace llvm;
if (VT->getElementType() != Type::getInt1Ty(Op0->getContext()))
return "vector select condition element type must be i1";
VectorType *ET = dyn_cast<VectorType>(Op1->getType());
- if (ET == 0)
+ if (!ET)
return "selected values for vector select must be vectors";
if (ET->getNumElements() != VT->getNumElements())
return "vector select requires selected vectors to have "
} else if (Op0->getType() != Type::getInt1Ty(Op0->getContext())) {
return "select condition must be i1 or <n x i1>";
}
- return 0;
+ return nullptr;
}
std::copy(block_begin() + Idx + 1, block_end(), block_begin() + Idx);
// Nuke the last value.
- Op<-1>().set(0);
+ Op<-1>().set(nullptr);
--NumOperands;
// If the PHI node is dead, because it has zero entries, nuke it now.
for (unsigned i = 1, e = getNumIncomingValues(); i != e; ++i)
if (getIncomingValue(i) != ConstantValue && getIncomingValue(i) != this) {
if (ConstantValue != this)
- return 0; // Incoming values not all the same.
+ return nullptr; // Incoming values not all the same.
// The case where the first value is this PHI.
ConstantValue = getIncomingValue(i);
}
LandingPadInst::LandingPadInst(Type *RetTy, Value *PersonalityFn,
unsigned NumReservedValues, const Twine &NameStr,
Instruction *InsertBefore)
- : Instruction(RetTy, Instruction::LandingPad, 0, 0, InsertBefore) {
+ : Instruction(RetTy, Instruction::LandingPad, nullptr, 0, InsertBefore) {
init(PersonalityFn, 1 + NumReservedValues, NameStr);
}
LandingPadInst::LandingPadInst(Type *RetTy, Value *PersonalityFn,
unsigned NumReservedValues, const Twine &NameStr,
BasicBlock *InsertAtEnd)
- : Instruction(RetTy, Instruction::LandingPad, 0, 0, InsertAtEnd) {
+ : Instruction(RetTy, Instruction::LandingPad, nullptr, 0, InsertAtEnd) {
init(PersonalityFn, 1 + NumReservedValues, NameStr);
}
Use::zap(OldOps, OldOps + e, true);
}
-void LandingPadInst::addClause(Value *Val) {
+void LandingPadInst::addClause(Constant *Val) {
unsigned OpNo = getNumOperands();
growOperands(1);
assert(OpNo < ReservedSpace && "Growing didn't work!");
OperandTraits<CallInst>::op_end(this) - CI.getNumOperands(),
CI.getNumOperands()) {
setAttributes(CI.getAttributes());
- setTailCall(CI.isTailCall());
+ setTailCallKind(CI.getTailCallKind());
setCallingConv(CI.getCallingConv());
std::copy(CI.op_begin(), CI.op_end(), op_begin());
setAttributes(PAL);
}
+void CallInst::addDereferenceableAttr(unsigned i, uint64_t Bytes) {
+ AttributeSet PAL = getAttributes();
+ PAL = PAL.addDereferenceableAttr(getContext(), i, Bytes);
+ setAttributes(PAL);
+}
+
+void CallInst::addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes) {
+ AttributeSet PAL = getAttributes();
+ PAL = PAL.addDereferenceableOrNullAttr(getContext(), i, Bytes);
+ setAttributes(PAL);
+}
+
bool CallInst::hasFnAttrImpl(Attribute::AttrKind A) const {
if (AttributeList.hasAttribute(AttributeSet::FunctionIndex, A))
return true;
/// IsConstantOne - Return true only if val is constant int 1
static bool IsConstantOne(Value *val) {
- assert(val && "IsConstantOne does not work with NULL val");
- return isa<ConstantInt>(val) && cast<ConstantInt>(val)->isOne();
+ assert(val && "IsConstantOne does not work with nullptr val");
+ const ConstantInt *CVal = dyn_cast<ConstantInt>(val);
+ return CVal && CVal->isOne();
}
static Instruction *createMalloc(Instruction *InsertBefore,
Value *MallocFunc = MallocF;
if (!MallocFunc)
// prototype malloc as "void *malloc(size_t)"
- MallocFunc = M->getOrInsertFunction("malloc", BPTy, IntPtrTy, NULL);
+ MallocFunc = M->getOrInsertFunction("malloc", BPTy, IntPtrTy, nullptr);
PointerType *AllocPtrType = PointerType::getUnqual(AllocTy);
- CallInst *MCall = NULL;
- Instruction *Result = NULL;
+ CallInst *MCall = nullptr;
+ Instruction *Result = nullptr;
if (InsertBefore) {
MCall = CallInst::Create(MallocFunc, AllocSize, "malloccall", InsertBefore);
Result = MCall;
Value *AllocSize, Value *ArraySize,
Function * MallocF,
const Twine &Name) {
- return createMalloc(InsertBefore, NULL, IntPtrTy, AllocTy, AllocSize,
+ return createMalloc(InsertBefore, nullptr, IntPtrTy, AllocTy, AllocSize,
ArraySize, MallocF, Name);
}
Type *IntPtrTy, Type *AllocTy,
Value *AllocSize, Value *ArraySize,
Function *MallocF, const Twine &Name) {
- return createMalloc(NULL, InsertAtEnd, IntPtrTy, AllocTy, AllocSize,
+ return createMalloc(nullptr, InsertAtEnd, IntPtrTy, AllocTy, AllocSize,
ArraySize, MallocF, Name);
}
Type *VoidTy = Type::getVoidTy(M->getContext());
Type *IntPtrTy = Type::getInt8PtrTy(M->getContext());
// prototype free as "void free(void*)"
- Value *FreeFunc = M->getOrInsertFunction("free", VoidTy, IntPtrTy, NULL);
- CallInst* Result = NULL;
+ Value *FreeFunc = M->getOrInsertFunction("free", VoidTy, IntPtrTy, nullptr);
+ CallInst* Result = nullptr;
Value *PtrCast = Source;
if (InsertBefore) {
if (Source->getType() != IntPtrTy)
/// CreateFree - Generate the IR for a call to the builtin free function.
Instruction * CallInst::CreateFree(Value* Source, Instruction *InsertBefore) {
- return createFree(Source, InsertBefore, NULL);
+ return createFree(Source, InsertBefore, nullptr);
}
/// CreateFree - Generate the IR for a call to the builtin free function.
/// Note: This function does not add the call to the basic block, that is the
/// responsibility of the caller.
Instruction* CallInst::CreateFree(Value* Source, BasicBlock *InsertAtEnd) {
- Instruction* FreeCall = createFree(Source, NULL, InsertAtEnd);
+ Instruction* FreeCall = createFree(Source, nullptr, InsertAtEnd);
assert(FreeCall && "CreateFree did not create a CallInst");
return FreeCall;
}
setAttributes(PAL);
}
+void InvokeInst::addDereferenceableAttr(unsigned i, uint64_t Bytes) {
+ AttributeSet PAL = getAttributes();
+ PAL = PAL.addDereferenceableAttr(getContext(), i, Bytes);
+ setAttributes(PAL);
+}
+
+void InvokeInst::addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes) {
+ AttributeSet PAL = getAttributes();
+ PAL = PAL.addDereferenceableOrNullAttr(getContext(), i, Bytes);
+ setAttributes(PAL);
+}
+
LandingPadInst *InvokeInst::getLandingPadInst() const {
return cast<LandingPadInst>(getUnwindDest()->getFirstNonPHI());
}
UnreachableInst::UnreachableInst(LLVMContext &Context,
Instruction *InsertBefore)
: TerminatorInst(Type::getVoidTy(Context), Instruction::Unreachable,
- 0, 0, InsertBefore) {
+ nullptr, 0, InsertBefore) {
}
UnreachableInst::UnreachableInst(LLVMContext &Context, BasicBlock *InsertAtEnd)
: TerminatorInst(Type::getVoidTy(Context), Instruction::Unreachable,
- 0, 0, InsertAtEnd) {
+ nullptr, 0, InsertAtEnd) {
}
unsigned UnreachableInst::getNumSuccessorsV() const {
: TerminatorInst(Type::getVoidTy(IfTrue->getContext()), Instruction::Br,
OperandTraits<BranchInst>::op_end(this) - 1,
1, InsertBefore) {
- assert(IfTrue != 0 && "Branch destination may not be null!");
+ assert(IfTrue && "Branch destination may not be null!");
Op<-1>() = IfTrue;
}
BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
: TerminatorInst(Type::getVoidTy(IfTrue->getContext()), Instruction::Br,
OperandTraits<BranchInst>::op_end(this) - 1,
1, InsertAtEnd) {
- assert(IfTrue != 0 && "Branch destination may not be null!");
+ assert(IfTrue && "Branch destination may not be null!");
Op<-1>() = IfTrue;
}
return;
// The first operand is the name. Fetch them backwards and build a new one.
- Value *Ops[] = {
- ProfileData->getOperand(0),
- ProfileData->getOperand(2),
- ProfileData->getOperand(1)
- };
+ Metadata *Ops[] = {ProfileData->getOperand(0), ProfileData->getOperand(2),
+ ProfileData->getOperand(1)};
setMetadata(LLVMContext::MD_prof,
MDNode::get(ProfileData->getContext(), Ops));
}
return Amt;
}
-AllocaInst::AllocaInst(Type *Ty, Value *ArraySize,
- const Twine &Name, Instruction *InsertBefore)
- : UnaryInstruction(PointerType::getUnqual(Ty), Alloca,
- getAISize(Ty->getContext(), ArraySize), InsertBefore) {
- setAlignment(0);
- assert(!Ty->isVoidTy() && "Cannot allocate void!");
- setName(Name);
-}
+AllocaInst::AllocaInst(Type *Ty, const Twine &Name, Instruction *InsertBefore)
+ : AllocaInst(Ty, /*ArraySize=*/nullptr, Name, InsertBefore) {}
-AllocaInst::AllocaInst(Type *Ty, Value *ArraySize,
- const Twine &Name, BasicBlock *InsertAtEnd)
- : UnaryInstruction(PointerType::getUnqual(Ty), Alloca,
- getAISize(Ty->getContext(), ArraySize), InsertAtEnd) {
- setAlignment(0);
- assert(!Ty->isVoidTy() && "Cannot allocate void!");
- setName(Name);
-}
+AllocaInst::AllocaInst(Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd)
+ : AllocaInst(Ty, /*ArraySize=*/nullptr, Name, InsertAtEnd) {}
-AllocaInst::AllocaInst(Type *Ty, const Twine &Name,
+AllocaInst::AllocaInst(Type *Ty, Value *ArraySize, const Twine &Name,
Instruction *InsertBefore)
- : UnaryInstruction(PointerType::getUnqual(Ty), Alloca,
- getAISize(Ty->getContext(), 0), InsertBefore) {
- setAlignment(0);
- assert(!Ty->isVoidTy() && "Cannot allocate void!");
- setName(Name);
-}
+ : AllocaInst(Ty, ArraySize, /*Align=*/0, Name, InsertBefore) {}
-AllocaInst::AllocaInst(Type *Ty, const Twine &Name,
+AllocaInst::AllocaInst(Type *Ty, Value *ArraySize, const Twine &Name,
BasicBlock *InsertAtEnd)
- : UnaryInstruction(PointerType::getUnqual(Ty), Alloca,
- getAISize(Ty->getContext(), 0), InsertAtEnd) {
- setAlignment(0);
- assert(!Ty->isVoidTy() && "Cannot allocate void!");
- setName(Name);
-}
+ : AllocaInst(Ty, ArraySize, /*Align=*/0, Name, InsertAtEnd) {}
AllocaInst::AllocaInst(Type *Ty, Value *ArraySize, unsigned Align,
const Twine &Name, Instruction *InsertBefore)
assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
assert(Align <= MaximumAlignment &&
"Alignment is greater than MaximumAlignment!");
- setInstructionSubclassData(Log2_32(Align) + 1);
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~31) |
+ (Log2_32(Align) + 1));
assert(getAlignment() == Align && "Alignment representation error!");
}
// Must be in the entry block.
const BasicBlock *Parent = getParent();
- return Parent == &Parent->getParent()->front();
+ return Parent == &Parent->getParent()->front() && !isUsedWithInAlloca();
}
//===----------------------------------------------------------------------===//
}
LoadInst::LoadInst(Value *Ptr, const Twine &Name, Instruction *InsertBef)
- : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
- Load, Ptr, InsertBef) {
- setVolatile(false);
- setAlignment(0);
- setAtomic(NotAtomic);
- AssertOK();
- setName(Name);
-}
+ : LoadInst(Ptr, Name, /*isVolatile=*/false, InsertBef) {}
LoadInst::LoadInst(Value *Ptr, const Twine &Name, BasicBlock *InsertAE)
- : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
- Load, Ptr, InsertAE) {
- setVolatile(false);
- setAlignment(0);
- setAtomic(NotAtomic);
- AssertOK();
- setName(Name);
-}
+ : LoadInst(Ptr, Name, /*isVolatile=*/false, InsertAE) {}
LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile,
Instruction *InsertBef)
- : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
- Load, Ptr, InsertBef) {
- setVolatile(isVolatile);
- setAlignment(0);
- setAtomic(NotAtomic);
- AssertOK();
- setName(Name);
-}
+ : LoadInst(Ptr, Name, isVolatile, /*Align=*/0, InsertBef) {}
LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile,
BasicBlock *InsertAE)
- : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
- Load, Ptr, InsertAE) {
- setVolatile(isVolatile);
- setAlignment(0);
- setAtomic(NotAtomic);
- AssertOK();
- setName(Name);
-}
+ : LoadInst(Ptr, Name, isVolatile, /*Align=*/0, InsertAE) {}
-LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile,
+LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile,
unsigned Align, Instruction *InsertBef)
- : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
- Load, Ptr, InsertBef) {
- setVolatile(isVolatile);
- setAlignment(Align);
- setAtomic(NotAtomic);
- AssertOK();
- setName(Name);
-}
+ : LoadInst(Ptr, Name, isVolatile, Align, NotAtomic, CrossThread,
+ InsertBef) {}
-LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile,
+LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile,
unsigned Align, BasicBlock *InsertAE)
- : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
- Load, Ptr, InsertAE) {
- setVolatile(isVolatile);
- setAlignment(Align);
- setAtomic(NotAtomic);
- AssertOK();
- setName(Name);
+ : LoadInst(Ptr, Name, isVolatile, Align, NotAtomic, CrossThread, InsertAE) {
}
-LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile,
+LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, bool isVolatile,
unsigned Align, AtomicOrdering Order,
- SynchronizationScope SynchScope,
- Instruction *InsertBef)
- : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
- Load, Ptr, InsertBef) {
+ SynchronizationScope SynchScope, Instruction *InsertBef)
+ : UnaryInstruction(Ty, Load, Ptr, InsertBef) {
setVolatile(isVolatile);
setAlignment(Align);
setAtomic(Order, SynchScope);
"Alignment required for atomic store");
}
-
StoreInst::StoreInst(Value *val, Value *addr, Instruction *InsertBefore)
- : Instruction(Type::getVoidTy(val->getContext()), Store,
- OperandTraits<StoreInst>::op_begin(this),
- OperandTraits<StoreInst>::operands(this),
- InsertBefore) {
- Op<0>() = val;
- Op<1>() = addr;
- setVolatile(false);
- setAlignment(0);
- setAtomic(NotAtomic);
- AssertOK();
-}
+ : StoreInst(val, addr, /*isVolatile=*/false, InsertBefore) {}
StoreInst::StoreInst(Value *val, Value *addr, BasicBlock *InsertAtEnd)
- : Instruction(Type::getVoidTy(val->getContext()), Store,
- OperandTraits<StoreInst>::op_begin(this),
- OperandTraits<StoreInst>::operands(this),
- InsertAtEnd) {
- Op<0>() = val;
- Op<1>() = addr;
- setVolatile(false);
- setAlignment(0);
- setAtomic(NotAtomic);
- AssertOK();
-}
+ : StoreInst(val, addr, /*isVolatile=*/false, InsertAtEnd) {}
StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
Instruction *InsertBefore)
- : Instruction(Type::getVoidTy(val->getContext()), Store,
- OperandTraits<StoreInst>::op_begin(this),
- OperandTraits<StoreInst>::operands(this),
- InsertBefore) {
- Op<0>() = val;
- Op<1>() = addr;
- setVolatile(isVolatile);
- setAlignment(0);
- setAtomic(NotAtomic);
- AssertOK();
-}
+ : StoreInst(val, addr, isVolatile, /*Align=*/0, InsertBefore) {}
StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
- unsigned Align, Instruction *InsertBefore)
- : Instruction(Type::getVoidTy(val->getContext()), Store,
- OperandTraits<StoreInst>::op_begin(this),
- OperandTraits<StoreInst>::operands(this),
- InsertBefore) {
- Op<0>() = val;
- Op<1>() = addr;
- setVolatile(isVolatile);
- setAlignment(Align);
- setAtomic(NotAtomic);
- AssertOK();
-}
+ BasicBlock *InsertAtEnd)
+ : StoreInst(val, addr, isVolatile, /*Align=*/0, InsertAtEnd) {}
+
+StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, unsigned Align,
+ Instruction *InsertBefore)
+ : StoreInst(val, addr, isVolatile, Align, NotAtomic, CrossThread,
+ InsertBefore) {}
+
+StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, unsigned Align,
+ BasicBlock *InsertAtEnd)
+ : StoreInst(val, addr, isVolatile, Align, NotAtomic, CrossThread,
+ InsertAtEnd) {}
StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
unsigned Align, AtomicOrdering Order,
AssertOK();
}
-StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
- BasicBlock *InsertAtEnd)
- : Instruction(Type::getVoidTy(val->getContext()), Store,
- OperandTraits<StoreInst>::op_begin(this),
- OperandTraits<StoreInst>::operands(this),
- InsertAtEnd) {
- Op<0>() = val;
- Op<1>() = addr;
- setVolatile(isVolatile);
- setAlignment(0);
- setAtomic(NotAtomic);
- AssertOK();
-}
-
-StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
- unsigned Align, BasicBlock *InsertAtEnd)
- : Instruction(Type::getVoidTy(val->getContext()), Store,
- OperandTraits<StoreInst>::op_begin(this),
- OperandTraits<StoreInst>::operands(this),
- InsertAtEnd) {
- Op<0>() = val;
- Op<1>() = addr;
- setVolatile(isVolatile);
- setAlignment(Align);
- setAtomic(NotAtomic);
- AssertOK();
-}
-
StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
unsigned Align, AtomicOrdering Order,
SynchronizationScope SynchScope,
//===----------------------------------------------------------------------===//
void AtomicCmpXchgInst::Init(Value *Ptr, Value *Cmp, Value *NewVal,
- AtomicOrdering Ordering,
+ AtomicOrdering SuccessOrdering,
+ AtomicOrdering FailureOrdering,
SynchronizationScope SynchScope) {
Op<0>() = Ptr;
Op<1>() = Cmp;
Op<2>() = NewVal;
- setOrdering(Ordering);
+ setSuccessOrdering(SuccessOrdering);
+ setFailureOrdering(FailureOrdering);
setSynchScope(SynchScope);
assert(getOperand(0) && getOperand(1) && getOperand(2) &&
assert(getOperand(2)->getType() ==
cast<PointerType>(getOperand(0)->getType())->getElementType()
&& "Ptr must be a pointer to NewVal type!");
- assert(Ordering != NotAtomic &&
+ assert(SuccessOrdering != NotAtomic &&
+ "AtomicCmpXchg instructions must be atomic!");
+ assert(FailureOrdering != NotAtomic &&
"AtomicCmpXchg instructions must be atomic!");
+ assert(SuccessOrdering >= FailureOrdering &&
+ "AtomicCmpXchg success ordering must be at least as strong as fail");
+ assert(FailureOrdering != Release && FailureOrdering != AcquireRelease &&
+ "AtomicCmpXchg failure ordering cannot include release semantics");
}
AtomicCmpXchgInst::AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal,
- AtomicOrdering Ordering,
+ AtomicOrdering SuccessOrdering,
+ AtomicOrdering FailureOrdering,
SynchronizationScope SynchScope,
Instruction *InsertBefore)
- : Instruction(Cmp->getType(), AtomicCmpXchg,
- OperandTraits<AtomicCmpXchgInst>::op_begin(this),
- OperandTraits<AtomicCmpXchgInst>::operands(this),
- InsertBefore) {
- Init(Ptr, Cmp, NewVal, Ordering, SynchScope);
+ : Instruction(
+ StructType::get(Cmp->getType(), Type::getInt1Ty(Cmp->getContext()),
+ nullptr),
+ AtomicCmpXchg, OperandTraits<AtomicCmpXchgInst>::op_begin(this),
+ OperandTraits<AtomicCmpXchgInst>::operands(this), InsertBefore) {
+ Init(Ptr, Cmp, NewVal, SuccessOrdering, FailureOrdering, SynchScope);
}
AtomicCmpXchgInst::AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal,
- AtomicOrdering Ordering,
+ AtomicOrdering SuccessOrdering,
+ AtomicOrdering FailureOrdering,
SynchronizationScope SynchScope,
BasicBlock *InsertAtEnd)
- : Instruction(Cmp->getType(), AtomicCmpXchg,
- OperandTraits<AtomicCmpXchgInst>::op_begin(this),
- OperandTraits<AtomicCmpXchgInst>::operands(this),
- InsertAtEnd) {
- Init(Ptr, Cmp, NewVal, Ordering, SynchScope);
+ : Instruction(
+ StructType::get(Cmp->getType(), Type::getInt1Ty(Cmp->getContext()),
+ nullptr),
+ AtomicCmpXchg, OperandTraits<AtomicCmpXchgInst>::op_begin(this),
+ OperandTraits<AtomicCmpXchgInst>::operands(this), InsertAtEnd) {
+ Init(Ptr, Cmp, NewVal, SuccessOrdering, FailureOrdering, SynchScope);
}
-
+
//===----------------------------------------------------------------------===//
// AtomicRMWInst Implementation
//===----------------------------------------------------------------------===//
FenceInst::FenceInst(LLVMContext &C, AtomicOrdering Ordering,
SynchronizationScope SynchScope,
Instruction *InsertBefore)
- : Instruction(Type::getVoidTy(C), Fence, 0, 0, InsertBefore) {
+ : Instruction(Type::getVoidTy(C), Fence, nullptr, 0, InsertBefore) {
setOrdering(Ordering);
setSynchScope(SynchScope);
}
FenceInst::FenceInst(LLVMContext &C, AtomicOrdering Ordering,
SynchronizationScope SynchScope,
BasicBlock *InsertAtEnd)
- : Instruction(Type::getVoidTy(C), Fence, 0, 0, InsertAtEnd) {
+ : Instruction(Type::getVoidTy(C), Fence, nullptr, 0, InsertAtEnd) {
setOrdering(Ordering);
setSynchScope(SynchScope);
}
/// pointer type.
///
template <typename IndexTy>
-static Type *getIndexedTypeInternal(Type *Ptr, ArrayRef<IndexTy> IdxList) {
- PointerType *PTy = dyn_cast<PointerType>(Ptr->getScalarType());
- if (!PTy) return 0; // Type isn't a pointer type!
- Type *Agg = PTy->getElementType();
-
+static Type *getIndexedTypeInternal(Type *Agg, ArrayRef<IndexTy> IdxList) {
// Handle the special case of the empty set index set, which is always valid.
if (IdxList.empty())
return Agg;
// If there is at least one index, the top level type must be sized, otherwise
// it cannot be 'stepped over'.
if (!Agg->isSized())
- return 0;
+ return nullptr;
unsigned CurIdx = 1;
for (; CurIdx != IdxList.size(); ++CurIdx) {
CompositeType *CT = dyn_cast<CompositeType>(Agg);
- if (!CT || CT->isPointerTy()) return 0;
+ if (!CT || CT->isPointerTy()) return nullptr;
IndexTy Index = IdxList[CurIdx];
- if (!CT->indexValid(Index)) return 0;
+ if (!CT->indexValid(Index)) return nullptr;
Agg = CT->getTypeAtIndex(Index);
}
- return CurIdx == IdxList.size() ? Agg : 0;
+ return CurIdx == IdxList.size() ? Agg : nullptr;
}
-Type *GetElementPtrInst::getIndexedType(Type *Ptr, ArrayRef<Value *> IdxList) {
- return getIndexedTypeInternal(Ptr, IdxList);
+Type *GetElementPtrInst::getIndexedType(Type *Ty, ArrayRef<Value *> IdxList) {
+ return getIndexedTypeInternal(Ty, IdxList);
}
-Type *GetElementPtrInst::getIndexedType(Type *Ptr,
+Type *GetElementPtrInst::getIndexedType(Type *Ty,
ArrayRef<Constant *> IdxList) {
- return getIndexedTypeInternal(Ptr, IdxList);
+ return getIndexedTypeInternal(Ty, IdxList);
}
-Type *GetElementPtrInst::getIndexedType(Type *Ptr, ArrayRef<uint64_t> IdxList) {
- return getIndexedTypeInternal(Ptr, IdxList);
+Type *GetElementPtrInst::getIndexedType(Type *Ty, ArrayRef<uint64_t> IdxList) {
+ return getIndexedTypeInternal(Ty, IdxList);
}
/// hasAllZeroIndices - Return true if all of the indices of this GEP are
bool ExtractElementInst::isValidOperands(const Value *Val, const Value *Index) {
- if (!Val->getType()->isVectorTy() || !Index->getType()->isIntegerTy(32))
+ if (!Val->getType()->isVectorTy() || !Index->getType()->isIntegerTy())
return false;
return true;
}
if (Elt->getType() != cast<VectorType>(Vec->getType())->getElementType())
return false;// Second operand of insertelement must be vector element type.
- if (!Index->getType()->isIntegerTy(32))
+ if (!Index->getType()->isIntegerTy())
return false; // Third operand of insertelement must be i32.
return true;
}
// Mask must be vector of i32.
VectorType *MaskTy = dyn_cast<VectorType>(Mask->getType());
- if (MaskTy == 0 || !MaskTy->getElementType()->isIntegerTy(32))
+ if (!MaskTy || !MaskTy->getElementType()->isIntegerTy(32))
return false;
// Check to see if Mask is valid.
if (const ConstantVector *MV = dyn_cast<ConstantVector>(Mask)) {
unsigned V1Size = cast<VectorType>(V1->getType())->getNumElements();
- for (unsigned i = 0, e = MV->getNumOperands(); i != e; ++i) {
- if (ConstantInt *CI = dyn_cast<ConstantInt>(MV->getOperand(i))) {
+ for (Value *Op : MV->operands()) {
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
if (CI->uge(V1Size*2))
return false;
- } else if (!isa<UndefValue>(MV->getOperand(i))) {
+ } else if (!isa<UndefValue>(Op)) {
return false;
}
}
//
Type *ExtractValueInst::getIndexedType(Type *Agg,
ArrayRef<unsigned> Idxs) {
- for (unsigned CurIdx = 0; CurIdx != Idxs.size(); ++CurIdx) {
- unsigned Index = Idxs[CurIdx];
+ for (unsigned Index : Idxs) {
// We can't use CompositeType::indexValid(Index) here.
// indexValid() always returns true for arrays because getelementptr allows
// out-of-bounds indices. Since we don't allow those for extractvalue and
// as easy to check those manually as well.
if (ArrayType *AT = dyn_cast<ArrayType>(Agg)) {
if (Index >= AT->getNumElements())
- return 0;
+ return nullptr;
} else if (StructType *ST = dyn_cast<StructType>(Agg)) {
if (Index >= ST->getNumElements())
- return 0;
+ return nullptr;
} else {
// Not a valid type to index into.
- return 0;
+ return nullptr;
}
Agg = cast<CompositeType>(Agg)->getTypeAtIndex(Index);
return cast<PossiblyExactOperator>(this)->isExact();
}
+void BinaryOperator::copyIRFlags(const Value *V) {
+ // Copy the wrapping flags.
+ if (auto *OB = dyn_cast<OverflowingBinaryOperator>(V)) {
+ setHasNoSignedWrap(OB->hasNoSignedWrap());
+ setHasNoUnsignedWrap(OB->hasNoUnsignedWrap());
+ }
+
+ // Copy the exact flag.
+ if (auto *PE = dyn_cast<PossiblyExactOperator>(V))
+ setIsExact(PE->isExact());
+
+ // Copy the fast-math flags.
+ if (auto *FP = dyn_cast<FPMathOperator>(V))
+ copyFastMathFlags(FP->getFastMathFlags());
+}
+
+void BinaryOperator::andIRFlags(const Value *V) {
+ if (auto *OB = dyn_cast<OverflowingBinaryOperator>(V)) {
+ setHasNoSignedWrap(hasNoSignedWrap() & OB->hasNoSignedWrap());
+ setHasNoUnsignedWrap(hasNoUnsignedWrap() & OB->hasNoUnsignedWrap());
+ }
+
+ if (auto *PE = dyn_cast<PossiblyExactOperator>(V))
+ setIsExact(isExact() & PE->isExact());
+
+ if (auto *FP = dyn_cast<FPMathOperator>(V)) {
+ FastMathFlags FM = getFastMathFlags();
+ FM &= FP->getFastMathFlags();
+ copyFastMathFlags(FM);
+ }
+}
+
+
//===----------------------------------------------------------------------===//
// FPMathOperator Class
//===----------------------------------------------------------------------===//
/// default precision.
float FPMathOperator::getFPAccuracy() const {
const MDNode *MD =
- cast<Instruction>(this)->getMetadata(LLVMContext::MD_fpmath);
+ cast<Instruction>(this)->getMetadata(LLVMContext::MD_fpmath);
if (!MD)
return 0.0;
- ConstantFP *Accuracy = cast<ConstantFP>(MD->getOperand(0));
+ ConstantFP *Accuracy = mdconst::extract<ConstantFP>(MD->getOperand(0));
return Accuracy->getValueAPF().convertToFloat();
}
return isNoopCast(getOpcode(), getOperand(0)->getType(), getType(), IntPtrTy);
}
-/// This function determines if a pair of casts can be eliminated and what
-/// opcode should be used in the elimination. This assumes that there are two
+bool CastInst::isNoopCast(const DataLayout &DL) const {
+ Type *PtrOpTy = nullptr;
+ if (getOpcode() == Instruction::PtrToInt)
+ PtrOpTy = getOperand(0)->getType();
+ else if (getOpcode() == Instruction::IntToPtr)
+ PtrOpTy = getType();
+
+ Type *IntPtrTy =
+ PtrOpTy ? DL.getIntPtrType(PtrOpTy) : DL.getIntPtrType(getContext(), 0);
+
+ return isNoopCast(getOpcode(), getOperand(0)->getType(), getType(), IntPtrTy);
+}
+
+/// This function determines if a pair of casts can be eliminated and what
+/// opcode should be used in the elimination. This assumes that there are two
/// instructions like this:
/// * %F = firstOpcode SrcTy %x to MidTy
/// * %S = secondOpcode MidTy %F to DstTy
// Allowed, use first cast's opcode
return firstOp;
case 14:
- // FIXME: this state can be merged with (2), but the following assert
- // is useful to check the correcteness of the sequence due to semantic
- // change of bitcast.
- assert(
- SrcTy->isPtrOrPtrVectorTy() &&
- MidTy->isPtrOrPtrVectorTy() &&
- DstTy->isPtrOrPtrVectorTy() &&
- SrcTy->getPointerAddressSpace() == MidTy->getPointerAddressSpace() &&
- MidTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace() &&
- "Illegal bitcast, addrspacecast sequence!");
- // Allowed, use second cast's opcode
- return secondOp;
+ // bitcast, addrspacecast -> addrspacecast if the element type of
+ // bitcast's source is the same as that of addrspacecast's destination.
+ if (SrcTy->getPointerElementType() == DstTy->getPointerElementType())
+ return Instruction::AddrSpaceCast;
+ return 0;
+
case 15:
// FIXME: this state can be merged with (1), but the following assert
// is useful to check the correcteness of the sequence due to semantic
if (Ty->isIntOrIntVectorTy())
return Create(Instruction::PtrToInt, S, Ty, Name, InsertAtEnd);
- Type *STy = S->getType();
- if (STy->getPointerAddressSpace() != Ty->getPointerAddressSpace())
- return Create(Instruction::AddrSpaceCast, S, Ty, Name, InsertAtEnd);
-
- return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
+ return CreatePointerBitCastOrAddrSpaceCast(S, Ty, Name, InsertAtEnd);
}
/// @brief Create a BitCast or a PtrToInt cast instruction
if (Ty->isIntOrIntVectorTy())
return Create(Instruction::PtrToInt, S, Ty, Name, InsertBefore);
- Type *STy = S->getType();
- if (STy->getPointerAddressSpace() != Ty->getPointerAddressSpace())
+ return CreatePointerBitCastOrAddrSpaceCast(S, Ty, Name, InsertBefore);
+}
+
+CastInst *CastInst::CreatePointerBitCastOrAddrSpaceCast(
+ Value *S, Type *Ty,
+ const Twine &Name,
+ BasicBlock *InsertAtEnd) {
+ assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast");
+ assert(Ty->isPtrOrPtrVectorTy() && "Invalid cast");
+
+ if (S->getType()->getPointerAddressSpace() != Ty->getPointerAddressSpace())
+ return Create(Instruction::AddrSpaceCast, S, Ty, Name, InsertAtEnd);
+
+ return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
+}
+
+CastInst *CastInst::CreatePointerBitCastOrAddrSpaceCast(
+ Value *S, Type *Ty,
+ const Twine &Name,
+ Instruction *InsertBefore) {
+ assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast");
+ assert(Ty->isPtrOrPtrVectorTy() && "Invalid cast");
+
+ if (S->getType()->getPointerAddressSpace() != Ty->getPointerAddressSpace())
return Create(Instruction::AddrSpaceCast, S, Ty, Name, InsertBefore);
return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
}
-CastInst *CastInst::CreateIntegerCast(Value *C, Type *Ty,
+CastInst *CastInst::CreateBitOrPointerCast(Value *S, Type *Ty,
+ const Twine &Name,
+ Instruction *InsertBefore) {
+ if (S->getType()->isPointerTy() && Ty->isIntegerTy())
+ return Create(Instruction::PtrToInt, S, Ty, Name, InsertBefore);
+ if (S->getType()->isIntegerTy() && Ty->isPointerTy())
+ return Create(Instruction::IntToPtr, S, Ty, Name, InsertBefore);
+
+ return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
+}
+
+CastInst *CastInst::CreateIntegerCast(Value *C, Type *Ty,
bool isSigned, const Twine &Name,
Instruction *InsertBefore) {
assert(C->getType()->isIntOrIntVectorTy() && Ty->isIntOrIntVectorTy() &&
// Run through the possibilities ...
if (DestTy->isIntegerTy()) { // Casting to integral
- if (SrcTy->isIntegerTy()) { // Casting from integral
+ if (SrcTy->isIntegerTy()) // Casting from integral
return true;
- } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
+ if (SrcTy->isFloatingPointTy()) // Casting from floating pt
return true;
- } else if (SrcTy->isVectorTy()) { // Casting from vector
+ if (SrcTy->isVectorTy()) // Casting from vector
return DestBits == SrcBits;
- } else { // Casting from something else
- return SrcTy->isPointerTy();
- }
- } else if (DestTy->isFloatingPointTy()) { // Casting to floating pt
- if (SrcTy->isIntegerTy()) { // Casting from integral
+ // Casting from something else
+ return SrcTy->isPointerTy();
+ }
+ if (DestTy->isFloatingPointTy()) { // Casting to floating pt
+ if (SrcTy->isIntegerTy()) // Casting from integral
return true;
- } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
+ if (SrcTy->isFloatingPointTy()) // Casting from floating pt
return true;
- } else if (SrcTy->isVectorTy()) { // Casting from vector
+ if (SrcTy->isVectorTy()) // Casting from vector
return DestBits == SrcBits;
- } else { // Casting from something else
- return false;
- }
- } else if (DestTy->isVectorTy()) { // Casting to vector
+ // Casting from something else
+ return false;
+ }
+ if (DestTy->isVectorTy()) // Casting to vector
return DestBits == SrcBits;
- } else if (DestTy->isPointerTy()) { // Casting to pointer
- if (SrcTy->isPointerTy()) { // Casting from pointer
+ if (DestTy->isPointerTy()) { // Casting to pointer
+ if (SrcTy->isPointerTy()) // Casting from pointer
return true;
- } else if (SrcTy->isIntegerTy()) { // Casting from integral
- return true;
- } else { // Casting from something else
- return false;
- }
- } else if (DestTy->isX86_MMXTy()) {
- if (SrcTy->isVectorTy()) {
+ return SrcTy->isIntegerTy(); // Casting from integral
+ }
+ if (DestTy->isX86_MMXTy()) {
+ if (SrcTy->isVectorTy())
return DestBits == SrcBits; // 64-bit vector to MMX
- } else {
- return false;
- }
- } else { // Casting to something else
return false;
- }
+ } // Casting to something else
+ return false;
}
bool CastInst::isBitCastable(Type *SrcTy, Type *DestTy) {
return true;
}
+bool CastInst::isBitOrNoopPointerCastable(Type *SrcTy, Type *DestTy,
+ const DataLayout &DL) {
+ if (auto *PtrTy = dyn_cast<PointerType>(SrcTy))
+ if (auto *IntTy = dyn_cast<IntegerType>(DestTy))
+ return IntTy->getBitWidth() == DL.getPointerTypeSizeInBits(PtrTy);
+ if (auto *PtrTy = dyn_cast<PointerType>(DestTy))
+ if (auto *IntTy = dyn_cast<IntegerType>(SrcTy))
+ return IntTy->getBitWidth() == DL.getPointerTypeSizeInBits(PtrTy);
+
+ return isBitCastable(SrcTy, DestTy);
+}
+
// Provide a way to get a "cast" where the cast opcode is inferred from the
// types and size of the operand. This, basically, is a parallel of the
// logic in the castIsValid function below. This axiom should hold:
// Check for type sanity on the arguments
Type *SrcTy = S->getType();
- // If this is a cast to the same type then it's trivially true.
- if (SrcTy == DstTy)
- return true;
-
if (!SrcTy->isFirstClassType() || !DstTy->isFirstClassType() ||
SrcTy->isAggregateType() || DstTy->isAggregateType())
return false;
return false;
return SrcTy->getScalarType()->isIntegerTy() &&
DstTy->getScalarType()->isPointerTy();
- case Instruction::BitCast:
+ case Instruction::BitCast: {
+ PointerType *SrcPtrTy = dyn_cast<PointerType>(SrcTy->getScalarType());
+ PointerType *DstPtrTy = dyn_cast<PointerType>(DstTy->getScalarType());
+
// BitCast implies a no-op cast of type only. No bits change.
// However, you can't cast pointers to anything but pointers.
- if (SrcTy->isPtrOrPtrVectorTy() != DstTy->isPtrOrPtrVectorTy())
+ if (!SrcPtrTy != !DstPtrTy)
return false;
// For non-pointer cases, the cast is okay if the source and destination bit
// widths are identical.
- if (!SrcTy->isPtrOrPtrVectorTy())
+ if (!SrcPtrTy)
return SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits();
- // If both are pointers then the address spaces must match and vector of
- // pointers must have the same number of elements.
- return SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace() &&
- SrcTy->isVectorTy() == DstTy->isVectorTy() &&
- (!SrcTy->isVectorTy() ||
- SrcTy->getVectorNumElements() == SrcTy->getVectorNumElements());
-
- case Instruction::AddrSpaceCast:
- return SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
- SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace() &&
- SrcTy->isVectorTy() == DstTy->isVectorTy() &&
- (!SrcTy->isVectorTy() ||
- SrcTy->getVectorNumElements() == SrcTy->getVectorNumElements());
+ // If both are pointers then the address spaces must match.
+ if (SrcPtrTy->getAddressSpace() != DstPtrTy->getAddressSpace())
+ return false;
+
+ // A vector of pointers must have the same number of elements.
+ if (VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy)) {
+ if (VectorType *DstVecTy = dyn_cast<VectorType>(DstTy))
+ return (SrcVecTy->getNumElements() == DstVecTy->getNumElements());
+
+ return false;
+ }
+
+ return true;
+ }
+ case Instruction::AddrSpaceCast: {
+ PointerType *SrcPtrTy = dyn_cast<PointerType>(SrcTy->getScalarType());
+ if (!SrcPtrTy)
+ return false;
+
+ PointerType *DstPtrTy = dyn_cast<PointerType>(DstTy->getScalarType());
+ if (!DstPtrTy)
+ return false;
+
+ if (SrcPtrTy->getAddressSpace() == DstPtrTy->getAddressSpace())
+ return false;
+
+ if (VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy)) {
+ if (VectorType *DstVecTy = dyn_cast<VectorType>(DstTy))
+ return (SrcVecTy->getNumElements() == DstVecTy->getNumElements());
+
+ return false;
+ }
+
+ return true;
+ }
}
}
SwitchInst::SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
Instruction *InsertBefore)
: TerminatorInst(Type::getVoidTy(Value->getContext()), Instruction::Switch,
- 0, 0, InsertBefore) {
+ nullptr, 0, InsertBefore) {
init(Value, Default, 2+NumCases*2);
}
SwitchInst::SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
BasicBlock *InsertAtEnd)
: TerminatorInst(Type::getVoidTy(Value->getContext()), Instruction::Switch,
- 0, 0, InsertAtEnd) {
+ nullptr, 0, InsertAtEnd) {
init(Value, Default, 2+NumCases*2);
}
SwitchInst::SwitchInst(const SwitchInst &SI)
- : TerminatorInst(SI.getType(), Instruction::Switch, 0, 0) {
+ : TerminatorInst(SI.getType(), Instruction::Switch, nullptr, 0) {
init(SI.getCondition(), SI.getDefaultDest(), SI.getNumOperands());
NumOperands = SI.getNumOperands();
Use *OL = OperandList, *InOL = SI.OperandList;
}
// Nuke the last value.
- OL[NumOps-2].set(0);
- OL[NumOps-2+1].set(0);
+ OL[NumOps-2].set(nullptr);
+ OL[NumOps-2+1].set(nullptr);
NumOperands = NumOps-2;
}
IndirectBrInst::IndirectBrInst(Value *Address, unsigned NumCases,
Instruction *InsertBefore)
: TerminatorInst(Type::getVoidTy(Address->getContext()),Instruction::IndirectBr,
- 0, 0, InsertBefore) {
+ nullptr, 0, InsertBefore) {
init(Address, NumCases);
}
IndirectBrInst::IndirectBrInst(Value *Address, unsigned NumCases,
BasicBlock *InsertAtEnd)
: TerminatorInst(Type::getVoidTy(Address->getContext()),Instruction::IndirectBr,
- 0, 0, InsertAtEnd) {
+ nullptr, 0, InsertAtEnd) {
init(Address, NumCases);
}
OL[idx+1] = OL[NumOps-1];
// Nuke the last value.
- OL[NumOps-1].set(0);
+ OL[NumOps-1].set(nullptr);
NumOperands = NumOps-1;
}
}
AllocaInst *AllocaInst::clone_impl() const {
- return new AllocaInst(getAllocatedType(),
- (Value*)getOperand(0),
- getAlignment());
+ AllocaInst *Result = new AllocaInst(getAllocatedType(),
+ (Value *)getOperand(0), getAlignment());
+ Result->setUsedWithInAlloca(isUsedWithInAlloca());
+ return Result;
}
LoadInst *LoadInst::clone_impl() const {
AtomicCmpXchgInst *AtomicCmpXchgInst::clone_impl() const {
AtomicCmpXchgInst *Result =
new AtomicCmpXchgInst(getOperand(0), getOperand(1), getOperand(2),
- getOrdering(), getSynchScope());
+ getSuccessOrdering(), getFailureOrdering(),
+ getSynchScope());
Result->setVolatile(isVolatile());
+ Result->setWeak(isWeak());
return Result;
}