aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp86
1 files changed, 59 insertions, 27 deletions
diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp
index 3daff3b4430b..d689e04da36f 100644
--- a/contrib/llvm-project/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp
+++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp
@@ -6,8 +6,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "assume-builder"
-
#include "llvm/Transforms/Utils/AssumeBundleBuilder.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/MapVector.h"
@@ -27,6 +25,7 @@
using namespace llvm;
+namespace llvm {
cl::opt<bool> ShouldPreserveAllAttributes(
"assume-preserve-all", cl::init(false), cl::Hidden,
cl::desc("enable preservation of all attrbitues. even those that are "
@@ -36,6 +35,9 @@ cl::opt<bool> EnableKnowledgeRetention(
"enable-knowledge-retention", cl::init(false), cl::Hidden,
cl::desc(
"enable preservation of attributes throughout code transformation"));
+} // namespace llvm
+
+#define DEBUG_TYPE "assume-builder"
STATISTIC(NumAssumeBuilt, "Number of assume built by the assume builder");
STATISTIC(NumBundlesInAssumes, "Total number of Bundles in the assume built");
@@ -65,7 +67,7 @@ bool isUsefullToPreserve(Attribute::AttrKind Kind) {
/// This function will try to transform the given knowledge into a more
/// canonical one. the canonical knowledge maybe the given one.
-RetainedKnowledge canonicalizedKnowledge(RetainedKnowledge RK, Module *M) {
+RetainedKnowledge canonicalizedKnowledge(RetainedKnowledge RK, DataLayout DL) {
switch (RK.AttrKind) {
default:
return RK;
@@ -76,8 +78,7 @@ RetainedKnowledge canonicalizedKnowledge(RetainedKnowledge RK, Module *M) {
Value *V = RK.WasOn->stripInBoundsOffsets([&](const Value *Strip) {
if (auto *GEP = dyn_cast<GEPOperator>(Strip))
RK.ArgValue =
- MinAlign(RK.ArgValue,
- GEP->getMaxPreservedAlignment(M->getDataLayout()).value());
+ MinAlign(RK.ArgValue, GEP->getMaxPreservedAlignment(DL).value());
});
RK.WasOn = V;
return RK;
@@ -85,8 +86,8 @@ RetainedKnowledge canonicalizedKnowledge(RetainedKnowledge RK, Module *M) {
case Attribute::Dereferenceable:
case Attribute::DereferenceableOrNull: {
int64_t Offset = 0;
- Value *V = GetPointerBaseWithConstantOffset(
- RK.WasOn, Offset, M->getDataLayout(), /*AllowNonInBounds*/ false);
+ Value *V = GetPointerBaseWithConstantOffset(RK.WasOn, Offset, DL,
+ /*AllowNonInBounds*/ false);
if (Offset < 0)
return RK;
RK.ArgValue = RK.ArgValue + Offset;
@@ -103,16 +104,16 @@ struct AssumeBuilderState {
using MapKey = std::pair<Value *, Attribute::AttrKind>;
SmallMapVector<MapKey, unsigned, 8> AssumedKnowledgeMap;
- Instruction *InstBeingRemoved = nullptr;
+ Instruction *InstBeingModified = nullptr;
AssumptionCache* AC = nullptr;
DominatorTree* DT = nullptr;
AssumeBuilderState(Module *M, Instruction *I = nullptr,
AssumptionCache *AC = nullptr, DominatorTree *DT = nullptr)
- : M(M), InstBeingRemoved(I), AC(AC), DT(DT) {}
+ : M(M), InstBeingModified(I), AC(AC), DT(DT) {}
bool tryToPreserveWithoutAddingAssume(RetainedKnowledge RK) {
- if (!InstBeingRemoved || !RK.WasOn)
+ if (!InstBeingModified || !RK.WasOn)
return false;
bool HasBeenPreserved = false;
Use* ToUpdate = nullptr;
@@ -120,13 +121,12 @@ struct AssumeBuilderState {
RK.WasOn, {RK.AttrKind}, AC,
[&](RetainedKnowledge RKOther, Instruction *Assume,
const CallInst::BundleOpInfo *Bundle) {
- if (!isValidAssumeForContext(Assume, InstBeingRemoved, DT))
+ if (!isValidAssumeForContext(Assume, InstBeingModified, DT))
return false;
if (RKOther.ArgValue >= RK.ArgValue) {
HasBeenPreserved = true;
return true;
- } else if (isValidAssumeForContext(InstBeingRemoved, Assume,
- DT)) {
+ } else if (isValidAssumeForContext(InstBeingModified, Assume, DT)) {
HasBeenPreserved = true;
IntrinsicInst *Intr = cast<IntrinsicInst>(Assume);
ToUpdate = &Intr->op_begin()[Bundle->Begin + ABA_Argument];
@@ -152,7 +152,7 @@ struct AssumeBuilderState {
}
if (auto *Arg = dyn_cast<Argument>(RK.WasOn)) {
if (Arg->hasAttribute(RK.AttrKind) &&
- (!Attribute::doesAttrKindHaveArgument(RK.AttrKind) ||
+ (!Attribute::isIntAttrKind(RK.AttrKind) ||
Arg->getAttribute(RK.AttrKind).getValueAsInt() >= RK.ArgValue))
return false;
return true;
@@ -162,14 +162,14 @@ struct AssumeBuilderState {
if (RK.WasOn->use_empty())
return false;
Use *SingleUse = RK.WasOn->getSingleUndroppableUse();
- if (SingleUse && SingleUse->getUser() == InstBeingRemoved)
+ if (SingleUse && SingleUse->getUser() == InstBeingModified)
return false;
}
return true;
}
void addKnowledge(RetainedKnowledge RK) {
- RK = canonicalizedKnowledge(RK, M);
+ RK = canonicalizedKnowledge(RK, M->getDataLayout());
if (!isKnowledgeWorthPreserving(RK))
return;
@@ -206,8 +206,12 @@ struct AssumeBuilderState {
auto addAttrList = [&](AttributeList AttrList) {
for (unsigned Idx = AttributeList::FirstArgIndex;
Idx < AttrList.getNumAttrSets(); Idx++)
- for (Attribute Attr : AttrList.getAttributes(Idx))
- addAttribute(Attr, Call->getArgOperand(Idx - 1));
+ for (Attribute Attr : AttrList.getAttributes(Idx)) {
+ bool IsPoisonAttr = Attr.hasAttribute(Attribute::NonNull) ||
+ Attr.hasAttribute(Attribute::Alignment);
+ if (!IsPoisonAttr || Call->isPassingUndefUB(Idx - 1))
+ addAttribute(Attr, Call->getArgOperand(Idx - 1));
+ }
for (Attribute Attr : AttrList.getFnAttributes())
addAttribute(Attr, nullptr);
};
@@ -216,7 +220,7 @@ struct AssumeBuilderState {
addAttrList(Fn->getAttributes());
}
- IntrinsicInst *build() {
+ AssumeInst *build() {
if (AssumedKnowledgeMap.empty())
return nullptr;
if (!DebugCounter::shouldExecute(BuildAssumeCounter))
@@ -240,7 +244,7 @@ struct AssumeBuilderState {
NumBundlesInAssumes++;
}
NumAssumeBuilt++;
- return cast<IntrinsicInst>(CallInst::Create(
+ return cast<AssumeInst>(CallInst::Create(
FnAssume, ArrayRef<Value *>({ConstantInt::getTrue(C)}), OpBundle));
}
@@ -278,7 +282,7 @@ struct AssumeBuilderState {
} // namespace
-IntrinsicInst *llvm::buildAssumeFromInst(Instruction *I) {
+AssumeInst *llvm::buildAssumeFromInst(Instruction *I) {
if (!EnableKnowledgeRetention)
return nullptr;
AssumeBuilderState Builder(I->getModule());
@@ -292,13 +296,38 @@ void llvm::salvageKnowledge(Instruction *I, AssumptionCache *AC,
return;
AssumeBuilderState Builder(I->getModule(), I, AC, DT);
Builder.addInstruction(I);
- if (IntrinsicInst *Intr = Builder.build()) {
+ if (auto *Intr = Builder.build()) {
Intr->insertBefore(I);
if (AC)
AC->registerAssumption(Intr);
}
}
+AssumeInst *
+llvm::buildAssumeFromKnowledge(ArrayRef<RetainedKnowledge> Knowledge,
+ Instruction *CtxI, AssumptionCache *AC,
+ DominatorTree *DT) {
+ AssumeBuilderState Builder(CtxI->getModule(), CtxI, AC, DT);
+ for (const RetainedKnowledge &RK : Knowledge)
+ Builder.addKnowledge(RK);
+ return Builder.build();
+}
+
+RetainedKnowledge llvm::simplifyRetainedKnowledge(AssumeInst *Assume,
+ RetainedKnowledge RK,
+ AssumptionCache *AC,
+ DominatorTree *DT) {
+ AssumeBuilderState Builder(Assume->getModule(), Assume, AC, DT);
+ RK = canonicalizedKnowledge(RK, Assume->getModule()->getDataLayout());
+
+ if (!Builder.isKnowledgeWorthPreserving(RK))
+ return RetainedKnowledge::none();
+
+ if (Builder.tryToPreserveWithoutAddingAssume(RK))
+ return RetainedKnowledge::none();
+ return RK;
+}
+
namespace {
struct AssumeSimplify {
@@ -344,7 +373,8 @@ struct AssumeSimplify {
for (IntrinsicInst *Assume : CleanupToDo) {
auto *Arg = dyn_cast<ConstantInt>(Assume->getOperand(0));
if (!Arg || Arg->isZero() ||
- (!ForceCleanup && !isAssumeWithEmptyBundle(*Assume)))
+ (!ForceCleanup &&
+ !isAssumeWithEmptyBundle(cast<AssumeInst>(*Assume))))
continue;
MadeChange = true;
if (ForceCleanup)
@@ -387,11 +417,12 @@ struct AssumeSimplify {
CleanupToDo.insert(Assume);
continue;
}
- RetainedKnowledge RK = getKnowledgeFromBundle(*Assume, BOI);
+ RetainedKnowledge RK =
+ getKnowledgeFromBundle(cast<AssumeInst>(*Assume), BOI);
if (auto *Arg = dyn_cast_or_null<Argument>(RK.WasOn)) {
bool HasSameKindAttr = Arg->hasAttribute(RK.AttrKind);
if (HasSameKindAttr)
- if (!Attribute::doesAttrKindHaveArgument(RK.AttrKind) ||
+ if (!Attribute::isIntAttrKind(RK.AttrKind) ||
Arg->getAttribute(RK.AttrKind).getValueAsInt() >=
RK.ArgValue) {
RemoveFromAssume();
@@ -446,7 +477,8 @@ struct AssumeSimplify {
for (IntrinsicInst *I : make_range(Begin, End)) {
CleanupToDo.insert(I);
for (CallInst::BundleOpInfo &BOI : I->bundle_op_infos()) {
- RetainedKnowledge RK = getKnowledgeFromBundle(*I, BOI);
+ RetainedKnowledge RK =
+ getKnowledgeFromBundle(cast<AssumeInst>(*I), BOI);
if (!RK)
continue;
Builder.addKnowledge(RK);
@@ -466,7 +498,7 @@ struct AssumeSimplify {
InsertPt = It->getNextNode();
break;
}
- IntrinsicInst *MergedAssume = Builder.build();
+ auto *MergedAssume = Builder.build();
if (!MergedAssume)
return;
MadeChange = true;