diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -4065,9 +4065,12 @@ /// Get the optimistic edges. virtual const SetVector &getOptimisticEdges() const = 0; - /// Is there in this function call with a unknown Callee. + /// Is there any call with a unknown callee. virtual bool hasUnknownCallee() const = 0; + /// Is there any call with a unknown callee, excluding any inline asm. + virtual bool hasNonAsmUnknownCallee() const = 0; + /// Iterator for exploring the call graph. AACallEdgeIterator optimisticEdgesBegin() const override { return AACallEdgeIterator(A, getOptimisticEdges().begin()); diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -8186,6 +8186,7 @@ ChangeStatus updateImpl(Attributor &A) override { ChangeStatus Change = ChangeStatus::UNCHANGED; bool OldHasUnknownCallee = HasUnknownCallee; + bool OldHasUnknownCalleeNonAsm = HasUnknownCalleeNonAsm; auto AddCalledFunction = [&](Function *Fn) { if (CalledFunctions.insert(Fn)) { @@ -8202,6 +8203,7 @@ } else { LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n"); HasUnknown = true; + HasUnknownCalleeNonAsm = true; } // Explore all values. @@ -8210,16 +8212,22 @@ // Process any value that we might call. auto ProcessCalledOperand = [&](Value *V, Instruction *Ctx) { - if (!genericValueTraversal(A, IRPosition::value(*V), - *this, HasUnknownCallee, - VisitValue, nullptr, false)) + if (!genericValueTraversal( + A, IRPosition::value(*V), *this, HasUnknownCallee, VisitValue, + nullptr, false)) { // If we haven't gone through all values, assume that there are unknown // callees. HasUnknownCallee = true; + HasUnknownCalleeNonAsm = true; + } }; auto ProcessCallInst = [&](Instruction &Inst) { CallBase &CB = static_cast(Inst); + if (CB.isInlineAsm()) { + HasUnknownCallee = true; + return true; + } // Process callee metadata if available. if (auto *MD = Inst.getMetadata(LLVMContext::MD_callees)) { @@ -8246,12 +8254,16 @@ }; // Visit all callable instructions. - if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this)) + if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this)) { // If we haven't looked at all call like instructions, assume that there // are unknown callees. HasUnknownCallee = true; + HasUnknownCalleeNonAsm = true; + } + // Track changes. - if (OldHasUnknownCallee != HasUnknownCallee) + if (OldHasUnknownCallee != HasUnknownCallee || + OldHasUnknownCalleeNonAsm != HasUnknownCalleeNonAsm) Change = ChangeStatus::CHANGED; return Change; @@ -8263,6 +8275,10 @@ 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()) + "]"; @@ -8273,8 +8289,11 @@ /// Optimistic set of functions that might be called by this function. SetVector CalledFunctions; - /// Does this function have a call to a function that we don't know about. + /// 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 {