diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp | 86 |
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; |
