blob: 8c3887a9447e49257be9083ea53abc4b54502e7c [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 {
Bill Buzbeea114add2012-05-03 15:00:40 -070032 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
buzbee67bf8852011-08-17 17:51:35 -070038/*
39 * Get the "real" sreg number associated with an sReg slot. In general,
40 * sReg values passed through codegen are the SSA names created by
41 * dataflow analysis and refer to slot numbers in the cUnit->regLocation
42 * array. However, renaming is accomplished by simply replacing RegLocation
43 * entries in the cUnit->reglocation[] array. Therefore, when location
44 * records for operands are first created, we need to ask the locRecord
45 * identified by the dataflow pass what it's new name is.
46 */
47
buzbeee3acd072012-02-25 17:03:10 -080048inline int oatSRegHi(int lowSreg) {
Bill Buzbeea114add2012-05-03 15:00:40 -070049 return (lowSreg == INVALID_SREG) ? INVALID_SREG : lowSreg + 1;
buzbee67bf8852011-08-17 17:51:35 -070050}
51
52
buzbeee3acd072012-02-25 17:03:10 -080053inline bool oatLiveOut(CompilationUnit* cUnit, int sReg)
buzbee67bf8852011-08-17 17:51:35 -070054{
Bill Buzbeea114add2012-05-03 15:00:40 -070055 //For now.
56 return true;
buzbee67bf8852011-08-17 17:51:35 -070057}
58
buzbeee3acd072012-02-25 17:03:10 -080059inline int oatSSASrc(MIR* mir, int num)
buzbee67bf8852011-08-17 17:51:35 -070060{
Bill Buzbeea114add2012-05-03 15:00:40 -070061 DCHECK_GT(mir->ssaRep->numUses, num);
62 return mir->ssaRep->uses[num];
buzbee67bf8852011-08-17 17:51:35 -070063}
64
65extern RegLocation oatEvalLoc(CompilationUnit* cUnit, RegLocation loc,
Bill Buzbeea114add2012-05-03 15:00:40 -070066 int regClass, bool update);
buzbee67bf8852011-08-17 17:51:35 -070067/* Mark a temp register as dead. Does not affect allocation state. */
68extern void oatClobber(CompilationUnit* cUnit, int reg);
Bill Buzbeea114add2012-05-03 15:00:40 -070069extern RegLocation oatUpdateLoc(CompilationUnit* cUnit, RegLocation loc);
buzbee67bf8852011-08-17 17:51:35 -070070
71/* see comments for updateLoc */
Bill Buzbeea114add2012-05-03 15:00:40 -070072extern RegLocation oatUpdateLocWide(CompilationUnit* cUnit, RegLocation loc);
buzbee67bf8852011-08-17 17:51:35 -070073
Bill Buzbeea114add2012-05-03 15:00:40 -070074extern RegLocation oatUpdateRawLoc(CompilationUnit* cUnit, RegLocation loc);
buzbeeed3e9302011-09-23 17:34:19 -070075
buzbee67bf8852011-08-17 17:51:35 -070076extern void oatMarkLive(CompilationUnit* cUnit, int reg, int sReg);
77
78extern void oatMarkTemp(CompilationUnit* cUnit, int reg);
79
buzbee9e0f9b02011-08-24 15:32:46 -070080extern void oatUnmarkTemp(CompilationUnit* cUnit, int reg);
81
buzbee67bf8852011-08-17 17:51:35 -070082extern void oatMarkDirty(CompilationUnit* cUnit, RegLocation loc);
83
Bill Buzbeea114add2012-05-03 15:00:40 -070084extern void oatMarkPair(CompilationUnit* cUnit, int lowReg, int highReg);
buzbee67bf8852011-08-17 17:51:35 -070085
86extern void oatMarkClean(CompilationUnit* cUnit, RegLocation loc);
87
88extern void oatResetDef(CompilationUnit* cUnit, int reg);
89
90extern void oatResetDefLoc(CompilationUnit* cUnit, RegLocation rl);
91
92/* Set up temp & preserved register pools specialized by target */
Elliott Hughes7b9d9962012-04-20 18:48:18 -070093extern void oatInitPool(RegisterInfo* regs, int* regNums, int num);
buzbee67bf8852011-08-17 17:51:35 -070094
95/*
96 * Mark the beginning and end LIR of a def sequence. Note that
97 * on entry start points to the LIR prior to the beginning of the
98 * sequence.
99 */
Bill Buzbeea114add2012-05-03 15:00:40 -0700100extern void oatMarkDef(CompilationUnit* cUnit, RegLocation rl, LIR* start,
101 LIR* finish);
buzbee67bf8852011-08-17 17:51:35 -0700102/*
103 * Mark the beginning and end LIR of a def sequence. Note that
104 * on entry start points to the LIR prior to the beginning of the
105 * sequence.
106 */
107extern void oatMarkDefWide(CompilationUnit* cUnit, RegLocation rl,
Bill Buzbeea114add2012-05-03 15:00:40 -0700108 LIR* start, LIR* finish);
buzbee67bf8852011-08-17 17:51:35 -0700109
buzbee67bf8852011-08-17 17:51:35 -0700110
buzbee67bf8852011-08-17 17:51:35 -0700111// Get the LocRecord associated with an SSA name use.
112extern RegLocation oatGetSrc(CompilationUnit* cUnit, MIR* mir, int num);
buzbee15bf9802012-06-12 17:49:27 -0700113extern RegLocation oatGetSrcWide(CompilationUnit* cUnit, MIR* mir, int low);
114// Non-width checking version
buzbeee9a72f62011-09-04 17:59:07 -0700115extern RegLocation oatGetRawSrc(CompilationUnit* cUnit, MIR* mir, int num);
buzbee67bf8852011-08-17 17:51:35 -0700116
117// Get the LocRecord associated with an SSA name def.
buzbee15bf9802012-06-12 17:49:27 -0700118extern RegLocation oatGetDest(CompilationUnit* cUnit, MIR* mir);
119extern RegLocation oatGetDestWide(CompilationUnit* cUnit, MIR* mir);
120// Non-width checking version
121extern RegLocation oatGetRawDest(CompilationUnit* cUnit, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700122
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700123extern RegLocation oatGetReturnWide(CompilationUnit* cUnit, bool isDouble);
buzbee67bf8852011-08-17 17:51:35 -0700124
125/* Clobber all regs that might be used by an external C call */
buzbee6181f792011-09-29 11:14:04 -0700126extern void oatClobberCalleeSave(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700127
128extern RegisterInfo *oatIsTemp(CompilationUnit* cUnit, int reg);
129
buzbeeb29e4d12011-09-26 15:05:48 -0700130extern RegisterInfo *oatIsPromoted(CompilationUnit* cUnit, int reg);
131
buzbee67bf8852011-08-17 17:51:35 -0700132extern bool oatIsDirty(CompilationUnit* cUnit, int reg);
133
134extern void oatMarkInUse(CompilationUnit* cUnit, int reg);
135
136extern int oatAllocTemp(CompilationUnit* cUnit);
137
138extern int oatAllocTempFloat(CompilationUnit* cUnit);
139
140//REDO: too many assumptions.
141extern int oatAllocTempDouble(CompilationUnit* cUnit);
142
143extern void oatFreeTemp(CompilationUnit* cUnit, int reg);
144
145extern void oatResetDefLocWide(CompilationUnit* cUnit, RegLocation rl);
146
147extern void oatResetDefTracking(CompilationUnit* cUnit);
148
buzbee67bf8852011-08-17 17:51:35 -0700149extern RegisterInfo *oatIsLive(CompilationUnit* cUnit, int reg);
150
151/* To be used when explicitly managing register use */
buzbee2e748f32011-08-29 21:02:19 -0700152extern void oatLockCallTemps(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700153
buzbee0d966cf2011-09-08 17:34:58 -0700154extern void oatFreeCallTemps(CompilationUnit* cUnit);
155
buzbee67bf8852011-08-17 17:51:35 -0700156extern void oatFlushAllRegs(CompilationUnit* cUnit);
157
158extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit);
159
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700160extern RegLocation oatGetReturn(CompilationUnit* cUnit, bool isFloat);
buzbee67bf8852011-08-17 17:51:35 -0700161
162extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit);
163
164/* Clobber any temp associated with an sReg. Could be in either class */
165extern void oatClobberSReg(CompilationUnit* cUnit, int sReg);
166
167/* Return a temp if one is available, -1 otherwise */
168extern int oatAllocFreeTemp(CompilationUnit* cUnit);
169
170/* Attempt to allocate a callee-save register */
171extern int oatAllocPreservedCoreReg(CompilationUnit* cUnit, int sreg);
172extern int oatAllocPreservedFPReg(CompilationUnit* cUnit, int sReg,
173 bool doubleStart);
174
175/*
176 * Similar to oatAllocTemp(), but forces the allocation of a specific
177 * register. No check is made to see if the register was previously
178 * allocated. Use with caution.
179 */
180extern void oatLockTemp(CompilationUnit* cUnit, int reg);
181
Bill Buzbeea114add2012-05-03 15:00:40 -0700182extern RegLocation oatWideToNarrow(CompilationUnit* cUnit, RegLocation rl);
buzbee67bf8852011-08-17 17:51:35 -0700183
184/*
185 * Free all allocated temps in the temp pools. Note that this does
186 * not affect the "liveness" of a temp register, which will stay
187 * live until it is either explicitly killed or reallocated.
188 */
189extern void oatResetRegPool(CompilationUnit* cUnit);
190
191extern void oatClobberAllRegs(CompilationUnit* cUnit);
192
193extern void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2);
194
195extern void oatFlushReg(CompilationUnit* cUnit, int reg);
196
buzbeee3acd072012-02-25 17:03:10 -0800197extern void oatDoPromotion(CompilationUnit* cUnit);
198extern int oatVRegOffset(CompilationUnit* cUnit, int reg);
199extern int oatSRegOffset(CompilationUnit* cUnit, int reg);
200extern void oatCountRefs(CompilationUnit*, BasicBlock*, RefCounts*, RefCounts*);
201extern int oatSortCounts(const void *val1, const void *val2);
202extern void oatDumpCounts(const RefCounts* arr, int size, const char* msg);
203
buzbee67bf8852011-08-17 17:51:35 -0700204/*
205 * Architecture-dependent register allocation routines implemented in
206 * ${TARGET_ARCH}/${TARGET_ARCH_VARIANT}/Ralloc.c
207 */
208extern int oatAllocTypedTempPair(CompilationUnit* cUnit,
209 bool fpHint, int regClass);
210
Bill Buzbeea114add2012-05-03 15:00:40 -0700211extern int oatAllocTypedTemp(CompilationUnit* cUnit, bool fpHint, int regClass);
buzbee67bf8852011-08-17 17:51:35 -0700212
buzbee67bf8852011-08-17 17:51:35 -0700213extern void oatRegCopyWide(CompilationUnit* cUnit, int destLo,
214 int destHi, int srcLo, int srcHi);
215
216extern void oatFlushRegImpl(CompilationUnit* cUnit, int rBase,
217 int displacement, int rSrc, OpSize size);
218
219extern void oatFlushRegWideImpl(CompilationUnit* cUnit, int rBase,
220 int displacement, int rSrcLo, int rSrcHi);
221
buzbee6181f792011-09-29 11:14:04 -0700222extern void oatDumpCoreRegPool(CompilationUnit* cUint);
223extern void oatDumpFPRegPool(CompilationUnit* cUint);
224extern bool oatCheckCorePoolSanity(CompilationUnit* cUnit);
buzbee68253262011-10-07 14:02:25 -0700225extern RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg);
buzbeee3acd072012-02-25 17:03:10 -0800226extern void oatNopLIR(LIR* lir);
227extern bool oatIsFPReg(int reg);
228extern uint32_t oatFPRegMask(void);
229extern void oatAdjustSpillMask(CompilationUnit* cUnit);
buzbee9c044ce2012-03-18 13:24:07 -0700230void oatMarkPreservedSingle(CompilationUnit* cUnit, int vReg, int reg);
buzbeee3acd072012-02-25 17:03:10 -0800231void oatRegCopy(CompilationUnit* cUnit, int rDest, int rSrc);
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800232
233} // namespace art
234
buzbee67bf8852011-08-17 17:51:35 -0700235#endif // ART_SRC_COMPILER_RALLOC_H_