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))
166 dyn_cast_or_null<FixedStackPseudoSourceValue>(
168 int FI = FSV->getFrameIndex();
170 SSRefs[FI].push_back(MMO);
179 void StackSlotColoring::InitializeSlots() {
180 int LastFI = MFI->getObjectIndexEnd();
181 OrigAlignments.resize(LastFI);
182 OrigSizes.resize(LastFI);
183 AllColors.resize(LastFI);
184 UsedColors.resize(LastFI);
185 Assignments.resize(LastFI);
187 typedef std::iterator_traits<LiveStacks::iterator>::value_type Pair;
189 Intervals.
reserve(
LS->getNumIntervals());
192 std::sort(Intervals.
begin(), Intervals.
end(),
193 [](Pair *LHS, Pair *RHS) {
return LHS->first < RHS->first; });
196 DEBUG(
dbgs() <<
"Spill slot intervals:\n");
197 for (
auto *
I : Intervals) {
201 if (MFI->isDeadObjectIndex(FI))
203 SSIntervals.push_back(&li);
204 OrigAlignments[FI] = MFI->getObjectAlignment(FI);
205 OrigSizes[FI] = MFI->getObjectSize(FI);
211 std::stable_sort(SSIntervals.begin(), SSIntervals.end(), IntervalSorter());
214 NextColor = AllColors.find_first();
222 for (
unsigned i = 0, e = OtherLIs.
size(); i != e; ++i) {
237 Color = UsedColors.find_first();
238 while (Color != -1) {
239 if (!OverlapWithAssignments(li, Color)) {
244 Color = UsedColors.find_next(Color);
251 assert(NextColor != -1 &&
"No more spill slots?");
253 UsedColors.set(Color);
254 NextColor = AllColors.find_next(NextColor);
258 Assignments[
Color].push_back(li);
260 DEBUG(
dbgs() <<
"Assigning fi#" << FI <<
" to fi#" << Color <<
"\n");
265 unsigned Align = OrigAlignments[FI];
266 if (!Share || Align > MFI->getObjectAlignment(Color))
267 MFI->setObjectAlignment(Color, Align);
268 int64_t Size = OrigSizes[FI];
269 if (!Share || Size > MFI->getObjectSize(Color))
270 MFI->setObjectSize(Color, Size);
277 unsigned NumObjs = MFI->getObjectIndexEnd();
283 DEBUG(
dbgs() <<
"Color spill slot intervals:\n");
284 bool Changed =
false;
285 for (
unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
288 int NewSS = ColorSlot(li);
289 assert(NewSS >= 0 &&
"Stack coloring failed?");
291 RevMap[NewSS].push_back(SS);
292 SlotWeights[NewSS] += li->
weight;
293 UsedColors.set(NewSS);
294 Changed |= (SS != NewSS);
297 DEBUG(
dbgs() <<
"\nSpill slots after coloring:\n");
298 for (
unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
301 li->
weight = SlotWeights[SS];
304 std::stable_sort(SSIntervals.begin(), SSIntervals.end(), IntervalSorter());
307 for (
unsigned i = 0, e = SSIntervals.size(); i != e; ++i)
316 for (
unsigned SS = 0, SE = SSRefs.size(); SS != SE; ++SS) {
318 if (NewFI == -1 || (NewFI == (
int)SS))
323 for (
unsigned i = 0, e = RefMMOs.
size(); i != e; ++i)
324 RefMMOs[i]->setValue(NewSV);
334 RemoveDeadStores(MBB);
338 while (NextColor != -1) {
339 DEBUG(
dbgs() <<
"Removing unused stack object fi#" << NextColor <<
"\n");
340 MFI->RemoveStackObject(NextColor);
341 NextColor = AllColors.find_next(NextColor);
349 void StackSlotColoring::RewriteInstruction(
MachineInstr *MI,
360 int NewFI = SlotMapping[OldFI];
361 if (NewFI == -1 || NewFI == OldFI)
378 bool changed =
false;
387 int FirstSS, SecondSS;
388 if (
TII->isStackSlotCopy(
I, FirstSS, SecondSS) &&
389 FirstSS == SecondSS &&
398 if (NextMI == MBB->
end())
continue;
400 unsigned LoadReg = 0;
401 unsigned StoreReg = 0;
404 if (FirstSS != SecondSS || LoadReg != StoreReg || FirstSS == -1)
continue;
409 if (NextMI->findRegisterUseOperandIdx(LoadReg,
true,
nullptr) != -1) {
419 E = toErase.
end();
I != E; ++
I)
420 (*I)->eraseFromParent();
428 dbgs() <<
"********** Stack Slot Coloring **********\n"
429 <<
"********** Function: " << MF.
getName() <<
'\n';
434 LS = &getAnalysis<LiveStacks>();
435 MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
437 bool Changed =
false;
439 unsigned NumSlots = LS->getNumIntervals();
452 ScanForSpillSlotRefs(MF);
454 Changed = ColorSlots(MF);
458 for (
unsigned i = 0, e = SSRefs.size(); i != e; ++i)
461 OrigAlignments.clear();
465 for (
unsigned i = 0, e = Assignments.size(); i != e; ++i)
466 Assignments[i].clear();
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)
stackSlot2Index - Compute the frame index from a register value representing a stack slot...
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
MachineMemOperand - A description of a memory reference used in the backend.
unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const override
isLoadFromStackSlot - If the specified machine instruction is a direct load from a stack slot...
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
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
static const PseudoSourceValue * getFixedStack(int FI)
A pseudo source value referencing a fixed stack frame entry, e.g., a spill slot.
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)
TargetInstrInfo - Interface to description of machine instruction set.
bool isDebugValue() const
mmo_iterator memoperands_end() const
void initializeStackSlotColoringPass(PassRegistry &)
bundle_iterator< MachineInstr, instr_iterator > iterator
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.
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.
static float getSpillWeight(bool isDef, bool isUse, const MachineBlockFrequencyInfo *MBFI, const MachineInstr *Instr)
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"))
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.
MachineFrameInfo * getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
PseudoSourceValue - Special value supplied for machine level alias analysis.
This struct contains the mapping from the slot numbers to unnamed metadata nodes and global values...
Representation of each machine instruction.
stack slot Stack Slot Coloring
bool exposesReturnsTwice() const
exposesReturnsTwice - Returns true if the function calls setjmp or any other similar functions with a...
unsigned isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const override
isStoreToStackSlot - If the specified machine instruction is a direct store to a stack slot...
INITIALIZE_PASS_BEGIN(StackSlotColoring,"stack-slot-coloring","Stack Slot Coloring", false, false) INITIALIZE_PASS_END(StackSlotColoring
virtual const TargetInstrInfo * getInstrInfo() const
BasicBlockListType::iterator iterator
FixedStackPseudoSourceValue - A specialized PseudoSourceValue for holding FixedStack values...
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.