49#define DEBUG_TYPE "stack-slot-coloring"
54 cl::desc(
"Suppress slot sharing during stack coloring"));
58STATISTIC(NumEliminated,
"Number of stack slots eliminated due to coloring");
59STATISTIC(NumDead,
"Number of trivially dead stack accesses eliminated");
71 std::vector<LiveInterval*> SSIntervals;
99 class ColorAssignmentInfo {
109 ~ColorAssignmentInfo() {
111 LIU->~LiveIntervalUnion();
119 return SingleLI ? SingleLI->
overlaps(*LI) :
false;
126 LIU->
unify(*LI, *LI);
127 }
else if (SingleLI) {
129 LIU->
unify(*SingleLI, *SingleLI);
130 LIU->
unify(*LI, *LI);
171 void InitializeSlots();
182char StackSlotColoring::ID = 0;
187 "Stack Slot Coloring",
false,
false)
200 return LHS->weight() >
RHS->weight();
217 int FI = MO.getIndex();
220 if (!
LS->hasInterval(FI))
223 if (!
MI.isDebugInstr())
229 dyn_cast_or_null<FixedStackPseudoSourceValue>(
230 MMO->getPseudoValue())) {
231 int FI = FSV->getFrameIndex();
242void StackSlotColoring::InitializeSlots() {
249 OrigAlignments.
resize(LastFI);
251 AllColors[0].
resize(LastFI);
252 UsedColors[0].
resize(LastFI);
253 Assignments.
resize(LastFI);
255 using Pair = std::iterator_traits<LiveStacks::iterator>::value_type;
259 Intervals.
reserve(
LS->getNumIntervals());
263 [](Pair *LHS, Pair *RHS) {
return LHS->first <
RHS->first; });
267 for (
auto *
I : Intervals) {
274 SSIntervals.push_back(&li);
280 AllColors.
resize(StackID + 1);
281 UsedColors.
resize(StackID + 1);
282 AllColors[StackID].
resize(LastFI);
283 UsedColors[StackID].
resize(LastFI);
286 AllColors[StackID].set(FI);
296 for (
unsigned I = 0, E = AllColors.
size();
I != E; ++
I)
297 NextColors[
I] = AllColors[
I].find_first();
310 Color = UsedColors[StackID].find_first();
311 while (Color != -1) {
312 if (!Assignments[Color].overlaps(li)) {
317 Color = UsedColors[StackID].find_next(Color);
322 LLVM_DEBUG(
dbgs() <<
"cannot share FIs with different stack IDs\n");
329 assert(NextColors[StackID] != -1 &&
"No more spill slots?");
330 Color = NextColors[StackID];
331 UsedColors[StackID].set(Color);
332 NextColors[StackID] = AllColors[StackID].find_next(NextColors[StackID]);
338 Assignments[Color].add(li, LIUAlloc);
339 LLVM_DEBUG(
dbgs() <<
"Assigning fi#" << FI <<
" to fi#" << Color <<
"\n");
344 Align Alignment = OrigAlignments[FI];
347 int64_t
Size = OrigSizes[FI];
363 bool Changed =
false;
366 int NewSS = ColorSlot(li);
367 assert(NewSS >= 0 &&
"Stack coloring failed?");
369 RevMap[NewSS].push_back(SS);
370 SlotWeights[NewSS] += li->
weight();
371 UsedColors.set(NewSS);
372 Changed |= (
SS != NewSS);
393 for (
unsigned SS = 0, SE = SSRefs.
size(); SS != SE; ++SS) {
395 if (NewFI == -1 || (NewFI == (
int)SS))
401 MMO->setValue(NewSV);
408 RemoveDeadStores(&
MBB);
412 for (
int StackID = 0, E = AllColors.
size(); StackID != E; ++StackID) {
413 int NextColor = NextColors[StackID];
414 while (NextColor != -1) {
415 LLVM_DEBUG(
dbgs() <<
"Removing unused stack object fi#" << NextColor <<
"\n");
417 NextColor = AllColors[StackID].find_next(NextColor);
433 int OldFI = MO.getIndex();
437 if (NewFI == -1 || NewFI == OldFI)
455 bool changed =
false;
463 int FirstSS, SecondSS;
464 if (
TII->isStackSlotCopy(*
I, FirstSS, SecondSS) && FirstSS == SecondSS &&
475 unsigned LoadReg = 0;
476 unsigned StoreReg = 0;
477 unsigned LoadSize = 0;
478 unsigned StoreSize = 0;
482 while ((NextMI != E) && NextMI->isDebugInstr()) {
486 if (NextMI == E)
continue;
489 if (FirstSS != SecondSS || LoadReg != StoreReg || FirstSS == -1 ||
496 if (NextMI->findRegisterUseOperandIdx(LoadReg,
nullptr,
true) !=
509 MI->eraseFromParent();
517 dbgs() <<
"********** Stack Slot Coloring **********\n"
518 <<
"********** Function: " << MF.
getName() <<
'\n';
526 LS = &getAnalysis<LiveStacks>();
527 MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
528 Indexes = &getAnalysis<SlotIndexesWrapperPass>().getSI();
530 bool Changed =
false;
532 unsigned NumSlots =
LS->getNumIntervals();
544 ScanForSpillSlotRefs(MF);
546 Changed = ColorSlots(MF);
548 for (
int &Next : NextColors)
552 for (
auto &RefMMOs : SSRefs)
555 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)
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.
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,...