diff --git a/llvm/include/llvm/CodeGen/Passes.h b/llvm/include/llvm/CodeGen/Passes.h --- a/llvm/include/llvm/CodeGen/Passes.h +++ b/llvm/include/llvm/CodeGen/Passes.h @@ -578,6 +578,9 @@ /// otherwise this does nothing FunctionPass *createRegAllocScoringPass(); + // When learning an eviction policy, export basic blocks and profile info + FunctionPass *createRegAllocBBProfileDumpPass(); + /// JMC instrument pass. ModulePass *createJMCInstrumenterPass(); diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -337,6 +337,7 @@ void initializeRegAllocFastPass(PassRegistry&); void initializeRegAllocPriorityAdvisorAnalysisPass(PassRegistry &); void initializeRegAllocScoringPass(PassRegistry &); +void initializeRegAllocBBProfileDumpPass(PassRegistry &); void initializeRegBankSelectPass(PassRegistry&); void initializeRegToMemLegacyPass(PassRegistry&); void initializeRegUsageInfoCollectorPass(PassRegistry&); diff --git a/llvm/lib/CodeGen/MLRegallocEvictAdvisor.cpp b/llvm/lib/CodeGen/MLRegallocEvictAdvisor.cpp --- a/llvm/lib/CodeGen/MLRegallocEvictAdvisor.cpp +++ b/llvm/lib/CodeGen/MLRegallocEvictAdvisor.cpp @@ -70,6 +70,10 @@ cl::desc("Whether or not to enable features under development for the ML " "regalloc advisor")); +static cl::opt BasicBlockProfileDump( + "regalloc-bb-profile-dump", cl::Hidden, + cl::desc("Basic block profile dump for external cost modelling")); + #else static const bool EnableDevelopmentFeatures = false; #endif // #ifdef LLVM_HAVE_TFLITE @@ -115,6 +119,55 @@ INITIALIZE_PASS(RegAllocScoring, "regallocscoringpass", "Register Allocation Scoring Pass", false, false) +// The BB frequency/mc dump pass. +// This dumps the basic blocks along with some frequency info right before +// assembly printing time so that they can be processed by an external cost +// model. +// This only happens in development mode with a flag. It's a no-op otherwise. +namespace llvm { +class RegAllocBBProfileDump : public MachineFunctionPass { +public: + static char ID; + std::unique_ptr FileOutput; + + RegAllocBBProfileDump() : MachineFunctionPass(ID) { + initializeRegAllocBBProfileDumpPass(*PassRegistry::getPassRegistry()); + if(!BasicBlockProfileDump.empty()) { + std::error_code PossibleFileError; + FileOutput = std::make_unique(BasicBlockProfileDump, + PossibleFileError); + } + } + + ~RegAllocBBProfileDump() override { + if(FileOutput) { + FileOutput->close(); + } + } + + StringRef getPassName() const override { + return "Register Allocation BB Profile Dump"; + } + + // Analysis usage + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + AU.addRequired(); + MachineFunctionPass::getAnalysisUsage(AU); + } + + // Perform the pass + bool runOnMachineFunction(MachineFunction &) override; +}; + +char RegAllocBBProfileDump::ID = 0; +FunctionPass *createRegAllocBBProfileDumpPass() { return new RegAllocBBProfileDump(); } + +} // namespace llvm + +INITIALIZE_PASS(RegAllocBBProfileDump, "regallocbbdump", "Register Allocation BB Dump", + false, false) + // =================================== // Common ML Advisor declarations // =================================== @@ -1128,6 +1181,18 @@ GetReward); return false; } + +bool RegAllocBBProfileDump::runOnMachineFunction(MachineFunction &MF) { + if (!BasicBlockProfileDump.empty()) { + MachineBlockFrequencyInfo &MBFI = getAnalysis(); + for (auto &MBB : MF) { + *FileOutput.get() << MF.getName() << "," + << MBB.getNumber() << "," + << MBFI.getBlockFreqRelativeToEntryBlock(&MBB) << "\n"; + } + } + return false; +} #endif // #ifdef LLVM_HAVE_TFLITE RegAllocEvictionAdvisorAnalysis *llvm::createReleaseModeAdvisor() { @@ -1137,4 +1202,5 @@ // In all cases except development mode, we don't need scoring. #if !defined(LLVM_HAVE_TFLITE) bool RegAllocScoring::runOnMachineFunction(MachineFunction &) { return false; } +bool RegAllocBBProfileDump::runOnMachineFunction(MachineFunction &) { return false; } #endif diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp --- a/llvm/lib/CodeGen/TargetPassConfig.cpp +++ b/llvm/lib/CodeGen/TargetPassConfig.cpp @@ -1273,6 +1273,9 @@ // Add passes that directly emit MI after all other MI passes. addPreEmitPass2(); + // Export basic blocks for training ML Regalloc models + addPass(createRegAllocBBProfileDumpPass()); + AddingMachinePasses = false; } diff --git a/llvm/test/CodeGen/MLRegalloc/bb-profile-dump.ll b/llvm/test/CodeGen/MLRegalloc/bb-profile-dump.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/MLRegalloc/bb-profile-dump.ll @@ -0,0 +1,21 @@ +; REQUIRES: have_tflite +; REQUIRES: default_triple +; +; Check that the basic block profile dump outputs data and in the correct +; format. +; +; RUN: llc -o /dev/null -regalloc-enable-advisor=release -regalloc-bb-profile-dump=%t %s +; RUN: FileCheck --input-file %t %s + +define i64 @f2(i64 %a, i64 %b) { + %sum = add i64 %a, %b + ret i64 %sum +} + +define i64 @f1() { + %sum = call i64 @f2(i64 2, i64 2) + ret i64 %sum +} + +; CHECK: f2,0,1.000000e+00 +; CHECK-NEXT: f1,0,1.000000e+00