48#define DEBUG_TYPE "stack-slot-coloring"
53 cl::desc(
"Suppress slot sharing during stack coloring"));
57STATISTIC(NumEliminated,
"Number of stack slots eliminated due to coloring");
58STATISTIC(NumDead,
"Number of trivially dead stack accesses eliminated");
70 std::vector<LiveInterval*> SSIntervals;
98 class ColorAssignmentInfo {
108 ~ColorAssignmentInfo() {
110 LIU->~LiveIntervalUnion();
118 return SingleLI ? SingleLI->
overlaps(*LI) :
false;
125 LIU->
unify(*LI, *LI);
126 }
else if (SingleLI) {
128 LIU->
unify(*SingleLI, *SingleLI);
129 LIU->
unify(*LI, *LI);
170 void InitializeSlots();
181char StackSlotColoring::ID = 0;
186 "Stack Slot Coloring",
false,
false)
199 return LHS->weight() >
RHS->weight();
216 int FI = MO.getIndex();
219 if (!
LS->hasInterval(FI))
222 if (!
MI.isDebugInstr())
228 dyn_cast_or_null<FixedStackPseudoSourceValue>(
229 MMO->getPseudoValue())) {
230 int FI = FSV->getFrameIndex();
241void StackSlotColoring::InitializeSlots() {
248 OrigAlignments.
resize(LastFI);
250 AllColors[0].
resize(LastFI);
251 UsedColors[0].
resize(LastFI);
252 Assignments.
resize(LastFI);
254 using Pair = std::iterator_traits<LiveStacks::iterator>::value_type;
258 Intervals.
reserve(
LS->getNumIntervals());
262 [](Pair *LHS, Pair *RHS) {
return LHS->first <
RHS->first; });
266 for (
auto *
I : Intervals) {
273 SSIntervals.push_back(&li);
279 AllColors.
resize(StackID + 1);
280 UsedColors.
resize(StackID + 1);
281 AllColors[StackID].
resize(LastFI);
282 UsedColors[StackID].
resize(LastFI);
285 AllColors[StackID].set(FI);
295 for (
unsigned I = 0, E = AllColors.
size();
I != E; ++
I)
296 NextColors[
I] = AllColors[
I].find_first();
309 Color = UsedColors[StackID].find_first();
310 while (Color != -1) {
311 if (!Assignments[Color].overlaps(li)) {
316 Color = UsedColors[StackID].find_next(Color);
321 LLVM_DEBUG(
dbgs() <<
"cannot share FIs with different stack IDs\n");
328 assert(NextColors[StackID] != -1 &&
"No more spill slots?");
329 Color = NextColors[StackID];
330 UsedColors[StackID].set(Color);
331 NextColors[StackID] = AllColors[StackID].find_next(NextColors[StackID]);
337 Assignments[Color].add(li, LIUAlloc);
338 LLVM_DEBUG(
dbgs() <<
"Assigning fi#" << FI <<
" to fi#" << Color <<
"\n");
343 Align Alignment = OrigAlignments[FI];
346 int64_t
Size = OrigSizes[FI];
362 bool Changed =
false;
365 int NewSS = ColorSlot(li);
366 assert(NewSS >= 0 &&
"Stack coloring failed?");
368 RevMap[NewSS].push_back(SS);
369 SlotWeights[NewSS] += li->
weight();
370 UsedColors.set(NewSS);
371 Changed |= (
SS != NewSS);
392 for (
unsigned SS = 0, SE = SSRefs.
size(); SS != SE; ++SS) {
394 if (NewFI == -1 || (NewFI == (
int)SS))
400 MMO->setValue(NewSV);
407 RemoveDeadStores(&
MBB);
411 for (
int StackID = 0, E = AllColors.
size(); StackID != E; ++StackID) {
412 int NextColor = NextColors[StackID];
413 while (NextColor != -1) {
414 LLVM_DEBUG(
dbgs() <<
"Removing unused stack object fi#" << NextColor <<
"\n");
416 NextColor = AllColors[StackID].find_next(NextColor);
432 int OldFI = MO.getIndex();
436 if (NewFI == -1 || NewFI == OldFI)
454 bool changed =
false;
462 int FirstSS, SecondSS;
463 if (
TII->isStackSlotCopy(*
I, FirstSS, SecondSS) && FirstSS == SecondSS &&
476 unsigned LoadSize = 0;
477 unsigned StoreSize = 0;
481 while ((NextMI != E) && NextMI->isDebugInstr()) {
485 if (NextMI == E)
continue;
488 if (FirstSS != SecondSS || LoadReg != StoreReg || FirstSS == -1 ||
495 if (NextMI->findRegisterUseOperandIdx(LoadReg,
nullptr,
true) !=
508 MI->eraseFromParent();
516 dbgs() <<
"********** Stack Slot Coloring **********\n"
517 <<
"********** Function: " << MF.
getName() <<
'\n';
525 LS = &getAnalysis<LiveStacksWrapperLegacy>().getLS();
526 MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
527 Indexes = &getAnalysis<SlotIndexesWrapperPass>().getSI();
529 bool Changed =
false;
531 unsigned NumSlots =
LS->getNumIntervals();
543 ScanForSpillSlotRefs(MF);
545 Changed = ColorSlots(MF);
547 for (
int &Next : NextColors)
551 for (
auto &RefMMOs : SSRefs)
554 OrigAlignments.
clear();
This file implements the BitVector class.
const HexagonInstrInfo * TII
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
Represent the analysis usage information of a pass.
AnalysisUsage & addPreservedID(const void *ID)
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
A specialized PseudoSourceValue for holding FixedStack values, which must include a frame index.
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...
Query interferences between a single live virtual register and a live interval union.
Union of live intervals that are strong candidates for coalescing into a single register (either phys...
void unify(const LiveInterval &VirtReg, const LiveRange &Range)
LiveSegments::Allocator Allocator
LiveInterval - This class represents the liveness of a register, or stack slot.
void incrementWeight(float Inc)
void setWeight(float Value)
static 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.
bool overlaps(const LiveRange &other) const
overlaps - Return true if the intersection of the two live ranges is not empty.
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
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.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
PseudoSourceValueManager & getPSVManager() const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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...
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
A description of a memory reference used in the backend.
MachineOperand class - Representation of each machine instruction operand.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
const PseudoSourceValue * getFixedStack(int FI)
Return a pseudo source value referencing a fixed stack frame entry, e.g., a spill slot.
Special value supplied for machine level alias analysis.
Wrapper class representing virtual and physical registers.
static int stackSlot2Index(Register Reg)
Compute the frame index from a register value representing a stack slot.
void removeMachineInstrFromMaps(MachineInstr &MI, bool AllowBundled=false)
Removes machine instruction (bundle) MI from the mapping.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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.
TargetInstrInfo - Interface to description of machine instruction set.
virtual const TargetInstrInfo * getInstrInfo() const
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
void initializeStackSlotColoringPass(PassRegistry &)
char & MachineDominatorsID
MachineDominators - This pass is a machine dominators analysis pass.
void sort(IteratorTy Start, IteratorTy End)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
char & StackSlotColoringID
StackSlotColoring - This pass performs stack slot coloring.
bool operator()(LiveInterval *LHS, LiveInterval *RHS) const
This struct is a compact representation of a valid (non-zero power of two) alignment.
This struct contains the mappings from the slot numbers to unnamed metadata nodes,...