};
std::unique_ptr<InlineAdvisor>
-getReleaseModeAdvisor(Module &M, ModuleAnalysisManager &MAM);
+getReleaseModeAdvisor(Module &M, ModuleAnalysisManager &MAM,
+ std::function<bool(CallBase &)> GetDefaultAdvice);
std::unique_ptr<InlineAdvisor>
getDevelopmentModeAdvisor(Module &M, ModuleAnalysisManager &MAM,
extern const char *const DecisionName;
extern const TensorSpec InlineDecisionSpec;
extern const char *const DefaultDecisionName;
+extern const TensorSpec DefaultDecisionSpec;
extern const char *const RewardName;
using InlineFeatures = std::vector<int64_t>;
class MLInlineAdvisor : public InlineAdvisor {
public:
MLInlineAdvisor(Module &M, ModuleAnalysisManager &MAM,
- std::unique_ptr<MLModelRunner> ModelRunner);
+ std::unique_ptr<MLModelRunner> ModelRunner,
+ std::function<bool(CallBase &)> GetDefaultAdvice);
virtual ~MLInlineAdvisor() = default;
unsigned getInitialFunctionLevel(const Function &F) const;
std::unique_ptr<MLModelRunner> ModelRunner;
+ std::function<bool(CallBase &)> GetDefaultAdvice;
private:
int64_t getModuleIRSize() const;
bool isLogging() const { return !!Logger; }
std::unique_ptr<MLInlineAdvice> getMandatoryAdviceImpl(CallBase &CB) override;
- std::function<bool(CallBase &)> GetDefaultAdvice;
const bool IsDoingInference;
std::unique_ptr<TrainingLogger> Logger;
append_range(FT, MUTR->extraOutputsForLoggingSpecs());
DefaultDecisionPos = FT.size();
- FT.push_back(TensorSpec::createSpec<int64_t>(DefaultDecisionName, {1}));
+ FT.push_back(DefaultDecisionSpec);
DecisionPos = FT.size();
FT.push_back(InlineDecisionSpec);
std::unique_ptr<MLModelRunner> ModelRunner,
std::function<bool(CallBase &)> GetDefaultAdvice,
std::unique_ptr<TrainingLogger> Logger)
- : MLInlineAdvisor(M, MAM, std::move(ModelRunner)),
- GetDefaultAdvice(GetDefaultAdvice),
+ : MLInlineAdvisor(M, MAM, std::move(ModelRunner), GetDefaultAdvice),
IsDoingInference(isa<ModelUnderTrainingRunner>(getModelRunner())),
Logger(std::move(Logger)),
InitialNativeSize(isLogging() ? getTotalSizeEstimate() : 0),
Advisor.reset(DA.Factory(M, FAM, Params, IC));
return !!Advisor;
}
+ auto GetDefaultAdvice = [&FAM, Params](CallBase &CB) {
+ auto OIC = getDefaultInlineAdvice(CB, FAM, Params);
+ return OIC.has_value();
+ };
switch (Mode) {
case InliningAdvisorMode::Default:
LLVM_DEBUG(dbgs() << "Using default inliner heuristic.\n");
case InliningAdvisorMode::Development:
#ifdef LLVM_HAVE_TFLITE
LLVM_DEBUG(dbgs() << "Using development-mode inliner policy.\n");
- Advisor =
- llvm::getDevelopmentModeAdvisor(M, MAM, [&FAM, Params](CallBase &CB) {
- auto OIC = getDefaultInlineAdvice(CB, FAM, Params);
- return OIC.has_value();
- });
+ Advisor = llvm::getDevelopmentModeAdvisor(M, MAM, GetDefaultAdvice);
#endif
break;
case InliningAdvisorMode::Release:
LLVM_DEBUG(dbgs() << "Using release-mode inliner policy.\n");
- Advisor = llvm::getReleaseModeAdvisor(M, MAM);
+ Advisor = llvm::getReleaseModeAdvisor(M, MAM, GetDefaultAdvice);
break;
}
"Base file path for the interactive mode. The incoming filename should "
"have the name <inliner-interactive-channel-base>.in, while the "
"outgoing name should be <inliner-interactive-channel-base>.out"));
+static cl::opt<bool> InteractiveIncludeDefault(
+ "inliner-interactive-include-default", cl::Hidden,
+ cl::desc(
+ (Twine("In interactive mode, also send the default policy decision: ") +
+ DefaultDecisionName + ".")
+ .str()));
#if defined(LLVM_HAVE_TF_AOT_INLINERSIZEMODEL)
// codegen-ed file
#endif
std::unique_ptr<InlineAdvisor>
-llvm::getReleaseModeAdvisor(Module &M, ModuleAnalysisManager &MAM) {
+llvm::getReleaseModeAdvisor(Module &M, ModuleAnalysisManager &MAM,
+ std::function<bool(CallBase &)> GetDefaultAdvice) {
if (!llvm::isEmbeddedModelEvaluatorValid<CompiledModelType>() &&
InteractiveChannelBaseName.empty())
return nullptr;
if (InteractiveChannelBaseName.empty())
AOTRunner = std::make_unique<ReleaseModeModelRunner<CompiledModelType>>(
M.getContext(), FeatureMap, DecisionName);
- else
+ else {
+ auto Features = FeatureMap;
+ if (InteractiveIncludeDefault)
+ Features.push_back(DefaultDecisionSpec);
AOTRunner = std::make_unique<InteractiveModelRunner>(
- M.getContext(), FeatureMap, InlineDecisionSpec,
+ M.getContext(), Features, InlineDecisionSpec,
InteractiveChannelBaseName + ".out",
InteractiveChannelBaseName + ".in");
- return std::make_unique<MLInlineAdvisor>(M, MAM, std::move(AOTRunner));
+ }
+ return std::make_unique<MLInlineAdvisor>(M, MAM, std::move(AOTRunner),
+ GetDefaultAdvice);
}
#define DEBUG_TYPE "inline-ml"
const TensorSpec llvm::InlineDecisionSpec =
TensorSpec::createSpec<int64_t>(DecisionName, {1});
const char *const llvm::DefaultDecisionName = "inlining_default";
+const TensorSpec llvm::DefaultDecisionSpec =
+ TensorSpec::createSpec<int64_t>(DefaultDecisionName, {1});
const char *const llvm::RewardName = "delta_size";
CallBase *getInlinableCS(Instruction &I) {
return nullptr;
}
-MLInlineAdvisor::MLInlineAdvisor(Module &M, ModuleAnalysisManager &MAM,
- std::unique_ptr<MLModelRunner> Runner)
+MLInlineAdvisor::MLInlineAdvisor(
+ Module &M, ModuleAnalysisManager &MAM,
+ std::unique_ptr<MLModelRunner> Runner,
+ std::function<bool(CallBase &)> GetDefaultAdvice)
: InlineAdvisor(
M, MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager()),
- ModelRunner(std::move(Runner)),
+ ModelRunner(std::move(Runner)), GetDefaultAdvice(GetDefaultAdvice),
CG(MAM.getResult<LazyCallGraphAnalysis>(M)),
InitialIRSize(getModuleIRSize()), CurrentIRSize(InitialIRSize) {
assert(ModelRunner);
*ModelRunner->getTensor<int64_t>(inlineCostFeatureToMlFeature(
static_cast<InlineCostFeatureIndex>(I))) = CostFeatures->at(I);
}
-
+ // This one would have been set up to be right at the end.
+ if (!InteractiveChannelBaseName.empty() && InteractiveIncludeDefault)
+ *ModelRunner->getTensor<int64_t>(InlineCostFeatureIndex::NumberOfFeatures) =
+ GetDefaultAdvice(CB);
return getAdviceFromModel(CB, ORE);
}
; RUN: cp %S/Inputs/interactive_main.py %t.rundir
; RUN: %python %t.rundir/interactive_main.py %t.channel-basename \
; RUN: opt -passes=scc-oz-module-inliner -interactive-model-runner-echo-reply \
-; RUN: -enable-ml-inliner=release --inliner-interactive-channel-base=%t.channel-basename %S/Inputs/test-module.ll -S -o /dev/null | FileCheck %s
+; RUN: -enable-ml-inliner=release -inliner-interactive-channel-base=%t.channel-basename %S/Inputs/test-module.ll -S -o /dev/null | FileCheck %s
+; RUN: %python %t.rundir/interactive_main.py %t.channel-basename \
+; RUN: opt -passes=scc-oz-module-inliner -interactive-model-runner-echo-reply \
+; RUN: -inliner-interactive-include-default -enable-ml-inliner=release \
+; RUN: -inliner-interactive-channel-base=%t.channel-basename %S/Inputs/test-module.ll -S -o /dev/null | FileCheck %s -check-prefixes=CHECK,CHECK-DEFAULT
+
;; It'd be nice if we had stdout and stderr interleaved, but we don't, so
;; let's just check the features have non-zero values, and that we see as many
; CHECK-NEXT: sroa_savings: 0
; CHECK: unsimplified_common_instructions: 5
; CHECK: callee_users: 3
+; CHECK-DEFAULT: inlining_default: 0
; CHECK: observation: 5
; CHECK-NOT: observation: 6