35 #define DEBUG_TYPE "stackslotcoloring"
40 cl::desc(
"Suppress slot sharing during stack coloring"));
44 STATISTIC(NumEliminated,
"Number of stack slots eliminated due to coloring");
45 STATISTIC(NumDead,
"Number of trivially dead stack accesses eliminated");
55 std::vector<LiveInterval*> SSIntervals;
105 void InitializeSlots();
120 "Stack Slot Coloring",
false,
false)
140 SSRefs.resize(MFI->getObjectIndexEnd());
156 if (!
LS->hasInterval(FI))
164 MMOI != EE; ++MMOI) {
167 dyn_cast_or_null<FixedStackPseudoSourceValue>(
169 int FI = FSV->getFrameIndex();
171 SSRefs[FI].push_back(MMO);
180 void StackSlotColoring::InitializeSlots() {
181 int LastFI = MFI->getObjectIndexEnd();
182 OrigAlignments.resize(LastFI);
183 OrigSizes.resize(LastFI);
184 AllColors.resize(LastFI);
185 UsedColors.resize(LastFI);
186 Assignments.resize(LastFI);
188 typedef std::iterator_traits<LiveStacks::iterator>::value_type Pair;
190 Intervals.
reserve(
LS->getNumIntervals());
193 std::sort(Intervals.
begin(), Intervals.
end(),
194 [](Pair *LHS, Pair *RHS) {
return LHS->first < RHS->first; });
197 DEBUG(
dbgs() <<
"Spill slot intervals:\n");
198 for (
auto *
I : Intervals) {
202 if (MFI->isDeadObjectIndex(FI))
204 SSIntervals.push_back(&li);
205 OrigAlignments[FI] = MFI->getObjectAlignment(FI);
206 OrigSizes[FI] = MFI->getObjectSize(FI);
212 std::stable_sort(SSIntervals.begin(), SSIntervals.end(), IntervalSorter());
215 NextColor = AllColors.find_first();
223 for (
unsigned i = 0, e = OtherLIs.
size();
i != e; ++
i) {
238 Color = UsedColors.find_first();
239 while (Color != -1) {
240 if (!OverlapWithAssignments(li, Color)) {
245 Color = UsedColors.find_next(Color);
252 assert(NextColor != -1 &&
"No more spill slots?");
254 UsedColors.set(Color);
255 NextColor = AllColors.find_next(NextColor);
259 Assignments[
Color].push_back(li);
261 DEBUG(
dbgs() <<
"Assigning fi#" << FI <<
" to fi#" << Color <<
"\n");
266 unsigned Align = OrigAlignments[FI];
267 if (!Share || Align > MFI->getObjectAlignment(Color))
268 MFI->setObjectAlignment(Color, Align);
269 int64_t Size = OrigSizes[FI];
270 if (!Share || Size > MFI->getObjectSize(Color))
271 MFI->setObjectSize(Color, Size);
278 unsigned NumObjs = MFI->getObjectIndexEnd();
284 DEBUG(
dbgs() <<
"Color spill slot intervals:\n");
285 bool Changed =
false;
286 for (
unsigned i = 0, e = SSIntervals.size();
i != e; ++
i) {
289 int NewSS = ColorSlot(li);
290 assert(NewSS >= 0 &&
"Stack coloring failed?");
292 RevMap[NewSS].push_back(SS);
293 SlotWeights[NewSS] += li->
weight;
294 UsedColors.set(NewSS);
295 Changed |= (SS != NewSS);
298 DEBUG(
dbgs() <<
"\nSpill slots after coloring:\n");
299 for (
unsigned i = 0, e = SSIntervals.size();
i != e; ++
i) {
302 li->
weight = SlotWeights[SS];
305 std::stable_sort(SSIntervals.begin(), SSIntervals.end(), IntervalSorter());
308 for (
unsigned i = 0, e = SSIntervals.size();
i != e; ++
i)
317 for (
unsigned SS = 0, SE = SSRefs.size(); SS != SE; ++SS) {
319 if (NewFI == -1 || (NewFI == (
int)SS))
324 for (
unsigned i = 0, e = RefMMOs.
size();
i != e; ++
i)
325 RefMMOs[
i]->setValue(NewSV);
332 RemoveDeadStores(&MBB);
336 while (NextColor != -1) {
337 DEBUG(
dbgs() <<
"Removing unused stack object fi#" << NextColor <<
"\n");
338 MFI->RemoveStackObject(NextColor);
339 NextColor = AllColors.find_next(NextColor);
347 void StackSlotColoring::RewriteInstruction(
MachineInstr &MI,
358 int NewFI = SlotMapping[OldFI];
359 if (NewFI == -1 || NewFI == OldFI)
376 bool changed =
false;
384 int FirstSS, SecondSS;
385 if (
TII->isStackSlotCopy(*
I, FirstSS, SecondSS) && FirstSS == SecondSS &&
396 unsigned LoadReg = 0;
397 unsigned StoreReg = 0;
401 while ((NextMI !=
E) && NextMI->isDebugValue()) {
405 if (NextMI ==
E)
continue;
408 if (FirstSS != SecondSS || LoadReg != StoreReg || FirstSS == -1)
continue;
413 if (NextMI->findRegisterUseOperandIdx(LoadReg,
true,
nullptr) != -1) {
423 E = toErase.
end();
I !=
E; ++
I)
424 (*I)->eraseFromParent();
432 dbgs() <<
"********** Stack Slot Coloring **********\n"
433 <<
"********** Function: " << MF.
getName() <<
'\n';
438 LS = &getAnalysis<LiveStacks>();
439 MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
441 bool Changed =
false;
443 unsigned NumSlots = LS->getNumIntervals();
456 ScanForSpillSlotRefs(MF);
458 Changed = ColorSlots(MF);
462 for (
unsigned i = 0, e = SSRefs.size();
i != e; ++
i)
465 OrigAlignments.clear();
469 for (
unsigned i = 0, e = Assignments.size();
i != e; ++
i)
void push_back(const T &Elt)
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...
STATISTIC(NumFunctions,"Total number of functions")
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...
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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
unsigned getNumOperands() const
Access to explicit operands of the instruction.
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
char & StackSlotColoringID
StackSlotColoring - This pass performs stack slot coloring.
AnalysisUsage & addPreservedID(const void *ID)
PseudoSourceValueManager & getPSVManager() const
const PseudoSourceValue * getFixedStack(int FI)
Return a pseudo source value referencing a fixed stack frame entry, e.g., a spill slot...
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
TargetInstrInfo - Interface to description of machine instruction set.
bool isDebugValue() const
mmo_iterator memoperands_end() const
void initializeStackSlotColoringPass(PassRegistry &)
initializer< Ty > init(const Ty &Val)
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
const MachineOperand & getOperand(unsigned i) const
static cl::opt< int > DCELimit("ssc-dce-limit", cl::init(-1), cl::Hidden)
bool overlaps(const LiveRange &other) const
overlaps - Return true if the intersection of the two live ranges is not empty.
Represent the analysis usage information of a pass.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
const PseudoSourceValue * getPseudoValue() const
stack slot Stack Slot false
static cl::opt< bool > DisableSharing("no-stack-slot-sharing", cl::init(false), cl::Hidden, cl::desc("Suppress slot sharing during stack coloring"))
Iterator for intrusive lists based on ilist_node.
Color
A "color", which is either even or odd.
bool operator()(LiveInterval *LHS, LiveInterval *RHS) 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...
Module.h This file contains the declarations for the Module class.
unsigned 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...
void setPreservesCFG()
This function should be called by the pass, iff they do not:
static float getSpillWeight(bool isDef, bool isUse, const MachineBlockFrequencyInfo *MBFI, const MachineInstr &Instr)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Special value supplied for machine level alias analysis.
unsigned isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
TargetInstrInfo overrides.
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()
stack slot Stack Slot Coloring
bool exposesReturnsTwice() const
exposesReturnsTwice - Returns true if the function calls setjmp or any other similar functions with a...
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
INITIALIZE_PASS_BEGIN(StackSlotColoring,"stack-slot-coloring","Stack Slot Coloring", false, false) INITIALIZE_PASS_END(StackSlotColoring
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
virtual const TargetInstrInfo * getInstrInfo() const
A specialized PseudoSourceValue for holding FixedStack values, which must include a frame index...
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.