diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h --- a/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -236,6 +236,10 @@ /// split stack prologue. bool HasNoSplitStack = false; + /// Raw FDOstream for outputting machine basic block frequncies if the + /// --mbb-profile-dump flag is set for downstream cost modelling applications + std::unique_ptr MBBProfileDumpFileOutput; + protected: explicit AsmPrinter(TargetMachine &TM, std::unique_ptr Streamer); diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -39,6 +39,7 @@ #include "llvm/BinaryFormat/ELF.h" #include "llvm/CodeGen/GCMetadata.h" #include "llvm/CodeGen/GCMetadataPrinter.h" +#include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineDominators.h" @@ -128,6 +129,13 @@ #define DEBUG_TYPE "asm-printer" +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. Enabling this " + "flag during in-process ThinLTO is not supported.")); + const char DWARFGroupName[] = "dwarf"; const char DWARFGroupDescription[] = "DWARF Emission"; const char DbgTimerName[] = "emit"; @@ -352,11 +360,23 @@ VerboseAsm = OutStreamer->isVerboseAsm(); DwarfUsesRelocationsAcrossSections = MAI->doesDwarfUseRelocationsAcrossSections(); + if (!BasicBlockProfileDump.empty()) { + std::error_code PossibleFileError; + MBBProfileDumpFileOutput = std::make_unique( + BasicBlockProfileDump, PossibleFileError); + if (PossibleFileError) { + errs() << "Failed to open file for MBB Profile Dump:" + << PossibleFileError.message() << "\n"; + } + } } AsmPrinter::~AsmPrinter() { assert(!DD && Handlers.size() == NumUserHandlers && "Debug/EH info didn't get finalized"); + if(MBBProfileDumpFileOutput) { + MBBProfileDumpFileOutput->close(); + } } bool AsmPrinter::isPositionIndependent() const { @@ -414,6 +434,7 @@ MachineFunctionPass::getAnalysisUsage(AU); AU.addRequired(); AU.addRequired(); + AU.addRequired(); } bool AsmPrinter::doInitialization(Module &M) { @@ -1862,6 +1883,18 @@ OutStreamer->getCommentOS() << "-- End function\n"; OutStreamer->addBlankLine(); + + // Output MBB numbers, function names, and frequencies if the flag to dump + // MBB profile information has been set + if (!BasicBlockProfileDump.empty()) { + MachineBlockFrequencyInfo &MBFI = + getAnalysis().getBFI(); + for (const auto &MBB : *MF) { + *MBBProfileDumpFileOutput.get() + << MF->getName() << "," << MBB.getNumber() << "," + << MBFI.getBlockFreqRelativeToEntryBlock(&MBB) << "\n"; + } + } } /// Compute the number of Global Variables that uses a Constant. 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