[llvm] [NFC][AlwaysInliner] Reduce AlwaysInliner memory consumption. (PR #96958)
Daniil Fukalov via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 1 13:55:43 PDT 2024
https://github.com/dfukalov updated https://github.com/llvm/llvm-project/pull/96958
>From 3a6f85d45ec1f3f4012a36b3f0942fde46c86a0d Mon Sep 17 00:00:00 2001
From: dfukalov <1671137+dfukalov at users.noreply.github.com>
Date: Thu, 27 Jun 2024 21:46:46 +0200
Subject: [PATCH 1/6] [NFC][AlwaysInliner] Reduce AlwaysInliner memory
consumption.
Refactored AlwaysInliner to remove some of inlined functions earlier.
Fixes out of memory issue on a huge test case from issue 59126.
Also cleaned up one test.
---
llvm/lib/Transforms/IPO/AlwaysInliner.cpp | 105 ++++++++++--------
.../Inline/always-inline-phase-ordering.ll | 13 +--
2 files changed, 63 insertions(+), 55 deletions(-)
diff --git a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
index cc375f9badcd4..e97e167412bfe 100644
--- a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
+++ b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
@@ -15,12 +15,12 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/InlineAdvisor.h"
#include "llvm/Analysis/InlineCost.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/IR/Module.h"
#include "llvm/InitializePasses.h"
-#include "llvm/Transforms/IPO/Inliner.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
@@ -38,6 +38,7 @@ bool AlwaysInlineImpl(
SmallSetVector<CallBase *, 16> Calls;
bool Changed = false;
SmallVector<Function *, 16> InlinedFunctions;
+ SmallVector<Function *, 16> WorkList;
for (Function &F : M) {
// When callee coroutine function is inlined into caller coroutine function
// before coro-split pass,
@@ -46,64 +47,74 @@ bool AlwaysInlineImpl(
if (F.isPresplitCoroutine())
continue;
- if (!F.isDeclaration() && isInlineViable(F).isSuccess()) {
- Calls.clear();
-
- for (User *U : F.users())
- if (auto *CB = dyn_cast<CallBase>(U))
- if (CB->getCalledFunction() == &F &&
- CB->hasFnAttr(Attribute::AlwaysInline) &&
- !CB->getAttributes().hasFnAttr(Attribute::NoInline))
- Calls.insert(CB);
-
- for (CallBase *CB : Calls) {
- Function *Caller = CB->getCaller();
- OptimizationRemarkEmitter ORE(Caller);
- DebugLoc DLoc = CB->getDebugLoc();
- BasicBlock *Block = CB->getParent();
-
- InlineFunctionInfo IFI(GetAssumptionCache, &PSI,
- GetBFI ? &GetBFI(*Caller) : nullptr,
- GetBFI ? &GetBFI(F) : nullptr);
-
- InlineResult Res = InlineFunction(*CB, IFI, /*MergeAttributes=*/true,
- &GetAAR(F), InsertLifetime);
- if (!Res.isSuccess()) {
- ORE.emit([&]() {
- return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc,
- Block)
- << "'" << ore::NV("Callee", &F) << "' is not inlined into '"
- << ore::NV("Caller", Caller)
- << "': " << ore::NV("Reason", Res.getFailureReason());
- });
- continue;
- }
-
- emitInlinedIntoBasedOnCost(
- ORE, DLoc, Block, F, *Caller,
- InlineCost::getAlways("always inline attribute"),
- /*ForProfileContext=*/false, DEBUG_TYPE);
+ if (!F.isDeclaration() && isInlineViable(F).isSuccess())
+ WorkList.push_back(&F);
+ }
- Changed = true;
+ for (Function *F : WorkList) {
+ Calls.clear();
+
+ for (User *U : F->users())
+ if (auto *CB = dyn_cast<CallBase>(U))
+ if (CB->getCalledFunction() == F &&
+ CB->hasFnAttr(Attribute::AlwaysInline) &&
+ !CB->getAttributes().hasFnAttr(Attribute::NoInline))
+ Calls.insert(CB);
+
+ for (CallBase *CB : Calls) {
+ Function *Caller = CB->getCaller();
+ OptimizationRemarkEmitter ORE(Caller);
+ DebugLoc DLoc = CB->getDebugLoc();
+ BasicBlock *Block = CB->getParent();
+
+ InlineFunctionInfo IFI(GetAssumptionCache, &PSI,
+ GetBFI ? &GetBFI(*Caller) : nullptr,
+ GetBFI ? &GetBFI(*F) : nullptr);
+
+ InlineResult Res = InlineFunction(*CB, IFI, /*MergeAttributes=*/true,
+ &GetAAR(*F), InsertLifetime);
+ if (!Res.isSuccess()) {
+ ORE.emit([&]() {
+ return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc,
+ Block)
+ << "'" << ore::NV("Callee", F) << "' is not inlined into '"
+ << ore::NV("Caller", Caller)
+ << "': " << ore::NV("Reason", Res.getFailureReason());
+ });
+ continue;
}
- if (F.hasFnAttribute(Attribute::AlwaysInline)) {
- // Remember to try and delete this function afterward. This both avoids
- // re-walking the rest of the module and avoids dealing with any
- // iterator invalidation issues while deleting functions.
- InlinedFunctions.push_back(&F);
+ emitInlinedIntoBasedOnCost(
+ ORE, DLoc, Block, *F, *Caller,
+ InlineCost::getAlways("always inline attribute"),
+ /*ForProfileContext=*/false, DEBUG_TYPE);
+
+ Changed = true;
+ }
+
+ F->removeDeadConstantUsers();
+ if (F->hasFnAttribute(Attribute::AlwaysInline) && F->isDefTriviallyDead()) {
+ // Remember to try and delete this function afterward. This both avoids
+ // re-walking the rest of the module and avoids dealing with any
+ // iterator invalidation issues while deleting functions.
+ if (F->hasComdat()){
+ InlinedFunctions.push_back(F);
+ } else {
+ M.getFunctionList().erase(F);
+ Changed = true;
}
}
+
}
- // Remove any live functions.
+ // Final cleanup stage. Firstly, remove any live functions.
erase_if(InlinedFunctions, [&](Function *F) {
F->removeDeadConstantUsers();
return !F->isDefTriviallyDead();
});
// Delete the non-comdat ones from the module and also from our vector.
- auto NonComdatBegin = partition(
+ auto *NonComdatBegin = partition(
InlinedFunctions, [&](Function *F) { return F->hasComdat(); });
for (Function *F : make_range(NonComdatBegin, InlinedFunctions.end())) {
M.getFunctionList().erase(F);
@@ -191,7 +202,7 @@ PreservedAnalyses AlwaysInlinerPass::run(Module &M,
auto &PSI = MAM.getResult<ProfileSummaryAnalysis>(M);
bool Changed = AlwaysInlineImpl(M, InsertLifetime, PSI, GetAssumptionCache,
- GetAAR, GetBFI);
+ GetAAR, GetBFI);
return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
}
diff --git a/llvm/test/Transforms/Inline/always-inline-phase-ordering.ll b/llvm/test/Transforms/Inline/always-inline-phase-ordering.ll
index e69ca48344900..237cf180947bf 100644
--- a/llvm/test/Transforms/Inline/always-inline-phase-ordering.ll
+++ b/llvm/test/Transforms/Inline/always-inline-phase-ordering.ll
@@ -1,12 +1,10 @@
; RUN: opt --Os -pass-remarks=inline -S < %s 2>&1 | FileCheck %s
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
-target triple = "arm64e-apple-macosx13"
; CHECK: remark: <unknown>:0:0: 'wibble' inlined into 'bar.8' with (cost=always): always inline attribute
; CHECK: remark: <unknown>:0:0: 'wibble' inlined into 'pluto' with (cost=always): always inline attribute
; CHECK: remark: <unknown>:0:0: 'snork' inlined into 'blam' with (cost=always): always inline attribute
; CHECK: remark: <unknown>:0:0: 'wobble' inlined into 'blam' with (cost=always): always inline attribute
-; CHECK: remark: <unknown>:0:0: 'wobble' inlined into 'snork' with (cost=always): always inline attribute
; CHECK: remark: <unknown>:0:0: 'spam' inlined into 'blam' with (cost=65, threshold=75)
; CHECK: remark: <unknown>:0:0: 'wibble.1' inlined into 'widget' with (cost=30, threshold=75)
; CHECK: remark: <unknown>:0:0: 'widget' inlined into 'bar.8' with (cost=30, threshold=75)
@@ -24,14 +22,14 @@ bb:
unreachable
}
-define linkonce_odr void @pluto() #1 !prof !38 {
+define linkonce_odr void @pluto() !prof !38 {
bb:
call void @wibble()
ret void
}
; Function Attrs: alwaysinline
-define linkonce_odr void @wibble() #2 {
+define linkonce_odr void @wibble() #1 {
bb:
call void @widget()
ret void
@@ -62,7 +60,7 @@ bb:
}
; Function Attrs: alwaysinline
-define linkonce_odr i32 @snork() #2 {
+define linkonce_odr i32 @snork() #1 {
bb:
%tmpv1 = call i32 @spam()
%tmpv2 = call i32 @wobble()
@@ -83,7 +81,7 @@ bb:
}
; Function Attrs: alwaysinline
-define linkonce_odr i32 @wobble() #2 {
+define linkonce_odr i32 @wobble() #1 {
bb:
%tmpv = call i64 @wobble.5(i8 0)
%tmpv1 = call i64 @eggs.7()
@@ -119,8 +117,7 @@ bb:
}
attributes #0 = { "frame-pointer"="non-leaf" }
-attributes #1 = { "target-cpu"="apple-m1" }
-attributes #2 = { alwaysinline }
+attributes #1 = { alwaysinline }
!llvm.module.flags = !{!0, !1, !30, !31, !32, !36, !37}
>From e3f4142be3abc9f5bc395a1ce54717d7577f4fdd Mon Sep 17 00:00:00 2001
From: dfukalov <1671137+dfukalov at users.noreply.github.com>
Date: Thu, 27 Jun 2024 22:14:39 +0200
Subject: [PATCH 2/6] Addressed comment.
---
llvm/lib/Transforms/IPO/AlwaysInliner.cpp | 3 +--
.../Inline/always-inline-phase-ordering.ll | 12 +++++++-----
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
index e97e167412bfe..02ff549560a30 100644
--- a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
+++ b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
@@ -104,7 +104,6 @@ bool AlwaysInlineImpl(
Changed = true;
}
}
-
}
// Final cleanup stage. Firstly, remove any live functions.
@@ -202,7 +201,7 @@ PreservedAnalyses AlwaysInlinerPass::run(Module &M,
auto &PSI = MAM.getResult<ProfileSummaryAnalysis>(M);
bool Changed = AlwaysInlineImpl(M, InsertLifetime, PSI, GetAssumptionCache,
- GetAAR, GetBFI);
+ GetAAR, GetBFI);
return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
}
diff --git a/llvm/test/Transforms/Inline/always-inline-phase-ordering.ll b/llvm/test/Transforms/Inline/always-inline-phase-ordering.ll
index 237cf180947bf..defd1f4fd426b 100644
--- a/llvm/test/Transforms/Inline/always-inline-phase-ordering.ll
+++ b/llvm/test/Transforms/Inline/always-inline-phase-ordering.ll
@@ -1,5 +1,6 @@
; RUN: opt --Os -pass-remarks=inline -S < %s 2>&1 | FileCheck %s
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+target triple = "arm64e-apple-macosx13"
; CHECK: remark: <unknown>:0:0: 'wibble' inlined into 'bar.8' with (cost=always): always inline attribute
; CHECK: remark: <unknown>:0:0: 'wibble' inlined into 'pluto' with (cost=always): always inline attribute
@@ -22,14 +23,14 @@ bb:
unreachable
}
-define linkonce_odr void @pluto() !prof !38 {
+define linkonce_odr void @pluto() #1 !prof !38 {
bb:
call void @wibble()
ret void
}
; Function Attrs: alwaysinline
-define linkonce_odr void @wibble() #1 {
+define linkonce_odr void @wibble() #2 {
bb:
call void @widget()
ret void
@@ -60,7 +61,7 @@ bb:
}
; Function Attrs: alwaysinline
-define linkonce_odr i32 @snork() #1 {
+define linkonce_odr i32 @snork() #2 {
bb:
%tmpv1 = call i32 @spam()
%tmpv2 = call i32 @wobble()
@@ -81,7 +82,7 @@ bb:
}
; Function Attrs: alwaysinline
-define linkonce_odr i32 @wobble() #1 {
+define linkonce_odr i32 @wobble() #2 {
bb:
%tmpv = call i64 @wobble.5(i8 0)
%tmpv1 = call i64 @eggs.7()
@@ -117,7 +118,8 @@ bb:
}
attributes #0 = { "frame-pointer"="non-leaf" }
-attributes #1 = { alwaysinline }
+attributes #1 = { "target-cpu"="apple-m1" }
+attributes #2 = { alwaysinline }
!llvm.module.flags = !{!0, !1, !30, !31, !32, !36, !37}
>From 3a2078ea7a8cdf9ede7fcbeabb0219ff1b038143 Mon Sep 17 00:00:00 2001
From: dfukalov <1671137+dfukalov at users.noreply.github.com>
Date: Mon, 1 Jul 2024 16:04:29 +0200
Subject: [PATCH 3/6] Addressed comments.
---
llvm/lib/Transforms/IPO/AlwaysInliner.cpp | 40 ++++++++---------------
1 file changed, 14 insertions(+), 26 deletions(-)
diff --git a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
index 02ff549560a30..9290435bab640 100644
--- a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
+++ b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
@@ -38,25 +38,19 @@ bool AlwaysInlineImpl(
SmallSetVector<CallBase *, 16> Calls;
bool Changed = false;
SmallVector<Function *, 16> InlinedFunctions;
- SmallVector<Function *, 16> WorkList;
- for (Function &F : M) {
- // When callee coroutine function is inlined into caller coroutine function
- // before coro-split pass,
- // coro-early pass can not handle this quiet well.
- // So we won't inline the coroutine function if it have not been unsplited
+
+ for (Function &F : make_early_inc_range(M)) {
if (F.isPresplitCoroutine())
continue;
- if (!F.isDeclaration() && isInlineViable(F).isSuccess())
- WorkList.push_back(&F);
- }
+ if (F.isDeclaration() || !isInlineViable(F).isSuccess())
+ continue;
- for (Function *F : WorkList) {
Calls.clear();
- for (User *U : F->users())
+ for (User *U : F.users())
if (auto *CB = dyn_cast<CallBase>(U))
- if (CB->getCalledFunction() == F &&
+ if (CB->getCalledFunction() == &F &&
CB->hasFnAttr(Attribute::AlwaysInline) &&
!CB->getAttributes().hasFnAttr(Attribute::NoInline))
Calls.insert(CB);
@@ -69,15 +63,15 @@ bool AlwaysInlineImpl(
InlineFunctionInfo IFI(GetAssumptionCache, &PSI,
GetBFI ? &GetBFI(*Caller) : nullptr,
- GetBFI ? &GetBFI(*F) : nullptr);
+ GetBFI ? &GetBFI(F) : nullptr);
InlineResult Res = InlineFunction(*CB, IFI, /*MergeAttributes=*/true,
- &GetAAR(*F), InsertLifetime);
+ &GetAAR(F), InsertLifetime);
if (!Res.isSuccess()) {
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc,
Block)
- << "'" << ore::NV("Callee", F) << "' is not inlined into '"
+ << "'" << ore::NV("Callee", &F) << "' is not inlined into '"
<< ore::NV("Caller", Caller)
<< "': " << ore::NV("Reason", Res.getFailureReason());
});
@@ -85,20 +79,20 @@ bool AlwaysInlineImpl(
}
emitInlinedIntoBasedOnCost(
- ORE, DLoc, Block, *F, *Caller,
+ ORE, DLoc, Block, F, *Caller,
InlineCost::getAlways("always inline attribute"),
/*ForProfileContext=*/false, DEBUG_TYPE);
Changed = true;
}
- F->removeDeadConstantUsers();
- if (F->hasFnAttribute(Attribute::AlwaysInline) && F->isDefTriviallyDead()) {
+ F.removeDeadConstantUsers();
+ if (F.hasFnAttribute(Attribute::AlwaysInline) && F.isDefTriviallyDead()) {
// Remember to try and delete this function afterward. This both avoids
// re-walking the rest of the module and avoids dealing with any
// iterator invalidation issues while deleting functions.
- if (F->hasComdat()){
- InlinedFunctions.push_back(F);
+ if (F.hasComdat()) {
+ InlinedFunctions.push_back(&F);
} else {
M.getFunctionList().erase(F);
Changed = true;
@@ -106,12 +100,6 @@ bool AlwaysInlineImpl(
}
}
- // Final cleanup stage. Firstly, remove any live functions.
- erase_if(InlinedFunctions, [&](Function *F) {
- F->removeDeadConstantUsers();
- return !F->isDefTriviallyDead();
- });
-
// Delete the non-comdat ones from the module and also from our vector.
auto *NonComdatBegin = partition(
InlinedFunctions, [&](Function *F) { return F->hasComdat(); });
>From f51d5417975068d09f6594cb1cde46d8f313c8cc Mon Sep 17 00:00:00 2001
From: dfukalov <1671137+dfukalov at users.noreply.github.com>
Date: Mon, 1 Jul 2024 16:59:12 +0200
Subject: [PATCH 4/6] clang-format
---
llvm/lib/Transforms/IPO/AlwaysInliner.cpp | 23 +++++++++++------------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
index 9290435bab640..d73518c627bd7 100644
--- a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
+++ b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
@@ -51,9 +51,9 @@ bool AlwaysInlineImpl(
for (User *U : F.users())
if (auto *CB = dyn_cast<CallBase>(U))
if (CB->getCalledFunction() == &F &&
- CB->hasFnAttr(Attribute::AlwaysInline) &&
- !CB->getAttributes().hasFnAttr(Attribute::NoInline))
- Calls.insert(CB);
+ CB->hasFnAttr(Attribute::AlwaysInline) &&
+ !CB->getAttributes().hasFnAttr(Attribute::NoInline))
+ Calls.insert(CB);
for (CallBase *CB : Calls) {
Function *Caller = CB->getCaller();
@@ -62,18 +62,17 @@ bool AlwaysInlineImpl(
BasicBlock *Block = CB->getParent();
InlineFunctionInfo IFI(GetAssumptionCache, &PSI,
- GetBFI ? &GetBFI(*Caller) : nullptr,
- GetBFI ? &GetBFI(F) : nullptr);
+ GetBFI ? &GetBFI(*Caller) : nullptr,
+ GetBFI ? &GetBFI(F) : nullptr);
InlineResult Res = InlineFunction(*CB, IFI, /*MergeAttributes=*/true,
&GetAAR(F), InsertLifetime);
if (!Res.isSuccess()) {
ORE.emit([&]() {
- return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc,
- Block)
- << "'" << ore::NV("Callee", &F) << "' is not inlined into '"
- << ore::NV("Caller", Caller)
- << "': " << ore::NV("Reason", Res.getFailureReason());
+ return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block)
+ << "'" << ore::NV("Callee", &F) << "' is not inlined into '"
+ << ore::NV("Caller", Caller)
+ << "': " << ore::NV("Reason", Res.getFailureReason());
});
continue;
}
@@ -101,8 +100,8 @@ bool AlwaysInlineImpl(
}
// Delete the non-comdat ones from the module and also from our vector.
- auto *NonComdatBegin = partition(
- InlinedFunctions, [&](Function *F) { return F->hasComdat(); });
+ auto *NonComdatBegin =
+ partition(InlinedFunctions, [&](Function *F) { return F->hasComdat(); });
for (Function *F : make_range(NonComdatBegin, InlinedFunctions.end())) {
M.getFunctionList().erase(F);
Changed = true;
>From f29f1d2aaa3b843cf750f8f220c6e74013891ded Mon Sep 17 00:00:00 2001
From: dfukalov <1671137+dfukalov at users.noreply.github.com>
Date: Mon, 1 Jul 2024 22:36:59 +0200
Subject: [PATCH 5/6] removed obsolete part of InlinedFunctions.
---
llvm/lib/Transforms/IPO/AlwaysInliner.cpp | 19 +++++--------------
1 file changed, 5 insertions(+), 14 deletions(-)
diff --git a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
index d73518c627bd7..517d3c3f81155 100644
--- a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
+++ b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
@@ -37,7 +37,7 @@ bool AlwaysInlineImpl(
function_ref<BlockFrequencyInfo &(Function &)> GetBFI) {
SmallSetVector<CallBase *, 16> Calls;
bool Changed = false;
- SmallVector<Function *, 16> InlinedFunctions;
+ SmallVector<Function *, 16> InlinedComdatFunctions;
for (Function &F : make_early_inc_range(M)) {
if (F.isPresplitCoroutine())
@@ -91,7 +91,7 @@ bool AlwaysInlineImpl(
// re-walking the rest of the module and avoids dealing with any
// iterator invalidation issues while deleting functions.
if (F.hasComdat()) {
- InlinedFunctions.push_back(&F);
+ InlinedComdatFunctions.push_back(&F);
} else {
M.getFunctionList().erase(F);
Changed = true;
@@ -99,21 +99,12 @@ bool AlwaysInlineImpl(
}
}
- // Delete the non-comdat ones from the module and also from our vector.
- auto *NonComdatBegin =
- partition(InlinedFunctions, [&](Function *F) { return F->hasComdat(); });
- for (Function *F : make_range(NonComdatBegin, InlinedFunctions.end())) {
- M.getFunctionList().erase(F);
- Changed = true;
- }
- InlinedFunctions.erase(NonComdatBegin, InlinedFunctions.end());
-
- if (!InlinedFunctions.empty()) {
+ if (!InlinedComdatFunctions.empty()) {
// Now we just have the comdat functions. Filter out the ones whose comdats
// are not actually dead.
- filterDeadComdatFunctions(InlinedFunctions);
+ filterDeadComdatFunctions(InlinedComdatFunctions);
// The remaining functions are actually dead.
- for (Function *F : InlinedFunctions) {
+ for (Function *F : InlinedComdatFunctions) {
M.getFunctionList().erase(F);
Changed = true;
}
>From c0aa14d134b70273fe10fb1bbea2c8de519ba755 Mon Sep 17 00:00:00 2001
From: dfukalov <1671137+dfukalov at users.noreply.github.com>
Date: Mon, 1 Jul 2024 22:55:10 +0200
Subject: [PATCH 6/6] Comment updated.
---
llvm/lib/Transforms/IPO/AlwaysInliner.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
index 517d3c3f81155..1f787c733079e 100644
--- a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
+++ b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
@@ -87,9 +87,8 @@ bool AlwaysInlineImpl(
F.removeDeadConstantUsers();
if (F.hasFnAttribute(Attribute::AlwaysInline) && F.isDefTriviallyDead()) {
- // Remember to try and delete this function afterward. This both avoids
- // re-walking the rest of the module and avoids dealing with any
- // iterator invalidation issues while deleting functions.
+ // Remember to try and delete this function afterward. This allows to call
+ // filterDeadComdatFunctions() only once.
if (F.hasComdat()) {
InlinedComdatFunctions.push_back(&F);
} else {
More information about the llvm-commits
mailing list