14 #define DEBUG_TYPE "stackslotcoloring"
39 cl::desc(
"Suppress slot sharing during stack coloring"));
43 STATISTIC(NumEliminated,
"Number of stack slots eliminated due to coloring");
44 STATISTIC(NumDead,
"Number of trivially dead stack accesses eliminated");
54 std::vector<LiveInterval*> SSIntervals;
104 void InitializeSlots();
106 bool OverlapWithAssignments(
LiveInterval *li,
int Color)
const;
119 "Stack Slot Coloring",
false,
false)
139 SSRefs.resize(MFI->getObjectIndexEnd());
156 if (!
LS->hasInterval(FI))
167 dyn_cast<FixedStackPseudoSourceValue>(V)) {
168 int FI = FSV->getFrameIndex();
170 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);
189 DEBUG(
dbgs() <<
"Spill slot intervals:\n");
194 if (MFI->isDeadObjectIndex(FI))
196 SSIntervals.push_back(&li);
197 OrigAlignments[FI] = MFI->getObjectAlignment(FI);
198 OrigSizes[FI] = MFI->getObjectSize(FI);
204 std::stable_sort(SSIntervals.begin(), SSIntervals.end(), IntervalSorter());
207 NextColor = AllColors.find_first();
213 StackSlotColoring::OverlapWithAssignments(
LiveInterval *li,
int Color)
const {
215 for (
unsigned i = 0, e = OtherLIs.
size(); i != e; ++i) {
230 Color = UsedColors.find_first();
231 while (Color != -1) {
232 if (!OverlapWithAssignments(li, Color)) {
237 Color = UsedColors.find_next(Color);
244 assert(NextColor != -1 &&
"No more spill slots?");
246 UsedColors.set(Color);
247 NextColor = AllColors.find_next(NextColor);
251 Assignments[Color].push_back(li);
253 DEBUG(
dbgs() <<
"Assigning fi#" << FI <<
" to fi#" << Color <<
"\n");
258 unsigned Align = OrigAlignments[FI];
259 if (!Share || Align > MFI->getObjectAlignment(Color))
260 MFI->setObjectAlignment(Color, Align);
261 int64_t Size = OrigSizes[FI];
262 if (!Share || Size > MFI->getObjectSize(Color))
263 MFI->setObjectSize(Color, Size);
270 unsigned NumObjs = MFI->getObjectIndexEnd();
276 DEBUG(
dbgs() <<
"Color spill slot intervals:\n");
277 bool Changed =
false;
278 for (
unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
281 int NewSS = ColorSlot(li);
282 assert(NewSS >= 0 &&
"Stack coloring failed?");
283 SlotMapping[SS] = NewSS;
284 RevMap[NewSS].push_back(SS);
285 SlotWeights[NewSS] += li->
weight;
286 UsedColors.set(NewSS);
287 Changed |= (SS != NewSS);
290 DEBUG(
dbgs() <<
"\nSpill slots after coloring:\n");
291 for (
unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
294 li->
weight = SlotWeights[SS];
297 std::stable_sort(SSIntervals.begin(), SSIntervals.end(), IntervalSorter());
300 for (
unsigned i = 0, e = SSIntervals.size(); i != e; ++i)
309 for (
unsigned SS = 0, SE = SSRefs.size(); SS != SE; ++SS) {
310 int NewFI = SlotMapping[SS];
311 if (NewFI == -1 || (NewFI == (
int)SS))
316 for (
unsigned i = 0, e = RefMMOs.
size(); i != e; ++i)
317 RefMMOs[i]->setValue(NewSV);
326 RewriteInstruction(
MII, SlotMapping, MF);
327 RemoveDeadStores(MBB);
331 while (NextColor != -1) {
332 DEBUG(
dbgs() <<
"Removing unused stack object fi#" << NextColor <<
"\n");
333 MFI->RemoveStackObject(NextColor);
334 NextColor = AllColors.find_next(NextColor);
342 void StackSlotColoring::RewriteInstruction(
MachineInstr *MI,
353 int NewFI = SlotMapping[OldFI];
354 if (NewFI == -1 || NewFI == OldFI)
371 bool changed =
false;
380 int FirstSS, SecondSS;
381 if (
TII->isStackSlotCopy(
I, FirstSS, SecondSS) &&
382 FirstSS == SecondSS &&
391 if (NextMI == MBB->
end())
continue;
393 unsigned LoadReg = 0;
394 unsigned StoreReg = 0;
397 if (FirstSS != SecondSS || LoadReg != StoreReg || FirstSS == -1)
continue;
402 if (NextMI->findRegisterUseOperandIdx(LoadReg,
true, 0) != -1) {
412 E = toErase.
end();
I != E; ++
I)
413 (*I)->eraseFromParent();
421 dbgs() <<
"********** Stack Slot Coloring **********\n"
422 <<
"********** Function: " << MF.
getName() <<
'\n';
427 LS = &getAnalysis<LiveStacks>();
428 MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
430 bool Changed =
false;
432 unsigned NumSlots =
LS->getNumIntervals();
445 ScanForSpillSlotRefs(MF);
447 Changed = ColorSlots(MF);
451 for (
unsigned i = 0, e = SSRefs.size(); i != e; ++i)
454 OrigAlignments.clear();
458 for (
unsigned i = 0, e = Assignments.size(); i != e; ++i)
459 Assignments[i].clear();
static float getSpillWeight(bool isDef, bool isUse, BlockFrequency freq)
void push_back(const T &Elt)
AnalysisUsage & addPreserved()
static PassRegistry * getPassRegistry()
char & MachineDominatorsID
MachineDominators - This pass is a machine dominators analysis pass.
static int stackSlot2Index(unsigned Reg)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
const HexagonInstrInfo * TII
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Abstract Stack Frame Information.
static const PseudoSourceValue * getFixedStack(int FI)
ID
LLVM Calling Convention Representation.
unsigned getNumOperands() const
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)
STATISTIC(NumEliminated,"Number of stack slots eliminated due to coloring")
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)
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
ItTy next(ItTy it, Dist n)
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"))
virtual const TargetInstrInfo * getInstrInfo() const
bool operator()(LiveInterval *LHS, LiveInterval *RHS) const
MachineFrameInfo * getFrameInfo()
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
const Value * getValue() const
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
stack slot Stack Slot Coloring
bool exposesReturnsTwice() const
virtual void getAnalysisUsage(AnalysisUsage &AU) const
INITIALIZE_PASS_BEGIN(StackSlotColoring,"stack-slot-coloring","Stack Slot Coloring", false, false) INITIALIZE_PASS_END(StackSlotColoring
const TargetMachine & getTarget() const
virtual unsigned isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const
virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const
LLVM Value Representation.
BasicBlockListType::iterator iterator
SS2IntervalMap::iterator iterator
StringRef getName() const
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.