blob: b1e14ec145445afb4373f0e991531287cda5c589 [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 */
34static inline RegisterClass oatRegClassBySize(OpSize size)
35{
36 return (size == kUnsignedHalf ||
37 size == kSignedHalf ||
38 size == kUnsignedByte ||
39 size == kSignedByte ) ? kCoreReg : kAnyReg;
40}
41
42static inline int oatS2VReg(CompilationUnit* cUnit, int sReg)
43{
44 assert(sReg != INVALID_SREG);
45 return DECODE_REG(oatConvertSSARegToDalvik(cUnit, sReg));
46}
47
48/* Reset the tracker to unknown state */
49static inline void oatResetNullCheck(CompilationUnit* cUnit)
50{
51 oatClearAllBits(cUnit->regPool->nullCheckedRegs);
52}
53
54/*
55 * Get the "real" sreg number associated with an sReg slot. In general,
56 * sReg values passed through codegen are the SSA names created by
57 * dataflow analysis and refer to slot numbers in the cUnit->regLocation
58 * array. However, renaming is accomplished by simply replacing RegLocation
59 * entries in the cUnit->reglocation[] array. Therefore, when location
60 * records for operands are first created, we need to ask the locRecord
61 * identified by the dataflow pass what it's new name is.
62 */
63
64static inline int oatSRegHi(int lowSreg) {
65 return (lowSreg == INVALID_SREG) ? INVALID_SREG : lowSreg + 1;
66}
67
68
69static inline bool oatLiveOut(CompilationUnit* cUnit, int sReg)
70{
71 //For now.
72 return true;
73}
74
75static inline int oatSSASrc(MIR* mir, int num)
76{
77 assert(mir->ssaRep->numUses > num);
78 return mir->ssaRep->uses[num];
79}
80
81extern RegLocation oatEvalLoc(CompilationUnit* cUnit, RegLocation loc,
82 int regClass, bool update);
83/* Mark a temp register as dead. Does not affect allocation state. */
84extern void oatClobber(CompilationUnit* cUnit, int reg);
85
86extern RegLocation oatUpdateLoc(CompilationUnit* cUnit,
87 RegLocation loc);
88
89/* see comments for updateLoc */
90extern RegLocation oatUpdateLocWide(CompilationUnit* cUnit,
91 RegLocation loc);
92
93/* Clobber all of the temps that might be used by a handler. */
94extern void oatClobberHandlerRegs(CompilationUnit* cUnit);
95
96extern void oatMarkLive(CompilationUnit* cUnit, int reg, int sReg);
97
98extern void oatMarkTemp(CompilationUnit* cUnit, int reg);
99
buzbee9e0f9b02011-08-24 15:32:46 -0700100extern void oatUnmarkTemp(CompilationUnit* cUnit, int reg);
101
buzbee67bf8852011-08-17 17:51:35 -0700102extern void oatMarkDirty(CompilationUnit* cUnit, RegLocation loc);
103
104extern void oatMarkPair(CompilationUnit* cUnit, int lowReg,
105 int highReg);
106
107extern void oatMarkClean(CompilationUnit* cUnit, RegLocation loc);
108
109extern void oatResetDef(CompilationUnit* cUnit, int reg);
110
111extern void oatResetDefLoc(CompilationUnit* cUnit, RegLocation rl);
112
113/* Set up temp & preserved register pools specialized by target */
114extern void oatInitPool(RegisterInfo* regs, int* regNums, int num);
115
116/*
117 * Mark the beginning and end LIR of a def sequence. Note that
118 * on entry start points to the LIR prior to the beginning of the
119 * sequence.
120 */
121extern void oatMarkDef(CompilationUnit* cUnit, RegLocation rl,
122 LIR* start, LIR* finish);
123/*
124 * Mark the beginning and end LIR of a def sequence. Note that
125 * on entry start points to the LIR prior to the beginning of the
126 * sequence.
127 */
128extern void oatMarkDefWide(CompilationUnit* cUnit, RegLocation rl,
129 LIR* start, LIR* finish);
130
131extern RegLocation oatGetSrcWide(CompilationUnit* cUnit, MIR* mir,
132 int low, int high);
133
134extern RegLocation oatGetDestWide(CompilationUnit* cUnit, MIR* mir,
135 int low, int high);
136// Get the LocRecord associated with an SSA name use.
137extern RegLocation oatGetSrc(CompilationUnit* cUnit, MIR* mir, int num);
138
139// Get the LocRecord associated with an SSA name def.
140extern RegLocation oatGetDest(CompilationUnit* cUnit, MIR* mir, int num);
141
142extern RegLocation oatGetReturnWide(CompilationUnit* cUnit);
143
144/* Clobber all regs that might be used by an external C call */
145extern void oatClobberCallRegs(CompilationUnit* cUnit);
146
147extern RegisterInfo *oatIsTemp(CompilationUnit* cUnit, int reg);
148
149extern bool oatIsDirty(CompilationUnit* cUnit, int reg);
150
151extern void oatMarkInUse(CompilationUnit* cUnit, int reg);
152
153extern int oatAllocTemp(CompilationUnit* cUnit);
154
155extern int oatAllocTempFloat(CompilationUnit* cUnit);
156
157//REDO: too many assumptions.
158extern int oatAllocTempDouble(CompilationUnit* cUnit);
159
160extern void oatFreeTemp(CompilationUnit* cUnit, int reg);
161
162extern void oatResetDefLocWide(CompilationUnit* cUnit, RegLocation rl);
163
164extern void oatResetDefTracking(CompilationUnit* cUnit);
165
166/* Kill the corresponding bit in the null-checked register list */
167extern void oatKillNullCheckedLoc(CompilationUnit* cUnit,
168 RegLocation loc);
169
170//FIXME - this needs to also check the preserved pool.
171extern RegisterInfo *oatIsLive(CompilationUnit* cUnit, int reg);
172
173/* To be used when explicitly managing register use */
174extern void oatLockAllTemps(CompilationUnit* cUnit);
175
176extern void oatFlushAllRegs(CompilationUnit* cUnit);
177
178extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit);
179
180extern RegLocation oatGetReturn(CompilationUnit* cUnit);
181
182extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit);
183
184/* Clobber any temp associated with an sReg. Could be in either class */
185extern void oatClobberSReg(CompilationUnit* cUnit, int sReg);
186
187/* Return a temp if one is available, -1 otherwise */
188extern int oatAllocFreeTemp(CompilationUnit* cUnit);
189
190/* Attempt to allocate a callee-save register */
191extern int oatAllocPreservedCoreReg(CompilationUnit* cUnit, int sreg);
192extern int oatAllocPreservedFPReg(CompilationUnit* cUnit, int sReg,
193 bool doubleStart);
194
195/*
196 * Similar to oatAllocTemp(), but forces the allocation of a specific
197 * register. No check is made to see if the register was previously
198 * allocated. Use with caution.
199 */
200extern void oatLockTemp(CompilationUnit* cUnit, int reg);
201
202extern RegLocation oatWideToNarrow(CompilationUnit* cUnit,
203 RegLocation rl);
204
205/*
206 * Free all allocated temps in the temp pools. Note that this does
207 * not affect the "liveness" of a temp register, which will stay
208 * live until it is either explicitly killed or reallocated.
209 */
210extern void oatResetRegPool(CompilationUnit* cUnit);
211
212extern void oatClobberAllRegs(CompilationUnit* cUnit);
213
214extern void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2);
215
216extern void oatFlushReg(CompilationUnit* cUnit, int reg);
217
218/*
219 * Architecture-dependent register allocation routines implemented in
220 * ${TARGET_ARCH}/${TARGET_ARCH_VARIANT}/Ralloc.c
221 */
222extern int oatAllocTypedTempPair(CompilationUnit* cUnit,
223 bool fpHint, int regClass);
224
225extern int oatAllocTypedTemp(CompilationUnit* cUnit, bool fpHint,
226 int regClass);
227
228extern ArmLIR* oatRegCopy(CompilationUnit* cUnit, int rDest, int rSrc);
229
230extern void oatRegCopyWide(CompilationUnit* cUnit, int destLo,
231 int destHi, int srcLo, int srcHi);
232
233extern void oatFlushRegImpl(CompilationUnit* cUnit, int rBase,
234 int displacement, int rSrc, OpSize size);
235
236extern void oatFlushRegWideImpl(CompilationUnit* cUnit, int rBase,
237 int displacement, int rSrcLo, int rSrcHi);
238
239extern void oatDoPromotion(CompilationUnit* cUnit);
240extern int oatVRegOffset(CompilationUnit* cUnit, int reg);
241#endif // ART_SRC_COMPILER_RALLOC_H_