blob: 8c8c693edbd86edbddc34e0b0bd3b27722fd7814 [file] [log] [blame]
buzbee67bf8852011-08-17 17:51:35 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_SRC_COMPILER_RALLOC_H_
18#define ART_SRC_COMPILER_RALLOC_H_
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080019
buzbee67bf8852011-08-17 17:51:35 -070020/*
21 * This file contains target independent register alloction support.
22 */
23
24#include "../CompilerUtility.h"
25#include "../CompilerIR.h"
26#include "../Dataflow.h"
buzbee67bf8852011-08-17 17:51:35 -070027
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080028namespace art {
29
buzbeee3acd072012-02-25 17:03:10 -080030/* Static register use counts */
Elliott Hughes719ace42012-03-09 18:06:03 -080031struct RefCounts {
buzbeee3acd072012-02-25 17:03:10 -080032 int count;
33 int sReg;
34 bool doubleStart; // Starting vReg for a double
Elliott Hughes719ace42012-03-09 18:06:03 -080035};
buzbee67bf8852011-08-17 17:51:35 -070036
buzbeee3acd072012-02-25 17:03:10 -080037
38inline int oatS2VReg(CompilationUnit* cUnit, int sReg)
buzbee67bf8852011-08-17 17:51:35 -070039{
buzbeeed3e9302011-09-23 17:34:19 -070040 DCHECK_NE(sReg, INVALID_SREG);
buzbee67bf8852011-08-17 17:51:35 -070041 return DECODE_REG(oatConvertSSARegToDalvik(cUnit, sReg));
42}
43
buzbee67bf8852011-08-17 17:51:35 -070044/*
45 * Get the "real" sreg number associated with an sReg slot. In general,
46 * sReg values passed through codegen are the SSA names created by
47 * dataflow analysis and refer to slot numbers in the cUnit->regLocation
48 * array. However, renaming is accomplished by simply replacing RegLocation
49 * entries in the cUnit->reglocation[] array. Therefore, when location
50 * records for operands are first created, we need to ask the locRecord
51 * identified by the dataflow pass what it's new name is.
52 */
53
buzbeee3acd072012-02-25 17:03:10 -080054inline int oatSRegHi(int lowSreg) {
buzbee67bf8852011-08-17 17:51:35 -070055 return (lowSreg == INVALID_SREG) ? INVALID_SREG : lowSreg + 1;
56}
57
58
buzbeee3acd072012-02-25 17:03:10 -080059inline bool oatLiveOut(CompilationUnit* cUnit, int sReg)
buzbee67bf8852011-08-17 17:51:35 -070060{
61 //For now.
62 return true;
63}
64
buzbeee3acd072012-02-25 17:03:10 -080065inline int oatSSASrc(MIR* mir, int num)
buzbee67bf8852011-08-17 17:51:35 -070066{
buzbeeed3e9302011-09-23 17:34:19 -070067 DCHECK_GT(mir->ssaRep->numUses, num);
buzbee67bf8852011-08-17 17:51:35 -070068 return mir->ssaRep->uses[num];
69}
70
71extern RegLocation oatEvalLoc(CompilationUnit* cUnit, RegLocation loc,
72 int regClass, bool update);
73/* Mark a temp register as dead. Does not affect allocation state. */
74extern void oatClobber(CompilationUnit* cUnit, int reg);
75
76extern RegLocation oatUpdateLoc(CompilationUnit* cUnit,
77 RegLocation loc);
78
79/* see comments for updateLoc */
80extern RegLocation oatUpdateLocWide(CompilationUnit* cUnit,
81 RegLocation loc);
82
buzbeeed3e9302011-09-23 17:34:19 -070083extern RegLocation oatUpdateRawLoc(CompilationUnit* cUnit,
84 RegLocation loc);
85
buzbee67bf8852011-08-17 17:51:35 -070086extern void oatMarkLive(CompilationUnit* cUnit, int reg, int sReg);
87
88extern void oatMarkTemp(CompilationUnit* cUnit, int reg);
89
buzbee9e0f9b02011-08-24 15:32:46 -070090extern void oatUnmarkTemp(CompilationUnit* cUnit, int reg);
91
buzbee67bf8852011-08-17 17:51:35 -070092extern void oatMarkDirty(CompilationUnit* cUnit, RegLocation loc);
93
94extern void oatMarkPair(CompilationUnit* cUnit, int lowReg,
95 int highReg);
96
97extern void oatMarkClean(CompilationUnit* cUnit, RegLocation loc);
98
99extern void oatResetDef(CompilationUnit* cUnit, int reg);
100
101extern void oatResetDefLoc(CompilationUnit* cUnit, RegLocation rl);
102
103/* Set up temp & preserved register pools specialized by target */
buzbeee3acd072012-02-25 17:03:10 -0800104extern void oatInitPool(struct RegisterInfo* regs, int* regNums, int num);
buzbee67bf8852011-08-17 17:51:35 -0700105
106/*
107 * Mark the beginning and end LIR of a def sequence. Note that
108 * on entry start points to the LIR prior to the beginning of the
109 * sequence.
110 */
111extern void oatMarkDef(CompilationUnit* cUnit, RegLocation rl,
112 LIR* start, LIR* finish);
113/*
114 * Mark the beginning and end LIR of a def sequence. Note that
115 * on entry start points to the LIR prior to the beginning of the
116 * sequence.
117 */
118extern void oatMarkDefWide(CompilationUnit* cUnit, RegLocation rl,
119 LIR* start, LIR* finish);
120
121extern RegLocation oatGetSrcWide(CompilationUnit* cUnit, MIR* mir,
122 int low, int high);
123
124extern RegLocation oatGetDestWide(CompilationUnit* cUnit, MIR* mir,
125 int low, int high);
126// Get the LocRecord associated with an SSA name use.
127extern RegLocation oatGetSrc(CompilationUnit* cUnit, MIR* mir, int num);
buzbeee9a72f62011-09-04 17:59:07 -0700128extern RegLocation oatGetRawSrc(CompilationUnit* cUnit, MIR* mir, int num);
buzbee67bf8852011-08-17 17:51:35 -0700129
130// Get the LocRecord associated with an SSA name def.
131extern RegLocation oatGetDest(CompilationUnit* cUnit, MIR* mir, int num);
132
133extern RegLocation oatGetReturnWide(CompilationUnit* cUnit);
134
135/* Clobber all regs that might be used by an external C call */
buzbee6181f792011-09-29 11:14:04 -0700136extern void oatClobberCalleeSave(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700137
138extern RegisterInfo *oatIsTemp(CompilationUnit* cUnit, int reg);
139
buzbeeb29e4d12011-09-26 15:05:48 -0700140extern RegisterInfo *oatIsPromoted(CompilationUnit* cUnit, int reg);
141
buzbee67bf8852011-08-17 17:51:35 -0700142extern bool oatIsDirty(CompilationUnit* cUnit, int reg);
143
144extern void oatMarkInUse(CompilationUnit* cUnit, int reg);
145
146extern int oatAllocTemp(CompilationUnit* cUnit);
147
148extern int oatAllocTempFloat(CompilationUnit* cUnit);
149
150//REDO: too many assumptions.
151extern int oatAllocTempDouble(CompilationUnit* cUnit);
152
153extern void oatFreeTemp(CompilationUnit* cUnit, int reg);
154
155extern void oatResetDefLocWide(CompilationUnit* cUnit, RegLocation rl);
156
157extern void oatResetDefTracking(CompilationUnit* cUnit);
158
buzbee67bf8852011-08-17 17:51:35 -0700159extern RegisterInfo *oatIsLive(CompilationUnit* cUnit, int reg);
160
161/* To be used when explicitly managing register use */
buzbee2e748f32011-08-29 21:02:19 -0700162extern void oatLockCallTemps(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700163
buzbee0d966cf2011-09-08 17:34:58 -0700164extern void oatFreeCallTemps(CompilationUnit* cUnit);
165
buzbee67bf8852011-08-17 17:51:35 -0700166extern void oatFlushAllRegs(CompilationUnit* cUnit);
167
168extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit);
169
170extern RegLocation oatGetReturn(CompilationUnit* cUnit);
171
172extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit);
173
174/* Clobber any temp associated with an sReg. Could be in either class */
175extern void oatClobberSReg(CompilationUnit* cUnit, int sReg);
176
177/* Return a temp if one is available, -1 otherwise */
178extern int oatAllocFreeTemp(CompilationUnit* cUnit);
179
180/* Attempt to allocate a callee-save register */
181extern int oatAllocPreservedCoreReg(CompilationUnit* cUnit, int sreg);
182extern int oatAllocPreservedFPReg(CompilationUnit* cUnit, int sReg,
183 bool doubleStart);
184
185/*
186 * Similar to oatAllocTemp(), but forces the allocation of a specific
187 * register. No check is made to see if the register was previously
188 * allocated. Use with caution.
189 */
190extern void oatLockTemp(CompilationUnit* cUnit, int reg);
191
192extern RegLocation oatWideToNarrow(CompilationUnit* cUnit,
193 RegLocation rl);
194
195/*
196 * Free all allocated temps in the temp pools. Note that this does
197 * not affect the "liveness" of a temp register, which will stay
198 * live until it is either explicitly killed or reallocated.
199 */
200extern void oatResetRegPool(CompilationUnit* cUnit);
201
202extern void oatClobberAllRegs(CompilationUnit* cUnit);
203
204extern void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2);
205
206extern void oatFlushReg(CompilationUnit* cUnit, int reg);
207
buzbeee3acd072012-02-25 17:03:10 -0800208extern void oatDoPromotion(CompilationUnit* cUnit);
209extern int oatVRegOffset(CompilationUnit* cUnit, int reg);
210extern int oatSRegOffset(CompilationUnit* cUnit, int reg);
211extern void oatCountRefs(CompilationUnit*, BasicBlock*, RefCounts*, RefCounts*);
212extern int oatSortCounts(const void *val1, const void *val2);
213extern void oatDumpCounts(const RefCounts* arr, int size, const char* msg);
214
buzbee67bf8852011-08-17 17:51:35 -0700215/*
216 * Architecture-dependent register allocation routines implemented in
217 * ${TARGET_ARCH}/${TARGET_ARCH_VARIANT}/Ralloc.c
218 */
219extern int oatAllocTypedTempPair(CompilationUnit* cUnit,
220 bool fpHint, int regClass);
221
222extern int oatAllocTypedTemp(CompilationUnit* cUnit, bool fpHint,
223 int regClass);
224
buzbee67bf8852011-08-17 17:51:35 -0700225extern void oatRegCopyWide(CompilationUnit* cUnit, int destLo,
226 int destHi, int srcLo, int srcHi);
227
228extern void oatFlushRegImpl(CompilationUnit* cUnit, int rBase,
229 int displacement, int rSrc, OpSize size);
230
231extern void oatFlushRegWideImpl(CompilationUnit* cUnit, int rBase,
232 int displacement, int rSrcLo, int rSrcHi);
233
buzbee6181f792011-09-29 11:14:04 -0700234extern void oatDumpCoreRegPool(CompilationUnit* cUint);
235extern void oatDumpFPRegPool(CompilationUnit* cUint);
236extern bool oatCheckCorePoolSanity(CompilationUnit* cUnit);
buzbee68253262011-10-07 14:02:25 -0700237extern RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg);
buzbeee3acd072012-02-25 17:03:10 -0800238extern void oatNopLIR(LIR* lir);
239extern bool oatIsFPReg(int reg);
240extern uint32_t oatFPRegMask(void);
241extern void oatAdjustSpillMask(CompilationUnit* cUnit);
242void oatMarkPreservedSingle(CompilationUnit* cUnit, int sReg, int reg);
243void oatRegCopy(CompilationUnit* cUnit, int rDest, int rSrc);
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800244
245} // namespace art
246
buzbee67bf8852011-08-17 17:51:35 -0700247#endif // ART_SRC_COMPILER_RALLOC_H_