diff options
author | Rahman Lavaee <rahmanl@google.com> | 2022-12-06 22:37:33 -0800 |
---|---|---|
committer | Rahman Lavaee <rahmanl@google.com> | 2022-12-06 22:50:09 -0800 |
commit | 6015a045d768feab3bae9ad9c0c81e118df8b04a (patch) | |
tree | 1b262fb982848781568ea17eb8da8aa4563d798a /llvm/lib/CodeGen/BasicBlockSections.cpp | |
parent | 1f421b6d7e4dde37be9ca490175ca4725add762b (diff) | |
download | llvm-6015a045d768feab3bae9ad9c0c81e118df8b04a.zip llvm-6015a045d768feab3bae9ad9c0c81e118df8b04a.tar.gz llvm-6015a045d768feab3bae9ad9c0c81e118df8b04a.tar.bz2 |
[Propeller] Use Fixed MBB ID instead of volatile MachineBasicBlock::Number.
Let Propeller use specialized IDs for basic blocks, instead of MBB number.
This allows optimizations not just prior to asm-printer, but throughout the entire codegen.
This patch only implements the functionality under the new `LLVM_BB_ADDR_MAP` version, but the old version is still being used. A later patch will change the used version.
####Background
Today Propeller uses machine basic block (MBB) numbers, which already exist, to map native assembly to machine IR. This is done as follows.
- Basic block addresses are captured and dumped into the `LLVM_BB_ADDR_MAP` section just before the AsmPrinter pass which writes out object files. This ensures that we have a mapping that is close to assembly.
- Profiling mapping works by taking a virtual address of an instruction and looking up the `LLVM_BB_ADDR_MAP` section to find the MBB number it corresponds to.
- While this works well today, we need to do better when we scale Propeller to target other Machine IR optimizations like spill code optimization. Register allocation happens earlier in the Machine IR pipeline and we need an annotation mechanism that is valid at that point.
- The current scheme will not work in this scenario because the MBB number of a particular basic block is not fixed and changes over the course of codegen (via renumbering, adding, and removing the basic blocks).
- In other words, the volatile MBB numbers do not provide a one-to-one correspondence throughout the lifetime of Machine IR. Profile annotation using MBB numbers is restricted to a fixed point; only valid at the exact point where it was dumped.
- Further, the object file can only be dumped before AsmPrinter and cannot be dumped at an arbitrary point in the Machine IR pass pipeline. Hence, MBB numbers are not suitable and we need something else.
####Solution
We propose using fixed unique incremental MBB IDs for basic blocks instead of volatile MBB numbers. These IDs are assigned upon the creation of machine basic blocks. We modify `MachineFunction::CreateMachineBasicBlock` to assign the fixed ID to every newly created basic block. It assigns `MachineFunction::NextMBBID` to the MBB ID and then increments it, which ensures having unique IDs.
To ensure correct profile attribution, multiple equivalent compilations must generate the same Propeller IDs. This is guaranteed as long as the MachineFunction passes run in the same order. Since the `NextBBID` variable is scoped to `MachineFunction`, interleaving of codegen for different functions won't cause any inconsistencies.
The new encoding is generated under the new version number 2 and we keep backward-compatibility with older versions.
####Impact on Size of the `LLVM_BB_ADDR_MAP` Section
Emitting the Propeller ID results in a 23% increase in the size of the `LLVM_BB_ADDR_MAP` section for the clang binary.
Reviewed By: tmsriram
Differential Revision: https://reviews.llvm.org/D100808
Diffstat (limited to 'llvm/lib/CodeGen/BasicBlockSections.cpp')
-rw-r--r-- | llvm/lib/CodeGen/BasicBlockSections.cpp | 76 |
1 files changed, 42 insertions, 34 deletions
diff --git a/llvm/lib/CodeGen/BasicBlockSections.cpp b/llvm/lib/CodeGen/BasicBlockSections.cpp index 3249022..8b6cf04 100644 --- a/llvm/lib/CodeGen/BasicBlockSections.cpp +++ b/llvm/lib/CodeGen/BasicBlockSections.cpp @@ -71,8 +71,8 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" -#include "llvm/CodeGen/BasicBlockSectionsProfileReader.h" #include "llvm/CodeGen/BasicBlockSectionUtils.h" +#include "llvm/CodeGen/BasicBlockSectionsProfileReader.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/Passes.h" @@ -131,9 +131,9 @@ INITIALIZE_PASS(BasicBlockSections, "bbsections-prepare", // This function updates and optimizes the branching instructions of every basic // block in a given function to account for changes in the layout. -static void updateBranches( - MachineFunction &MF, - const SmallVector<MachineBasicBlock *, 4> &PreLayoutFallThroughs) { +static void +updateBranches(MachineFunction &MF, + const SmallVector<MachineBasicBlock *> &PreLayoutFallThroughs) { const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); SmallVector<MachineOperand, 4> Cond; for (auto &MBB : MF) { @@ -168,7 +168,7 @@ static void updateBranches( bool getBBClusterInfoForFunction( const MachineFunction &MF, BasicBlockSectionsProfileReader *BBSectionsProfileReader, - std::vector<Optional<BBClusterInfo>> &V) { + DenseMap<unsigned, BBClusterInfo> &V) { // Find the assoicated cluster information. std::pair<bool, SmallVector<BBClusterInfo, 4>> P = @@ -183,13 +183,8 @@ bool getBBClusterInfoForFunction( return true; } - V.resize(MF.getNumBlockIDs()); - for (auto bbClusterInfo : P.second) { - // Bail out if the cluster information contains invalid MBB numbers. - if (bbClusterInfo.MBBNumber >= MF.getNumBlockIDs()) - return false; - V[bbClusterInfo.MBBNumber] = bbClusterInfo; - } + for (const BBClusterInfo &BBCI : P.second) + V[BBCI.BBID] = BBCI; return true; } @@ -200,11 +195,12 @@ bool getBBClusterInfoForFunction( // clusters, they are moved into a single "Exception" section. Eventually, // clusters are ordered in increasing order of their IDs, with the "Exception" // and "Cold" succeeding all other clusters. -// FuncBBClusterInfo represent the cluster information for basic blocks. If this -// is empty, it means unique sections for all basic blocks in the function. +// FuncBBClusterInfo represent the cluster information for basic blocks. It +// maps from BBID of basic blocks to their cluster information. If this is +// empty, it means unique sections for all basic blocks in the function. static void assignSections(MachineFunction &MF, - const std::vector<Optional<BBClusterInfo>> &FuncBBClusterInfo) { + const DenseMap<unsigned, BBClusterInfo> &FuncBBClusterInfo) { assert(MF.hasBBSections() && "BB Sections is not set for function."); // This variable stores the section ID of the cluster containing eh_pads (if // all eh_pads are one cluster). If more than one cluster contain eh_pads, we @@ -219,15 +215,21 @@ assignSections(MachineFunction &MF, if (MF.getTarget().getBBSectionsType() == llvm::BasicBlockSection::All || FuncBBClusterInfo.empty()) { // If unique sections are desired for all basic blocks of the function, we - // set every basic block's section ID equal to its number (basic block - // id). This further ensures that basic blocks are ordered canonically. - MBB.setSectionID({static_cast<unsigned int>(MBB.getNumber())}); - } else if (FuncBBClusterInfo[MBB.getNumber()]) - MBB.setSectionID(FuncBBClusterInfo[MBB.getNumber()]->ClusterID); - else { - // BB goes into the special cold section if it is not specified in the - // cluster info map. - MBB.setSectionID(MBBSectionID::ColdSectionID); + // set every basic block's section ID equal to its original position in + // the layout (which is equal to its number). This ensures that basic + // blocks are ordered canonically. + MBB.setSectionID(MBB.getNumber()); + } else { + // TODO: Replace `getBBIDOrNumber` with `getBBID` once version 1 is + // deprecated. + auto I = FuncBBClusterInfo.find(MBB.getBBIDOrNumber()); + if (I != FuncBBClusterInfo.end()) { + MBB.setSectionID(I->second.ClusterID); + } else { + // BB goes into the special cold section if it is not specified in the + // cluster info map. + MBB.setSectionID(MBBSectionID::ColdSectionID); + } } if (MBB.isEHPad() && EHPadsSectionID != MBB.getSectionID() && @@ -250,12 +252,14 @@ assignSections(MachineFunction &MF, void llvm::sortBasicBlocksAndUpdateBranches( MachineFunction &MF, MachineBasicBlockComparator MBBCmp) { - SmallVector<MachineBasicBlock *, 4> PreLayoutFallThroughs( - MF.getNumBlockIDs()); + [[maybe_unused]] const MachineBasicBlock *EntryBlock = &MF.front(); + SmallVector<MachineBasicBlock *> PreLayoutFallThroughs(MF.getNumBlockIDs()); for (auto &MBB : MF) PreLayoutFallThroughs[MBB.getNumber()] = MBB.getFallThrough(); MF.sort(MBBCmp); + assert(&MF.front() == EntryBlock && + "Entry block should not be displaced by basic block sections"); // Set IsBeginSection and IsEndSection according to the assigned section IDs. MF.assignBeginEndSections(); @@ -318,11 +322,14 @@ bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) { if (BBSectionsType == BasicBlockSection::List && hasInstrProfHashMismatch(MF)) return true; - - // Renumber blocks before sorting them for basic block sections. This is - // useful during sorting, basic blocks in the same section will retain the - // default order. This renumbering should also be done for basic block - // labels to match the profiles with the correct blocks. + // Renumber blocks before sorting them. This is useful during sorting, + // basic blocks in the same section will retain the default order. + // This renumbering should also be done for basic block labels to match the + // profiles with the correct blocks. + // For LLVM_BB_ADDR_MAP versions 2 and higher, this renumbering serves + // the different purpose of accessing the original layout positions and + // finding the original fallthroughs. + // TODO: Change the above comment accordingly when version 1 is deprecated. MF.RenumberBlocks(); if (BBSectionsType == BasicBlockSection::Labels) { @@ -332,7 +339,8 @@ bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) { BBSectionsProfileReader = &getAnalysis<BasicBlockSectionsProfileReader>(); - std::vector<Optional<BBClusterInfo>> FuncBBClusterInfo; + // Map from BBID of blocks to their cluster information. + DenseMap<unsigned, BBClusterInfo> FuncBBClusterInfo; if (BBSectionsType == BasicBlockSection::List && !getBBClusterInfoForFunction(MF, BBSectionsProfileReader, FuncBBClusterInfo)) @@ -372,8 +380,8 @@ bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) { // If the two basic block are in the same section, the order is decided by // their position within the section. if (XSectionID.Type == MBBSectionID::SectionType::Default) - return FuncBBClusterInfo[X.getNumber()]->PositionInCluster < - FuncBBClusterInfo[Y.getNumber()]->PositionInCluster; + return FuncBBClusterInfo.lookup(X.getBBIDOrNumber()).PositionInCluster < + FuncBBClusterInfo.lookup(Y.getBBIDOrNumber()).PositionInCluster; return X.getNumber() < Y.getNumber(); }; |