blob: 1f99600efb9f16edae756a080a71bd4d075efe99 [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
buzbee395116c2013-02-27 14:30:25 -080017#ifndef ART_SRC_COMPILER_DEX_QUICK_RALLOCUTIL_H_
18#define ART_SRC_COMPILER_DEX_QUICK_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
buzbee395116c2013-02-27 14:30:25 -080024#include "compiler/dex/compiler_ir.h"
25#include "compiler/dex/compiler_utility.h"
buzbee67bf8852011-08-17 17:51:35 -070026
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080027namespace art {
28
buzbeee3acd072012-02-25 17:03:10 -080029/* Static register use counts */
Elliott Hughes719ace42012-03-09 18:06:03 -080030struct RefCounts {
Bill Buzbeea114add2012-05-03 15:00:40 -070031 int count;
buzbeefa57c472012-11-21 12:06:18 -080032 int s_reg;
33 bool double_start; // Starting v_reg for a double
Elliott Hughes719ace42012-03-09 18:06:03 -080034};
buzbee67bf8852011-08-17 17:51:35 -070035
buzbee67bf8852011-08-17 17:51:35 -070036/*
buzbeefa57c472012-11-21 12:06:18 -080037 * Get the "real" sreg number associated with an s_reg slot. In general,
38 * s_reg values passed through codegen are the SSA names created by
39 * dataflow analysis and refer to slot numbers in the cu->reg_location
buzbee67bf8852011-08-17 17:51:35 -070040 * array. However, renaming is accomplished by simply replacing RegLocation
buzbeefa57c472012-11-21 12:06:18 -080041 * entries in the cu->reglocation[] array. Therefore, when location
buzbee67bf8852011-08-17 17:51:35 -070042 * records for operands are first created, we need to ask the locRecord
43 * identified by the dataflow pass what it's new name is.
44 */
buzbeefa57c472012-11-21 12:06:18 -080045inline int GetSRegHi(int lowSreg) {
Bill Buzbeea114add2012-05-03 15:00:40 -070046 return (lowSreg == INVALID_SREG) ? INVALID_SREG : lowSreg + 1;
buzbee67bf8852011-08-17 17:51:35 -070047}
48
buzbeefa57c472012-11-21 12:06:18 -080049inline bool oat_live_out(CompilationUnit* cu, int s_reg) {
Bill Buzbeea114add2012-05-03 15:00:40 -070050 //For now.
51 return true;
buzbee67bf8852011-08-17 17:51:35 -070052}
53
Elliott Hughes74847412012-06-20 18:10:21 -070054inline int oatSSASrc(MIR* mir, int num) {
buzbeefa57c472012-11-21 12:06:18 -080055 DCHECK_GT(mir->ssa_rep->num_uses, num);
56 return mir->ssa_rep->uses[num];
buzbee67bf8852011-08-17 17:51:35 -070057}
58
buzbeefa57c472012-11-21 12:06:18 -080059void ClobberSReg(CompilationUnit* cu, int s_reg);
60RegLocation EvalLoc(CompilationUnit* cu, RegLocation loc,
61 int reg_class, bool update);
buzbee02031b12012-11-23 09:41:35 -080062// Mark a temp register as dead. Does not affect allocation state.
buzbeefa57c472012-11-21 12:06:18 -080063void Clobber(CompilationUnit* cu, int reg);
buzbee02031b12012-11-23 09:41:35 -080064
buzbeefa57c472012-11-21 12:06:18 -080065RegLocation UpdateLoc(CompilationUnit* cu, RegLocation loc);
buzbeefa57c472012-11-21 12:06:18 -080066RegLocation UpdateLocWide(CompilationUnit* cu, RegLocation loc);
buzbeefa57c472012-11-21 12:06:18 -080067RegLocation UpdateRawLoc(CompilationUnit* cu, RegLocation loc);
buzbeeed3e9302011-09-23 17:34:19 -070068
buzbeefa57c472012-11-21 12:06:18 -080069void MarkLive(CompilationUnit* cu, int reg, int s_reg);
buzbeefa57c472012-11-21 12:06:18 -080070void MarkTemp(CompilationUnit* cu, int reg);
buzbeefa57c472012-11-21 12:06:18 -080071void UnmarkTemp(CompilationUnit* cu, int reg);
buzbeefa57c472012-11-21 12:06:18 -080072void MarkDirty(CompilationUnit* cu, RegLocation loc);
buzbeefa57c472012-11-21 12:06:18 -080073void MarkPair(CompilationUnit* cu, int low_reg, int high_reg);
buzbeefa57c472012-11-21 12:06:18 -080074void MarkClean(CompilationUnit* cu, RegLocation loc);
buzbeefa57c472012-11-21 12:06:18 -080075void ResetDef(CompilationUnit* cu, int reg);
buzbeefa57c472012-11-21 12:06:18 -080076void ResetDefLoc(CompilationUnit* cu, RegLocation rl);
buzbee67bf8852011-08-17 17:51:35 -070077
buzbee02031b12012-11-23 09:41:35 -080078// Set up temp & preserved register pools specialized by target.
buzbeefa57c472012-11-21 12:06:18 -080079void CompilerInitPool(RegisterInfo* regs, int* reg_nums, int num);
buzbee67bf8852011-08-17 17:51:35 -070080
81/*
82 * Mark the beginning and end LIR of a def sequence. Note that
83 * on entry start points to the LIR prior to the beginning of the
84 * sequence.
85 */
buzbee02031b12012-11-23 09:41:35 -080086void MarkDef(CompilationUnit* cu, RegLocation rl, LIR* start, LIR* finish);
87void MarkDefWide(CompilationUnit* cu, RegLocation rl, LIR* start, LIR* finish);
88void ResetDefLocWide(CompilationUnit* cu, RegLocation rl);
89void ResetDefTracking(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -070090
buzbee67bf8852011-08-17 17:51:35 -070091
buzbee67bf8852011-08-17 17:51:35 -070092// Get the LocRecord associated with an SSA name use.
buzbeefa57c472012-11-21 12:06:18 -080093RegLocation GetSrc(CompilationUnit* cu, MIR* mir, int num);
94RegLocation GetSrcWide(CompilationUnit* cu, MIR* mir, int low);
buzbee02031b12012-11-23 09:41:35 -080095// Non-width checking version.
buzbeefa57c472012-11-21 12:06:18 -080096RegLocation GetRawSrc(CompilationUnit* cu, MIR* mir, int num);
buzbee67bf8852011-08-17 17:51:35 -070097
98// Get the LocRecord associated with an SSA name def.
buzbeefa57c472012-11-21 12:06:18 -080099RegLocation GetDest(CompilationUnit* cu, MIR* mir);
100RegLocation GetDestWide(CompilationUnit* cu, MIR* mir);
buzbee02031b12012-11-23 09:41:35 -0800101// Non-width checking version.
buzbeefa57c472012-11-21 12:06:18 -0800102RegLocation GetRawDest(CompilationUnit* cu, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700103
buzbee02031b12012-11-23 09:41:35 -0800104// Clobber all regs that might be used by an external C call.
buzbeefa57c472012-11-21 12:06:18 -0800105void ClobberCalleeSave(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700106
buzbeefa57c472012-11-21 12:06:18 -0800107RegisterInfo *IsTemp(CompilationUnit* cu, int reg);
buzbeefa57c472012-11-21 12:06:18 -0800108RegisterInfo *IsPromoted(CompilationUnit* cu, int reg);
buzbee02031b12012-11-23 09:41:35 -0800109RegisterInfo *IsLive(CompilationUnit* cu, int reg);
buzbeefa57c472012-11-21 12:06:18 -0800110bool IsDirty(CompilationUnit* cu, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700111
buzbeefa57c472012-11-21 12:06:18 -0800112void MarkInUse(CompilationUnit* cu, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700113
buzbeefa57c472012-11-21 12:06:18 -0800114int AllocTemp(CompilationUnit* cu);
buzbeefa57c472012-11-21 12:06:18 -0800115int AllocTempFloat(CompilationUnit* cu);
buzbeefa57c472012-11-21 12:06:18 -0800116int AllocTempDouble(CompilationUnit* cu);
buzbeefa57c472012-11-21 12:06:18 -0800117void FreeTemp(CompilationUnit* cu, int reg);
buzbee02031b12012-11-23 09:41:35 -0800118// Return a temp if one is available, -1 otherwise.
buzbeefa57c472012-11-21 12:06:18 -0800119int AllocFreeTemp(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700120/*
buzbee02031b12012-11-23 09:41:35 -0800121 * Attempt to allocate a callee-save register.
buzbee52a77fc2012-11-20 19:50:46 -0800122 * Similar to AllocTemp(), but forces the allocation of a specific
buzbee67bf8852011-08-17 17:51:35 -0700123 * register. No check is made to see if the register was previously
124 * allocated. Use with caution.
125 */
buzbeefa57c472012-11-21 12:06:18 -0800126void LockTemp(CompilationUnit* cu, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700127
buzbee02031b12012-11-23 09:41:35 -0800128/* To be used when explicitly managing register use */
129void LockCallTemps(CompilationUnit* cu);
130void FreeCallTemps(CompilationUnit* cu);
131
132void FlushAllRegs(CompilationUnit* cu);
133
134RegLocation GetReturn(CompilationUnit* cu, bool is_float);
135RegLocation GetReturnWide(CompilationUnit* cu, bool is_double);
136RegLocation GetBadLoc();
buzbeefa57c472012-11-21 12:06:18 -0800137RegLocation WideToNarrow(CompilationUnit* cu, RegLocation rl);
buzbee67bf8852011-08-17 17:51:35 -0700138
139/*
140 * Free all allocated temps in the temp pools. Note that this does
141 * not affect the "liveness" of a temp register, which will stay
142 * live until it is either explicitly killed or reallocated.
143 */
buzbeefa57c472012-11-21 12:06:18 -0800144void ResetRegPool(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700145
buzbeefa57c472012-11-21 12:06:18 -0800146void ClobberAllRegs(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700147
buzbeefa57c472012-11-21 12:06:18 -0800148void FlushRegWide(CompilationUnit* cu, int reg1, int reg2);
buzbee67bf8852011-08-17 17:51:35 -0700149
buzbeefa57c472012-11-21 12:06:18 -0800150void FlushReg(CompilationUnit* cu, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700151
buzbeefa57c472012-11-21 12:06:18 -0800152void DoPromotion(CompilationUnit* cu);
153int VRegOffset(CompilationUnit* cu, int reg);
154int SRegOffset(CompilationUnit* cu, int reg);
155void RecordCorePromotion(CompilationUnit* cu, int reg, int s_reg);
156void RecordFpPromotion(CompilationUnit* cu, int reg, int s_reg);
buzbee5f61f672012-11-28 17:22:17 -0800157int SRegToPMap(CompilationUnit* cu, int s_reg);
buzbee4ef3e452012-12-14 13:35:28 -0800158void DumpRegPool(RegisterInfo* p, int num_regs);
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800159
160} // namespace art
161
buzbee395116c2013-02-27 14:30:25 -0800162#endif // ART_SRC_COMPILER_DEX_QUICK_RALLOCUTIL_H_