blob: fee0e9a9136c87ff4d8fa3c17c85c45735c66cab [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_
19/*
20 * This file contains target independent register alloction support.
21 */
22
23#include "../CompilerUtility.h"
24#include "../CompilerIR.h"
25#include "../Dataflow.h"
26#include "arm/ArmLIR.h"
27
28/*
29 * Return most flexible allowed register class based on size.
30 * Bug: 2813841
31 * Must use a core register for data types narrower than word (due
32 * to possible unaligned load/store.
33 */
buzbeeed3e9302011-09-23 17:34:19 -070034STATIC inline RegisterClass oatRegClassBySize(OpSize size)
buzbee67bf8852011-08-17 17:51:35 -070035{
36 return (size == kUnsignedHalf ||
37 size == kSignedHalf ||
38 size == kUnsignedByte ||
39 size == kSignedByte ) ? kCoreReg : kAnyReg;
40}
41
buzbeeed3e9302011-09-23 17:34:19 -070042STATIC inline int oatS2VReg(CompilationUnit* cUnit, int sReg)
buzbee67bf8852011-08-17 17:51:35 -070043{
buzbeeed3e9302011-09-23 17:34:19 -070044 DCHECK_NE(sReg, INVALID_SREG);
buzbee67bf8852011-08-17 17:51:35 -070045 return DECODE_REG(oatConvertSSARegToDalvik(cUnit, sReg));
46}
47
buzbee67bf8852011-08-17 17:51:35 -070048/*
49 * Get the "real" sreg number associated with an sReg slot. In general,
50 * sReg values passed through codegen are the SSA names created by
51 * dataflow analysis and refer to slot numbers in the cUnit->regLocation
52 * array. However, renaming is accomplished by simply replacing RegLocation
53 * entries in the cUnit->reglocation[] array. Therefore, when location
54 * records for operands are first created, we need to ask the locRecord
55 * identified by the dataflow pass what it's new name is.
56 */
57
buzbeeed3e9302011-09-23 17:34:19 -070058STATIC inline int oatSRegHi(int lowSreg) {
buzbee67bf8852011-08-17 17:51:35 -070059 return (lowSreg == INVALID_SREG) ? INVALID_SREG : lowSreg + 1;
60}
61
62
buzbeeed3e9302011-09-23 17:34:19 -070063STATIC inline bool oatLiveOut(CompilationUnit* cUnit, int sReg)
buzbee67bf8852011-08-17 17:51:35 -070064{
65 //For now.
66 return true;
67}
68
buzbeeed3e9302011-09-23 17:34:19 -070069STATIC inline int oatSSASrc(MIR* mir, int num)
buzbee67bf8852011-08-17 17:51:35 -070070{
buzbeeed3e9302011-09-23 17:34:19 -070071 DCHECK_GT(mir->ssaRep->numUses, num);
buzbee67bf8852011-08-17 17:51:35 -070072 return mir->ssaRep->uses[num];
73}
74
75extern RegLocation oatEvalLoc(CompilationUnit* cUnit, RegLocation loc,
76 int regClass, bool update);
77/* Mark a temp register as dead. Does not affect allocation state. */
78extern void oatClobber(CompilationUnit* cUnit, int reg);
79
80extern RegLocation oatUpdateLoc(CompilationUnit* cUnit,
81 RegLocation loc);
82
83/* see comments for updateLoc */
84extern RegLocation oatUpdateLocWide(CompilationUnit* cUnit,
85 RegLocation loc);
86
buzbeeed3e9302011-09-23 17:34:19 -070087extern RegLocation oatUpdateRawLoc(CompilationUnit* cUnit,
88 RegLocation loc);
89
buzbee67bf8852011-08-17 17:51:35 -070090extern void oatMarkLive(CompilationUnit* cUnit, int reg, int sReg);
91
92extern void oatMarkTemp(CompilationUnit* cUnit, int reg);
93
buzbee9e0f9b02011-08-24 15:32:46 -070094extern void oatUnmarkTemp(CompilationUnit* cUnit, int reg);
95
buzbee67bf8852011-08-17 17:51:35 -070096extern void oatMarkDirty(CompilationUnit* cUnit, RegLocation loc);
97
98extern void oatMarkPair(CompilationUnit* cUnit, int lowReg,
99 int highReg);
100
101extern void oatMarkClean(CompilationUnit* cUnit, RegLocation loc);
102
103extern void oatResetDef(CompilationUnit* cUnit, int reg);
104
105extern void oatResetDefLoc(CompilationUnit* cUnit, RegLocation rl);
106
107/* Set up temp & preserved register pools specialized by target */
108extern void oatInitPool(RegisterInfo* regs, int* regNums, int num);
109
110/*
111 * Mark the beginning and end LIR of a def sequence. Note that
112 * on entry start points to the LIR prior to the beginning of the
113 * sequence.
114 */
115extern void oatMarkDef(CompilationUnit* cUnit, RegLocation rl,
116 LIR* start, LIR* finish);
117/*
118 * Mark the beginning and end LIR of a def sequence. Note that
119 * on entry start points to the LIR prior to the beginning of the
120 * sequence.
121 */
122extern void oatMarkDefWide(CompilationUnit* cUnit, RegLocation rl,
123 LIR* start, LIR* finish);
124
125extern RegLocation oatGetSrcWide(CompilationUnit* cUnit, MIR* mir,
126 int low, int high);
127
128extern RegLocation oatGetDestWide(CompilationUnit* cUnit, MIR* mir,
129 int low, int high);
130// Get the LocRecord associated with an SSA name use.
131extern RegLocation oatGetSrc(CompilationUnit* cUnit, MIR* mir, int num);
buzbeee9a72f62011-09-04 17:59:07 -0700132extern RegLocation oatGetRawSrc(CompilationUnit* cUnit, MIR* mir, int num);
buzbee67bf8852011-08-17 17:51:35 -0700133
134// Get the LocRecord associated with an SSA name def.
135extern RegLocation oatGetDest(CompilationUnit* cUnit, MIR* mir, int num);
136
137extern RegLocation oatGetReturnWide(CompilationUnit* cUnit);
138
139/* Clobber all regs that might be used by an external C call */
buzbee6181f792011-09-29 11:14:04 -0700140extern void oatClobberCalleeSave(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700141
142extern RegisterInfo *oatIsTemp(CompilationUnit* cUnit, int reg);
143
buzbeeb29e4d12011-09-26 15:05:48 -0700144extern RegisterInfo *oatIsPromoted(CompilationUnit* cUnit, int reg);
145
buzbee67bf8852011-08-17 17:51:35 -0700146extern bool oatIsDirty(CompilationUnit* cUnit, int reg);
147
148extern void oatMarkInUse(CompilationUnit* cUnit, int reg);
149
150extern int oatAllocTemp(CompilationUnit* cUnit);
151
152extern int oatAllocTempFloat(CompilationUnit* cUnit);
153
154//REDO: too many assumptions.
155extern int oatAllocTempDouble(CompilationUnit* cUnit);
156
157extern void oatFreeTemp(CompilationUnit* cUnit, int reg);
158
159extern void oatResetDefLocWide(CompilationUnit* cUnit, RegLocation rl);
160
161extern void oatResetDefTracking(CompilationUnit* cUnit);
162
buzbee67bf8852011-08-17 17:51:35 -0700163extern RegisterInfo *oatIsLive(CompilationUnit* cUnit, int reg);
164
165/* To be used when explicitly managing register use */
buzbee2e748f32011-08-29 21:02:19 -0700166extern void oatLockCallTemps(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700167
buzbee0d966cf2011-09-08 17:34:58 -0700168extern void oatFreeCallTemps(CompilationUnit* cUnit);
169
buzbee67bf8852011-08-17 17:51:35 -0700170extern void oatFlushAllRegs(CompilationUnit* cUnit);
171
172extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit);
173
174extern RegLocation oatGetReturn(CompilationUnit* cUnit);
175
176extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit);
177
178/* Clobber any temp associated with an sReg. Could be in either class */
179extern void oatClobberSReg(CompilationUnit* cUnit, int sReg);
180
181/* Return a temp if one is available, -1 otherwise */
182extern int oatAllocFreeTemp(CompilationUnit* cUnit);
183
184/* Attempt to allocate a callee-save register */
185extern int oatAllocPreservedCoreReg(CompilationUnit* cUnit, int sreg);
186extern int oatAllocPreservedFPReg(CompilationUnit* cUnit, int sReg,
187 bool doubleStart);
188
189/*
190 * Similar to oatAllocTemp(), but forces the allocation of a specific
191 * register. No check is made to see if the register was previously
192 * allocated. Use with caution.
193 */
194extern void oatLockTemp(CompilationUnit* cUnit, int reg);
195
196extern RegLocation oatWideToNarrow(CompilationUnit* cUnit,
197 RegLocation rl);
198
199/*
200 * Free all allocated temps in the temp pools. Note that this does
201 * not affect the "liveness" of a temp register, which will stay
202 * live until it is either explicitly killed or reallocated.
203 */
204extern void oatResetRegPool(CompilationUnit* cUnit);
205
206extern void oatClobberAllRegs(CompilationUnit* cUnit);
207
208extern void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2);
209
210extern void oatFlushReg(CompilationUnit* cUnit, int reg);
211
212/*
213 * Architecture-dependent register allocation routines implemented in
214 * ${TARGET_ARCH}/${TARGET_ARCH_VARIANT}/Ralloc.c
215 */
216extern int oatAllocTypedTempPair(CompilationUnit* cUnit,
217 bool fpHint, int regClass);
218
219extern int oatAllocTypedTemp(CompilationUnit* cUnit, bool fpHint,
220 int regClass);
221
222extern ArmLIR* oatRegCopy(CompilationUnit* cUnit, int rDest, int rSrc);
223
224extern void oatRegCopyWide(CompilationUnit* cUnit, int destLo,
225 int destHi, int srcLo, int srcHi);
226
227extern void oatFlushRegImpl(CompilationUnit* cUnit, int rBase,
228 int displacement, int rSrc, OpSize size);
229
230extern void oatFlushRegWideImpl(CompilationUnit* cUnit, int rBase,
231 int displacement, int rSrcLo, int rSrcHi);
232
233extern void oatDoPromotion(CompilationUnit* cUnit);
234extern int oatVRegOffset(CompilationUnit* cUnit, int reg);
buzbee67bc2362011-10-11 18:08:40 -0700235extern int oatSRegOffset(CompilationUnit* cUnit, int reg);
buzbee6181f792011-09-29 11:14:04 -0700236extern void oatDumpCoreRegPool(CompilationUnit* cUint);
237extern void oatDumpFPRegPool(CompilationUnit* cUint);
238extern bool oatCheckCorePoolSanity(CompilationUnit* cUnit);
buzbee68253262011-10-07 14:02:25 -0700239extern RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700240#endif // ART_SRC_COMPILER_RALLOC_H_