blob: 69476564695e1e32ca7df70273b18aa6708ee2f5 [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
buzbeeeaf09bc2012-11-15 14:51:41 -080017#ifndef ART_SRC_COMPILER_CODEGEN_RALLOCUTIL_H_
18#define ART_SRC_COMPILER_CODEGEN_RALLOCUTIL_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
buzbee52a77fc2012-11-20 19:50:46 -080063extern RegLocation EvalLoc(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. */
buzbee52a77fc2012-11-20 19:50:46 -080066extern void Clobber(CompilationUnit* cUnit, int reg);
67extern RegLocation UpdateLoc(CompilationUnit* cUnit, RegLocation loc);
buzbee67bf8852011-08-17 17:51:35 -070068
69/* see comments for updateLoc */
buzbee52a77fc2012-11-20 19:50:46 -080070extern RegLocation UpdateLocWide(CompilationUnit* cUnit, RegLocation loc);
buzbee67bf8852011-08-17 17:51:35 -070071
buzbee52a77fc2012-11-20 19:50:46 -080072extern RegLocation UpdateRawLoc(CompilationUnit* cUnit, RegLocation loc);
buzbeeed3e9302011-09-23 17:34:19 -070073
buzbee52a77fc2012-11-20 19:50:46 -080074extern void MarkLive(CompilationUnit* cUnit, int reg, int sReg);
buzbee67bf8852011-08-17 17:51:35 -070075
buzbee52a77fc2012-11-20 19:50:46 -080076extern void MarkTemp(CompilationUnit* cUnit, int reg);
buzbee67bf8852011-08-17 17:51:35 -070077
buzbee52a77fc2012-11-20 19:50:46 -080078extern void UnmarkTemp(CompilationUnit* cUnit, int reg);
buzbee9e0f9b02011-08-24 15:32:46 -070079
buzbee52a77fc2012-11-20 19:50:46 -080080extern void MarkDirty(CompilationUnit* cUnit, RegLocation loc);
buzbee67bf8852011-08-17 17:51:35 -070081
buzbee52a77fc2012-11-20 19:50:46 -080082extern void MarkPair(CompilationUnit* cUnit, int lowReg, int highReg);
buzbee67bf8852011-08-17 17:51:35 -070083
buzbee52a77fc2012-11-20 19:50:46 -080084extern void MarkClean(CompilationUnit* cUnit, RegLocation loc);
buzbee67bf8852011-08-17 17:51:35 -070085
buzbee52a77fc2012-11-20 19:50:46 -080086extern void ResetDef(CompilationUnit* cUnit, int reg);
buzbee67bf8852011-08-17 17:51:35 -070087
buzbee52a77fc2012-11-20 19:50:46 -080088extern void ResetDefLoc(CompilationUnit* cUnit, RegLocation rl);
buzbee67bf8852011-08-17 17:51:35 -070089
90/* Set up temp & preserved register pools specialized by target */
buzbee52a77fc2012-11-20 19:50:46 -080091extern void CompilerInitPool(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 */
buzbee52a77fc2012-11-20 19:50:46 -080098extern void MarkDef(CompilationUnit* cUnit, RegLocation rl, LIR* start,
Bill Buzbeea114add2012-05-03 15:00:40 -070099 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 */
buzbee52a77fc2012-11-20 19:50:46 -0800105extern void MarkDefWide(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.
buzbee52a77fc2012-11-20 19:50:46 -0800110extern RegLocation GetSrc(CompilationUnit* cUnit, MIR* mir, int num);
111extern RegLocation GetSrcWide(CompilationUnit* cUnit, MIR* mir, int low);
buzbee15bf9802012-06-12 17:49:27 -0700112// Non-width checking version
buzbee52a77fc2012-11-20 19:50:46 -0800113extern RegLocation GetRawSrc(CompilationUnit* cUnit, MIR* mir, int num);
buzbee67bf8852011-08-17 17:51:35 -0700114
115// Get the LocRecord associated with an SSA name def.
buzbee52a77fc2012-11-20 19:50:46 -0800116extern RegLocation GetDest(CompilationUnit* cUnit, MIR* mir);
117extern RegLocation GetDestWide(CompilationUnit* cUnit, MIR* mir);
buzbee15bf9802012-06-12 17:49:27 -0700118// Non-width checking version
buzbee52a77fc2012-11-20 19:50:46 -0800119extern RegLocation GetRawDest(CompilationUnit* cUnit, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700120
buzbee52a77fc2012-11-20 19:50:46 -0800121extern RegLocation GetReturnWide(CompilationUnit* cUnit, bool isDouble);
buzbee67bf8852011-08-17 17:51:35 -0700122
123/* Clobber all regs that might be used by an external C call */
buzbee52a77fc2012-11-20 19:50:46 -0800124extern void ClobberCalleeSave(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700125
buzbee52a77fc2012-11-20 19:50:46 -0800126extern RegisterInfo *IsTemp(CompilationUnit* cUnit, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700127
buzbee52a77fc2012-11-20 19:50:46 -0800128extern RegisterInfo *IsPromoted(CompilationUnit* cUnit, int reg);
buzbeeb29e4d12011-09-26 15:05:48 -0700129
buzbee52a77fc2012-11-20 19:50:46 -0800130extern bool IsDirty(CompilationUnit* cUnit, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700131
buzbee52a77fc2012-11-20 19:50:46 -0800132extern void MarkInUse(CompilationUnit* cUnit, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700133
buzbee52a77fc2012-11-20 19:50:46 -0800134extern int AllocTemp(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700135
buzbee52a77fc2012-11-20 19:50:46 -0800136extern int AllocTempFloat(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700137
138//REDO: too many assumptions.
buzbee52a77fc2012-11-20 19:50:46 -0800139extern int AllocTempDouble(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700140
buzbee52a77fc2012-11-20 19:50:46 -0800141extern void FreeTemp(CompilationUnit* cUnit, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700142
buzbee52a77fc2012-11-20 19:50:46 -0800143extern void ResetDefLocWide(CompilationUnit* cUnit, RegLocation rl);
buzbee67bf8852011-08-17 17:51:35 -0700144
buzbee52a77fc2012-11-20 19:50:46 -0800145extern void ResetDefTracking(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700146
buzbee52a77fc2012-11-20 19:50:46 -0800147extern RegisterInfo *IsLive(CompilationUnit* cUnit, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700148
149/* To be used when explicitly managing register use */
buzbee52a77fc2012-11-20 19:50:46 -0800150extern void LockCallTemps(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700151
buzbee52a77fc2012-11-20 19:50:46 -0800152extern void FreeCallTemps(CompilationUnit* cUnit);
buzbee0d966cf2011-09-08 17:34:58 -0700153
buzbee52a77fc2012-11-20 19:50:46 -0800154extern void FlushAllRegs(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700155
buzbee52a77fc2012-11-20 19:50:46 -0800156extern RegLocation GetReturnWideAlt(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700157
buzbee52a77fc2012-11-20 19:50:46 -0800158extern RegLocation GetReturn(CompilationUnit* cUnit, bool isFloat);
buzbee67bf8852011-08-17 17:51:35 -0700159
buzbee52a77fc2012-11-20 19:50:46 -0800160extern RegLocation GetReturnAlt(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700161
162/* Clobber any temp associated with an sReg. Could be in either class */
buzbee52a77fc2012-11-20 19:50:46 -0800163extern void ClobberSReg(CompilationUnit* cUnit, int sReg);
buzbee67bf8852011-08-17 17:51:35 -0700164
165/* Return a temp if one is available, -1 otherwise */
buzbee52a77fc2012-11-20 19:50:46 -0800166extern int AllocFreeTemp(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700167
168/* Attempt to allocate a callee-save register */
buzbee52a77fc2012-11-20 19:50:46 -0800169extern int AllocPreservedCoreReg(CompilationUnit* cUnit, int sreg);
170extern int AllocPreservedFPReg(CompilationUnit* cUnit, int sReg,
buzbee67bf8852011-08-17 17:51:35 -0700171 bool doubleStart);
172
173/*
buzbee52a77fc2012-11-20 19:50:46 -0800174 * Similar to AllocTemp(), but forces the allocation of a specific
buzbee67bf8852011-08-17 17:51:35 -0700175 * register. No check is made to see if the register was previously
176 * allocated. Use with caution.
177 */
buzbee52a77fc2012-11-20 19:50:46 -0800178extern void LockTemp(CompilationUnit* cUnit, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700179
buzbee52a77fc2012-11-20 19:50:46 -0800180extern RegLocation WideToNarrow(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 */
buzbee52a77fc2012-11-20 19:50:46 -0800187extern void ResetRegPool(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700188
buzbee52a77fc2012-11-20 19:50:46 -0800189extern void ClobberAllRegs(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700190
buzbee52a77fc2012-11-20 19:50:46 -0800191extern void FlushRegWide(CompilationUnit* cUnit, int reg1, int reg2);
buzbee67bf8852011-08-17 17:51:35 -0700192
buzbee52a77fc2012-11-20 19:50:46 -0800193extern void FlushReg(CompilationUnit* cUnit, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700194
buzbee52a77fc2012-11-20 19:50:46 -0800195extern void DoPromotion(CompilationUnit* cUnit);
196extern int VRegOffset(CompilationUnit* cUnit, int reg);
197extern int SRegOffset(CompilationUnit* cUnit, int reg);
198extern void CountRefs(CompilationUnit*, BasicBlock*, RefCounts*, RefCounts*);
199extern int SortCounts(const void *val1, const void *val2);
200extern void DumpCounts(const RefCounts* arr, int size, const char* msg);
201extern void RecordCorePromotion(CompilationUnit* cUnit, int reg, int sReg);
202extern void RecordFpPromotion(CompilationUnit* cUnit, int reg, int sReg);
buzbeeca7a5e42012-08-20 11:12:18 -0700203
buzbeee3acd072012-02-25 17:03:10 -0800204
buzbeeb046e162012-10-30 15:48:42 -0700205/* Architecture-dependent register allocation routines. */
buzbee52a77fc2012-11-20 19:50:46 -0800206extern int AllocTypedTempPair(CompilationUnit* cUnit,
buzbee67bf8852011-08-17 17:51:35 -0700207 bool fpHint, int regClass);
208
buzbee52a77fc2012-11-20 19:50:46 -0800209extern int AllocTypedTemp(CompilationUnit* cUnit, bool fpHint, int regClass);
buzbee67bf8852011-08-17 17:51:35 -0700210
buzbee52a77fc2012-11-20 19:50:46 -0800211extern void DumpCoreRegPool(CompilationUnit* cUint);
buzbee6181f792011-09-29 11:14:04 -0700212extern void oatDumpFPRegPool(CompilationUnit* cUint);
buzbee52a77fc2012-11-20 19:50:46 -0800213extern bool CheckCorePoolSanity(CompilationUnit* cUnit);
214extern RegisterInfo* GetRegInfo(CompilationUnit* cUnit, int reg);
215extern void NopLIR(LIR* lir);
buzbeee3acd072012-02-25 17:03:10 -0800216extern bool oatIsFPReg(int reg);
217extern uint32_t oatFPRegMask(void);
buzbee52a77fc2012-11-20 19:50:46 -0800218extern void AdjustSpillMask(CompilationUnit* cUnit);
219void MarkPreservedSingle(CompilationUnit* cUnit, int vReg, int reg);
220int ComputeFrameSize(CompilationUnit* cUnit);
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800221
222} // namespace art
223
buzbeeeaf09bc2012-11-15 14:51:41 -0800224#endif // ART_SRC_COMPILER_CODEGEN_RALLOCUTIL_H_