diff options
author | Tyker <tyker1@outlook.com> | 2020-06-15 10:57:17 +0200 |
---|---|---|
committer | Tyker <tyker1@outlook.com> | 2020-06-16 13:12:35 +0200 |
commit | 90c50cad1983c5e29107a78382dead0fe2a9562c (patch) | |
tree | 331b2424a6da7c0cc44386883befeb21f009bc8c /llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp | |
parent | 740575dc232b25de0a4bedb41e825ee2e5a056ea (diff) | |
download | llvm-90c50cad1983c5e29107a78382dead0fe2a9562c.zip llvm-90c50cad1983c5e29107a78382dead0fe2a9562c.tar.gz llvm-90c50cad1983c5e29107a78382dead0fe2a9562c.tar.bz2 |
[AssumeBundles] add cannonicalisation to the assume builder
Summary:
this reduces significantly the number of assumes generated without aftecting too much
the information that is preserved. this improves the compile-time cost
of enable-knowledge-retention significantly.
Reviewers: jdoerfert, sstefan1
Reviewed By: jdoerfert
Subscribers: hiraditya, asbirlea, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D79650
Diffstat (limited to 'llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp | 78 |
1 files changed, 72 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp b/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp index 77d0ede..ad45744 100644 --- a/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp +++ b/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp @@ -48,6 +48,39 @@ 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) { + switch (RK.AttrKind) { + default: + return RK; + case Attribute::NonNull: + RK.WasOn = GetUnderlyingObject(RK.WasOn, M->getDataLayout()); + return RK; + case Attribute::Alignment: { + 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()); + }); + RK.WasOn = V; + return RK; + } + case Attribute::Dereferenceable: + case Attribute::DereferenceableOrNull: { + int64_t Offset = 0; + Value *V = GetPointerBaseWithConstantOffset( + RK.WasOn, Offset, M->getDataLayout(), /*AllowNonInBounds*/ false); + if (Offset < 0) + return RK; + RK.ArgValue = RK.ArgValue + Offset; + RK.WasOn = V; + } + } + return RK; +} + /// This class contain all knowledge that have been gather while building an /// llvm.assume and the function to manipulate it. struct AssumeBuilderState { @@ -55,16 +88,16 @@ struct AssumeBuilderState { using MapKey = std::pair<Value *, Attribute::AttrKind>; SmallMapVector<MapKey, unsigned, 8> AssumedKnowledgeMap; - Instruction *InsertBeforeInstruction = nullptr; + Instruction *InstBeingRemoved = nullptr; AssumptionCache* AC = nullptr; DominatorTree* DT = nullptr; AssumeBuilderState(Module *M, Instruction *I = nullptr, AssumptionCache *AC = nullptr, DominatorTree *DT = nullptr) - : M(M), InsertBeforeInstruction(I), AC(AC), DT(DT) {} + : M(M), InstBeingRemoved(I), AC(AC), DT(DT) {} bool tryToPreserveWithoutAddingAssume(RetainedKnowledge RK) { - if (!InsertBeforeInstruction || !AC || !RK.WasOn) + if (!InstBeingRemoved || !RK.WasOn) return false; bool HasBeenPreserved = false; Use* ToUpdate = nullptr; @@ -72,12 +105,12 @@ struct AssumeBuilderState { RK.WasOn, {RK.AttrKind}, AC, [&](RetainedKnowledge RKOther, Instruction *Assume, const CallInst::BundleOpInfo *Bundle) { - if (!isValidAssumeForContext(Assume, InsertBeforeInstruction, DT)) + if (!isValidAssumeForContext(Assume, InstBeingRemoved, DT)) return false; if (RKOther.ArgValue >= RK.ArgValue) { HasBeenPreserved = true; return true; - } else if (isValidAssumeForContext(InsertBeforeInstruction, Assume, + } else if (isValidAssumeForContext(InstBeingRemoved, Assume, DT)) { HasBeenPreserved = true; IntrinsicInst *Intr = cast<IntrinsicInst>(Assume); @@ -92,8 +125,41 @@ struct AssumeBuilderState { return HasBeenPreserved; } + bool isKnowledgeWorthPreserving(RetainedKnowledge RK) { + if (!RK) + return false; + if (!RK.WasOn) + return true; + if (RK.WasOn->getType()->isPointerTy()) { + Value *UnderlyingPtr = GetUnderlyingObject(RK.WasOn, M->getDataLayout()); + if (isa<AllocaInst>(UnderlyingPtr) || isa<GlobalValue>(UnderlyingPtr)) + return false; + } + if (auto *Arg = dyn_cast<Argument>(RK.WasOn)) { + if (Arg->hasAttribute(RK.AttrKind) && + (!Attribute::doesAttrKindHaveArgument(RK.AttrKind) || + Arg->getAttribute(RK.AttrKind).getValueAsInt() >= RK.ArgValue)) + return false; + return true; + } + if (auto *Inst = dyn_cast<Instruction>(RK.WasOn)) + if (wouldInstructionBeTriviallyDead(Inst)) { + if (RK.WasOn->use_empty()) + return false; + Use *SingleUse = RK.WasOn->getSingleUndroppableUse(); + if (SingleUse && SingleUse->getUser() == InstBeingRemoved) + return false; + } + return true; + } + void addKnowledge(RetainedKnowledge RK) { - if (RK.AttrKind == Attribute::None || tryToPreserveWithoutAddingAssume(RK)) + RK = canonicalizedKnowledge(RK, M); + + if (!isKnowledgeWorthPreserving(RK)) + return; + + if (tryToPreserveWithoutAddingAssume(RK)) return; MapKey Key{RK.WasOn, RK.AttrKind}; auto Lookup = AssumedKnowledgeMap.find(Key); |