[llvm] [MLGO] Add EvolutionInlineAdvisor (PR #166386)
Hongzheng Chen via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 4 10:52:39 PST 2025
https://github.com/chhzh123 updated https://github.com/llvm/llvm-project/pull/166386
>From e9ba1fef1e2a010844eec2d295a6d70ce10c7e57 Mon Sep 17 00:00:00 2001
From: chhzh123 <hc676 at cornell.edu>
Date: Tue, 4 Nov 2025 15:35:30 +0000
Subject: [PATCH 1/4] Add EvolutionInlineAdvisor
---
.../llvm/Analysis/EvolutionInlineAdvisor.h | 35 ++++++++++
llvm/include/llvm/Analysis/InlineAdvisor.h | 7 +-
llvm/lib/Analysis/CMakeLists.txt | 1 +
llvm/lib/Analysis/EvolutionInlineAdvisor.cpp | 64 +++++++++++++++++++
llvm/lib/Analysis/InlineAdvisor.cpp | 5 ++
llvm/lib/Passes/PassBuilderPipelines.cpp | 4 +-
.../Transforms/Inline/ML/default-evolution.ll | 20 ++++++
.../gn/secondary/llvm/lib/Analysis/BUILD.gn | 1 +
8 files changed, 135 insertions(+), 2 deletions(-)
create mode 100644 llvm/include/llvm/Analysis/EvolutionInlineAdvisor.h
create mode 100644 llvm/lib/Analysis/EvolutionInlineAdvisor.cpp
create mode 100644 llvm/test/Transforms/Inline/ML/default-evolution.ll
diff --git a/llvm/include/llvm/Analysis/EvolutionInlineAdvisor.h b/llvm/include/llvm/Analysis/EvolutionInlineAdvisor.h
new file mode 100644
index 0000000000000..9c797e4ec1ca3
--- /dev/null
+++ b/llvm/include/llvm/Analysis/EvolutionInlineAdvisor.h
@@ -0,0 +1,35 @@
+//===- EvolutionInlineAdvisor.h - LLM+Evolution-based InlineAdvisor factories
+//---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_EvolutionInlineAdvisor_H
+#define LLVM_ANALYSIS_EvolutionInlineAdvisor_H
+
+#include "llvm/Analysis/FunctionPropertiesAnalysis.h"
+#include "llvm/Analysis/InlineAdvisor.h"
+#include "llvm/Analysis/LazyCallGraph.h"
+#include "llvm/IR/PassManager.h"
+
+#include <memory>
+
+namespace llvm {
+
+class EvolutionInlineAdvisor : public InlineAdvisor {
+public:
+ EvolutionInlineAdvisor(Module &M, FunctionAnalysisManager &FAM,
+ InlineContext IC)
+ : InlineAdvisor(M, FAM, IC) {}
+
+private:
+ std::unique_ptr<InlineAdvice> getAdviceImpl(CallBase &CB) override;
+ std::unique_ptr<InlineAdvice> getEvolutionAdviceImpl(CallBase &CB);
+};
+
+} // namespace llvm
+
+#endif // LLVM_ANALYSIS_EvolutionInlineAdvisor_H
\ No newline at end of file
diff --git a/llvm/include/llvm/Analysis/InlineAdvisor.h b/llvm/include/llvm/Analysis/InlineAdvisor.h
index 50ba3c13da70f..b0380635b920d 100644
--- a/llvm/include/llvm/Analysis/InlineAdvisor.h
+++ b/llvm/include/llvm/Analysis/InlineAdvisor.h
@@ -40,7 +40,12 @@ struct ReplayInlinerSettings;
/// also permits generating training logs, for offline training.
///
/// - Dynamically load an advisor via a plugin (PluginInlineAdvisorAnalysis)
-enum class InliningAdvisorMode : int { Default, Release, Development };
+enum class InliningAdvisorMode : int {
+ Default,
+ Release,
+ Development,
+ Evolution
+};
// Each entry represents an inline driver.
enum class InlinePass : int {
diff --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt
index 16dd6f8b86006..46a31af4725da 100644
--- a/llvm/lib/Analysis/CMakeLists.txt
+++ b/llvm/lib/Analysis/CMakeLists.txt
@@ -74,6 +74,7 @@ add_llvm_component_library(LLVMAnalysis
DXILResource.cpp
DXILMetadataAnalysis.cpp
EphemeralValuesCache.cpp
+ EvolutionInlineAdvisor.cpp
FloatingPointPredicateUtils.cpp
FunctionPropertiesAnalysis.cpp
GlobalsModRef.cpp
diff --git a/llvm/lib/Analysis/EvolutionInlineAdvisor.cpp b/llvm/lib/Analysis/EvolutionInlineAdvisor.cpp
new file mode 100644
index 0000000000000..b99134b42fef9
--- /dev/null
+++ b/llvm/lib/Analysis/EvolutionInlineAdvisor.cpp
@@ -0,0 +1,64 @@
+//-------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements EvolutionInlineAdvisor.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/EvolutionInlineAdvisor.h"
+#include "llvm/Analysis/InlineAdvisor.h"
+#include "llvm/Analysis/OptimizationRemarkEmitter.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Support/CommandLine.h"
+
+using namespace llvm;
+
+// EVOLVE-BLOCK-START
+// You can include additional LLVM headers here.
+
+std::unique_ptr<InlineAdvice>
+EvolutionInlineAdvisor::getEvolutionAdviceImpl(CallBase &CB) {
+ // Implementation of inlining strategy. Do not change the function interface.
+ bool IsInliningRecommended = false;
+ return std::make_unique<InlineAdvice>(
+ this, CB,
+ FAM.getResult<OptimizationRemarkEmitterAnalysis>(*CB.getCaller()),
+ IsInliningRecommended);
+}
+
+// EVOLVE-BLOCK-END
+
+std::unique_ptr<InlineAdvice>
+EvolutionInlineAdvisor::getAdviceImpl(CallBase &CB) {
+ // legality check
+ // reference: MLInlineAdvisor::getAdviceImpl
+ auto &Caller = *CB.getCaller();
+ auto &Callee = *CB.getCalledFunction();
+ auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(Caller);
+
+ auto MandatoryKind = InlineAdvisor::getMandatoryKind(CB, FAM, ORE);
+ // If this is a "never inline" case, there won't be any changes to internal
+ // state we need to track, so we can just return the base InlineAdvice, which
+ // will do nothing interesting.
+ // Same thing if this is a recursive case.
+ if (MandatoryKind == InlineAdvisor::MandatoryInliningKind::Never ||
+ &Caller == &Callee)
+ return getMandatoryAdvice(CB, false);
+
+ auto IsViable = isInlineViable(Callee);
+ if (!IsViable.isSuccess())
+ return std::make_unique<InlineAdvice>(this, CB, ORE, false);
+
+ bool Mandatory =
+ MandatoryKind == InlineAdvisor::MandatoryInliningKind::Always;
+
+ if (Mandatory)
+ return std::make_unique<InlineAdvice>(this, CB, ORE, true);
+
+ return getEvolutionAdviceImpl(CB);
+}
diff --git a/llvm/lib/Analysis/InlineAdvisor.cpp b/llvm/lib/Analysis/InlineAdvisor.cpp
index 0fa804f2959e8..48053161ff32e 100644
--- a/llvm/lib/Analysis/InlineAdvisor.cpp
+++ b/llvm/lib/Analysis/InlineAdvisor.cpp
@@ -14,6 +14,7 @@
#include "llvm/Analysis/InlineAdvisor.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/EvolutionInlineAdvisor.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/EphemeralValuesCache.h"
#include "llvm/Analysis/IR2Vec.h"
@@ -270,6 +271,10 @@ bool InlineAdvisorAnalysis::Result::tryCreate(
return false;
Advisor = llvm::getReleaseModeAdvisor(M, MAM, GetDefaultAdvice);
break;
+ case InliningAdvisorMode::Evolution:
+ LLVM_DEBUG(dbgs() << "Using evolution-mode inliner policy.\n");
+ Advisor.reset(new EvolutionInlineAdvisor(M, FAM, IC));
+ break;
}
return !!Advisor;
diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
index bd03ac090721c..51f26e219f3fd 100644
--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
+++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -160,7 +160,9 @@ static cl::opt<InliningAdvisorMode> UseInlineAdvisor(
clEnumValN(InliningAdvisorMode::Development, "development",
"Use development mode (runtime-loadable model)"),
clEnumValN(InliningAdvisorMode::Release, "release",
- "Use release mode (AOT-compiled model)")));
+ "Use release mode (AOT-compiled model)"),
+ clEnumValN(InliningAdvisorMode::Evolution, "evolution",
+ "Use evolution mode (AlphaEvolve-like framework)")));
/// Flag to enable inline deferral during PGO.
static cl::opt<bool>
diff --git a/llvm/test/Transforms/Inline/ML/default-evolution.ll b/llvm/test/Transforms/Inline/ML/default-evolution.ll
new file mode 100644
index 0000000000000..81d16deeebbaf
--- /dev/null
+++ b/llvm/test/Transforms/Inline/ML/default-evolution.ll
@@ -0,0 +1,20 @@
+; RUN: opt -passes='default<O3>' \
+; RUN: -S -enable-ml-inliner=evolution < %s 2>&1 | FileCheck %s
+
+declare i32 @f1()
+
+define i32 @f2() {
+ ret i32 1
+}
+
+define i32 @f3() {
+ %a = call i32 @f1()
+ %b = call i32 @f2()
+ %c = add i32 %a, %b
+ ret i32 %c
+}
+
+; all the functions are not inlined by default
+; CHECK-LABEL: @f1
+; CHECK-LABEL: @f2
+; CHECK-LABEL: @f3
\ No newline at end of file
diff --git a/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn
index ab25c263095fa..6cb46067d7c8c 100644
--- a/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn
@@ -53,6 +53,7 @@ static_library("Analysis") {
"DomTreeUpdater.cpp",
"DominanceFrontier.cpp",
"EphemeralValuesCache.cpp",
+ "EvolutionInlineAdvisor.cpp",
"FloatingPointPredicateUtils.cpp",
"FunctionPropertiesAnalysis.cpp",
"GlobalsModRef.cpp",
>From 6c6045547222217e0332dc3d5a46de10804537a9 Mon Sep 17 00:00:00 2001
From: chhzh123 <hc676 at cornell.edu>
Date: Tue, 4 Nov 2025 15:47:48 +0000
Subject: [PATCH 2/4] Fix format
---
llvm/lib/Analysis/InlineAdvisor.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Analysis/InlineAdvisor.cpp b/llvm/lib/Analysis/InlineAdvisor.cpp
index 48053161ff32e..858e7e5ac5429 100644
--- a/llvm/lib/Analysis/InlineAdvisor.cpp
+++ b/llvm/lib/Analysis/InlineAdvisor.cpp
@@ -14,9 +14,9 @@
#include "llvm/Analysis/InlineAdvisor.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/Analysis/EvolutionInlineAdvisor.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/EphemeralValuesCache.h"
+#include "llvm/Analysis/EvolutionInlineAdvisor.h"
#include "llvm/Analysis/IR2Vec.h"
#include "llvm/Analysis/InlineCost.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
>From 3e162dd6ba2a1dc0706dfd28d5a9a27ed3778ff4 Mon Sep 17 00:00:00 2001
From: chhzh123 <hc676 at cornell.edu>
Date: Tue, 4 Nov 2025 15:53:52 +0000
Subject: [PATCH 3/4] Fix macro
---
llvm/include/llvm/Analysis/EvolutionInlineAdvisor.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/Analysis/EvolutionInlineAdvisor.h b/llvm/include/llvm/Analysis/EvolutionInlineAdvisor.h
index 9c797e4ec1ca3..a8fb1877a757c 100644
--- a/llvm/include/llvm/Analysis/EvolutionInlineAdvisor.h
+++ b/llvm/include/llvm/Analysis/EvolutionInlineAdvisor.h
@@ -1,4 +1,4 @@
-//===- EvolutionInlineAdvisor.h - LLM+Evolution-based InlineAdvisor factories
+//===- EvolutionInlineAdvisor.h - LLM+Evolutionary Algorithm-based InlineAdvisor
//---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_EvolutionInlineAdvisor_H
-#define LLVM_ANALYSIS_EvolutionInlineAdvisor_H
+#ifndef LLVM_ANALYSIS_EVOLUTIONINLINEADVISOR_H
+#define LLVM_ANALYSIS_EVOLUTIONINLINEADVISOR_H
#include "llvm/Analysis/FunctionPropertiesAnalysis.h"
#include "llvm/Analysis/InlineAdvisor.h"
@@ -32,4 +32,4 @@ class EvolutionInlineAdvisor : public InlineAdvisor {
} // namespace llvm
-#endif // LLVM_ANALYSIS_EvolutionInlineAdvisor_H
\ No newline at end of file
+#endif // LLVM_ANALYSIS_EVOLUTIONINLINEADVISOR_H
\ No newline at end of file
>From 360aa608d00f44c59051575d8f986407a7e63ee6 Mon Sep 17 00:00:00 2001
From: chhzh123 <hc676 at cornell.edu>
Date: Tue, 4 Nov 2025 18:52:18 +0000
Subject: [PATCH 4/4] fix
---
llvm/include/llvm/Analysis/EvolutionInlineAdvisor.h | 2 +-
llvm/lib/Analysis/EvolutionInlineAdvisor.cpp | 10 +++++-----
llvm/test/Transforms/Inline/ML/default-evolution.ll | 6 ++++++
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/llvm/include/llvm/Analysis/EvolutionInlineAdvisor.h b/llvm/include/llvm/Analysis/EvolutionInlineAdvisor.h
index a8fb1877a757c..66311ecfe3174 100644
--- a/llvm/include/llvm/Analysis/EvolutionInlineAdvisor.h
+++ b/llvm/include/llvm/Analysis/EvolutionInlineAdvisor.h
@@ -27,7 +27,7 @@ class EvolutionInlineAdvisor : public InlineAdvisor {
private:
std::unique_ptr<InlineAdvice> getAdviceImpl(CallBase &CB) override;
- std::unique_ptr<InlineAdvice> getEvolutionAdviceImpl(CallBase &CB);
+ std::unique_ptr<InlineAdvice> getEvolvableAdvice(CallBase &CB);
};
} // namespace llvm
diff --git a/llvm/lib/Analysis/EvolutionInlineAdvisor.cpp b/llvm/lib/Analysis/EvolutionInlineAdvisor.cpp
index b99134b42fef9..57d8a41b4e4c4 100644
--- a/llvm/lib/Analysis/EvolutionInlineAdvisor.cpp
+++ b/llvm/lib/Analysis/EvolutionInlineAdvisor.cpp
@@ -1,4 +1,4 @@
-//-------------------===//
+//===- EvolutionInlineAdvisor.cpp - skeleton implementation ------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -22,7 +22,7 @@ using namespace llvm;
// You can include additional LLVM headers here.
std::unique_ptr<InlineAdvice>
-EvolutionInlineAdvisor::getEvolutionAdviceImpl(CallBase &CB) {
+EvolutionInlineAdvisor::getEvolvableAdvice(CallBase &CB) {
// Implementation of inlining strategy. Do not change the function interface.
bool IsInliningRecommended = false;
return std::make_unique<InlineAdvice>(
@@ -35,8 +35,8 @@ EvolutionInlineAdvisor::getEvolutionAdviceImpl(CallBase &CB) {
std::unique_ptr<InlineAdvice>
EvolutionInlineAdvisor::getAdviceImpl(CallBase &CB) {
- // legality check
- // reference: MLInlineAdvisor::getAdviceImpl
+ // TODO: refactor the legality check to make them common with
+ // MLInlineAdvisor::getAdviceImpl
auto &Caller = *CB.getCaller();
auto &Callee = *CB.getCalledFunction();
auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(Caller);
@@ -60,5 +60,5 @@ EvolutionInlineAdvisor::getAdviceImpl(CallBase &CB) {
if (Mandatory)
return std::make_unique<InlineAdvice>(this, CB, ORE, true);
- return getEvolutionAdviceImpl(CB);
+ return getEvolvableAdvice(CB);
}
diff --git a/llvm/test/Transforms/Inline/ML/default-evolution.ll b/llvm/test/Transforms/Inline/ML/default-evolution.ll
index 81d16deeebbaf..2761f07b8e219 100644
--- a/llvm/test/Transforms/Inline/ML/default-evolution.ll
+++ b/llvm/test/Transforms/Inline/ML/default-evolution.ll
@@ -1,5 +1,7 @@
; RUN: opt -passes='default<O3>' \
; RUN: -S -enable-ml-inliner=evolution < %s 2>&1 | FileCheck %s
+; RUN: opt -passes='default<O3>' \
+; RUN: -S -enable-ml-inliner=default < %s 2>&1 | FileCheck %s
declare i32 @f1()
@@ -17,4 +19,8 @@ define i32 @f3() {
; all the functions are not inlined by default
; CHECK-LABEL: @f1
; CHECK-LABEL: @f2
+; CHECK-LABEL: @f3
+; default inlining policy may inline @f2
+; CHECK-LABEL: @f1
+; CHECK-NOT-LABEL: @f2
; CHECK-LABEL: @f3
\ No newline at end of file
More information about the llvm-commits
mailing list