llvm.org GIT mirror llvm / 3f32d65
Add a stack slot coloring pass. Not yet enabled. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51934 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 12 years ago
10 changed file(s) with 527 addition(s) and 51 deletion(s). Raw diff Collapse all Expand all
3434 /// merge point), it contains ~0u,x. If the value number is not in use, it
3535 /// contains ~1u,x to indicate that the value # is not used.
3636 /// def - Instruction # of the definition.
37 /// - or reg # of the definition if it's a stack slot liveinterval.
3738 /// copy - Copy iff val# is defined by a copy; zero otherwise.
3839 /// hasPHIKill - One or more of the kills are PHI nodes.
3940 /// kills - Instruction # of the kills.
99100 typedef SmallVector Ranges;
100101 typedef SmallVector VNInfoList;
101102
102 unsigned reg; // the register of this interval
103 bool isSS; // True if this represents a stack slot
104 unsigned reg; // the register or stack slot of this interval
103105 unsigned preference; // preferred register to allocate for this interval
104106 float weight; // weight of this interval
105107 Ranges ranges; // the ranges in which this register is live
106108 VNInfoList valnos; // value#'s
107109
108110 public:
109 LiveInterval(unsigned Reg, float Weight)
110 : reg(Reg), preference(0), weight(Weight) {
111 LiveInterval(unsigned Reg, float Weight, bool IsSS = false)
112 : isSS(IsSS), reg(Reg), preference(0), weight(Weight) {
111113 }
112114
113115 typedef Ranges::iterator iterator;
136138 return end();
137139 while (I->end <= Pos) ++I;
138140 return I;
141 }
142
143 /// isStackSlot - Return true if this is a stack slot interval.
144 ///
145 bool isStackSlot() const { return isSS; }
146
147 /// getStackSlotIndex - Return stack slot index if this is a stack slot
148 /// interval.
149 int getStackSlotIndex() const {
150 assert(isStackSlot() && "Interval is not a stack slot interval!");
151 return reg;
139152 }
140153
141154 bool containsOneValue() const { return valnos.size() == 1; }
312325 /// FindLiveRangeContaining - Return an iterator to the live range that
313326 /// contains the specified index, or end() if there is none.
314327 iterator FindLiveRangeContaining(unsigned Idx);
328
329 /// findDefinedVNInfo - Find the VNInfo that's defined at the specified
330 /// index (register interval) or defined by the specified register (stack
331 /// inteval).
332 VNInfo *findDefinedVNInfo(unsigned DefIdxOrReg) const;
315333
316334 /// overlaps - Return true if the intersection of the two live intervals is
317335 /// not empty.
0 //===-- LiveStackAnalysis.h - Live Stack Slot Analysis ----------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the live stack slot analysis pass. It is analogous to
10 // live interval analysis except it's analyzing liveness of stack slots rather
11 // than registers.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_CODEGEN_LIVESTACK_ANALYSIS_H
16 #define LLVM_CODEGEN_LIVESTACK_ANALYSIS_H
17
18 #include "llvm/CodeGen/MachineFunctionPass.h"
19 #include "llvm/CodeGen/LiveInterval.h"
20 #include "llvm/Support/Allocator.h"
21 #include
22
23 namespace llvm {
24
25 class LiveStacks : public MachineFunctionPass {
26 /// Special pool allocator for VNInfo's (LiveInterval val#).
27 ///
28 BumpPtrAllocator VNInfoAllocator;
29
30 /// s2iMap - Stack slot indices to live interval mapping.
31 ///
32 typedef std::map SS2IntervalMap;
33 SS2IntervalMap s2iMap;
34
35 public:
36 static char ID; // Pass identification, replacement for typeid
37 LiveStacks() : MachineFunctionPass((intptr_t)&ID) {}
38
39 typedef SS2IntervalMap::iterator iterator;
40 typedef SS2IntervalMap::const_iterator const_iterator;
41 const_iterator begin() const { return s2iMap.begin(); }
42 const_iterator end() const { return s2iMap.end(); }
43 iterator begin() { return s2iMap.begin(); }
44 iterator end() { return s2iMap.end(); }
45 unsigned getNumIntervals() const { return (unsigned)s2iMap.size(); }
46
47 LiveInterval &getOrCreateInterval(int Slot) {
48 SS2IntervalMap::iterator I = s2iMap.find(Slot);
49 if (I == s2iMap.end())
50 I = s2iMap.insert(I,std::make_pair(Slot,LiveInterval(Slot,0.0F,true)));
51 return I->second;
52 }
53
54 BumpPtrAllocator& getVNInfoAllocator() { return VNInfoAllocator; }
55
56 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
57 virtual void releaseMemory();
58
59 /// runOnMachineFunction - pass entry point
60 virtual bool runOnMachineFunction(MachineFunction&);
61
62 /// print - Implement the dump method.
63 virtual void print(std::ostream &O, const Module* = 0) const;
64 void print(std::ostream *O, const Module* M = 0) const {
65 if (O) print(*O, M);
66 }
67 };
68 }
69
70 #endif /* LLVM_CODEGEN_LIVESTACK_ANALYSIS_H */
194194 ///
195195 int getObjectIndexEnd() const { return (int)Objects.size()-NumFixedObjects; }
196196
197 /// getNumFixedObjects() - Return the number of fixed objects.
198 unsigned getNumFixedObjects() const { return NumFixedObjects; }
199
200 /// getNumObjects() - Return the number of objects.
201 ///
202 unsigned getNumObjects() const { return Objects.size(); }
203
197204 /// getObjectSize - Return the size of the specified object
198205 ///
199206 int64_t getObjectSize(int ObjectIdx) const {
200207 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
201208 "Invalid Object Idx!");
202209 return Objects[ObjectIdx+NumFixedObjects].Size;
210 }
211
212 // setObjectSize - Change the size of the specified stack object...
213 void setObjectSize(int ObjectIdx, int64_t Size) {
214 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
215 "Invalid Object Idx!");
216 Objects[ObjectIdx+NumFixedObjects].Size = Size;
203217 }
204218
205219 /// getObjectAlignment - Return the alignment of the specified stack object...
323337 /// RemoveStackObject - Remove or mark dead a statically sized stack object.
324338 ///
325339 void RemoveStackObject(int ObjectIdx) {
326 if (ObjectIdx == (int)(Objects.size()-NumFixedObjects-1))
327 // Last object, simply pop it off the list.
328 Objects.pop_back();
329 else
330 // Mark it dead.
331 Objects[ObjectIdx+NumFixedObjects].Size = ~0ULL;
340 // Mark it dead.
341 Objects[ObjectIdx+NumFixedObjects].Size = ~0ULL;
332342 }
333343
334344 /// CreateVariableSizedObject - Notify the MachineFrameInfo object that a
171171 /// createMachineSinkingPass - This pass performs sinking on machine
172172 /// instructions.
173173 FunctionPass *createMachineSinkingPass();
174
175 /// createStackSlotColoringPass - This pass performs stack slot coloring.
176 FunctionPass *createStackSlotColoringPass();
174177
175178 } // End llvm namespace
176179
3737 EnableSinking("enable-sinking", cl::init(false), cl::Hidden,
3838 cl::desc("Perform sinking on machine code"));
3939 static cl::opt
40 AlignLoops("align-loops", cl::init(true), cl::Hidden,
41 cl::desc("Align loop headers"));
42 static cl::opt
43 PerformLICM("machine-licm",
44 cl::init(false), cl::Hidden,
45 cl::desc("Perform loop-invariant code motion on machine code"));
40 EnableStackColoring("stack-coloring",
41 cl::init(true), cl::Hidden,
42 cl::desc("Perform stack slot coloring"));
43 static cl::opt
44 EnableLICM("machine-licm",
45 cl::init(false), cl::Hidden,
46 cl::desc("Perform loop-invariant code motion on machine code"));
4647
4748 // When this works it will be on by default.
4849 static cl::opt
8788 if (PrintMachineCode)
8889 PM.add(createMachineFunctionPrinterPass(cerr));
8990
90 if (PerformLICM)
91 if (EnableLICM)
9192 PM.add(createMachineLICMPass());
9293
9394 if (EnableSinking)
100101 // Perform register allocation to convert to a concrete x86 representation
101102 PM.add(createRegisterAllocator());
102103
103 if (PrintMachineCode)
104 PM.add(createMachineFunctionPrinterPass(cerr));
105
106 PM.add(createLowerSubregsPass());
107
108 if (PrintMachineCode) // Print the subreg lowered code
109 PM.add(createMachineFunctionPrinterPass(cerr));
110
104 // Perform stack slot coloring.
105 if (EnableStackColoring)
106 PM.add(createStackSlotColoringPass());
107
108 if (PrintMachineCode) // Print the register-allocated code
109 PM.add(createMachineFunctionPrinterPass(cerr));
110
111111 // Run post-ra passes.
112112 if (addPostRegAlloc(PM, Fast) && PrintMachineCode)
113113 PM.add(createMachineFunctionPrinterPass(cerr));
114114
115 PM.add(createLowerSubregsPass());
116
117 if (PrintMachineCode) // Print the subreg lowered code
118 PM.add(createMachineFunctionPrinterPass(cerr));
119
115120 // Insert prolog/epilog code. Eliminate abstract frame index references...
116121 PM.add(createPrologEpilogCodeInserter());
122
123 if (PrintMachineCode)
124 PM.add(createMachineFunctionPrinterPass(cerr));
117125
118126 // Second pass scheduler.
119127 if (!Fast && !DisablePostRAScheduler)
139147 if (addPreEmitPass(PM, Fast) && PrintMachineCode)
140148 PM.add(createMachineFunctionPrinterPass(cerr));
141149
142 if (AlignLoops && !Fast && !OptimizeForSize)
150 if (!Fast && !OptimizeForSize)
143151 PM.add(createLoopAlignerPass());
144152
145153 switch (FileType) {
217225 if (PrintMachineCode)
218226 PM.add(createMachineFunctionPrinterPass(cerr));
219227
220 if (PerformLICM)
228 if (EnableLICM)
221229 PM.add(createMachineLICMPass());
222230
223231 if (EnableSinking)
227235 if (addPreRegAlloc(PM, Fast) && PrintMachineCode)
228236 PM.add(createMachineFunctionPrinterPass(cerr));
229237
230 // Perform register allocation to convert to a concrete x86 representation
238 // Perform register allocation.
231239 PM.add(createRegisterAllocator());
232
240
241 // Perform stack slot coloring.
242 if (EnableStackColoring)
243 PM.add(createStackSlotColoringPass());
244
233245 if (PrintMachineCode)
234246 PM.add(createMachineFunctionPrinterPass(cerr));
235247
236 PM.add(createLowerSubregsPass());
237
238 if (PrintMachineCode) // Print the subreg lowered code
239 PM.add(createMachineFunctionPrinterPass(cerr));
240
241248 // Run post-ra passes.
242249 if (addPostRegAlloc(PM, Fast) && PrintMachineCode)
243250 PM.add(createMachineFunctionPrinterPass(cerr));
244251
252 if (PrintMachineCode) // Print the register-allocated code
253 PM.add(createMachineFunctionPrinterPass(cerr));
254
255 PM.add(createLowerSubregsPass());
256
257 if (PrintMachineCode) // Print the subreg lowered code
258 PM.add(createMachineFunctionPrinterPass(cerr));
259
245260 // Insert prolog/epilog code. Eliminate abstract frame index references...
246261 PM.add(createPrologEpilogCodeInserter());
247262
248 if (PrintMachineCode) // Print the register-allocated code
263 if (PrintMachineCode)
249264 PM.add(createMachineFunctionPrinterPass(cerr));
250265
251266 // Second pass scheduler.
257272 PM.add(createBranchFoldingPass(getEnableTailMergeDefault()));
258273
259274 PM.add(createGCMachineCodeAnalysisPass());
275
260276 if (PrintMachineCode)
261277 PM.add(createMachineFunctionPrinterPass(cerr));
262278
357357 return end();
358358 }
359359
360 /// findDefinedVNInfo - Find the VNInfo that's defined at the specified index
361 /// (register interval) or defined by the specified register (stack inteval).
362 VNInfo *LiveInterval::findDefinedVNInfo(unsigned DefIdxOrReg) const {
363 VNInfo *VNI = NULL;
364 for (LiveInterval::const_vni_iterator i = vni_begin(), e = vni_end();
365 i != e; ++i)
366 if ((*i)->def == DefIdxOrReg) {
367 VNI = *i;
368 break;
369 }
370 return VNI;
371 }
372
373
360374 /// join - Join two live intervals (this, and other) together. This applies
361375 /// mappings to the value numbers in the LHS/RHS intervals as specified. If
362376 /// the intervals are not joinable, this aborts.
663677
664678 void LiveInterval::print(std::ostream &OS,
665679 const TargetRegisterInfo *TRI) const {
666 if (TRI && TargetRegisterInfo::isPhysicalRegister(reg))
680 if (isSS)
681 OS << "SS#" << reg;
682 else if (TRI && TargetRegisterInfo::isPhysicalRegister(reg))
667683 OS << TRI->getName(reg);
668684 else
669685 OS << "%reg" << reg;
671687 OS << ',' << weight;
672688
673689 if (empty())
674 OS << "EMPTY";
690 OS << " EMPTY";
675691 else {
676692 OS << " = ";
677693 for (LiveInterval::Ranges::const_iterator I = ranges.begin(),
6464 }
6565
6666 void LiveIntervals::releaseMemory() {
67 MBB2IdxMap.clear();
6768 Idx2MBBMap.clear();
6869 mi2iMap_.clear();
6970 i2miMap_.clear();
228229 void LiveIntervals::print(std::ostream &O, const Module* ) const {
229230 O << "********** INTERVALS **********\n";
230231 for (const_iterator I = begin(), E = end(); I != E; ++I) {
231 I->second.print(DOUT, tri_);
232 DOUT << "\n";
232 I->second.print(O, tri_);
233 O << "\n";
233234 }
234235
235236 O << "********** MACHINEINSTRS **********\n";
11591160 return false;
11601161 }
11611162
1162 static const VNInfo *findDefinedVNInfo(const LiveInterval &li, unsigned DefIdx) {
1163 const VNInfo *VNI = NULL;
1164 for (LiveInterval::const_vni_iterator i = li.vni_begin(),
1165 e = li.vni_end(); i != e; ++i)
1166 if ((*i)->def == DefIdx) {
1167 VNI = *i;
1168 break;
1169 }
1170 return VNI;
1171 }
1172
11731163 /// RewriteInfo - Keep track of machine instrs that will be rewritten
11741164 /// during spilling.
11751165 namespace {
13171307 HasKill = anyKillInMBBAfterIdx(li, I->valno, MBB, getDefIndex(index));
13181308 else {
13191309 // If this is a two-address code, then this index starts a new VNInfo.
1320 const VNInfo *VNI = findDefinedVNInfo(li, getDefIndex(index));
1310 const VNInfo *VNI = li.findDefinedVNInfo(getDefIndex(index));
13211311 if (VNI)
13221312 HasKill = anyKillInMBBAfterIdx(li, VNI, MBB, getDefIndex(index));
13231313 }
0 //===-- LiveStackAnalysis.cpp - Live Stack Slot Analysis ------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the live stack slot analysis pass. It is analogous to
10 // live interval analysis except it's analyzing liveness of stack slots rather
11 // than registers.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #define DEBUG_TYPE "livestacks"
16 #include "llvm/CodeGen/LiveStackAnalysis.h"
17 #include "llvm/CodeGen/Passes.h"
18 #include "llvm/Target/TargetRegisterInfo.h"
19 #include "llvm/Support/Debug.h"
20 #include "llvm/ADT/Statistic.h"
21 using namespace llvm;
22
23 char LiveStacks::ID = 0;
24 static RegisterPass X("livestacks", "Live Stack Slot Analysis");
25
26 void LiveStacks::getAnalysisUsage(AnalysisUsage &AU) const {
27 AU.setPreservesAll();
28 }
29
30 void LiveStacks::releaseMemory() {
31 // Release VNInfo memroy regions after all VNInfo objects are dtor'd.
32 VNInfoAllocator.Reset();
33 s2iMap.clear();
34 }
35
36 bool LiveStacks::runOnMachineFunction(MachineFunction &) {
37 // FIXME: No analysis is being done right now. We are relying on the
38 // register allocators to provide the information.
39 return false;
40 }
41
42 /// print - Implement the dump method.
43 void LiveStacks::print(std::ostream &O, const Module* ) const {
44 O << "********** INTERVALS **********\n";
45 for (const_iterator I = begin(), E = end(); I != E; ++I) {
46 I->second.print(O);
47 O << "\n";
48 }
49 }
1111 //===----------------------------------------------------------------------===//
1212
1313 #define DEBUG_TYPE "regalloc"
14 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
1514 #include "PhysRegTracker.h"
1615 #include "VirtRegMap.h"
1716 #include "llvm/Function.h"
17 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
18 #include "llvm/CodeGen/LiveStackAnalysis.h"
1819 #include "llvm/CodeGen/MachineFunctionPass.h"
1920 #include "llvm/CodeGen/MachineInstr.h"
2021 #include "llvm/CodeGen/MachineLoopInfo.h"
6667 MachineRegisterInfo *reginfo_;
6768 BitVector allocatableRegs_;
6869 LiveIntervals* li_;
70 LiveStacks* ls_;
6971 const MachineLoopInfo *loopInfo;
7072
7173 /// handled_ - Intervals are added to the handled_ set in the order of their
102104 // Make sure PassManager knows which analyses to make available
103105 // to coalescing and which analyses coalescing invalidates.
104106 AU.addRequiredTransitive();
107 AU.addRequired();
108 AU.addPreserved();
105109 AU.addRequired();
106110 AU.addPreserved();
107111 AU.addPreservedID(MachineDominatorsID);
169173 };
170174 char RALinScan::ID = 0;
171175 }
176
177 static RegisterPass
178 X("linearscan-regalloc", "Linear Scan Register Allocator");
172179
173180 void RALinScan::ComputeRelatedRegClasses() {
174181 const TargetRegisterInfo &TRI = *tri_;
257264 reginfo_ = &mf_->getRegInfo();
258265 allocatableRegs_ = tri_->getAllocatableSet(fn);
259266 li_ = &getAnalysis();
267 ls_ = &getAnalysis();
260268 loopInfo = &getAnalysis();
261269
262270 // We don't run the coalescer here because we have no reason to
501509 if (I != IP.first->begin()) --I;
502510 IP.second = I;
503511 }
512 }
513
514 /// addStackInterval - Create a LiveInterval for stack if the specified live
515 /// interval has been spilled.
516 static void addStackInterval(LiveInterval *cur, LiveStacks *ls_,
517 LiveIntervals *li_, VirtRegMap &vrm_) {
518 int SS = vrm_.getStackSlot(cur->reg);
519 if (SS == VirtRegMap::NO_STACK_SLOT)
520 return;
521 LiveInterval &SI = ls_->getOrCreateInterval(SS);
522 VNInfo *VNI;
523 if (SI.getNumValNums())
524 VNI = SI.getValNumInfo(0);
525 else
526 VNI = SI.getNextValue(~0U, 0, ls_->getVNInfoAllocator());
527
528 LiveInterval &RI = li_->getInterval(cur->reg);
529 // FIXME: This may be overly conservative.
530 SI.MergeRangesInAsValue(RI, VNI);
531 SI.weight += RI.weight;
504532 }
505533
506534 /// assignRegOrStackSlotAtInterval - assign a register if one is available, or
716744 DOUT << "\t\t\tspilling(c): " << *cur << '\n';
717745 std::vector added =
718746 li_->addIntervalsForSpills(*cur, loopInfo, *vrm_);
747 addStackInterval(cur, ls_, li_, *vrm_);
719748 if (added.empty())
720749 return; // Early exit if all spills were folded.
721750
768797 earliestStart = std::min(earliestStart, i->first->beginNumber());
769798 std::vector newIs =
770799 li_->addIntervalsForSpills(*i->first, loopInfo, *vrm_);
800 addStackInterval(i->first, ls_, li_, *vrm_);
771801 std::copy(newIs.begin(), newIs.end(), std::back_inserter(added));
772802 spilled.insert(reg);
773803 }
781811 earliestStart = std::min(earliestStart, i->first->beginNumber());
782812 std::vector newIs =
783813 li_->addIntervalsForSpills(*i->first, loopInfo, *vrm_);
814 addStackInterval(i->first, ls_, li_, *vrm_);
784815 std::copy(newIs.begin(), newIs.end(), std::back_inserter(added));
785816 spilled.insert(reg);
786817 }
0 //===-- StackSlotColoring.cpp - Sinking for machine instructions ----------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the stack slot coloring pass.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #define DEBUG_TYPE "stackcoloring"
14 #include "llvm/CodeGen/LiveStackAnalysis.h"
15 #include "llvm/CodeGen/MachineFrameInfo.h"
16 #include "llvm/CodeGen/Passes.h"
17 #include "llvm/Support/CommandLine.h"
18 #include "llvm/Support/Compiler.h"
19 #include "llvm/Support/Debug.h"
20 #include "llvm/ADT/BitVector.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/ADT/Statistic.h"
23 #include
24 using namespace llvm;
25
26 static cl::opt
27 DisableSharing("no-stack-slot-sharing",
28 cl::init(false), cl::Hidden,
29 cl::desc("Surpress slot sharing during stack coloring"));
30
31 static cl::opt
32 DeleteLimit("slot-delete-limit", cl::init(-1), cl::Hidden,
33 cl::desc("Stack coloring slot deletion limit"));
34
35 STATISTIC(NumEliminated, "Number of stack slots eliminated due to coloring");
36
37 namespace {
38 class VISIBILITY_HIDDEN StackSlotColoring : public MachineFunctionPass {
39 LiveStacks* LS;
40 MachineFrameInfo *MFI;
41
42 // SSIntervals - Spill slot intervals.
43 std::vector SSIntervals;
44
45 // OrigAlignments - Alignments of stack objects before coloring.
46 SmallVector OrigAlignments;
47
48 // OrigSizes - Sizess of stack objects before coloring.
49 SmallVector OrigSizes;
50
51 // AllColors - If index is set, it's a spill slot, i.e. color.
52 // FIXME: This assumes PEI locate spill slot with smaller indices
53 // closest to stack pointer / frame pointer. Therefore, smaller
54 // index == better color.
55 BitVector AllColors;
56
57 // NextColor - Next "color" that's not yet used.
58 int NextColor;
59
60 // UsedColors - "Colors" that have been assigned.
61 BitVector UsedColors;
62
63 // Assignments - Color to intervals mapping.
64 SmallVector,16> Assignments;
65
66 public:
67 static char ID; // Pass identification
68 StackSlotColoring() : MachineFunctionPass((intptr_t)&ID), NextColor(-1) {}
69
70 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
71 AU.addRequired();
72 MachineFunctionPass::getAnalysisUsage(AU);
73 }
74
75 virtual bool runOnMachineFunction(MachineFunction &MF);
76 virtual const char* getPassName() const {
77 return "Stack Slot Coloring";
78 }
79
80 private:
81 bool InitializeSlots();
82 bool OverlapWithAssignments(LiveInterval *li, int Color) const;
83 int ColorSlot(LiveInterval *li);
84 bool ColorSlots(MachineFunction &MF);
85 };
86 } // end anonymous namespace
87
88 char StackSlotColoring::ID = 0;
89
90 static RegisterPass
91 X("stack-slot-coloring", "Stack Slot Coloring");
92
93 FunctionPass *llvm::createStackSlotColoringPass() {
94 return new StackSlotColoring();
95 }
96
97 namespace {
98 // IntervalSorter - Comparison predicate that sort live intervals by
99 // their weight.
100 struct IntervalSorter {
101 bool operator()(LiveInterval* LHS, LiveInterval* RHS) const {
102 return LHS->weight > RHS->weight;
103 }
104 };
105 }
106
107 /// InitializeSlots - Process all spill stack slot liveintervals and add them
108 /// to a sorted (by weight) list.
109 bool StackSlotColoring::InitializeSlots() {
110 if (LS->getNumIntervals() < 2)
111 return false;
112
113 int LastFI = MFI->getObjectIndexEnd();
114 OrigAlignments.resize(LastFI);
115 OrigSizes.resize(LastFI);
116 AllColors.resize(LastFI);
117 UsedColors.resize(LastFI);
118 Assignments.resize(LastFI);
119
120 // Gather all spill slots into a list.
121 for (LiveStacks::iterator i = LS->begin(), e = LS->end(); i != e; ++i) {
122 LiveInterval &li = i->second;
123 int FI = li.getStackSlotIndex();
124 if (MFI->isDeadObjectIndex(FI))
125 continue;
126 SSIntervals.push_back(&li);
127 OrigAlignments[FI] = MFI->getObjectAlignment(FI);
128 OrigSizes[FI] = MFI->getObjectSize(FI);
129 AllColors.set(FI);
130 }
131
132 // Sort them by weight.
133 std::stable_sort(SSIntervals.begin(), SSIntervals.end(), IntervalSorter());
134
135 // Get first "color".
136 NextColor = AllColors.find_first();
137 return true;
138 }
139
140 /// OverlapWithAssignments - Return true if LiveInterval overlaps with any
141 /// LiveIntervals that have already been assigned to the specified color.
142 bool
143 StackSlotColoring::OverlapWithAssignments(LiveInterval *li, int Color) const {
144 const SmallVector &OtherLIs = Assignments[Color];
145 for (unsigned i = 0, e = OtherLIs.size(); i != e; ++i) {
146 LiveInterval *OtherLI = OtherLIs[i];
147 if (OtherLI->overlaps(*li))
148 return true;
149 }
150 return false;
151 }
152
153 /// ColorSlot - Assign a "color" (stack slot) to the specified stack slot.
154 ///
155 int StackSlotColoring::ColorSlot(LiveInterval *li) {
156 int Color = -1;
157 bool Share = false;
158 if (!DisableSharing &&
159 (DeleteLimit == -1 || (int)NumEliminated < DeleteLimit)) {
160 // Check if it's possible to reuse any of the used colors.
161 Color = UsedColors.find_first();
162 while (Color != -1) {
163 if (!OverlapWithAssignments(li, Color)) {
164 Share = true;
165 ++NumEliminated;
166 break;
167 }
168 Color = UsedColors.find_next(Color);
169 }
170 }
171
172 // Assign it to the first available color (assumed to be the best) if it's
173 // not possible to share a used color with other objects.
174 if (!Share) {
175 assert(NextColor != -1 && "No more spill slots?");
176 Color = NextColor;
177 UsedColors.set(Color);
178 NextColor = AllColors.find_next(NextColor);
179 }
180
181 // Record the assignment.
182 Assignments[Color].push_back(li);
183 int FI = li->getStackSlotIndex();
184 DOUT << "Assigning fi #" << FI << " to fi #" << Color << "\n";
185
186 // Change size and alignment of the allocated slot. If there are multiple
187 // objects sharing the same slot, then make sure the size and alignment
188 // are large enough for all.
189 unsigned Align = OrigAlignments[FI];
190 if (!Share || Align > MFI->getObjectAlignment(Color))
191 MFI->setObjectAlignment(Color, Align);
192 int64_t Size = OrigSizes[FI];
193 if (!Share || Size > MFI->getObjectSize(Color))
194 MFI->setObjectSize(Color, Size);
195 return Color;
196 }
197
198 /// Colorslots - Color all spill stack slots and rewrite all frameindex machine
199 /// operands in the function.
200 bool StackSlotColoring::ColorSlots(MachineFunction &MF) {
201 unsigned NumObjs = MFI->getObjectIndexEnd();
202 std::vector SlotMapping(NumObjs, -1);
203 SlotMapping.resize(NumObjs, -1);
204
205 bool Changed = false;
206 for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
207 LiveInterval *li = SSIntervals[i];
208 int SS = li->getStackSlotIndex();
209 int NewSS = ColorSlot(li);
210 SlotMapping[SS] = NewSS;
211 Changed |= (SS != NewSS);
212 }
213
214 if (!Changed)
215 return false;
216
217 // Rewrite all MO_FrameIndex operands.
218 // FIXME: Need the equivalent of MachineRegisterInfo for frameindex operands.
219 for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
220 MBB != E; ++MBB) {
221 for (MachineBasicBlock::iterator MII = MBB->begin(), EE = MBB->end();
222 MII != EE; ++MII) {
223 MachineInstr &MI = *MII;
224 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
225 MachineOperand &MO = MI.getOperand(i);
226 if (!MO.isFrameIndex())
227 continue;
228 int FI = MO.getIndex();
229 if (FI < 0)
230 continue;
231 FI = SlotMapping[FI];
232 if (FI == -1)
233 continue;
234 MO.setIndex(FI);
235 }
236 }
237 }
238
239 // Delete unused stack slots.
240 while (NextColor != -1) {
241 DOUT << "Removing unused stack object fi #" << NextColor << "\n";
242 MFI->RemoveStackObject(NextColor);
243 NextColor = AllColors.find_next(NextColor);
244 }
245
246 return true;
247 }
248
249 bool StackSlotColoring::runOnMachineFunction(MachineFunction &MF) {
250 DOUT << "******** Stack Slot Coloring ********\n";
251
252 MFI = MF.getFrameInfo();
253 LS = &getAnalysis();
254
255 bool Changed = false;
256 if (InitializeSlots())
257 Changed = ColorSlots(MF);
258
259 NextColor = -1;
260 SSIntervals.clear();
261 OrigAlignments.clear();
262 OrigSizes.clear();
263 AllColors.clear();
264 UsedColors.clear();
265 for (unsigned i = 0, e = Assignments.size(); i != e; ++i)
266 Assignments[i].clear();
267 Assignments.clear();
268
269 return Changed;
270 }