47 #define DEBUG_TYPE "stack-slot-coloring" 52 cl::desc(
"Suppress slot sharing during stack coloring"));
56 STATISTIC(NumEliminated,
"Number of stack slots eliminated due to coloring");
57 STATISTIC(NumDead,
"Number of trivially dead stack accesses eliminated");
68 std::vector<LiveInterval*> SSIntervals;
118 void InitializeSlots();
135 "Stack Slot Coloring",
false,
false)
181 MMOI != EE; ++MMOI) {
184 dyn_cast_or_null<FixedStackPseudoSourceValue>(
186 int FI = FSV->getFrameIndex();
197 void StackSlotColoring::InitializeSlots() {
204 OrigAlignments.
resize(LastFI);
206 AllColors[0].
resize(LastFI);
207 UsedColors[0].
resize(LastFI);
208 Assignments.
resize(LastFI);
210 using Pair = std::iterator_traits<LiveStacks::iterator>::value_type;
218 [](Pair *LHS, Pair *RHS) {
return LHS->first < RHS->first; });
222 for (
auto *
I : Intervals) {
229 SSIntervals.push_back(&li);
235 AllColors.
resize(StackID + 1);
236 UsedColors.
resize(StackID + 1);
237 AllColors[StackID].
resize(LastFI);
238 UsedColors[StackID].
resize(LastFI);
241 AllColors[StackID].set(FI);
246 std::stable_sort(SSIntervals.begin(), SSIntervals.end(),
IntervalSorter());
251 for (
unsigned I = 0,
E = AllColors.
size();
I !=
E; ++
I)
252 NextColors[
I] = AllColors[
I].find_first();
260 for (
unsigned i = 0, e = OtherLIs.
size(); i != e; ++i) {
278 Color = UsedColors[StackID].find_first();
279 while (Color != -1) {
280 if (!OverlapWithAssignments(li, Color)) {
285 Color = UsedColors[StackID].find_next(Color);
290 LLVM_DEBUG(
dbgs() <<
"cannot share FIs with different stack IDs\n");
297 assert(NextColors[StackID] != -1 &&
"No more spill slots?");
298 Color = NextColors[StackID];
299 UsedColors[StackID].set(Color);
300 NextColors[StackID] = AllColors[StackID].find_next(NextColors[StackID]);
307 LLVM_DEBUG(
dbgs() <<
"Assigning fi#" << FI <<
" to fi#" << Color <<
"\n");
312 unsigned Align = OrigAlignments[FI];
315 int64_t
Size = OrigSizes[FI];
331 bool Changed =
false;
332 for (
unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
335 int NewSS = ColorSlot(li);
336 assert(NewSS >= 0 &&
"Stack coloring failed?");
337 SlotMapping[SS] = NewSS;
339 SlotWeights[NewSS] += li->
weight;
340 UsedColors.
set(NewSS);
341 Changed |= (SS != NewSS);
345 for (
unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
348 li->
weight = SlotWeights[SS];
351 std::stable_sort(SSIntervals.begin(), SSIntervals.end(),
IntervalSorter());
354 for (
unsigned i = 0, e = SSIntervals.size(); i != e; ++i)
363 for (
unsigned SS = 0, SE = SSRefs.
size(); SS != SE; ++SS) {
364 int NewFI = SlotMapping[SS];
365 if (NewFI == -1 || (NewFI == (
int)SS))
370 for (
unsigned i = 0, e = RefMMOs.
size(); i != e; ++i)
371 RefMMOs[i]->setValue(NewSV);
377 RewriteInstruction(
MI, SlotMapping, MF);
378 RemoveDeadStores(&MBB);
382 for (
int StackID = 0,
E = AllColors.
size(); StackID !=
E; ++StackID) {
383 int NextColor = NextColors[StackID];
384 while (NextColor != -1) {
385 LLVM_DEBUG(
dbgs() <<
"Removing unused stack object fi#" << NextColor <<
"\n");
387 NextColor = AllColors[StackID].find_next(NextColor);
407 int NewFI = SlotMapping[OldFI];
408 if (NewFI == -1 || NewFI == OldFI)
426 bool changed =
false;
434 int FirstSS, SecondSS;
446 unsigned LoadReg = 0;
447 unsigned StoreReg = 0;
448 unsigned LoadSize = 0;
449 unsigned StoreSize = 0;
453 while ((NextMI !=
E) && NextMI->isDebugInstr()) {
457 if (NextMI ==
E)
continue;
460 if (FirstSS != SecondSS || LoadReg != StoreReg || FirstSS == -1 ||
461 LoadSize != StoreSize)
467 if (NextMI->findRegisterUseOperandIdx(LoadReg,
true,
nullptr) != -1) {
477 E = toErase.
end();
I !=
E; ++
I)
478 (*I)->eraseFromParent();
485 dbgs() <<
"********** Stack Slot Coloring **********\n" 486 <<
"********** Function: " << MF.
getName() <<
'\n';
494 LS = &getAnalysis<LiveStacks>();
495 MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
497 bool Changed =
false;
512 ScanForSpillSlotRefs(MF);
514 Changed = ColorSlots(MF);
516 for (
int &Next : NextColors)
520 for (
unsigned i = 0, e = SSRefs.
size(); i != e; ++i)
523 OrigAlignments.
clear();
527 for (
unsigned i = 0, e = Assignments.
size(); i != e; ++i)
528 Assignments[i].
clear();
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static float getSpillWeight(bool isDef, bool isUse, const MachineBlockFrequencyInfo *MBFI, const MachineInstr &MI)
Calculate the spill weight to assign to a single instruction.
This class represents lattice values for constants.
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
void push_back(const T &Elt)
char & MachineDominatorsID
MachineDominators - This pass is a machine dominators analysis pass.
LiveInterval - This class represents the liveness of a register, or stack slot.
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
LiveInterval & getInterval(int Slot)
STATISTIC(NumFunctions, "Total number of functions")
void reserve(size_type N)
static int stackSlot2Index(unsigned Reg)
Compute the frame index from a register value representing a stack slot.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
A description of a memory reference used in the backend.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
unsigned getNumOperands() const
Retuns the total number of operands.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
PseudoSourceValueManager & getPSVManager() const
bool operator()(LiveInterval *LHS, LiveInterval *RHS) const
char & StackSlotColoringID
StackSlotColoring - This pass performs stack slot coloring.
AnalysisUsage & addPreservedID(const void *ID)
virtual unsigned isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const
If the specified machine instruction is a direct store to a stack slot, return the virtual or physica...
int getObjectIndexEnd() const
Return one past the maximum frame object index.
virtual const TargetInstrInfo * getInstrInfo() const
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const PseudoSourceValue * getFixedStack(int FI)
Return a pseudo source value referencing a fixed stack frame entry, e.g., a spill slot...
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
TargetInstrInfo - Interface to description of machine instruction set.
void initializeStackSlotColoringPass(PassRegistry &)
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
initializer< Ty > init(const Ty &Val)
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
void RemoveStackObject(int ObjectIdx)
Remove or mark dead a statically sized stack object.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
static cl::opt< int > DCELimit("ssc-dce-limit", cl::init(-1), cl::Hidden)
Represent the analysis usage information of a pass.
const PseudoSourceValue * getPseudoValue() const
void setObjectSize(int ObjectIdx, int64_t Size)
Change the size of the specified stack object.
static cl::opt< bool > DisableSharing("no-stack-slot-sharing", cl::init(false), cl::Hidden, cl::desc("Suppress slot sharing during stack coloring"))
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
void sort(IteratorTy Start, IteratorTy End)
virtual bool isStackSlotCopy(const MachineInstr &MI, int &DestFrameIndex, int &SrcFrameIndex) const
Return true if the specified machine instruction is a copy of one stack slot to another and has no ot...
Iterator for intrusive lists based on ilist_node.
Color
A "color", which is either even or odd.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
INITIALIZE_PASS_BEGIN(StackSlotColoring, DEBUG_TYPE, "Stack Slot Coloring", false, false) INITIALIZE_PASS_END(StackSlotColoring
bool isDebugValue() const
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
void setPreservesCFG()
This function should be called by the pass, iff they do not:
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Special value supplied for machine level alias analysis.
This struct contains the mappings from the slot numbers to unnamed metadata nodes, global values and types.
static void clear(coro::Shape &Shape)
Representation of each machine instruction.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
bool overlaps(const LiveRange &other) const
overlaps - Return true if the intersection of the two live ranges is not empty.
bool exposesReturnsTwice() const
exposesReturnsTwice - Returns true if the function calls setjmp or any other similar functions with a...
virtual unsigned isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const
If the specified machine instruction is a direct load from a stack slot, return the virtual or physic...
unsigned getNumIntervals() const
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
uint8_t getStackID(int ObjectIdx) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool hasInterval(int Slot) const
A specialized PseudoSourceValue for holding FixedStack values, which must include a frame index...
const MachineOperand & getOperand(unsigned i) const
void setObjectAlignment(int ObjectIdx, unsigned Align)
setObjectAlignment - Change the alignment of the specified stack object.
mmo_iterator memoperands_end() const
Access to memory operands of the instruction.