aboutsummaryrefslogtreecommitdiff
path: root/lib/IR/Value.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/IR/Value.cpp')
-rw-r--r--lib/IR/Value.cpp111
1 files changed, 61 insertions, 50 deletions
diff --git a/lib/IR/Value.cpp b/lib/IR/Value.cpp
index b7f77dc3043e..3c8a5b536695 100644
--- a/lib/IR/Value.cpp
+++ b/lib/IR/Value.cpp
@@ -444,15 +444,11 @@ void Value::replaceUsesOutsideBlock(Value *New, BasicBlock *BB) {
"replaceUses of value with new value of different type!");
assert(BB && "Basic block that may contain a use of 'New' must be defined\n");
- use_iterator UI = use_begin(), E = use_end();
- for (; UI != E;) {
- Use &U = *UI;
- ++UI;
- auto *Usr = dyn_cast<Instruction>(U.getUser());
- if (Usr && Usr->getParent() == BB)
- continue;
- U.set(New);
- }
+ replaceUsesWithIf(New, [BB](Use &U) {
+ auto *I = dyn_cast<Instruction>(U.getUser());
+ // Don't replace if it's an instruction in the BB basic block.
+ return !I || I->getParent() != BB;
+ });
}
namespace {
@@ -460,8 +456,8 @@ namespace {
enum PointerStripKind {
PSK_ZeroIndices,
PSK_ZeroIndicesAndAliases,
- PSK_ZeroIndicesAndAliasesSameRepresentation,
- PSK_ZeroIndicesAndAliasesAndInvariantGroups,
+ PSK_ZeroIndicesSameRepresentation,
+ PSK_ZeroIndicesAndInvariantGroups,
PSK_InBoundsConstantIndices,
PSK_InBounds
};
@@ -479,10 +475,10 @@ static const Value *stripPointerCastsAndOffsets(const Value *V) {
do {
if (auto *GEP = dyn_cast<GEPOperator>(V)) {
switch (StripKind) {
- case PSK_ZeroIndicesAndAliases:
- case PSK_ZeroIndicesAndAliasesSameRepresentation:
- case PSK_ZeroIndicesAndAliasesAndInvariantGroups:
case PSK_ZeroIndices:
+ case PSK_ZeroIndicesAndAliases:
+ case PSK_ZeroIndicesSameRepresentation:
+ case PSK_ZeroIndicesAndInvariantGroups:
if (!GEP->hasAllZeroIndices())
return V;
break;
@@ -498,15 +494,13 @@ static const Value *stripPointerCastsAndOffsets(const Value *V) {
V = GEP->getPointerOperand();
} else if (Operator::getOpcode(V) == Instruction::BitCast) {
V = cast<Operator>(V)->getOperand(0);
- } else if (StripKind != PSK_ZeroIndicesAndAliasesSameRepresentation &&
+ } else if (StripKind != PSK_ZeroIndicesSameRepresentation &&
Operator::getOpcode(V) == Instruction::AddrSpaceCast) {
// TODO: If we know an address space cast will not change the
// representation we could look through it here as well.
V = cast<Operator>(V)->getOperand(0);
- } else if (auto *GA = dyn_cast<GlobalAlias>(V)) {
- if (StripKind == PSK_ZeroIndices || GA->isInterposable())
- return V;
- V = GA->getAliasee();
+ } else if (StripKind == PSK_ZeroIndicesAndAliases && isa<GlobalAlias>(V)) {
+ V = cast<GlobalAlias>(V)->getAliasee();
} else {
if (const auto *Call = dyn_cast<CallBase>(V)) {
if (const Value *RV = Call->getReturnedArgOperand()) {
@@ -516,7 +510,7 @@ static const Value *stripPointerCastsAndOffsets(const Value *V) {
// The result of launder.invariant.group must alias it's argument,
// but it can't be marked with returned attribute, that's why it needs
// special case.
- if (StripKind == PSK_ZeroIndicesAndAliasesAndInvariantGroups &&
+ if (StripKind == PSK_ZeroIndicesAndInvariantGroups &&
(Call->getIntrinsicID() == Intrinsic::launder_invariant_group ||
Call->getIntrinsicID() == Intrinsic::strip_invariant_group)) {
V = Call->getArgOperand(0);
@@ -533,16 +527,15 @@ static const Value *stripPointerCastsAndOffsets(const Value *V) {
} // end anonymous namespace
const Value *Value::stripPointerCasts() const {
- return stripPointerCastsAndOffsets<PSK_ZeroIndicesAndAliases>(this);
+ return stripPointerCastsAndOffsets<PSK_ZeroIndices>(this);
}
-const Value *Value::stripPointerCastsSameRepresentation() const {
- return stripPointerCastsAndOffsets<
- PSK_ZeroIndicesAndAliasesSameRepresentation>(this);
+const Value *Value::stripPointerCastsAndAliases() const {
+ return stripPointerCastsAndOffsets<PSK_ZeroIndicesAndAliases>(this);
}
-const Value *Value::stripPointerCastsNoFollowAliases() const {
- return stripPointerCastsAndOffsets<PSK_ZeroIndices>(this);
+const Value *Value::stripPointerCastsSameRepresentation() const {
+ return stripPointerCastsAndOffsets<PSK_ZeroIndicesSameRepresentation>(this);
}
const Value *Value::stripInBoundsConstantOffsets() const {
@@ -550,8 +543,7 @@ const Value *Value::stripInBoundsConstantOffsets() const {
}
const Value *Value::stripPointerCastsAndInvariantGroups() const {
- return stripPointerCastsAndOffsets<PSK_ZeroIndicesAndAliasesAndInvariantGroups>(
- this);
+ return stripPointerCastsAndOffsets<PSK_ZeroIndicesAndInvariantGroups>(this);
}
const Value *
@@ -650,6 +642,19 @@ uint64_t Value::getPointerDereferenceableBytes(const DataLayout &DL,
}
CanBeNull = true;
}
+ } else if (auto *IP = dyn_cast<IntToPtrInst>(this)) {
+ if (MDNode *MD = IP->getMetadata(LLVMContext::MD_dereferenceable)) {
+ ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(0));
+ DerefBytes = CI->getLimitedValue();
+ }
+ if (DerefBytes == 0) {
+ if (MDNode *MD =
+ IP->getMetadata(LLVMContext::MD_dereferenceable_or_null)) {
+ ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(0));
+ DerefBytes = CI->getLimitedValue();
+ }
+ CanBeNull = true;
+ }
} else if (auto *AI = dyn_cast<AllocaInst>(this)) {
if (!AI->isArrayAllocation()) {
DerefBytes = DL.getTypeStoreSize(AI->getAllocatedType());
@@ -666,21 +671,21 @@ uint64_t Value::getPointerDereferenceableBytes(const DataLayout &DL,
return DerefBytes;
}
-unsigned Value::getPointerAlignment(const DataLayout &DL) const {
+MaybeAlign Value::getPointerAlignment(const DataLayout &DL) const {
assert(getType()->isPointerTy() && "must be pointer");
-
- unsigned Align = 0;
if (auto *GO = dyn_cast<GlobalObject>(this)) {
if (isa<Function>(GO)) {
+ const MaybeAlign FunctionPtrAlign = DL.getFunctionPtrAlign();
switch (DL.getFunctionPtrAlignType()) {
case DataLayout::FunctionPtrAlignType::Independent:
- return DL.getFunctionPtrAlign();
+ return FunctionPtrAlign;
case DataLayout::FunctionPtrAlignType::MultipleOfFunctionAlign:
- return std::max(DL.getFunctionPtrAlign(), GO->getAlignment());
+ return std::max(FunctionPtrAlign, MaybeAlign(GO->getAlignment()));
}
+ llvm_unreachable("Unhandled FunctionPtrAlignType");
}
- Align = GO->getAlignment();
- if (Align == 0) {
+ const MaybeAlign Alignment(GO->getAlignment());
+ if (!Alignment) {
if (auto *GVar = dyn_cast<GlobalVariable>(GO)) {
Type *ObjectType = GVar->getValueType();
if (ObjectType->isSized()) {
@@ -688,37 +693,43 @@ unsigned Value::getPointerAlignment(const DataLayout &DL) const {
// it the preferred alignment. Otherwise, we have to assume that it
// may only have the minimum ABI alignment.
if (GVar->isStrongDefinitionForLinker())
- Align = DL.getPreferredAlignment(GVar);
+ return MaybeAlign(DL.getPreferredAlignment(GVar));
else
- Align = DL.getABITypeAlignment(ObjectType);
+ return Align(DL.getABITypeAlignment(ObjectType));
}
}
}
+ return Alignment;
} else if (const Argument *A = dyn_cast<Argument>(this)) {
- Align = A->getParamAlignment();
-
- if (!Align && A->hasStructRetAttr()) {
+ const MaybeAlign Alignment(A->getParamAlignment());
+ if (!Alignment && A->hasStructRetAttr()) {
// An sret parameter has at least the ABI alignment of the return type.
Type *EltTy = cast<PointerType>(A->getType())->getElementType();
if (EltTy->isSized())
- Align = DL.getABITypeAlignment(EltTy);
+ return Align(DL.getABITypeAlignment(EltTy));
}
+ return Alignment;
} else if (const AllocaInst *AI = dyn_cast<AllocaInst>(this)) {
- Align = AI->getAlignment();
- if (Align == 0) {
+ const MaybeAlign Alignment(AI->getAlignment());
+ if (!Alignment) {
Type *AllocatedType = AI->getAllocatedType();
if (AllocatedType->isSized())
- Align = DL.getPrefTypeAlignment(AllocatedType);
+ return MaybeAlign(DL.getPrefTypeAlignment(AllocatedType));
}
- } else if (const auto *Call = dyn_cast<CallBase>(this))
- Align = Call->getAttributes().getRetAlignment();
- else if (const LoadInst *LI = dyn_cast<LoadInst>(this))
+ return Alignment;
+ } else if (const auto *Call = dyn_cast<CallBase>(this)) {
+ const MaybeAlign Alignment(Call->getRetAlignment());
+ if (!Alignment && Call->getCalledFunction())
+ return MaybeAlign(
+ Call->getCalledFunction()->getAttributes().getRetAlignment());
+ return Alignment;
+ } else if (const LoadInst *LI = dyn_cast<LoadInst>(this)) {
if (MDNode *MD = LI->getMetadata(LLVMContext::MD_align)) {
ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(0));
- Align = CI->getLimitedValue();
+ return MaybeAlign(CI->getLimitedValue());
}
-
- return Align;
+ }
+ return llvm::None;
}
const Value *Value::DoPHITranslation(const BasicBlock *CurBB,