Skip to content

Commit 2cc6f7c

Browse files
committed
[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
1 parent fb7fbe4 commit 2cc6f7c

File tree

1 file changed

+105
-77
lines changed

1 file changed

+105
-77
lines changed

llvm/lib/Transforms/IPO/AttributorAttributes.cpp

Lines changed: 105 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -9347,77 +9347,137 @@ struct AANoUndefCallSiteReturned final
93479347
void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
93489348
};
93499349

9350-
struct AACallEdgesFunction : public AACallEdges {
9351-
AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
9352-
: AACallEdges(IRP, A) {}
9350+
struct AACallEdgesImpl : public AACallEdges {
9351+
AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
9352+
9353+
virtual const SetVector<Function *> &getOptimisticEdges() const override {
9354+
return CalledFunctions;
9355+
}
9356+
9357+
virtual bool hasUnknownCallee() const override { return HasUnknownCallee; }
9358+
9359+
virtual bool hasNonAsmUnknownCallee() const override {
9360+
return HasUnknownCalleeNonAsm;
9361+
}
9362+
9363+
const std::string getAsStr() const override {
9364+
return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
9365+
std::to_string(CalledFunctions.size()) + "]";
9366+
}
9367+
9368+
void trackStatistics() const override {}
9369+
9370+
protected:
9371+
void addCalledFunction(Function *Fn, ChangeStatus &Change) {
9372+
if (CalledFunctions.insert(Fn)) {
9373+
Change = ChangeStatus::CHANGED;
9374+
LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
9375+
<< "\n");
9376+
}
9377+
}
93539378

9379+
void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) {
9380+
if (!HasUnknownCallee)
9381+
Change = ChangeStatus::CHANGED;
9382+
if (NonAsm && !HasUnknownCalleeNonAsm)
9383+
Change = ChangeStatus::CHANGED;
9384+
HasUnknownCalleeNonAsm |= NonAsm;
9385+
HasUnknownCallee = true;
9386+
}
9387+
9388+
private:
9389+
/// Optimistic set of functions that might be called by this position.
9390+
SetVector<Function *> CalledFunctions;
9391+
9392+
/// Is there any call with a unknown callee.
9393+
bool HasUnknownCallee = false;
9394+
9395+
/// Is there any call with a unknown callee, excluding any inline asm.
9396+
bool HasUnknownCalleeNonAsm = false;
9397+
};
9398+
9399+
struct AACallEdgesCallSite : public AACallEdgesImpl {
9400+
AACallEdgesCallSite(const IRPosition &IRP, Attributor &A)
9401+
: AACallEdgesImpl(IRP, A) {}
93549402
/// See AbstractAttribute::updateImpl(...).
93559403
ChangeStatus updateImpl(Attributor &A) override {
93569404
ChangeStatus Change = ChangeStatus::UNCHANGED;
9357-
bool OldHasUnknownCallee = HasUnknownCallee;
9358-
bool OldHasUnknownCalleeNonAsm = HasUnknownCalleeNonAsm;
9359-
9360-
auto AddCalledFunction = [&](Function *Fn) {
9361-
if (CalledFunctions.insert(Fn)) {
9362-
Change = ChangeStatus::CHANGED;
9363-
LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
9364-
<< "\n");
9365-
}
9366-
};
93679405

93689406
auto VisitValue = [&](Value &V, const Instruction *CtxI, bool &HasUnknown,
93699407
bool Stripped) -> bool {
93709408
if (Function *Fn = dyn_cast<Function>(&V)) {
9371-
AddCalledFunction(Fn);
9409+
addCalledFunction(Fn, Change);
93729410
} else {
93739411
LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n");
9374-
HasUnknown = true;
9375-
HasUnknownCalleeNonAsm = true;
9412+
setHasUnknownCallee(true, Change);
93769413
}
93779414

93789415
// Explore all values.
93799416
return true;
93809417
};
93819418

93829419
// Process any value that we might call.
9383-
auto ProcessCalledOperand = [&](Value *V, Instruction *Ctx) {
9420+
auto ProcessCalledOperand = [&](Value *V) {
9421+
bool DummyValue = false;
93849422
if (!genericValueTraversal<bool>(A, IRPosition::value(*V), *this,
9385-
HasUnknownCallee, VisitValue, nullptr,
9423+
DummyValue, VisitValue, nullptr,
93869424
false)) {
93879425
// If we haven't gone through all values, assume that there are unknown
93889426
// callees.
9389-
HasUnknownCallee = true;
9390-
HasUnknownCalleeNonAsm = true;
9427+
setHasUnknownCallee(true, Change);
93919428
}
93929429
};
93939430

9394-
auto ProcessCallInst = [&](Instruction &Inst) {
9395-
CallBase &CB = static_cast<CallBase &>(Inst);
9396-
if (CB.isInlineAsm()) {
9397-
HasUnknownCallee = true;
9398-
return true;
9399-
}
9431+
CallBase *CB = static_cast<CallBase *>(getCtxI());
94009432

9401-
// Process callee metadata if available.
9402-
if (auto *MD = Inst.getMetadata(LLVMContext::MD_callees)) {
9403-
for (auto &Op : MD->operands()) {
9404-
Function *Callee = mdconst::extract_or_null<Function>(Op);
9405-
if (Callee)
9406-
AddCalledFunction(Callee);
9407-
}
9408-
// Callees metadata grantees that the called function is one of its
9409-
// operands, So we are done.
9410-
return true;
9433+
if (CB->isInlineAsm()) {
9434+
setHasUnknownCallee(false, Change);
9435+
return Change;
9436+
}
9437+
9438+
// Process callee metadata if available.
9439+
if (auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees)) {
9440+
for (auto &Op : MD->operands()) {
9441+
Function *Callee = mdconst::extract_or_null<Function>(Op);
9442+
if (Callee)
9443+
addCalledFunction(Callee, Change);
94119444
}
9445+
return Change;
9446+
}
94129447

9413-
// The most simple case.
9414-
ProcessCalledOperand(CB.getCalledOperand(), &Inst);
9448+
// The most simple case.
9449+
ProcessCalledOperand(CB->getCalledOperand());
94159450

9416-
// Process callback functions.
9417-
SmallVector<const Use *, 4u> CallbackUses;
9418-
AbstractCallSite::getCallbackUses(CB, CallbackUses);
9419-
for (const Use *U : CallbackUses)
9420-
ProcessCalledOperand(U->get(), &Inst);
9451+
// Process callback functions.
9452+
SmallVector<const Use *, 4u> CallbackUses;
9453+
AbstractCallSite::getCallbackUses(*CB, CallbackUses);
9454+
for (const Use *U : CallbackUses)
9455+
ProcessCalledOperand(U->get());
9456+
9457+
return Change;
9458+
}
9459+
};
9460+
9461+
struct AACallEdgesFunction : public AACallEdgesImpl {
9462+
AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
9463+
: AACallEdgesImpl(IRP, A) {}
9464+
9465+
/// See AbstractAttribute::updateImpl(...).
9466+
ChangeStatus updateImpl(Attributor &A) override {
9467+
ChangeStatus Change = ChangeStatus::UNCHANGED;
9468+
9469+
auto ProcessCallInst = [&](Instruction &Inst) {
9470+
CallBase &CB = static_cast<CallBase &>(Inst);
9471+
9472+
auto &CBEdges = A.getAAFor<AACallEdges>(
9473+
*this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
9474+
if (CBEdges.hasNonAsmUnknownCallee())
9475+
setHasUnknownCallee(false, Change);
9476+
if (CBEdges.hasUnknownCallee())
9477+
setHasUnknownCallee(true, Change);
9478+
9479+
for (Function *F : CBEdges.getOptimisticEdges())
9480+
addCalledFunction(F, Change);
94219481

94229482
return true;
94239483
};
@@ -9428,43 +9488,11 @@ struct AACallEdgesFunction : public AACallEdges {
94289488
UsedAssumedInformation)) {
94299489
// If we haven't looked at all call like instructions, assume that there
94309490
// are unknown callees.
9431-
HasUnknownCallee = true;
9432-
HasUnknownCalleeNonAsm = true;
9491+
setHasUnknownCallee(true, Change);
94339492
}
94349493

9435-
// Track changes.
9436-
if (OldHasUnknownCallee != HasUnknownCallee ||
9437-
OldHasUnknownCalleeNonAsm != HasUnknownCalleeNonAsm)
9438-
Change = ChangeStatus::CHANGED;
9439-
94409494
return Change;
94419495
}
9442-
9443-
virtual const SetVector<Function *> &getOptimisticEdges() const override {
9444-
return CalledFunctions;
9445-
};
9446-
9447-
virtual bool hasUnknownCallee() const override { return HasUnknownCallee; }
9448-
9449-
virtual bool hasNonAsmUnknownCallee() const override {
9450-
return HasUnknownCalleeNonAsm;
9451-
}
9452-
9453-
const std::string getAsStr() const override {
9454-
return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
9455-
std::to_string(CalledFunctions.size()) + "]";
9456-
}
9457-
9458-
void trackStatistics() const override {}
9459-
9460-
/// Optimistic set of functions that might be called by this function.
9461-
SetVector<Function *> CalledFunctions;
9462-
9463-
/// Is there any call with a unknown callee.
9464-
bool HasUnknownCallee = false;
9465-
9466-
/// Is there any call with a unknown callee, excluding any inline asm.
9467-
bool HasUnknownCalleeNonAsm = false;
94689496
};
94699497

94709498
struct AAFunctionReachabilityFunction : public AAFunctionReachability {
@@ -9715,6 +9743,7 @@ CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn)
97159743
CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn)
97169744
CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReturnedValues)
97179745
CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryLocation)
9746+
CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AACallEdges)
97189747

97199748
CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull)
97209749
CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias)
@@ -9734,7 +9763,6 @@ CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree)
97349763
CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack)
97359764
CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReachability)
97369765
CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUndefinedBehavior)
9737-
CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AACallEdges)
97389766
CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAFunctionReachability)
97399767

97409768
CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior)

0 commit comments

Comments
 (0)