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,10 @@ /// otherwise this does nothing FunctionPass *createRegAllocScoringPass(); + // Export machine basic block profiles to a file if the necessary command + // line flags are set. + FunctionPass *createMBBProfileDumpPass(); + /// 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 initializeMBBProfileDumpPass(PassRegistry &); void initializeRegBankSelectPass(PassRegistry&); void initializeRegToMemLegacyPass(PassRegistry&); void initializeRegUsageInfoCollectorPass(PassRegistry&); diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt --- a/llvm/lib/CodeGen/CMakeLists.txt +++ b/llvm/lib/CodeGen/CMakeLists.txt @@ -144,6 +144,7 @@ MachineTraceMetrics.cpp MachineUniformityAnalysis.cpp MachineVerifier.cpp + MBBProfileDump.cpp MIRFSDiscriminator.cpp MIRSampleProfile.cpp MIRYamlMapping.cpp diff --git a/llvm/lib/CodeGen/MBBProfileDump.cpp b/llvm/lib/CodeGen/MBBProfileDump.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/CodeGen/MBBProfileDump.cpp @@ -0,0 +1,79 @@ +//===- MBBProfileDump.cpp - MBB Profile Dump Pass -------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Implementation of the MBB Profile Dump Pass +// +//===----------------------------------------------------------------------===// + +#include "llvm/CodeGen/MachineBlockFrequencyInfo.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/InitializePasses.h" +#include "llvm/Support/CommandLine.h" + +using namespace llvm; + +static cl::opt BasicBlockProfileDump( + "mbb-profile-dump", cl::Hidden, + cl::desc("Basic block profile dump for external cost modelling. If " + "matching up BBs with afterwards, the compilation must be " + "performed with -fbasic-block-sections=labels")); + +namespace llvm { +class MBBProfileDump : public MachineFunctionPass { +public: + static char ID; + std::unique_ptr FileOutput; + + MBBProfileDump() : MachineFunctionPass(ID) { + initializeMBBProfileDumpPass(*PassRegistry::getPassRegistry()); + if (!BasicBlockProfileDump.empty()) { + std::error_code PossibleFileError; + FileOutput = std::make_unique(BasicBlockProfileDump, + PossibleFileError); + } + } + + ~MBBProfileDump() 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 MBBProfileDump::ID = 0; +FunctionPass *createMBBProfileDumpPass() { return new MBBProfileDump(); } + +} // namespace llvm + +INITIALIZE_PASS(MBBProfileDump, "mbbprofiledump", "MBB Profile Dump", false, + false) + +bool MBBProfileDump::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; +} 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,11 @@ // Add passes that directly emit MI after all other MI passes. addPreEmitPass2(); + // Export machine basic block profile information to be used in downstream + // cost modelling applications. This needs to be right before the AsmPrinter + // so that nothing following it will mutate MBB numbers or frequencies. + addPass(createMBBProfileDumpPass()); + 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 -mbb-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