blob: 4e897ca5804131d066c6eca41cf3735363516ff5 [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;
buzbeefa57c472012-11-21 12:06:18 -080033 int s_reg;
34 bool double_start; // Starting v_reg 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/*
buzbeefa57c472012-11-21 12:06:18 -080039 * Get the "real" sreg number associated with an s_reg slot. In general,
40 * s_reg values passed through codegen are the SSA names created by
41 * dataflow analysis and refer to slot numbers in the cu->reg_location
buzbee67bf8852011-08-17 17:51:35 -070042 * array. However, renaming is accomplished by simply replacing RegLocation
buzbeefa57c472012-11-21 12:06:18 -080043 * entries in the cu->reglocation[] array. Therefore, when location
buzbee67bf8852011-08-17 17:51:35 -070044 * 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
buzbeefa57c472012-11-21 12:06:18 -080048inline int GetSRegHi(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
buzbeefa57c472012-11-21 12:06:18 -080053inline bool oat_live_out(CompilationUnit* cu, int s_reg) {
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) {
buzbeefa57c472012-11-21 12:06:18 -080059 DCHECK_GT(mir->ssa_rep->num_uses, num);
60 return mir->ssa_rep->uses[num];
buzbee67bf8852011-08-17 17:51:35 -070061}
62
buzbeefa57c472012-11-21 12:06:18 -080063void ClobberSReg(CompilationUnit* cu, int s_reg);
64RegLocation EvalLoc(CompilationUnit* cu, RegLocation loc,
65 int reg_class, bool update);
buzbee67bf8852011-08-17 17:51:35 -070066/* Mark a temp register as dead. Does not affect allocation state. */
buzbeefa57c472012-11-21 12:06:18 -080067void Clobber(CompilationUnit* cu, int reg);
68RegLocation UpdateLoc(CompilationUnit* cu, RegLocation loc);
buzbee67bf8852011-08-17 17:51:35 -070069
buzbeefa57c472012-11-21 12:06:18 -080070/* see comments for update_loc */
71RegLocation UpdateLocWide(CompilationUnit* cu, RegLocation loc);
buzbee67bf8852011-08-17 17:51:35 -070072
buzbeefa57c472012-11-21 12:06:18 -080073RegLocation UpdateRawLoc(CompilationUnit* cu, RegLocation loc);
buzbeeed3e9302011-09-23 17:34:19 -070074
buzbeefa57c472012-11-21 12:06:18 -080075void MarkLive(CompilationUnit* cu, int reg, int s_reg);
buzbee67bf8852011-08-17 17:51:35 -070076
buzbeefa57c472012-11-21 12:06:18 -080077void MarkTemp(CompilationUnit* cu, int reg);
buzbee67bf8852011-08-17 17:51:35 -070078
buzbeefa57c472012-11-21 12:06:18 -080079void UnmarkTemp(CompilationUnit* cu, int reg);
buzbee9e0f9b02011-08-24 15:32:46 -070080
buzbeefa57c472012-11-21 12:06:18 -080081void MarkDirty(CompilationUnit* cu, RegLocation loc);
buzbee67bf8852011-08-17 17:51:35 -070082
buzbeefa57c472012-11-21 12:06:18 -080083void MarkPair(CompilationUnit* cu, int low_reg, int high_reg);
buzbee67bf8852011-08-17 17:51:35 -070084
buzbeefa57c472012-11-21 12:06:18 -080085void MarkClean(CompilationUnit* cu, RegLocation loc);
buzbee67bf8852011-08-17 17:51:35 -070086
buzbeefa57c472012-11-21 12:06:18 -080087void ResetDef(CompilationUnit* cu, int reg);
buzbee67bf8852011-08-17 17:51:35 -070088
buzbeefa57c472012-11-21 12:06:18 -080089void ResetDefLoc(CompilationUnit* cu, RegLocation rl);
buzbee67bf8852011-08-17 17:51:35 -070090
91/* Set up temp & preserved register pools specialized by target */
buzbeefa57c472012-11-21 12:06:18 -080092void CompilerInitPool(RegisterInfo* regs, int* reg_nums, int num);
buzbee67bf8852011-08-17 17:51:35 -070093
94/*
95 * Mark the beginning and end LIR of a def sequence. Note that
96 * on entry start points to the LIR prior to the beginning of the
97 * sequence.
98 */
buzbeefa57c472012-11-21 12:06:18 -080099void MarkDef(CompilationUnit* cu, RegLocation rl, LIR* start,
Bill Buzbeea114add2012-05-03 15:00:40 -0700100 LIR* finish);
buzbee67bf8852011-08-17 17:51:35 -0700101/*
102 * Mark the beginning and end LIR of a def sequence. Note that
103 * on entry start points to the LIR prior to the beginning of the
104 * sequence.
105 */
buzbeefa57c472012-11-21 12:06:18 -0800106void MarkDefWide(CompilationUnit* cu, RegLocation rl,
Bill Buzbeea114add2012-05-03 15:00:40 -0700107 LIR* start, LIR* finish);
buzbee67bf8852011-08-17 17:51:35 -0700108
buzbee67bf8852011-08-17 17:51:35 -0700109
buzbee67bf8852011-08-17 17:51:35 -0700110// Get the LocRecord associated with an SSA name use.
buzbeefa57c472012-11-21 12:06:18 -0800111RegLocation GetSrc(CompilationUnit* cu, MIR* mir, int num);
112RegLocation GetSrcWide(CompilationUnit* cu, MIR* mir, int low);
buzbee15bf9802012-06-12 17:49:27 -0700113// Non-width checking version
buzbeefa57c472012-11-21 12:06:18 -0800114RegLocation GetRawSrc(CompilationUnit* cu, MIR* mir, int num);
buzbee67bf8852011-08-17 17:51:35 -0700115
116// Get the LocRecord associated with an SSA name def.
buzbeefa57c472012-11-21 12:06:18 -0800117RegLocation GetDest(CompilationUnit* cu, MIR* mir);
118RegLocation GetDestWide(CompilationUnit* cu, MIR* mir);
buzbee15bf9802012-06-12 17:49:27 -0700119// Non-width checking version
buzbeefa57c472012-11-21 12:06:18 -0800120RegLocation GetRawDest(CompilationUnit* cu, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700121
buzbeefa57c472012-11-21 12:06:18 -0800122RegLocation GetReturnWide(CompilationUnit* cu, bool is_double);
buzbee67bf8852011-08-17 17:51:35 -0700123
124/* Clobber all regs that might be used by an external C call */
buzbeefa57c472012-11-21 12:06:18 -0800125void ClobberCalleeSave(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700126
buzbeefa57c472012-11-21 12:06:18 -0800127RegisterInfo *IsTemp(CompilationUnit* cu, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700128
buzbeefa57c472012-11-21 12:06:18 -0800129RegisterInfo *IsPromoted(CompilationUnit* cu, int reg);
buzbeeb29e4d12011-09-26 15:05:48 -0700130
buzbeefa57c472012-11-21 12:06:18 -0800131bool IsDirty(CompilationUnit* cu, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700132
buzbeefa57c472012-11-21 12:06:18 -0800133void MarkInUse(CompilationUnit* cu, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700134
buzbeefa57c472012-11-21 12:06:18 -0800135int AllocTemp(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700136
buzbeefa57c472012-11-21 12:06:18 -0800137int AllocTempFloat(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700138
139//REDO: too many assumptions.
buzbeefa57c472012-11-21 12:06:18 -0800140int AllocTempDouble(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700141
buzbeefa57c472012-11-21 12:06:18 -0800142void FreeTemp(CompilationUnit* cu, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700143
buzbeefa57c472012-11-21 12:06:18 -0800144void ResetDefLocWide(CompilationUnit* cu, RegLocation rl);
buzbee67bf8852011-08-17 17:51:35 -0700145
buzbeefa57c472012-11-21 12:06:18 -0800146void ResetDefTracking(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700147
buzbeefa57c472012-11-21 12:06:18 -0800148RegisterInfo *IsLive(CompilationUnit* cu, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700149
150/* To be used when explicitly managing register use */
buzbeefa57c472012-11-21 12:06:18 -0800151void LockCallTemps(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700152
buzbeefa57c472012-11-21 12:06:18 -0800153void FreeCallTemps(CompilationUnit* cu);
buzbee0d966cf2011-09-08 17:34:58 -0700154
buzbeefa57c472012-11-21 12:06:18 -0800155void FlushAllRegs(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700156
buzbeefa57c472012-11-21 12:06:18 -0800157RegLocation GetReturnWideAlt(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700158
buzbeefa57c472012-11-21 12:06:18 -0800159RegLocation GetReturn(CompilationUnit* cu, bool is_float);
buzbee67bf8852011-08-17 17:51:35 -0700160
buzbeefa57c472012-11-21 12:06:18 -0800161RegLocation GetReturnAlt(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700162
buzbeefa57c472012-11-21 12:06:18 -0800163/* Clobber any temp associated with an s_reg. Could be in either class */
buzbee67bf8852011-08-17 17:51:35 -0700164
165/* Return a temp if one is available, -1 otherwise */
buzbeefa57c472012-11-21 12:06:18 -0800166int AllocFreeTemp(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700167
168/* Attempt to allocate a callee-save register */
buzbee67bf8852011-08-17 17:51:35 -0700169/*
buzbee52a77fc2012-11-20 19:50:46 -0800170 * Similar to AllocTemp(), but forces the allocation of a specific
buzbee67bf8852011-08-17 17:51:35 -0700171 * register. No check is made to see if the register was previously
172 * allocated. Use with caution.
173 */
buzbeefa57c472012-11-21 12:06:18 -0800174void LockTemp(CompilationUnit* cu, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700175
buzbeefa57c472012-11-21 12:06:18 -0800176RegLocation WideToNarrow(CompilationUnit* cu, RegLocation rl);
buzbee67bf8852011-08-17 17:51:35 -0700177
178/*
179 * Free all allocated temps in the temp pools. Note that this does
180 * not affect the "liveness" of a temp register, which will stay
181 * live until it is either explicitly killed or reallocated.
182 */
buzbeefa57c472012-11-21 12:06:18 -0800183void ResetRegPool(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700184
buzbeefa57c472012-11-21 12:06:18 -0800185void ClobberAllRegs(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700186
buzbeefa57c472012-11-21 12:06:18 -0800187void FlushRegWide(CompilationUnit* cu, int reg1, int reg2);
buzbee67bf8852011-08-17 17:51:35 -0700188
buzbeefa57c472012-11-21 12:06:18 -0800189void FlushReg(CompilationUnit* cu, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700190
buzbeefa57c472012-11-21 12:06:18 -0800191void DoPromotion(CompilationUnit* cu);
192int VRegOffset(CompilationUnit* cu, int reg);
193int SRegOffset(CompilationUnit* cu, int reg);
194void RecordCorePromotion(CompilationUnit* cu, int reg, int s_reg);
195void RecordFpPromotion(CompilationUnit* cu, int reg, int s_reg);
buzbeeca7a5e42012-08-20 11:12:18 -0700196
buzbeee3acd072012-02-25 17:03:10 -0800197
buzbeeb046e162012-10-30 15:48:42 -0700198/* Architecture-dependent register allocation routines. */
buzbeefa57c472012-11-21 12:06:18 -0800199int AllocTypedTempPair(CompilationUnit* cu,
200 bool fp_hint, int reg_class);
buzbee67bf8852011-08-17 17:51:35 -0700201
buzbeefa57c472012-11-21 12:06:18 -0800202int AllocTypedTemp(CompilationUnit* cu, bool fp_hint, int reg_class);
buzbee67bf8852011-08-17 17:51:35 -0700203
buzbeeaad94382012-11-21 07:40:50 -0800204void oatDumpFPRegPool(CompilationUnit* cUint);
buzbeefa57c472012-11-21 12:06:18 -0800205RegisterInfo* GetRegInfo(CompilationUnit* cu, int reg);
buzbeeaad94382012-11-21 07:40:50 -0800206void NopLIR(LIR* lir);
207bool oatIsFPReg(int reg);
208uint32_t oatFPRegMask(void);
buzbeefa57c472012-11-21 12:06:18 -0800209void AdjustSpillMask(CompilationUnit* cu);
210void MarkPreservedSingle(CompilationUnit* cu, int v_reg, int reg);
211int ComputeFrameSize(CompilationUnit* cu);
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800212
213} // namespace art
214
buzbeeeaf09bc2012-11-15 14:51:41 -0800215#endif // ART_SRC_COMPILER_CODEGEN_RALLOCUTIL_H_