Index: llvm/include/llvm/CodeGen/CommandFlags.inc =================================================================== --- llvm/include/llvm/CodeGen/CommandFlags.inc +++ llvm/include/llvm/CodeGen/CommandFlags.inc @@ -238,6 +238,14 @@ cl::desc("Emit functions into separate sections"), cl::init(false)); +static cl::opt BBSections( + "basicblock-sections", cl::desc("Emit basic blocks into separate sections"), + cl::init(BasicBlockSection::None), + cl::values(clEnumValN(BasicBlockSection::None, "none", "Off"), + clEnumValN(BasicBlockSection::All, "all", "All Basic Blocks"), + clEnumValN(BasicBlockSection::Labels, "labels", + "Labelled Basic Blocks"))); + static cl::opt TLSSize("tls-size", cl::desc("Bit size of immediate TLS offsets"), cl::init(0)); @@ -251,6 +259,11 @@ cl::desc("Give unique names to every section"), cl::init(true)); +static cl::opt UniqueBBSectionNames( + "unique-bb-section-names", + cl::desc("Give unique names to every basic block section"), + cl::init(false)); + static cl::opt EABIVersion("meabi", cl::desc("Set EABI type (default depends on triple):"), cl::init(EABI::Default), @@ -308,7 +321,9 @@ Options.RelaxELFRelocations = RelaxELFRelocations; Options.DataSections = DataSections; Options.FunctionSections = FunctionSections; + Options.BBSections = BBSections; Options.UniqueSectionNames = UniqueSectionNames; + Options.UniqueBBSectionNames = UniqueBBSectionNames; Options.TLSSize = TLSSize; Options.EmulatedTLS = EmulatedTLS; Options.ExplicitEmulatedTLS = EmulatedTLS.getNumOccurrences() > 0; Index: llvm/include/llvm/IR/BasicBlock.h =================================================================== --- llvm/include/llvm/IR/BasicBlock.h +++ llvm/include/llvm/IR/BasicBlock.h @@ -428,6 +428,12 @@ Optional getIrrLoopHeaderWeight() const; + /// Set the section prefix for this block. + void setSectionPrefix(StringRef Prefix); + + /// Get the section prefix for this block. + Optional getSectionPrefix() const; + private: /// Increment the internal refcount of the number of BlockAddresses /// referencing this BasicBlock by \p Amt. Index: llvm/include/llvm/IR/Function.h =================================================================== --- llvm/include/llvm/IR/Function.h +++ llvm/include/llvm/IR/Function.h @@ -96,6 +96,11 @@ friend class SymbolTableListTraits; + /// Whether Basic Block Sections is enabled for this function. + bool BBSections = false; + /// Whether Basic Block Labels is enabled for this function. + bool BasicBlockLabels = false; + /// hasLazyArguments/CheckLazyArguments - The argument list of a function is /// built on demand, so that the list isn't allocated until the first client /// needs it. The hasLazyArguments predicate returns true if the arg list @@ -159,6 +164,18 @@ /// within this function. unsigned getInstructionCount() const; + /// Returns true if this function has basic block sections enabled. + bool getBBSections() const { return BBSections; } + + /// Indicates that basic block sections is enabled for this function. + void setBBSections(bool value) { BBSections = value; } + + /// Returns true if this function has basic block labels enabled. + bool getBasicBlockLabels() const { return BasicBlockLabels; } + + /// Indicates that basic block labels is enabled for this function. + void setBasicBlockLabels(bool value) { BasicBlockLabels = value; } + /// Returns the FunctionType for me. FunctionType *getFunctionType() const { return cast(getValueType()); Index: llvm/include/llvm/Target/TargetMachine.h =================================================================== --- llvm/include/llvm/Target/TargetMachine.h +++ llvm/include/llvm/Target/TargetMachine.h @@ -242,6 +242,9 @@ bool getUniqueSectionNames() const { return Options.UniqueSectionNames; } + /// Return true if unique basic block section names must be generated. + bool getUniqueBBSectionNames() const { return Options.UniqueBBSectionNames; } + /// Return true if data objects should be emitted into their own section, /// corresponds to -fdata-sections. bool getDataSections() const { @@ -254,6 +257,24 @@ return Options.FunctionSections; } + /// If basic blocks should be emitted into their own section, + /// corresponding to -fbasicblock-sections. + llvm::BasicBlockSection::SectionMode getBBSections() const { + return Options.BBSections; + } + + /// Return true if a given function's name in the list of functions for which + /// basic block sections must be generated. + bool isFunctionInBBSectionsList(const StringRef &name) const { + return Options.BBSectionsList.find(name) != Options.BBSectionsList.end(); + } + + /// For a given function, return the set of basic block id's that must be + /// emitted in a unique section. + SmallSet getBBSectionsSet(const StringRef &name) const { + return Options.BBSectionsList.lookup(name); + } + /// Get a \c TargetIRAnalysis appropriate for the target. /// /// This is used to construct the new pass manager's target IR analysis pass, Index: llvm/include/llvm/Target/TargetOptions.h =================================================================== --- llvm/include/llvm/Target/TargetOptions.h +++ llvm/include/llvm/Target/TargetOptions.h @@ -14,6 +14,8 @@ #ifndef LLVM_TARGET_TARGETOPTIONS_H #define LLVM_TARGET_TARGETOPTIONS_H +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/StringMap.h" #include "llvm/MC/MCTargetOptions.h" namespace llvm { @@ -63,6 +65,15 @@ }; } + namespace BasicBlockSection { + enum SectionMode { + None, // Do not use Basic Block Sections. + All, // Use Basic Block Sections for all functions. + Labels, // Do not use Basic Block Sections but label basic blocks. + List // Get list of functions & BBs from a file + }; + } + enum class EABI { Unknown, Default, // Default means not specified @@ -114,9 +125,9 @@ EnableFastISel(false), EnableGlobalISel(false), UseInitArray(false), DisableIntegratedAS(false), RelaxELFRelocations(false), FunctionSections(false), DataSections(false), - UniqueSectionNames(true), TrapUnreachable(false), - NoTrapAfterNoreturn(false), TLSSize(0), EmulatedTLS(false), - ExplicitEmulatedTLS(false), EnableIPRA(false), + UniqueSectionNames(true), UniqueBBSectionNames(false), + TrapUnreachable(false), NoTrapAfterNoreturn(false), TLSSize(0), + EmulatedTLS(false), ExplicitEmulatedTLS(false), EnableIPRA(false), EmitStackSizeSection(false), EnableMachineOutliner(false), SupportsDefaultOutlining(false), EmitAddrsig(false), EnableDebugEntryValues(false), ForceDwarfFrameSection(false) {} @@ -224,6 +235,9 @@ unsigned UniqueSectionNames : 1; + /// Use unique names for basic block sections. + unsigned UniqueBBSectionNames : 1; + /// Emit target-specific trap instruction for 'unreachable' IR instructions. unsigned TrapUnreachable : 1; @@ -256,6 +270,13 @@ /// Emit address-significance table. unsigned EmitAddrsig : 1; + /// Emit basic blocks into separate sections. + BasicBlockSection::SectionMode BBSections = BasicBlockSection::None; + + /// A map from function name to a set of basic block id's that require + /// unique basic block sections. + StringMap> BBSectionsList; + /// Emit debug info about parameter's entry values. unsigned EnableDebugEntryValues : 1; Index: llvm/lib/CodeGen/CodeGenPrepare.cpp =================================================================== --- llvm/lib/CodeGen/CodeGenPrepare.cpp +++ llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -441,6 +441,24 @@ BFI.reset(new BlockFrequencyInfo(F, *BPI, *LI)); PSI = &getAnalysis().getPSI(); OptSize = F.hasOptSize(); + + /// Check if basic block sections must be enabled for this function. + /// Two basic block section modes are supported: + /// 1. "All" mode where where every block is placed in a separate section. + /// 2. "List" mode where the list of functions that needs sections is + /// specified in a file. + if (TM && TM->getBBSections() == llvm::BasicBlockSection::All) + F.setBBSections(true); + + if (TM && TM->getBBSections() == llvm::BasicBlockSection::List && + TM->isFunctionInBBSectionsList(F.getName())) + F.setBBSections(true); + + /// Check if basic block labels must be enabled for this function. Each + /// basic block in this function gets a unique symbol (label). + if (TM && TM->getBBSections() == llvm::BasicBlockSection::Labels) + F.setBasicBlockLabels(true); + if (ProfileGuidedSectionPrefix) { if (PSI->isFunctionHotInCallGraph(&F, *BFI)) F.setSectionPrefix(".hot");