LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
StackSlotColoring.cpp
Go to the documentation of this file.
1 //===-- StackSlotColoring.cpp - Stack slot coloring pass. -----------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the stack slot coloring pass.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #define DEBUG_TYPE "stackslotcoloring"
15 #include "llvm/CodeGen/Passes.h"
16 #include "llvm/ADT/BitVector.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/Statistic.h"
27 #include "llvm/IR/Module.h"
29 #include "llvm/Support/Debug.h"
33 #include <vector>
34 using namespace llvm;
35 
36 static cl::opt<bool>
37 DisableSharing("no-stack-slot-sharing",
38  cl::init(false), cl::Hidden,
39  cl::desc("Suppress slot sharing during stack coloring"));
40 
41 static cl::opt<int> DCELimit("ssc-dce-limit", cl::init(-1), cl::Hidden);
42 
43 STATISTIC(NumEliminated, "Number of stack slots eliminated due to coloring");
44 STATISTIC(NumDead, "Number of trivially dead stack accesses eliminated");
45 
46 namespace {
47  class StackSlotColoring : public MachineFunctionPass {
48  LiveStacks* LS;
49  MachineFrameInfo *MFI;
50  const TargetInstrInfo *TII;
51  const MachineBlockFrequencyInfo *MBFI;
52 
53  // SSIntervals - Spill slot intervals.
54  std::vector<LiveInterval*> SSIntervals;
55 
56  // SSRefs - Keep a list of MachineMemOperands for each spill slot.
57  // MachineMemOperands can be shared between instructions, so we need
58  // to be careful that renames like [FI0, FI1] -> [FI1, FI2] do not
59  // become FI0 -> FI1 -> FI2.
61 
62  // OrigAlignments - Alignments of stack objects before coloring.
63  SmallVector<unsigned, 16> OrigAlignments;
64 
65  // OrigSizes - Sizess of stack objects before coloring.
66  SmallVector<unsigned, 16> OrigSizes;
67 
68  // AllColors - If index is set, it's a spill slot, i.e. color.
69  // FIXME: This assumes PEI locate spill slot with smaller indices
70  // closest to stack pointer / frame pointer. Therefore, smaller
71  // index == better color.
72  BitVector AllColors;
73 
74  // NextColor - Next "color" that's not yet used.
75  int NextColor;
76 
77  // UsedColors - "Colors" that have been assigned.
78  BitVector UsedColors;
79 
80  // Assignments - Color to intervals mapping.
82 
83  public:
84  static char ID; // Pass identification
85  StackSlotColoring() :
86  MachineFunctionPass(ID), NextColor(-1) {
88  }
89 
90  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
91  AU.setPreservesCFG();
94  AU.addRequired<LiveStacks>();
99  }
100 
101  virtual bool runOnMachineFunction(MachineFunction &MF);
102 
103  private:
104  void InitializeSlots();
105  void ScanForSpillSlotRefs(MachineFunction &MF);
106  bool OverlapWithAssignments(LiveInterval *li, int Color) const;
107  int ColorSlot(LiveInterval *li);
108  bool ColorSlots(MachineFunction &MF);
109  void RewriteInstruction(MachineInstr *MI, SmallVectorImpl<int> &SlotMapping,
110  MachineFunction &MF);
111  bool RemoveDeadStores(MachineBasicBlock* MBB);
112  };
113 } // end anonymous namespace
114 
115 char StackSlotColoring::ID = 0;
117 
118 INITIALIZE_PASS_BEGIN(StackSlotColoring, "stack-slot-coloring",
119  "Stack Slot Coloring", false, false)
123 INITIALIZE_PASS_END(StackSlotColoring, "stack-slot-coloring",
124  "Stack Slot Coloring", false, false)
125 
126 namespace {
127  // IntervalSorter - Comparison predicate that sort live intervals by
128  // their weight.
129  struct IntervalSorter {
130  bool operator()(LiveInterval* LHS, LiveInterval* RHS) const {
131  return LHS->weight > RHS->weight;
132  }
133  };
134 }
135 
136 /// ScanForSpillSlotRefs - Scan all the machine instructions for spill slot
137 /// references and update spill slot weights.
138 void StackSlotColoring::ScanForSpillSlotRefs(MachineFunction &MF) {
139  SSRefs.resize(MFI->getObjectIndexEnd());
140 
141  // FIXME: Need the equivalent of MachineRegisterInfo for frameindex operands.
142  for (MachineFunction::iterator MBBI = MF.begin(), E = MF.end();
143  MBBI != E; ++MBBI) {
144  MachineBasicBlock *MBB = &*MBBI;
145  BlockFrequency Freq = MBFI->getBlockFreq(MBB);
146  for (MachineBasicBlock::iterator MII = MBB->begin(), EE = MBB->end();
147  MII != EE; ++MII) {
148  MachineInstr *MI = &*MII;
149  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
150  MachineOperand &MO = MI->getOperand(i);
151  if (!MO.isFI())
152  continue;
153  int FI = MO.getIndex();
154  if (FI < 0)
155  continue;
156  if (!LS->hasInterval(FI))
157  continue;
158  LiveInterval &li = LS->getInterval(FI);
159  if (!MI->isDebugValue())
160  li.weight += LiveIntervals::getSpillWeight(false, true, Freq);
161  }
163  EE = MI->memoperands_end(); MMOI != EE; ++MMOI) {
164  MachineMemOperand *MMO = *MMOI;
165  if (const Value *V = MMO->getValue()) {
166  if (const FixedStackPseudoSourceValue *FSV =
167  dyn_cast<FixedStackPseudoSourceValue>(V)) {
168  int FI = FSV->getFrameIndex();
169  if (FI >= 0)
170  SSRefs[FI].push_back(MMO);
171  }
172  }
173  }
174  }
175  }
176 }
177 
178 /// InitializeSlots - Process all spill stack slot liveintervals and add them
179 /// to a sorted (by weight) list.
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);
187 
188  // Gather all spill slots into a list.
189  DEBUG(dbgs() << "Spill slot intervals:\n");
190  for (LiveStacks::iterator i = LS->begin(), e = LS->end(); i != e; ++i) {
191  LiveInterval &li = i->second;
192  DEBUG(li.dump());
194  if (MFI->isDeadObjectIndex(FI))
195  continue;
196  SSIntervals.push_back(&li);
197  OrigAlignments[FI] = MFI->getObjectAlignment(FI);
198  OrigSizes[FI] = MFI->getObjectSize(FI);
199  AllColors.set(FI);
200  }
201  DEBUG(dbgs() << '\n');
202 
203  // Sort them by weight.
204  std::stable_sort(SSIntervals.begin(), SSIntervals.end(), IntervalSorter());
205 
206  // Get first "color".
207  NextColor = AllColors.find_first();
208 }
209 
210 /// OverlapWithAssignments - Return true if LiveInterval overlaps with any
211 /// LiveIntervals that have already been assigned to the specified color.
212 bool
213 StackSlotColoring::OverlapWithAssignments(LiveInterval *li, int Color) const {
214  const SmallVectorImpl<LiveInterval *> &OtherLIs = Assignments[Color];
215  for (unsigned i = 0, e = OtherLIs.size(); i != e; ++i) {
216  LiveInterval *OtherLI = OtherLIs[i];
217  if (OtherLI->overlaps(*li))
218  return true;
219  }
220  return false;
221 }
222 
223 /// ColorSlot - Assign a "color" (stack slot) to the specified stack slot.
224 ///
225 int StackSlotColoring::ColorSlot(LiveInterval *li) {
226  int Color = -1;
227  bool Share = false;
228  if (!DisableSharing) {
229  // Check if it's possible to reuse any of the used colors.
230  Color = UsedColors.find_first();
231  while (Color != -1) {
232  if (!OverlapWithAssignments(li, Color)) {
233  Share = true;
234  ++NumEliminated;
235  break;
236  }
237  Color = UsedColors.find_next(Color);
238  }
239  }
240 
241  // Assign it to the first available color (assumed to be the best) if it's
242  // not possible to share a used color with other objects.
243  if (!Share) {
244  assert(NextColor != -1 && "No more spill slots?");
245  Color = NextColor;
246  UsedColors.set(Color);
247  NextColor = AllColors.find_next(NextColor);
248  }
249 
250  // Record the assignment.
251  Assignments[Color].push_back(li);
253  DEBUG(dbgs() << "Assigning fi#" << FI << " to fi#" << Color << "\n");
254 
255  // Change size and alignment of the allocated slot. If there are multiple
256  // objects sharing the same slot, then make sure the size and alignment
257  // are large enough for all.
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);
264  return Color;
265 }
266 
267 /// Colorslots - Color all spill stack slots and rewrite all frameindex machine
268 /// operands in the function.
269 bool StackSlotColoring::ColorSlots(MachineFunction &MF) {
270  unsigned NumObjs = MFI->getObjectIndexEnd();
271  SmallVector<int, 16> SlotMapping(NumObjs, -1);
272  SmallVector<float, 16> SlotWeights(NumObjs, 0.0);
273  SmallVector<SmallVector<int, 4>, 16> RevMap(NumObjs);
274  BitVector UsedColors(NumObjs);
275 
276  DEBUG(dbgs() << "Color spill slot intervals:\n");
277  bool Changed = false;
278  for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
279  LiveInterval *li = SSIntervals[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);
288  }
289 
290  DEBUG(dbgs() << "\nSpill slots after coloring:\n");
291  for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
292  LiveInterval *li = SSIntervals[i];
294  li->weight = SlotWeights[SS];
295  }
296  // Sort them by new weight.
297  std::stable_sort(SSIntervals.begin(), SSIntervals.end(), IntervalSorter());
298 
299 #ifndef NDEBUG
300  for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i)
301  DEBUG(SSIntervals[i]->dump());
302  DEBUG(dbgs() << '\n');
303 #endif
304 
305  if (!Changed)
306  return false;
307 
308  // Rewrite all MachineMemOperands.
309  for (unsigned SS = 0, SE = SSRefs.size(); SS != SE; ++SS) {
310  int NewFI = SlotMapping[SS];
311  if (NewFI == -1 || (NewFI == (int)SS))
312  continue;
313 
314  const Value *NewSV = PseudoSourceValue::getFixedStack(NewFI);
315  SmallVectorImpl<MachineMemOperand *> &RefMMOs = SSRefs[SS];
316  for (unsigned i = 0, e = RefMMOs.size(); i != e; ++i)
317  RefMMOs[i]->setValue(NewSV);
318  }
319 
320  // Rewrite all MO_FrameIndex operands. Look for dead stores.
321  for (MachineFunction::iterator MBBI = MF.begin(), E = MF.end();
322  MBBI != E; ++MBBI) {
323  MachineBasicBlock *MBB = &*MBBI;
324  for (MachineBasicBlock::iterator MII = MBB->begin(), EE = MBB->end();
325  MII != EE; ++MII)
326  RewriteInstruction(MII, SlotMapping, MF);
327  RemoveDeadStores(MBB);
328  }
329 
330  // Delete unused stack slots.
331  while (NextColor != -1) {
332  DEBUG(dbgs() << "Removing unused stack object fi#" << NextColor << "\n");
333  MFI->RemoveStackObject(NextColor);
334  NextColor = AllColors.find_next(NextColor);
335  }
336 
337  return true;
338 }
339 
340 /// RewriteInstruction - Rewrite specified instruction by replacing references
341 /// to old frame index with new one.
342 void StackSlotColoring::RewriteInstruction(MachineInstr *MI,
343  SmallVectorImpl<int> &SlotMapping,
344  MachineFunction &MF) {
345  // Update the operands.
346  for (unsigned i = 0, ee = MI->getNumOperands(); i != ee; ++i) {
347  MachineOperand &MO = MI->getOperand(i);
348  if (!MO.isFI())
349  continue;
350  int OldFI = MO.getIndex();
351  if (OldFI < 0)
352  continue;
353  int NewFI = SlotMapping[OldFI];
354  if (NewFI == -1 || NewFI == OldFI)
355  continue;
356  MO.setIndex(NewFI);
357  }
358 
359  // The MachineMemOperands have already been updated.
360 }
361 
362 
363 /// RemoveDeadStores - Scan through a basic block and look for loads followed
364 /// by stores. If they're both using the same stack slot, then the store is
365 /// definitely dead. This could obviously be much more aggressive (consider
366 /// pairs with instructions between them), but such extensions might have a
367 /// considerable compile time impact.
368 bool StackSlotColoring::RemoveDeadStores(MachineBasicBlock* MBB) {
369  // FIXME: This could be much more aggressive, but we need to investigate
370  // the compile time impact of doing so.
371  bool changed = false;
372 
374 
375  for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
376  I != E; ++I) {
377  if (DCELimit != -1 && (int)NumDead >= DCELimit)
378  break;
379 
380  int FirstSS, SecondSS;
381  if (TII->isStackSlotCopy(I, FirstSS, SecondSS) &&
382  FirstSS == SecondSS &&
383  FirstSS != -1) {
384  ++NumDead;
385  changed = true;
386  toErase.push_back(I);
387  continue;
388  }
389 
391  if (NextMI == MBB->end()) continue;
392 
393  unsigned LoadReg = 0;
394  unsigned StoreReg = 0;
395  if (!(LoadReg = TII->isLoadFromStackSlot(I, FirstSS))) continue;
396  if (!(StoreReg = TII->isStoreToStackSlot(NextMI, SecondSS))) continue;
397  if (FirstSS != SecondSS || LoadReg != StoreReg || FirstSS == -1) continue;
398 
399  ++NumDead;
400  changed = true;
401 
402  if (NextMI->findRegisterUseOperandIdx(LoadReg, true, 0) != -1) {
403  ++NumDead;
404  toErase.push_back(I);
405  }
406 
407  toErase.push_back(NextMI);
408  ++I;
409  }
410 
412  E = toErase.end(); I != E; ++I)
413  (*I)->eraseFromParent();
414 
415  return changed;
416 }
417 
418 
419 bool StackSlotColoring::runOnMachineFunction(MachineFunction &MF) {
420  DEBUG({
421  dbgs() << "********** Stack Slot Coloring **********\n"
422  << "********** Function: " << MF.getName() << '\n';
423  });
424 
425  MFI = MF.getFrameInfo();
426  TII = MF.getTarget().getInstrInfo();
427  LS = &getAnalysis<LiveStacks>();
428  MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
429 
430  bool Changed = false;
431 
432  unsigned NumSlots = LS->getNumIntervals();
433  if (NumSlots == 0)
434  // Nothing to do!
435  return false;
436 
437  // If there are calls to setjmp or sigsetjmp, don't perform stack slot
438  // coloring. The stack could be modified before the longjmp is executed,
439  // resulting in the wrong value being used afterwards. (See
440  // <rdar://problem/8007500>.)
441  if (MF.exposesReturnsTwice())
442  return false;
443 
444  // Gather spill slot references
445  ScanForSpillSlotRefs(MF);
446  InitializeSlots();
447  Changed = ColorSlots(MF);
448 
449  NextColor = -1;
450  SSIntervals.clear();
451  for (unsigned i = 0, e = SSRefs.size(); i != e; ++i)
452  SSRefs[i].clear();
453  SSRefs.clear();
454  OrigAlignments.clear();
455  OrigSizes.clear();
456  AllColors.clear();
457  UsedColors.clear();
458  for (unsigned i = 0, e = Assignments.size(); i != e; ++i)
459  Assignments[i].clear();
460  Assignments.clear();
461 
462  return Changed;
463 }
static float getSpillWeight(bool isDef, bool isUse, BlockFrequency freq)
AnalysisUsage & addPreserved()
static PassRegistry * getPassRegistry()
const unsigned reg
Definition: LiveInterval.h:532
char & MachineDominatorsID
MachineDominators - This pass is a machine dominators analysis pass.
static int stackSlot2Index(unsigned Reg)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:167
const HexagonInstrInfo * TII
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:172
void setIndex(int Idx)
Abstract Stack Frame Information.
static const PseudoSourceValue * getFixedStack(int FI)
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
unsigned getNumOperands() const
Definition: MachineInstr.h:265
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
Definition: MachineInstr.h:639
mmo_iterator memoperands_end() const
Definition: MachineInstr.h:292
void initializeStackSlotColoringPass(PassRegistry &)
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:314
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
const MCInstrInfo & MII
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:267
static cl::opt< int > DCELimit("ssc-dce-limit", cl::init(-1), cl::Hidden)
bool overlaps(const LiveRange &other) const
Definition: LiveInterval.h:377
ItTy next(ItTy it, Dist n)
Definition: STLExtras.h:154
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()
void setPreservesCFG()
Definition: Pass.cpp:249
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
Definition: Debug.cpp:101
const Value * getValue() const
stack slot coloring
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
#define I(x, y, z)
Definition: MD5.cpp:54
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.
Definition: Value.h:66
BasicBlockListType::iterator iterator
#define DEBUG(X)
Definition: Debug.h:97
SS2IntervalMap::iterator iterator
StringRef getName() const
void dump() const
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:291