diff --git a/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/llvm/include/llvm/CodeGen/MachineBasicBlock.h --- a/llvm/include/llvm/CodeGen/MachineBasicBlock.h +++ b/llvm/include/llvm/CodeGen/MachineBasicBlock.h @@ -162,6 +162,8 @@ /// Indicate that this basic block is the entry block of a cleanup funclet. bool IsCleanupFuncletEntry = false; + unsigned PropellerID{0}; + /// With basic block sections, this stores the Section ID of the basic block. MBBSectionID SectionID{0}; @@ -479,6 +481,8 @@ void setIsEndSection(bool V = true) { IsEndSection = V; } + unsigned getPropellerID() const { return PropellerID; } + /// Returns the section ID of this basic block. MBBSectionID getSectionID() const { return SectionID; } @@ -488,6 +492,8 @@ ((unsigned)SectionID.Type) + SectionID.Number; } + void setPropellerID(unsigned V) { PropellerID = V; } + /// Sets the section ID for this basic block. void setSectionID(MBBSectionID V) { SectionID = V; } diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h --- a/llvm/include/llvm/CodeGen/MachineFunction.h +++ b/llvm/include/llvm/CodeGen/MachineFunction.h @@ -349,6 +349,8 @@ bool HasEHScopes = false; bool HasEHFunclets = false; + unsigned NextPropellerID = 0; + /// Section Type for basic blocks, only relevant with basic block sections. BasicBlockSection BBSectionsType = BasicBlockSection::None; @@ -377,6 +379,7 @@ void init(); public: + unsigned getNextPropellerID() const { return NextPropellerID; } struct VariableDbgInfo { const DILocalVariable *Var; const DIExpression *Expr; diff --git a/llvm/include/llvm/Object/ELFTypes.h b/llvm/include/llvm/Object/ELFTypes.h --- a/llvm/include/llvm/Object/ELFTypes.h +++ b/llvm/include/llvm/Object/ELFTypes.h @@ -797,6 +797,7 @@ uintX_t Addr; // Function address // Struct representing the BBAddrMap information for one basic block. struct BBEntry { + uint32_t ID; // Propeller ID. uint32_t Offset; // Offset of basic block relative to function start. uint32_t Size; // Size of the basic block. @@ -807,8 +808,8 @@ bool IsEHPad; // If this is an exception handling block. bool CanFallThrough; // If this block can fall through to its next. - BBEntry(uint32_t Offset, uint32_t Size, uint32_t Metadata) - : Offset(Offset), Size(Size), HasReturn(Metadata & 1), + BBEntry(uint32_t ID, uint32_t Offset, uint32_t Size, uint32_t Metadata) + : ID(ID), Offset(Offset), Size(Size), HasReturn(Metadata & 1), HasTailCall(Metadata & (1 << 1)), IsEHPad(Metadata & (1 << 2)), CanFallThrough(Metadata & (1 << 3)){}; }; 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 @@ -1119,6 +1119,7 @@ for (const MachineBasicBlock &MBB : MF) { const MCSymbol *MBBSymbol = MBB.isEntryBlock() ? FunctionSymbol : MBB.getSymbol(); + OutStreamer->emitULEB128IntValue(MBB.getPropellerID()); // Emit the basic block offset. emitLabelDifferenceAsULEB128(MBBSymbol, FunctionSymbol); // Emit the basic block size. When BBs have alignments, their size cannot diff --git a/llvm/lib/CodeGen/BasicBlockSections.cpp b/llvm/lib/CodeGen/BasicBlockSections.cpp --- a/llvm/lib/CodeGen/BasicBlockSections.cpp +++ b/llvm/lib/CodeGen/BasicBlockSections.cpp @@ -98,8 +98,8 @@ // This struct represents the cluster information for a machine basic block. struct BBClusterInfo { - // MachineBasicBlock ID. - unsigned MBBNumber; + // MachineBasicBlock Propeller ID. + unsigned PropellerID; // Cluster ID this basic block belongs to. unsigned ClusterID; // Position of basic block within the cluster. @@ -160,14 +160,15 @@ // 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 &PreLayoutFallThroughs) { +static void +updateBranches(MachineFunction &MF, + DenseMap + &PreLayoutFallThroughs) { const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); SmallVector Cond; for (auto &MBB : MF) { auto NextMBBI = std::next(MBB.getIterator()); - auto *FTMBB = PreLayoutFallThroughs[MBB.getNumber()]; + auto *FTMBB = PreLayoutFallThroughs[&MBB]; // If this block had a fallthrough before we need an explicit unconditional // branch to that block if either // 1- the block ends a section, which means its next block may be @@ -215,13 +216,13 @@ 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; - } + unsigned MaxPropellerID = 0; + for (auto bbClusterInfo : P->second) + if (bbClusterInfo.PropellerID > MaxPropellerID) + MaxPropellerID = bbClusterInfo.PropellerID; + V.resize(MaxPropellerID + 1); + for (auto bbClusterInfo : P->second) + V[bbClusterInfo.PropellerID] = bbClusterInfo; return true; } @@ -253,9 +254,10 @@ // 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(MBB.getNumber())}); - } else if (FuncBBClusterInfo[MBB.getNumber()].hasValue()) - MBB.setSectionID(FuncBBClusterInfo[MBB.getNumber()]->ClusterID); + MBB.setSectionID({static_cast(MBB.getPropellerID())}); + } else if (MBB.getPropellerID() < FuncBBClusterInfo.size() && + FuncBBClusterInfo[MBB.getPropellerID()].hasValue()) + MBB.setSectionID(FuncBBClusterInfo[MBB.getPropellerID()]->ClusterID); else { // BB goes into the special cold section if it is not specified in the // cluster info map. @@ -283,10 +285,10 @@ void llvm::sortBasicBlocksAndUpdateBranches( MachineFunction &MF, MachineBasicBlockComparator MBBCmp) { - SmallVector PreLayoutFallThroughs( - MF.getNumBlockIDs()); + DenseMap + PreLayoutFallThroughs; for (auto &MBB : MF) - PreLayoutFallThroughs[MBB.getNumber()] = MBB.getFallThrough(); + PreLayoutFallThroughs[&MBB] = MBB.getFallThrough(); MF.sort(MBBCmp); @@ -354,11 +356,10 @@ 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. - MF.RenumberBlocks(); + DenseMap PreLayoutPosition; + unsigned Position = 0; + for (const auto &MBB : MF) + PreLayoutPosition[&MBB] = Position++; if (BBSectionsType == BasicBlockSection::Labels) { MF.setBBSectionsType(BBSectionsType); @@ -405,9 +406,9 @@ // 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 X.getNumber() < Y.getNumber(); + return FuncBBClusterInfo[X.getPropellerID()]->PositionInCluster < + FuncBBClusterInfo[Y.getPropellerID()]->PositionInCluster; + return PreLayoutPosition[&X] < PreLayoutPosition[&Y]; }; sortBasicBlocksAndUpdateBranches(MF, Comparator); @@ -476,8 +477,9 @@ if (!FuncBBIDs.insert(BBIndex).second) return invalidProfileError(Twine("Duplicate basic block id found '") + BBIndexStr + "'."); - if (!BBIndex && CurrentPosition) - return invalidProfileError("Entry BB (0) does not begin a cluster."); + // if (!BBIndex && CurrentPosition) + // return invalidProfileError("Entry BB (0) does not begin a + // cluster."); FI->second.emplace_back(BBClusterInfo{ ((unsigned)BBIndex), CurrentCluster, CurrentPosition++}); diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -412,8 +412,13 @@ /// `new MachineBasicBlock'. MachineBasicBlock * MachineFunction::CreateMachineBasicBlock(const BasicBlock *bb) { - return new (BasicBlockRecycler.Allocate(Allocator)) - MachineBasicBlock(*this, bb); + MachineBasicBlock *MBB = + new (BasicBlockRecycler.Allocate(Allocator)) + MachineBasicBlock(*this, bb); + if (Target.getBBSectionsType() == BasicBlockSection::Labels || + Target.getBBSectionsType() == BasicBlockSection::List) + MBB->setPropellerID(NextPropellerID++); + return MBB; } /// Delete the given MachineBasicBlock. diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -650,10 +650,11 @@ std::vector BBEntries; for (uint32_t BlockID = 0; !ULEBSizeErr && Cur && (BlockID < NumBlocks); ++BlockID) { + uint32_t ID = ReadULEB128AsUInt32(); uint32_t Offset = ReadULEB128AsUInt32(); uint32_t Size = ReadULEB128AsUInt32(); uint32_t Metadata = ReadULEB128AsUInt32(); - BBEntries.push_back({Offset, Size, Metadata}); + BBEntries.push_back({ID, Offset, Size, Metadata}); } FunctionEntries.push_back({Address, BBEntries}); } diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -6678,6 +6678,7 @@ ListScope L(W, "BB entries"); for (const typename Elf_BBAddrMap::BBEntry &BBE : AM.BBEntries) { DictScope L(W); + W.printNumber("ID", BBE.ID); W.printHex("Offset", BBE.Offset); W.printHex("Size", BBE.Size); W.printBoolean("HasReturn", BBE.HasReturn);