Skip to content

Commit 8d1a31c

Browse files
committed
Allow norecurse on functions calling library functions only when there are no external references
1 parent d4f1637 commit 8d1a31c

File tree

2 files changed

+19
-30
lines changed

2 files changed

+19
-30
lines changed

llvm/lib/Transforms/IPO/FunctionAttrs.cpp

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2069,8 +2069,7 @@ static void inferAttrsFromFunctionBodies(const SCCNodeSet &SCCNodes,
20692069

20702070
static void addNoRecurseAttrs(const SCCNodeSet &SCCNodes,
20712071
SmallPtrSet<Function *, 8> &Changed,
2072-
bool AnyFunctionsAddressIsTaken,
2073-
bool IsLTOPostLink) {
2072+
bool NoFunctionsAddressIsTaken) {
20742073
// Try and identify functions that do not recurse.
20752074

20762075
// If the SCC contains multiple nodes we know for sure there is recursion.
@@ -2081,9 +2080,6 @@ static void addNoRecurseAttrs(const SCCNodeSet &SCCNodes,
20812080
if (!F || !F->hasExactDefinition() || F->doesNotRecurse())
20822081
return;
20832082

2084-
if (F->hasAddressTaken())
2085-
return;
2086-
20872083
Module *M = F->getParent();
20882084
llvm::TargetLibraryInfoImpl TLII(llvm::Triple(M->getTargetTriple()));
20892085
llvm::TargetLibraryInfo TLI(TLII);
@@ -2094,6 +2090,9 @@ static void addNoRecurseAttrs(const SCCNodeSet &SCCNodes,
20942090
for (auto &BB : *F) {
20952091
for (auto &I : BB.instructionsWithoutDebug()) {
20962092
if (auto *CB = dyn_cast<CallBase>(&I)) {
2093+
if (F->hasAddressTaken())
2094+
return;
2095+
20972096
Function *Callee = CB->getCalledFunction();
20982097

20992098
if (!Callee || Callee == F)
@@ -2104,19 +2103,11 @@ static void addNoRecurseAttrs(const SCCNodeSet &SCCNodes,
21042103

21052104
LibFunc LF;
21062105
if (Callee->isDeclaration()) {
2107-
// External call with NoCallback attribute.
2108-
if (Callee->hasFnAttribute(Attribute::NoCallback))
2106+
if (Callee->hasFnAttribute(Attribute::NoCallback) ||
2107+
(NoFunctionsAddressIsTaken &&
2108+
TLI.getLibFunc(Callee->getName(), LF)))
21092109
continue;
2110-
// We rely on this only in post link stage when all functions in the
2111-
// program are known.
2112-
if (IsLTOPostLink && !AnyFunctionsAddressIsTaken &&
2113-
TLI.getLibFunc(Callee->getName(), LF))
2114-
continue;
2115-
// Do not consider external functions safe unless we are in LTO
2116-
// post-link stage and have information about all functions in the
2117-
// program.
2118-
if (!IsLTOPostLink)
2119-
return;
2110+
return;
21202111
}
21212112
}
21222113
}
@@ -2268,8 +2259,8 @@ static SCCNodesResult createSCCNodeSet(ArrayRef<Function *> Functions) {
22682259
template <typename AARGetterT>
22692260
static SmallPtrSet<Function *, 8>
22702261
deriveAttrsInPostOrder(ArrayRef<Function *> Functions, AARGetterT &&AARGetter,
2271-
bool ArgAttrsOnly, bool AnyFunctionAddressTaken = false,
2272-
bool IsLTOPostLink = false) {
2262+
bool ArgAttrsOnly,
2263+
bool NoFunctionAddressIsTaken = false) {
22732264
SCCNodesResult Nodes = createSCCNodeSet(Functions);
22742265

22752266
// Bail if the SCC only contains optnone functions.
@@ -2299,8 +2290,7 @@ deriveAttrsInPostOrder(ArrayRef<Function *> Functions, AARGetterT &&AARGetter,
22992290
addNoAliasAttrs(Nodes.SCCNodes, Changed);
23002291
addNonNullAttrs(Nodes.SCCNodes, Changed);
23012292
inferAttrsFromFunctionBodies(Nodes.SCCNodes, Changed);
2302-
addNoRecurseAttrs(Nodes.SCCNodes, Changed, AnyFunctionAddressTaken,
2303-
IsLTOPostLink);
2293+
addNoRecurseAttrs(Nodes.SCCNodes, Changed, NoFunctionAddressIsTaken);
23042294

23052295
// Finally, infer the maximal set of attributes from the ones we've inferred
23062296
// above. This is handling the cases where one attribute on a signature
@@ -2342,12 +2332,13 @@ PreservedAnalyses PostOrderFunctionAttrsPass::run(LazyCallGraph::SCC &C,
23422332
Functions.push_back(&N.getFunction());
23432333
}
23442334

2345-
bool AnyFunctionsAddressIsTaken = false;
2335+
bool NoFunctionsAddressIsTaken = false;
23462336
// Check if any function in the whole program has its address taken.
23472337
// We use this information when inferring norecurse attribute: If there is
23482338
// no function whose address is taken, we conclude that any external function
23492339
// cannot callback into any user function.
23502340
if (IsLTOPostLink) {
2341+
bool AnyFunctionsAddressIsTaken = false;
23512342
// Get the parent Module of the Function
23522343
Module &M = *C.begin()->getFunction().getParent();
23532344
for (Function &F : M) {
@@ -2356,15 +2347,16 @@ PreservedAnalyses PostOrderFunctionAttrsPass::run(LazyCallGraph::SCC &C,
23562347
if (F.isDeclaration())
23572348
continue;
23582349

2359-
if (F.hasAddressTaken()) {
2350+
if (!F.hasLocalLinkage() || F.hasAddressTaken()) {
23602351
AnyFunctionsAddressIsTaken = true;
23612352
break; // break if we found one
23622353
}
23632354
}
2355+
NoFunctionsAddressIsTaken = !AnyFunctionsAddressIsTaken;
23642356
}
2365-
auto ChangedFunctions =
2366-
deriveAttrsInPostOrder(Functions, AARGetter, ArgAttrsOnly,
2367-
AnyFunctionsAddressIsTaken, IsLTOPostLink);
2357+
auto ChangedFunctions = deriveAttrsInPostOrder(
2358+
Functions, AARGetter, ArgAttrsOnly, NoFunctionsAddressIsTaken);
2359+
23682360
if (ChangedFunctions.empty())
23692361
return PreservedAnalyses::all();
23702362

llvm/test/Other/new-pm-lto-defaults.ll

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,7 @@
166166
; CHECK-O-NEXT: Running pass: PrintModulePass
167167

168168
; Make sure we get the IR back out without changes when we print the module.
169-
; CHECK-O23SZ: ; Function Attrs: norecurse
170-
; CHECK-O1-LABEL: define void @foo(i32 %n) local_unnamed_addr {
171-
; CHECK-O23SZ-LABEL: define void @foo(i32 %n) local_unnamed_addr #0 {
169+
; CHECK-O-LABEL: define void @foo(i32 %n) local_unnamed_addr {
172170
; CHECK-O-NEXT: entry:
173171
; CHECK-O-NEXT: br label %loop
174172
; CHECK-O: loop:
@@ -180,7 +178,6 @@
180178
; CHECK-O: exit:
181179
; CHECK-O-NEXT: ret void
182180
; CHECK-O-NEXT: }
183-
; CHECK-O23SZ: attributes #0 = { norecurse }
184181
;
185182

186183
declare void @bar() local_unnamed_addr

0 commit comments

Comments
 (0)