blob: 57cd96589f35de977aaf0c0aa57c21f0849cf5be [file] [log] [blame]
Ruchira Sasanka7cd2ca12001-09-08 14:22:50 +00001/* Title: PhyRegAlloc.h
2 Author: Ruchira Sasanka
3 Date: Aug 20, 01
4 Purpose: This is the main entry point for register allocation.
5
6 Notes:
7
8 * RegisterClasses: Each RegClass accepts a
9 MachineRegClass which contains machine specific info about that register
10 class. The code in the RegClass is machine independent and they use
11 access functions in the MachineRegClass object passed into it to get
12 machine specific info.
13
14 * Machine dependent work: All parts of the register coloring algorithm
15 except coloring of an individual node are machine independent.
16
17 Register allocation must be done as:
18
19 static const MachineRegInfo MRI = MachineRegInfo(); // machine reg info
20
21 MethodLiveVarInfo LVI(*MethodI ); // compute LV info
22 LVI.analyze();
23
24 PhyRegAlloc PRA(*MethodI, &MRI, &LVI); // allocate regs
25 PRA.allocateRegisters();
26
27 Assumptions:
28 All values in a live range will be of the same physical reg class.
29
30*/
31
Ruchira Sasanka7cd2ca12001-09-08 14:22:50 +000032#ifndef PHY_REG_ALLOC_H
33#define PHY_REG_ALLOC_H
34
35#include "llvm/CodeGen/MachineInstr.h"
Ruchira Sasanka7cd2ca12001-09-08 14:22:50 +000036#include "llvm/CodeGen/RegClass.h"
37#include "llvm/CodeGen/LiveRangeInfo.h"
38#include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
39
Ruchira Sasanka21721b62001-10-15 16:22:44 +000040#include <deque>
Ruchira Sasanka7cd2ca12001-09-08 14:22:50 +000041
Ruchira Sasanka20c82b12001-10-28 18:15:12 +000042
43//----------------------------------------------------------------------------
44// Class AddedInstrns:
45// When register allocator inserts new instructions in to the existing
46// instruction stream, it does NOT directly modify the instruction stream.
47// Rather, it creates an object of AddedInstrns and stick it in the
48// AddedInstrMap for an existing instruction. This class contains two vectors
49// to store such instructions added before and after an existing instruction.
50//----------------------------------------------------------------------------
51
Ruchira Sasanka7cd2ca12001-09-08 14:22:50 +000052class AddedInstrns
53{
54 public:
Ruchira Sasanka20c82b12001-10-28 18:15:12 +000055 deque<MachineInstr *> InstrnsBefore; // Added insts BEFORE an existing inst
56 deque<MachineInstr *> InstrnsAfter; // Added insts AFTER an existing inst
Ruchira Sasanka7cd2ca12001-09-08 14:22:50 +000057
58 AddedInstrns() : InstrnsBefore(), InstrnsAfter() { }
59};
60
61typedef hash_map<const MachineInstr *, AddedInstrns *> AddedInstrMapType;
62
63
64
Ruchira Sasanka20c82b12001-10-28 18:15:12 +000065//----------------------------------------------------------------------------
66// Class RegStackOffsets:
67// This class is responsible for managing stack frame of the method for
68// register allocation.
69//
70//----------------------------------------------------------------------------
71
72class RegStackOffsets {
73
74 private:
75 int curSpilledVarOff; // cur pos of spilled LRs
76 int curNewTmpPosOffset; // cur pos of tmp values on stack
77 bool isTmpRegionUsable; // can we call getNewTmpPosOffFromFP
78
79 const int SizeOfStackItem; // size of an item on stack
80 const int StackSpillStartFromFP; // start position of spill region
81 int StartOfTmpRegion; // start of the tmp var region
82
83 public:
84
85 // constructor
86
87 RegStackOffsets(int SEnSize=8, int StartSpill=176 ) :
88 SizeOfStackItem(SEnSize), StackSpillStartFromFP(StartSpill) {
89
90 curSpilledVarOff = StartSpill;
91 isTmpRegionUsable = false;
92 };
93
94
95 int getNewSpillOffFromFP() {
96 int tmp = curSpilledVarOff;
97 curSpilledVarOff += SizeOfStackItem;
98 return tmp; // **TODO: Is sending un-incremented value correct?
99 };
100
101
102 // The following method must be called only after allocating space
103 // for spilled LRs and calling setEndOfSpillRegion()
104 int getNewTmpPosOffFromFP() {
105 assert( isTmpRegionUsable && "Spill region still open");
106 int tmp = curNewTmpPosOffset;
107 curNewTmpPosOffset += SizeOfStackItem;
108 return tmp; //**TODO: Is sending un-incremented val correct?
109 };
110
111
112 // This method is called when we have allocated space for all spilled
113 // LRs. The tmp region can be used only after a call to this method.
114
115 void setEndOfSpillRegion() {
116 assert(( ! isTmpRegionUsable) && "setEndOfSpillRegion called again");
117 isTmpRegionUsable = true;
118 StartOfTmpRegion = curSpilledVarOff;
119 }
120
121
122 // called when temporary values allocated on stack are no longer needed
123 void resetTmpPos() {
124 curNewTmpPosOffset = StartOfTmpRegion;
125 }
126
127
128};
129
130
131
132//----------------------------------------------------------------------------
133// class PhyRegAlloc:
134// Main class the register allocator. Call allocateRegisters() to allocate
135// registers for a Method.
136//----------------------------------------------------------------------------
137
138
Ruchira Sasanka7cd2ca12001-09-08 14:22:50 +0000139class PhyRegAlloc
140{
141
142 vector<RegClass *> RegClassList ; // vector of register classes
143 const Method *const Meth; // name of the method we work on
144 const TargetMachine &TM; // target machine
145 MethodLiveVarInfo *const LVI; // LV information for this method
146 // (already computed for BBs)
147 LiveRangeInfo LRI; // LR info (will be computed)
148 const MachineRegInfo &MRI; // Machine Register information
149 const unsigned NumOfRegClasses; // recorded here for efficiency
150
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000151 //vector<const Instruction *> CallInstrList; // a list of all call instrs
152 //vector<const Instruction *> RetInstrList; // a list of all return instrs
Ruchira Sasanka7cd2ca12001-09-08 14:22:50 +0000153
Ruchira Sasanka51bc0e72001-11-03 17:14:44 +0000154
Ruchira Sasanka7cd2ca12001-09-08 14:22:50 +0000155 AddedInstrMapType AddedInstrMap; // to store instrns added in this phase
156
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000157 RegStackOffsets StackOffsets;
Ruchira Sasanka1bf6d642001-09-15 00:33:26 +0000158
Ruchira Sasanka80b1a1a2001-11-03 20:41:22 +0000159 //vector<const MachineInstr *> PhiInstList; // a list of all phi instrs
Ruchira Sasanka51bc0e72001-11-03 17:14:44 +0000160
Ruchira Sasanka7cd2ca12001-09-08 14:22:50 +0000161 //------- private methods ---------------------------------------------------
162
163 void addInterference(const Value *const Def, const LiveVarSet *const LVSet,
164 const bool isCallInst);
165
166 void addInterferencesForArgs();
167 void createIGNodeListsAndIGs();
168 void buildInterferenceGraphs();
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000169 //void insertCallerSavingCode(const MachineInstr *MInst,
170 // const BasicBlock *BB );
Ruchira Sasankac4d4b762001-10-16 01:23:19 +0000171
Ruchira Sasanka36f77072001-10-19 17:21:59 +0000172 void setCallInterferences(const MachineInstr *MInst,
173 const LiveVarSet *const LVSetAft );
Ruchira Sasanka7cd2ca12001-09-08 14:22:50 +0000174
Ruchira Sasankaf7434f02001-10-23 21:38:42 +0000175 void move2DelayedInstr(const MachineInstr *OrigMI,
176 const MachineInstr *DelayedMI );
177
Ruchira Sasanka44d2b942001-10-19 21:42:06 +0000178 void markUnusableSugColors();
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000179 void allocateStackSpace4SpilledLRs();
180
181 RegStackOffsets & getStackOffsets() {
182 return StackOffsets;
183 }
184
Ruchira Sasanka44d2b942001-10-19 21:42:06 +0000185
Ruchira Sasanka7cd2ca12001-09-08 14:22:50 +0000186 inline void constructLiveRanges()
187 { LRI.constructLiveRanges(); }
188
189 void colorIncomingArgs();
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000190 void colorCallRetArgs();
Ruchira Sasanka7cd2ca12001-09-08 14:22:50 +0000191 void updateMachineCode();
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000192
Ruchira Sasanka6053b932001-09-15 19:08:41 +0000193 void printLabel(const Value *const Val);
194 void printMachineCode();
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000195
196 friend class UltraSparcRegInfo;
Ruchira Sasanka80b1a1a2001-11-03 20:41:22 +0000197
198
199 int getUsableRegAtMI(RegClass *RC, const int RegType, const MachineInstr *MInst,
200 const LiveVarSet *LVSetBef, MachineInstr *MIBef,
201 MachineInstr *MIAft );
202
203 int getUnusedRegAtMI(RegClass *RC, const MachineInstr *MInst,
204 const LiveVarSet *LVSetBef);
205
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000206 void setRegsUsedByThisInst(RegClass *RC, const MachineInstr *MInst );
207 int getRegNotUsedByThisInst(RegClass *RC, const MachineInstr *MInst);
208
Ruchira Sasanka80b1a1a2001-11-03 20:41:22 +0000209
210
Ruchira Sasanka51bc0e72001-11-03 17:14:44 +0000211 void PhyRegAlloc::insertPhiEleminateInstrns();
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000212
Ruchira Sasanka7cd2ca12001-09-08 14:22:50 +0000213 public:
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000214
Ruchira Sasanka7cd2ca12001-09-08 14:22:50 +0000215 PhyRegAlloc(const Method *const M, const TargetMachine& TM,
216 MethodLiveVarInfo *const Lvi);
217
218 void allocateRegisters(); // main method called for allocatin
219
220};
221
222
223
Ruchira Sasanka51bc0e72001-11-03 17:14:44 +0000224/*
225
226
227What to do:
228
229 * Insert IntCCReg checking code to insertCallerSaving
230 * add methods like cpCCReg2Mem & cpMem2CCReg (these will accept an array
231 and push back or push_front the instr according to PUSH_BACK, PUSH_FRONT
232 flags
233
234*/
235
236
237
Ruchira Sasanka7cd2ca12001-09-08 14:22:50 +0000238
239
240
241
242
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000243
244
245
Ruchira Sasanka7cd2ca12001-09-08 14:22:50 +0000246#endif
247