blob: 67c22b56e221c8edbf08f9fee3e950cb194af4ef [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
Brian Carlstrom641ce032013-01-31 15:21:37 -080024#include "compiler/compiler_ir.h"
25#include "compiler/compiler_utility.h"
26#include "compiler/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
buzbee67bf8852011-08-17 17:51:35 -070037/*
buzbeefa57c472012-11-21 12:06:18 -080038 * Get the "real" sreg number associated with an s_reg slot. In general,
39 * s_reg values passed through codegen are the SSA names created by
40 * dataflow analysis and refer to slot numbers in the cu->reg_location
buzbee67bf8852011-08-17 17:51:35 -070041 * array. However, renaming is accomplished by simply replacing RegLocation
buzbeefa57c472012-11-21 12:06:18 -080042 * entries in the cu->reglocation[] array. Therefore, when location
buzbee67bf8852011-08-17 17:51:35 -070043 * records for operands are first created, we need to ask the locRecord
44 * identified by the dataflow pass what it's new name is.
45 */
buzbeefa57c472012-11-21 12:06:18 -080046inline int GetSRegHi(int lowSreg) {
Bill Buzbeea114add2012-05-03 15:00:40 -070047 return (lowSreg == INVALID_SREG) ? INVALID_SREG : lowSreg + 1;
buzbee67bf8852011-08-17 17:51:35 -070048}
49
buzbeefa57c472012-11-21 12:06:18 -080050inline bool oat_live_out(CompilationUnit* cu, int s_reg) {
Bill Buzbeea114add2012-05-03 15:00:40 -070051 //For now.
52 return true;
buzbee67bf8852011-08-17 17:51:35 -070053}
54
Elliott Hughes74847412012-06-20 18:10:21 -070055inline int oatSSASrc(MIR* mir, int num) {
buzbeefa57c472012-11-21 12:06:18 -080056 DCHECK_GT(mir->ssa_rep->num_uses, num);
57 return mir->ssa_rep->uses[num];
buzbee67bf8852011-08-17 17:51:35 -070058}
59
buzbeefa57c472012-11-21 12:06:18 -080060void ClobberSReg(CompilationUnit* cu, int s_reg);
61RegLocation EvalLoc(CompilationUnit* cu, RegLocation loc,
62 int reg_class, bool update);
buzbee02031b12012-11-23 09:41:35 -080063// Mark a temp register as dead. Does not affect allocation state.
buzbeefa57c472012-11-21 12:06:18 -080064void Clobber(CompilationUnit* cu, int reg);
buzbee02031b12012-11-23 09:41:35 -080065
buzbeefa57c472012-11-21 12:06:18 -080066RegLocation UpdateLoc(CompilationUnit* cu, RegLocation loc);
buzbeefa57c472012-11-21 12:06:18 -080067RegLocation UpdateLocWide(CompilationUnit* cu, RegLocation loc);
buzbeefa57c472012-11-21 12:06:18 -080068RegLocation UpdateRawLoc(CompilationUnit* cu, RegLocation loc);
buzbeeed3e9302011-09-23 17:34:19 -070069
buzbeefa57c472012-11-21 12:06:18 -080070void MarkLive(CompilationUnit* cu, int reg, int s_reg);
buzbeefa57c472012-11-21 12:06:18 -080071void MarkTemp(CompilationUnit* cu, int reg);
buzbeefa57c472012-11-21 12:06:18 -080072void UnmarkTemp(CompilationUnit* cu, int reg);
buzbeefa57c472012-11-21 12:06:18 -080073void MarkDirty(CompilationUnit* cu, RegLocation loc);
buzbeefa57c472012-11-21 12:06:18 -080074void MarkPair(CompilationUnit* cu, int low_reg, int high_reg);
buzbeefa57c472012-11-21 12:06:18 -080075void MarkClean(CompilationUnit* cu, RegLocation loc);
buzbeefa57c472012-11-21 12:06:18 -080076void ResetDef(CompilationUnit* cu, int reg);
buzbeefa57c472012-11-21 12:06:18 -080077void ResetDefLoc(CompilationUnit* cu, RegLocation rl);
buzbee67bf8852011-08-17 17:51:35 -070078
buzbee02031b12012-11-23 09:41:35 -080079// Set up temp & preserved register pools specialized by target.
buzbeefa57c472012-11-21 12:06:18 -080080void CompilerInitPool(RegisterInfo* regs, int* reg_nums, int num);
buzbee67bf8852011-08-17 17:51:35 -070081
82/*
83 * Mark the beginning and end LIR of a def sequence. Note that
84 * on entry start points to the LIR prior to the beginning of the
85 * sequence.
86 */
buzbee02031b12012-11-23 09:41:35 -080087void MarkDef(CompilationUnit* cu, RegLocation rl, LIR* start, LIR* finish);
88void MarkDefWide(CompilationUnit* cu, RegLocation rl, LIR* start, LIR* finish);
89void ResetDefLocWide(CompilationUnit* cu, RegLocation rl);
90void ResetDefTracking(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -070091
buzbee67bf8852011-08-17 17:51:35 -070092
buzbee67bf8852011-08-17 17:51:35 -070093// Get the LocRecord associated with an SSA name use.
buzbeefa57c472012-11-21 12:06:18 -080094RegLocation GetSrc(CompilationUnit* cu, MIR* mir, int num);
95RegLocation GetSrcWide(CompilationUnit* cu, MIR* mir, int low);
buzbee02031b12012-11-23 09:41:35 -080096// Non-width checking version.
buzbeefa57c472012-11-21 12:06:18 -080097RegLocation GetRawSrc(CompilationUnit* cu, MIR* mir, int num);
buzbee67bf8852011-08-17 17:51:35 -070098
99// Get the LocRecord associated with an SSA name def.
buzbeefa57c472012-11-21 12:06:18 -0800100RegLocation GetDest(CompilationUnit* cu, MIR* mir);
101RegLocation GetDestWide(CompilationUnit* cu, MIR* mir);
buzbee02031b12012-11-23 09:41:35 -0800102// Non-width checking version.
buzbeefa57c472012-11-21 12:06:18 -0800103RegLocation GetRawDest(CompilationUnit* cu, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700104
buzbee02031b12012-11-23 09:41:35 -0800105// Clobber all regs that might be used by an external C call.
buzbeefa57c472012-11-21 12:06:18 -0800106void ClobberCalleeSave(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700107
buzbeefa57c472012-11-21 12:06:18 -0800108RegisterInfo *IsTemp(CompilationUnit* cu, int reg);
buzbeefa57c472012-11-21 12:06:18 -0800109RegisterInfo *IsPromoted(CompilationUnit* cu, int reg);
buzbee02031b12012-11-23 09:41:35 -0800110RegisterInfo *IsLive(CompilationUnit* cu, int reg);
buzbeefa57c472012-11-21 12:06:18 -0800111bool IsDirty(CompilationUnit* cu, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700112
buzbeefa57c472012-11-21 12:06:18 -0800113void MarkInUse(CompilationUnit* cu, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700114
buzbeefa57c472012-11-21 12:06:18 -0800115int AllocTemp(CompilationUnit* cu);
buzbeefa57c472012-11-21 12:06:18 -0800116int AllocTempFloat(CompilationUnit* cu);
buzbeefa57c472012-11-21 12:06:18 -0800117int AllocTempDouble(CompilationUnit* cu);
buzbeefa57c472012-11-21 12:06:18 -0800118void FreeTemp(CompilationUnit* cu, int reg);
buzbee02031b12012-11-23 09:41:35 -0800119// Return a temp if one is available, -1 otherwise.
buzbeefa57c472012-11-21 12:06:18 -0800120int AllocFreeTemp(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700121/*
buzbee02031b12012-11-23 09:41:35 -0800122 * Attempt to allocate a callee-save register.
buzbee52a77fc2012-11-20 19:50:46 -0800123 * Similar to AllocTemp(), but forces the allocation of a specific
buzbee67bf8852011-08-17 17:51:35 -0700124 * register. No check is made to see if the register was previously
125 * allocated. Use with caution.
126 */
buzbeefa57c472012-11-21 12:06:18 -0800127void LockTemp(CompilationUnit* cu, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700128
buzbee02031b12012-11-23 09:41:35 -0800129/* To be used when explicitly managing register use */
130void LockCallTemps(CompilationUnit* cu);
131void FreeCallTemps(CompilationUnit* cu);
132
133void FlushAllRegs(CompilationUnit* cu);
134
135RegLocation GetReturn(CompilationUnit* cu, bool is_float);
136RegLocation GetReturnWide(CompilationUnit* cu, bool is_double);
137RegLocation GetBadLoc();
buzbeefa57c472012-11-21 12:06:18 -0800138RegLocation WideToNarrow(CompilationUnit* cu, RegLocation rl);
buzbee67bf8852011-08-17 17:51:35 -0700139
140/*
141 * Free all allocated temps in the temp pools. Note that this does
142 * not affect the "liveness" of a temp register, which will stay
143 * live until it is either explicitly killed or reallocated.
144 */
buzbeefa57c472012-11-21 12:06:18 -0800145void ResetRegPool(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700146
buzbeefa57c472012-11-21 12:06:18 -0800147void ClobberAllRegs(CompilationUnit* cu);
buzbee67bf8852011-08-17 17:51:35 -0700148
buzbeefa57c472012-11-21 12:06:18 -0800149void FlushRegWide(CompilationUnit* cu, int reg1, int reg2);
buzbee67bf8852011-08-17 17:51:35 -0700150
buzbeefa57c472012-11-21 12:06:18 -0800151void FlushReg(CompilationUnit* cu, int reg);
buzbee67bf8852011-08-17 17:51:35 -0700152
buzbeefa57c472012-11-21 12:06:18 -0800153void DoPromotion(CompilationUnit* cu);
154int VRegOffset(CompilationUnit* cu, int reg);
155int SRegOffset(CompilationUnit* cu, int reg);
156void RecordCorePromotion(CompilationUnit* cu, int reg, int s_reg);
157void RecordFpPromotion(CompilationUnit* cu, int reg, int s_reg);
buzbeefa57c472012-11-21 12:06:18 -0800158int ComputeFrameSize(CompilationUnit* cu);
buzbee5f61f672012-11-28 17:22:17 -0800159int SRegToPMap(CompilationUnit* cu, int s_reg);
buzbee4ef3e452012-12-14 13:35:28 -0800160void DumpRegPool(RegisterInfo* p, int num_regs);
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800161
162} // namespace art
163
buzbeeeaf09bc2012-11-15 14:51:41 -0800164#endif // ART_SRC_COMPILER_CODEGEN_RALLOCUTIL_H_