blob: 8c327e4d210e2fb79072c8c5f97d0e2abff31a86 [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
buzbeeefc63692012-11-14 16:31:52 -080024#include "../compiler_utility.h"
25#include "../compiler_ir.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
Elliott Hughes74847412012-06-20 18:10:21 -070053inline bool oatLiveOut(CompilationUnit* cUnit, int sReg) {
Bill Buzbeea114add2012-05-03 15:00:40 -070054 //For now.
55 return true;
buzbee67bf8852011-08-17 17:51:35 -070056}
57
Elliott Hughes74847412012-06-20 18:10:21 -070058inline int oatSSASrc(MIR* mir, int num) {
Bill Buzbeea114add2012-05-03 15:00:40 -070059 DCHECK_GT(mir->ssaRep->numUses, num);
60 return mir->ssaRep->uses[num];
buzbee67bf8852011-08-17 17:51:35 -070061}
62
63extern RegLocation oatEvalLoc(CompilationUnit* cUnit, RegLocation loc,
Bill Buzbeea114add2012-05-03 15:00:40 -070064 int regClass, bool update);
buzbee67bf8852011-08-17 17:51:35 -070065/* Mark a temp register as dead. Does not affect allocation state. */
66extern void oatClobber(CompilationUnit* cUnit, int reg);
Bill Buzbeea114add2012-05-03 15:00:40 -070067extern RegLocation oatUpdateLoc(CompilationUnit* cUnit, RegLocation loc);
buzbee67bf8852011-08-17 17:51:35 -070068
69/* see comments for updateLoc */
Bill Buzbeea114add2012-05-03 15:00:40 -070070extern RegLocation oatUpdateLocWide(CompilationUnit* cUnit, RegLocation loc);
buzbee67bf8852011-08-17 17:51:35 -070071
Bill Buzbeea114add2012-05-03 15:00:40 -070072extern RegLocation oatUpdateRawLoc(CompilationUnit* cUnit, RegLocation loc);
buzbeeed3e9302011-09-23 17:34:19 -070073
buzbee67bf8852011-08-17 17:51:35 -070074extern void oatMarkLive(CompilationUnit* cUnit, int reg, int sReg);
75
76extern void oatMarkTemp(CompilationUnit* cUnit, int reg);
77
buzbee9e0f9b02011-08-24 15:32:46 -070078extern void oatUnmarkTemp(CompilationUnit* cUnit, int reg);
79
buzbee67bf8852011-08-17 17:51:35 -070080extern void oatMarkDirty(CompilationUnit* cUnit, RegLocation loc);
81
Bill Buzbeea114add2012-05-03 15:00:40 -070082extern void oatMarkPair(CompilationUnit* cUnit, int lowReg, int highReg);
buzbee67bf8852011-08-17 17:51:35 -070083
84extern void oatMarkClean(CompilationUnit* cUnit, RegLocation loc);
85
86extern void oatResetDef(CompilationUnit* cUnit, int reg);
87
88extern void oatResetDefLoc(CompilationUnit* cUnit, RegLocation rl);
89
90/* Set up temp & preserved register pools specialized by target */
Elliott Hughes7b9d9962012-04-20 18:48:18 -070091extern void oatInitPool(RegisterInfo* regs, int* regNums, int num);
buzbee67bf8852011-08-17 17:51:35 -070092
93/*
94 * Mark the beginning and end LIR of a def sequence. Note that
95 * on entry start points to the LIR prior to the beginning of the
96 * sequence.
97 */
Bill Buzbeea114add2012-05-03 15:00:40 -070098extern void oatMarkDef(CompilationUnit* cUnit, RegLocation rl, LIR* start,
99 LIR* finish);
buzbee67bf8852011-08-17 17:51:35 -0700100/*
101 * Mark the beginning and end LIR of a def sequence. Note that
102 * on entry start points to the LIR prior to the beginning of the
103 * sequence.
104 */
105extern void oatMarkDefWide(CompilationUnit* cUnit, RegLocation rl,
Bill Buzbeea114add2012-05-03 15:00:40 -0700106 LIR* start, LIR* finish);
buzbee67bf8852011-08-17 17:51:35 -0700107
buzbee67bf8852011-08-17 17:51:35 -0700108
buzbee67bf8852011-08-17 17:51:35 -0700109// Get the LocRecord associated with an SSA name use.
110extern RegLocation oatGetSrc(CompilationUnit* cUnit, MIR* mir, int num);
buzbee15bf9802012-06-12 17:49:27 -0700111extern RegLocation oatGetSrcWide(CompilationUnit* cUnit, MIR* mir, int low);
112// Non-width checking version
buzbeee9a72f62011-09-04 17:59:07 -0700113extern RegLocation oatGetRawSrc(CompilationUnit* cUnit, MIR* mir, int num);
buzbee67bf8852011-08-17 17:51:35 -0700114
115// Get the LocRecord associated with an SSA name def.
buzbee15bf9802012-06-12 17:49:27 -0700116extern RegLocation oatGetDest(CompilationUnit* cUnit, MIR* mir);
117extern RegLocation oatGetDestWide(CompilationUnit* cUnit, MIR* mir);
118// Non-width checking version
119extern RegLocation oatGetRawDest(CompilationUnit* cUnit, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700120
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700121extern RegLocation oatGetReturnWide(CompilationUnit* cUnit, bool isDouble);
buzbee67bf8852011-08-17 17:51:35 -0700122
123/* Clobber all regs that might be used by an external C call */
buzbee6181f792011-09-29 11:14:04 -0700124extern void oatClobberCalleeSave(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700125
126extern RegisterInfo *oatIsTemp(CompilationUnit* cUnit, int reg);
127
buzbeeb29e4d12011-09-26 15:05:48 -0700128extern RegisterInfo *oatIsPromoted(CompilationUnit* cUnit, int reg);
129
buzbee67bf8852011-08-17 17:51:35 -0700130extern bool oatIsDirty(CompilationUnit* cUnit, int reg);
131
132extern void oatMarkInUse(CompilationUnit* cUnit, int reg);
133
134extern int oatAllocTemp(CompilationUnit* cUnit);
135
136extern int oatAllocTempFloat(CompilationUnit* cUnit);
137
138//REDO: too many assumptions.
139extern int oatAllocTempDouble(CompilationUnit* cUnit);
140
141extern void oatFreeTemp(CompilationUnit* cUnit, int reg);
142
143extern void oatResetDefLocWide(CompilationUnit* cUnit, RegLocation rl);
144
145extern void oatResetDefTracking(CompilationUnit* cUnit);
146
buzbee67bf8852011-08-17 17:51:35 -0700147extern RegisterInfo *oatIsLive(CompilationUnit* cUnit, int reg);
148
149/* To be used when explicitly managing register use */
buzbee2e748f32011-08-29 21:02:19 -0700150extern void oatLockCallTemps(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700151
buzbee0d966cf2011-09-08 17:34:58 -0700152extern void oatFreeCallTemps(CompilationUnit* cUnit);
153
buzbee67bf8852011-08-17 17:51:35 -0700154extern void oatFlushAllRegs(CompilationUnit* cUnit);
155
156extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit);
157
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700158extern RegLocation oatGetReturn(CompilationUnit* cUnit, bool isFloat);
buzbee67bf8852011-08-17 17:51:35 -0700159
160extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit);
161
162/* Clobber any temp associated with an sReg. Could be in either class */
163extern void oatClobberSReg(CompilationUnit* cUnit, int sReg);
164
165/* Return a temp if one is available, -1 otherwise */
166extern int oatAllocFreeTemp(CompilationUnit* cUnit);
167
168/* Attempt to allocate a callee-save register */
169extern int oatAllocPreservedCoreReg(CompilationUnit* cUnit, int sreg);
170extern int oatAllocPreservedFPReg(CompilationUnit* cUnit, int sReg,
171 bool doubleStart);
172
173/*
174 * Similar to oatAllocTemp(), but forces the allocation of a specific
175 * register. No check is made to see if the register was previously
176 * allocated. Use with caution.
177 */
178extern void oatLockTemp(CompilationUnit* cUnit, int reg);
179
Bill Buzbeea114add2012-05-03 15:00:40 -0700180extern RegLocation oatWideToNarrow(CompilationUnit* cUnit, RegLocation rl);
buzbee67bf8852011-08-17 17:51:35 -0700181
182/*
183 * Free all allocated temps in the temp pools. Note that this does
184 * not affect the "liveness" of a temp register, which will stay
185 * live until it is either explicitly killed or reallocated.
186 */
187extern void oatResetRegPool(CompilationUnit* cUnit);
188
189extern void oatClobberAllRegs(CompilationUnit* cUnit);
190
191extern void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2);
192
193extern void oatFlushReg(CompilationUnit* cUnit, int reg);
194
buzbeee3acd072012-02-25 17:03:10 -0800195extern void oatDoPromotion(CompilationUnit* cUnit);
196extern int oatVRegOffset(CompilationUnit* cUnit, int reg);
197extern int oatSRegOffset(CompilationUnit* cUnit, int reg);
198extern void oatCountRefs(CompilationUnit*, BasicBlock*, RefCounts*, RefCounts*);
199extern int oatSortCounts(const void *val1, const void *val2);
200extern void oatDumpCounts(const RefCounts* arr, int size, const char* msg);
buzbeeca7a5e42012-08-20 11:12:18 -0700201extern void oatRecordCorePromotion(CompilationUnit* cUnit, int reg, int sReg);
202extern void oatRecordFpPromotion(CompilationUnit* cUnit, int reg, int sReg);
203
buzbeee3acd072012-02-25 17:03:10 -0800204
buzbeeb046e162012-10-30 15:48:42 -0700205/* Architecture-dependent register allocation routines. */
buzbee67bf8852011-08-17 17:51:35 -0700206extern int oatAllocTypedTempPair(CompilationUnit* cUnit,
207 bool fpHint, int regClass);
208
Bill Buzbeea114add2012-05-03 15:00:40 -0700209extern int oatAllocTypedTemp(CompilationUnit* cUnit, bool fpHint, int regClass);
buzbee67bf8852011-08-17 17:51:35 -0700210
buzbee67bf8852011-08-17 17:51:35 -0700211extern void oatRegCopyWide(CompilationUnit* cUnit, int destLo,
212 int destHi, int srcLo, int srcHi);
213
214extern void oatFlushRegImpl(CompilationUnit* cUnit, int rBase,
215 int displacement, int rSrc, OpSize size);
216
217extern void oatFlushRegWideImpl(CompilationUnit* cUnit, int rBase,
218 int displacement, int rSrcLo, int rSrcHi);
219
buzbee6181f792011-09-29 11:14:04 -0700220extern void oatDumpCoreRegPool(CompilationUnit* cUint);
221extern void oatDumpFPRegPool(CompilationUnit* cUint);
222extern bool oatCheckCorePoolSanity(CompilationUnit* cUnit);
buzbee68253262011-10-07 14:02:25 -0700223extern RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg);
buzbeee3acd072012-02-25 17:03:10 -0800224extern void oatNopLIR(LIR* lir);
225extern bool oatIsFPReg(int reg);
226extern uint32_t oatFPRegMask(void);
227extern void oatAdjustSpillMask(CompilationUnit* cUnit);
buzbee9c044ce2012-03-18 13:24:07 -0700228void oatMarkPreservedSingle(CompilationUnit* cUnit, int vReg, int reg);
buzbeee3acd072012-02-25 17:03:10 -0800229void oatRegCopy(CompilationUnit* cUnit, int rDest, int rSrc);
buzbeead8f15e2012-06-18 14:49:45 -0700230int oatComputeFrameSize(CompilationUnit* cUnit);
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800231
232} // namespace art
233
buzbee67bf8852011-08-17 17:51:35 -0700234#endif // ART_SRC_COMPILER_RALLOC_H_