[llvm] 2cc6f7c - [Attributor] Create a call site position for AACalledges
Kuter Dinel via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 12 15:17:19 PDT 2021
Author: Kuter Dinel
Date: 2021-09-13T01:17:05+03:00
New Revision: 2cc6f7c8e108fbc5b5acb513b1edc086ba21563a
URL: https://github.com/llvm/llvm-project/commit/2cc6f7c8e108fbc5b5acb513b1edc086ba21563a
DIFF: https://github.com/llvm/llvm-project/commit/2cc6f7c8e108fbc5b5acb513b1edc086ba21563a.diff
LOG: [Attributor] Create a call site position for AACalledges
This patch adds a call site position for AACallEdges, this
allows us to ask questions about which functions a specific
`CallBase` might call.
Reviewed By: jdoerfert
Differential Revision: https://reviews.llvm.org/D106208
Added:
Modified:
llvm/lib/Transforms/IPO/AttributorAttributes.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 4da71f6c19caa..02f1d38f18984 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -9347,32 +9347,69 @@ struct AANoUndefCallSiteReturned final
void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
};
-struct AACallEdgesFunction : public AACallEdges {
- AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
- : AACallEdges(IRP, A) {}
+struct AACallEdgesImpl : public AACallEdges {
+ AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
+
+ virtual const SetVector<Function *> &getOptimisticEdges() const override {
+ return CalledFunctions;
+ }
+
+ virtual bool hasUnknownCallee() const override { return HasUnknownCallee; }
+
+ virtual bool hasNonAsmUnknownCallee() const override {
+ return HasUnknownCalleeNonAsm;
+ }
+
+ const std::string getAsStr() const override {
+ return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
+ std::to_string(CalledFunctions.size()) + "]";
+ }
+
+ void trackStatistics() const override {}
+
+protected:
+ void addCalledFunction(Function *Fn, ChangeStatus &Change) {
+ if (CalledFunctions.insert(Fn)) {
+ Change = ChangeStatus::CHANGED;
+ LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
+ << "\n");
+ }
+ }
+ void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) {
+ if (!HasUnknownCallee)
+ Change = ChangeStatus::CHANGED;
+ if (NonAsm && !HasUnknownCalleeNonAsm)
+ Change = ChangeStatus::CHANGED;
+ HasUnknownCalleeNonAsm |= NonAsm;
+ HasUnknownCallee = true;
+ }
+
+private:
+ /// Optimistic set of functions that might be called by this position.
+ SetVector<Function *> CalledFunctions;
+
+ /// Is there any call with a unknown callee.
+ bool HasUnknownCallee = false;
+
+ /// Is there any call with a unknown callee, excluding any inline asm.
+ bool HasUnknownCalleeNonAsm = false;
+};
+
+struct AACallEdgesCallSite : public AACallEdgesImpl {
+ AACallEdgesCallSite(const IRPosition &IRP, Attributor &A)
+ : AACallEdgesImpl(IRP, A) {}
/// See AbstractAttribute::updateImpl(...).
ChangeStatus updateImpl(Attributor &A) override {
ChangeStatus Change = ChangeStatus::UNCHANGED;
- bool OldHasUnknownCallee = HasUnknownCallee;
- bool OldHasUnknownCalleeNonAsm = HasUnknownCalleeNonAsm;
-
- auto AddCalledFunction = [&](Function *Fn) {
- if (CalledFunctions.insert(Fn)) {
- Change = ChangeStatus::CHANGED;
- LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
- << "\n");
- }
- };
auto VisitValue = [&](Value &V, const Instruction *CtxI, bool &HasUnknown,
bool Stripped) -> bool {
if (Function *Fn = dyn_cast<Function>(&V)) {
- AddCalledFunction(Fn);
+ addCalledFunction(Fn, Change);
} else {
LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n");
- HasUnknown = true;
- HasUnknownCalleeNonAsm = true;
+ setHasUnknownCallee(true, Change);
}
// Explore all values.
@@ -9380,44 +9417,67 @@ struct AACallEdgesFunction : public AACallEdges {
};
// Process any value that we might call.
- auto ProcessCalledOperand = [&](Value *V, Instruction *Ctx) {
+ auto ProcessCalledOperand = [&](Value *V) {
+ bool DummyValue = false;
if (!genericValueTraversal<bool>(A, IRPosition::value(*V), *this,
- HasUnknownCallee, VisitValue, nullptr,
+ DummyValue, VisitValue, nullptr,
false)) {
// If we haven't gone through all values, assume that there are unknown
// callees.
- HasUnknownCallee = true;
- HasUnknownCalleeNonAsm = true;
+ setHasUnknownCallee(true, Change);
}
};
- auto ProcessCallInst = [&](Instruction &Inst) {
- CallBase &CB = static_cast<CallBase &>(Inst);
- if (CB.isInlineAsm()) {
- HasUnknownCallee = true;
- return true;
- }
+ CallBase *CB = static_cast<CallBase *>(getCtxI());
- // Process callee metadata if available.
- if (auto *MD = Inst.getMetadata(LLVMContext::MD_callees)) {
- for (auto &Op : MD->operands()) {
- Function *Callee = mdconst::extract_or_null<Function>(Op);
- if (Callee)
- AddCalledFunction(Callee);
- }
- // Callees metadata grantees that the called function is one of its
- // operands, So we are done.
- return true;
+ if (CB->isInlineAsm()) {
+ setHasUnknownCallee(false, Change);
+ return Change;
+ }
+
+ // Process callee metadata if available.
+ if (auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees)) {
+ for (auto &Op : MD->operands()) {
+ Function *Callee = mdconst::extract_or_null<Function>(Op);
+ if (Callee)
+ addCalledFunction(Callee, Change);
}
+ return Change;
+ }
- // The most simple case.
- ProcessCalledOperand(CB.getCalledOperand(), &Inst);
+ // The most simple case.
+ ProcessCalledOperand(CB->getCalledOperand());
- // Process callback functions.
- SmallVector<const Use *, 4u> CallbackUses;
- AbstractCallSite::getCallbackUses(CB, CallbackUses);
- for (const Use *U : CallbackUses)
- ProcessCalledOperand(U->get(), &Inst);
+ // Process callback functions.
+ SmallVector<const Use *, 4u> CallbackUses;
+ AbstractCallSite::getCallbackUses(*CB, CallbackUses);
+ for (const Use *U : CallbackUses)
+ ProcessCalledOperand(U->get());
+
+ return Change;
+ }
+};
+
+struct AACallEdgesFunction : public AACallEdgesImpl {
+ AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
+ : AACallEdgesImpl(IRP, A) {}
+
+ /// See AbstractAttribute::updateImpl(...).
+ ChangeStatus updateImpl(Attributor &A) override {
+ ChangeStatus Change = ChangeStatus::UNCHANGED;
+
+ auto ProcessCallInst = [&](Instruction &Inst) {
+ CallBase &CB = static_cast<CallBase &>(Inst);
+
+ auto &CBEdges = A.getAAFor<AACallEdges>(
+ *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
+ if (CBEdges.hasNonAsmUnknownCallee())
+ setHasUnknownCallee(false, Change);
+ if (CBEdges.hasUnknownCallee())
+ setHasUnknownCallee(true, Change);
+
+ for (Function *F : CBEdges.getOptimisticEdges())
+ addCalledFunction(F, Change);
return true;
};
@@ -9428,43 +9488,11 @@ struct AACallEdgesFunction : public AACallEdges {
UsedAssumedInformation)) {
// If we haven't looked at all call like instructions, assume that there
// are unknown callees.
- HasUnknownCallee = true;
- HasUnknownCalleeNonAsm = true;
+ setHasUnknownCallee(true, Change);
}
- // Track changes.
- if (OldHasUnknownCallee != HasUnknownCallee ||
- OldHasUnknownCalleeNonAsm != HasUnknownCalleeNonAsm)
- Change = ChangeStatus::CHANGED;
-
return Change;
}
-
- virtual const SetVector<Function *> &getOptimisticEdges() const override {
- return CalledFunctions;
- };
-
- virtual bool hasUnknownCallee() const override { return HasUnknownCallee; }
-
- virtual bool hasNonAsmUnknownCallee() const override {
- return HasUnknownCalleeNonAsm;
- }
-
- const std::string getAsStr() const override {
- return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
- std::to_string(CalledFunctions.size()) + "]";
- }
-
- void trackStatistics() const override {}
-
- /// Optimistic set of functions that might be called by this function.
- SetVector<Function *> CalledFunctions;
-
- /// Is there any call with a unknown callee.
- bool HasUnknownCallee = false;
-
- /// Is there any call with a unknown callee, excluding any inline asm.
- bool HasUnknownCalleeNonAsm = false;
};
struct AAFunctionReachabilityFunction : public AAFunctionReachability {
@@ -9715,6 +9743,7 @@ CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn)
CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn)
CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReturnedValues)
CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryLocation)
+CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AACallEdges)
CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull)
CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias)
@@ -9734,7 +9763,6 @@ CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree)
CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack)
CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReachability)
CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUndefinedBehavior)
-CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AACallEdges)
CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAFunctionReachability)
CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior)
More information about the llvm-commits
mailing list