50#define DEBUG_TYPE "stack-slot-coloring" 
   55             cl::desc(
"Suppress slot sharing during stack coloring"));
 
   59STATISTIC(NumEliminated, 
"Number of stack slots eliminated due to coloring");
 
   60STATISTIC(NumDead,       
"Number of trivially dead stack accesses eliminated");
 
   64class StackSlotColoring {
 
   72  std::vector<LiveInterval *> SSIntervals;
 
  100  class ColorAssignmentInfo {
 
  102    LiveInterval *SingleLI = 
nullptr;
 
  104    LiveIntervalUnion *LIU = 
nullptr;
 
  107    uint8_t LIUPad[
sizeof(LiveIntervalUnion)];
 
  110    ~ColorAssignmentInfo() {
 
  112        LIU->~LiveIntervalUnion(); 
 
  117    bool overlaps(LiveInterval *LI)
 const {
 
  119        return LiveIntervalUnion::Query(*LI, *LIU).checkInterference();
 
  120      return SingleLI ? SingleLI->overlaps(*LI) : 
false;
 
  127        LIU->unify(*LI, *LI);
 
  128      } 
else if (SingleLI) {
 
  129        LIU = 
new (LIUPad) LiveIntervalUnion(
Alloc);
 
  130        LIU->unify(*SingleLI, *SingleLI);
 
  131        LIU->unify(*LI, *LI);
 
  144  StackSlotColoring(MachineFunction &MF, LiveStacks *LS,
 
  145                    MachineBlockFrequencyInfo *MBFI, SlotIndexes *Indexes)
 
  146      : MFI(&MF.getFrameInfo()), TII(MF.getSubtarget().getInstrInfo()), LS(LS),
 
  147        MBFI(MBFI), Indexes(Indexes) {}
 
  148  bool run(MachineFunction &MF);
 
  151  void InitializeSlots();
 
  152  void ScanForSpillSlotRefs(MachineFunction &MF);
 
  153  int ColorSlot(LiveInterval *li);
 
  154  bool ColorSlots(MachineFunction &MF);
 
  155  void RewriteInstruction(MachineInstr &
MI, SmallVectorImpl<int> &SlotMapping,
 
  156                          MachineFunction &MF);
 
  157  bool RemoveDeadStores(MachineBasicBlock *
MBB);
 
  164  StackSlotColoringLegacy() : MachineFunctionPass(ID) {
 
  168  void getAnalysisUsage(AnalysisUsage &AU)
 const override {
 
  173    AU.
addRequired<MachineBlockFrequencyInfoWrapperPass>();
 
  174    AU.
addPreserved<MachineBlockFrequencyInfoWrapperPass>();
 
  187  bool runOnMachineFunction(MachineFunction &MF) 
override;
 
  192char StackSlotColoringLegacy::ID = 0;
 
  197                      "Stack Slot Coloring", 
false, 
false)
 
  210    return LHS->weight() > RHS->weight();
 
 
 
  222  for (MachineBasicBlock &
MBB : MF) {
 
  223    for (MachineInstr &
MI : 
MBB) {
 
  224      for (
const MachineOperand &MO : 
MI.operands()) {
 
  227        int FI = MO.getIndex();
 
  230        if (!
LS->hasInterval(FI))
 
  232        LiveInterval &li = 
LS->getInterval(FI);
 
  233        if (!
MI.isDebugInstr())
 
  237      for (MachineMemOperand *MMO : 
MI.memoperands()) {
 
  238        if (
const FixedStackPseudoSourceValue *FSV =
 
  240                    MMO->getPseudoValue())) {
 
  241          int FI = FSV->getFrameIndex();
 
  252void StackSlotColoring::InitializeSlots() {
 
  259  OrigAlignments.
resize(LastFI);
 
  261  AllColors[0].
resize(LastFI);
 
  262  UsedColors[0].
resize(LastFI);
 
  263  Assignments.resize(LastFI);
 
  265  using Pair = std::iterator_traits<LiveStacks::iterator>::value_type;
 
  269  Intervals.
reserve(
LS->getNumIntervals());
 
  273             [](Pair *
LHS, Pair *
RHS) { 
return LHS->first < 
RHS->first; });
 
  277  for (
auto *
I : Intervals) {
 
  278    LiveInterval &li = 
I->second;
 
  284    SSIntervals.push_back(&li);
 
  290      if (StackID >= AllColors.
size()) {
 
  291        AllColors.
resize(StackID + 1);
 
  292        UsedColors.
resize(StackID + 1);
 
  294      AllColors[StackID].
resize(LastFI);
 
  295      UsedColors[StackID].
resize(LastFI);
 
  298    AllColors[StackID].set(FI);
 
  308  for (
unsigned I = 0, 
E = AllColors.
size(); 
I != 
E; ++
I)
 
  309    NextColors[
I] = AllColors[
I].find_first();
 
  313int StackSlotColoring::ColorSlot(LiveInterval *li) {
 
  322    Color = UsedColors[StackID].find_first();
 
  323    while (Color != -1) {
 
  324      if (!Assignments[Color].overlaps(li)) {
 
  329      Color = UsedColors[StackID].find_next(Color);
 
  334    LLVM_DEBUG(
dbgs() << 
"cannot share FIs with different stack IDs\n");
 
  341    assert(NextColors[StackID] != -1 && 
"No more spill slots?");
 
  342    Color = NextColors[StackID];
 
  343    UsedColors[StackID].set(Color);
 
  344    NextColors[StackID] = AllColors[StackID].find_next(NextColors[StackID]);
 
  350  Assignments[Color].add(li, LIUAlloc);
 
  351  LLVM_DEBUG(
dbgs() << 
"Assigning fi#" << FI << 
" to fi#" << Color << 
"\n");
 
  356  Align Alignment = OrigAlignments[FI];
 
  359  int64_t 
Size = OrigSizes[FI];
 
  367bool StackSlotColoring::ColorSlots(MachineFunction &MF) {
 
  369  SmallVector<int, 16> SlotMapping(NumObjs, -1);
 
  372  BitVector UsedColors(NumObjs);
 
  376  for (LiveInterval *li : SSIntervals) {
 
  378    int NewSS = ColorSlot(li);
 
  379    assert(NewSS >= 0 && 
"Stack coloring failed?");
 
  380    SlotMapping[
SS] = NewSS;
 
  381    RevMap[NewSS].push_back(SS);
 
  382    SlotWeights[NewSS] += li->
weight();
 
  383    UsedColors.set(NewSS);
 
  388  for (LiveInterval *li : SSIntervals) {
 
  396  for (LiveInterval *li : SSIntervals)
 
  405  for (
unsigned SS = 0, SE = SSRefs.
size(); SS != SE; ++SS) {
 
  406    int NewFI = SlotMapping[
SS];
 
  407    if (NewFI == -1 || (NewFI == (
int)SS))
 
  411    SmallVectorImpl<MachineMemOperand *> &RefMMOs = SSRefs[
SS];
 
  412    for (MachineMemOperand *MMO : RefMMOs)
 
  413      MMO->setValue(NewSV);
 
  417  for (MachineBasicBlock &
MBB : MF) {
 
  418    for (MachineInstr &
MI : 
MBB)
 
  419      RewriteInstruction(
MI, SlotMapping, MF);
 
  420    RemoveDeadStores(&
MBB);
 
  424  for (
int StackID = 0, 
E = AllColors.
size(); StackID != 
E; ++StackID) {
 
  425    int NextColor = NextColors[StackID];
 
  426    while (NextColor != -1) {
 
  427      LLVM_DEBUG(
dbgs() << 
"Removing unused stack object fi#" << NextColor << 
"\n");
 
  429      NextColor = AllColors[StackID].find_next(NextColor);
 
  438void StackSlotColoring::RewriteInstruction(MachineInstr &
MI,
 
  439                                           SmallVectorImpl<int> &SlotMapping,
 
  440                                           MachineFunction &MF) {
 
  442  for (MachineOperand &MO : 
MI.operands()) {
 
  445    int OldFI = MO.getIndex();
 
  448    int NewFI = SlotMapping[OldFI];
 
  449    if (NewFI == -1 || NewFI == OldFI)
 
  464bool StackSlotColoring::RemoveDeadStores(MachineBasicBlock* 
MBB) {
 
  467  bool changed = 
false;
 
  469  SmallVector<MachineInstr*, 4> toErase;
 
  475    int FirstSS, SecondSS;
 
  476    if (
TII->isStackSlotCopy(*
I, FirstSS, SecondSS) && FirstSS == SecondSS &&
 
  494    while ((NextMI != 
E) && NextMI->isDebugInstr()) {
 
  498    if (NextMI == 
E) 
continue;
 
  501    if (FirstSS != SecondSS || LoadReg != StoreReg || FirstSS == -1 ||
 
  508    if (NextMI->findRegisterUseOperandIdx(LoadReg, 
nullptr, 
true) !=
 
  518  for (MachineInstr *
MI : toErase) {
 
  521    MI->eraseFromParent();
 
  527bool StackSlotColoring::run(MachineFunction &MF) {
 
  529    dbgs() << 
"********** Stack Slot Coloring **********\n" 
  530           << 
"********** Function: " << MF.
getName() << 
'\n';
 
  535  unsigned NumSlots = 
LS->getNumIntervals();
 
  547  ScanForSpillSlotRefs(MF);
 
  551  for (
int &
Next : NextColors)
 
  555  for (
auto &RefMMOs : SSRefs)
 
  558  OrigAlignments.
clear();
 
  567bool StackSlotColoringLegacy::runOnMachineFunction(MachineFunction &MF) {
 
  571  LiveStacks *
LS = &getAnalysis<LiveStacksWrapperLegacy>().getLS();
 
  572  MachineBlockFrequencyInfo *MBFI =
 
  573      &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
 
  574  SlotIndexes *Indexes = &getAnalysis<SlotIndexesWrapperPass>().getSI();
 
  575  StackSlotColoring Impl(MF, LS, MBFI, Indexes);
 
  586  StackSlotColoring Impl(MF, LS, MBFI, Indexes);
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements the BitVector class.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
Promote Memory to Register
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file defines the SmallVector class.
static cl::opt< bool > DisableSharing("no-stack-slot-sharing", cl::init(false), cl::Hidden, cl::desc("Suppress slot sharing during stack coloring"))
static cl::opt< int > DCELimit("ssc-dce-limit", cl::init(-1), cl::Hidden)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addPreservedID(const void *ID)
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
TargetInstrInfo overrides.
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
If the specified machine instruction is a direct store to a stack slot, return the virtual or physica...
LiveSegments::Allocator Allocator
LiveInterval - This class represents the liveness of a register, or stack slot.
LLVM_ABI void dump() const
void incrementWeight(float Inc)
void setWeight(float Value)
static LLVM_ABI float getSpillWeight(bool isDef, bool isUse, const MachineBlockFrequencyInfo *MBFI, const MachineInstr &MI, ProfileSummaryInfo *PSI=nullptr)
Calculate the spill weight to assign to a single instruction.
MachineInstrBundleIterator< MachineInstr > iterator
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
Analysis pass which computes a MachineDominatorTree.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setObjectSize(int ObjectIdx, int64_t Size)
Change the size of the specified stack object.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
bool isSpillSlotObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a spill slot.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
void RemoveStackObject(int ObjectIdx)
Remove or mark dead a statically sized stack object.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
uint8_t getStackID(int ObjectIdx) const
void setObjectAlignment(int ObjectIdx, Align Alignment)
setObjectAlignment - Change the alignment of the specified stack object.
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
PseudoSourceValueManager & getPSVManager() const
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
bool exposesReturnsTwice() const
exposesReturnsTwice - Returns true if the function calls setjmp or any other similar functions with a...
Function & getFunction()
Return the LLVM function that this machine code represents.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
LLVM_ABI const PseudoSourceValue * getFixedStack(int FI)
Return a pseudo source value referencing a fixed stack frame entry, e.g., a spill slot.
int stackSlotIndex() const
Compute the frame index from a register value representing a stack slot.
LLVM_ABI void removeMachineInstrFromMaps(MachineInstr &MI, bool AllowBundled=false)
Removes machine instruction (bundle) MI from the mapping.
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
TargetInstrInfo - Interface to description of machine instruction set.
static constexpr TypeSize getZero()
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
LLVM_ABI char & MachineDominatorsID
MachineDominators - This pass is a machine dominators analysis pass.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI void initializeStackSlotColoringLegacyPass(PassRegistry &)
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
auto dyn_cast_or_null(const Y &Val)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI char & StackSlotColoringID
StackSlotColoring - This pass performs stack slot coloring.
FunctionAddr VTableAddr Next
bool operator()(LiveInterval *LHS, LiveInterval *RHS) const