blob: dce19392ce19637d32ddd2ece79a070137eb7913 [file] [log] [blame]
Ben Cheng5d90c202009-11-22 23:31:11 -08001/*
2 * Copyright (C) 2009 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/*
18 * This file contains register alloction support and is intended to be
19 * included by:
20 *
21 * Codegen-$(TARGET_ARCH_VARIANT).c
22 *
23 */
24
25#include "compiler/CompilerUtility.h"
26#include "compiler/CompilerIR.h"
27#include "compiler/Dataflow.h"
28#include "compiler/codegen/arm/ArmLIR.h"
29
30/*
31 * The following are register allocation routines exposed to the code generator
32 * FIXME - dvmCompiler prefixes are not added yet
33 */
34
35static inline int sReg2vReg(CompilationUnit *cUnit, int sReg)
36{
37 assert(sReg != INVALID_SREG);
38 return DECODE_REG(dvmConvertSSARegToDalvik(cUnit, sReg));
39}
40
41/* Reset the tracker to unknown state */
42static inline void resetNullCheckTracker(CompilationUnit *cUnit)
43{
44 dvmClearAllBits(cUnit->regPool->nullCheckedRegs);
45}
46
47/*
48 * Get the "real" sreg number associated with an sReg slot. In general,
49 * sReg values passed through codegen are the SSA names created by
50 * dataflow analysis and refer to slot numbers in the cUnit->regLocation
51 * array. However, renaming is accomplished by simply replacing RegLocation
52 * entries in the cUnit->reglocation[] array. Therefore, when location
53 * records for operands are first created, we need to ask the locRecord
54 * identified by the dataflow pass what it's new name is.
55 */
56
57static inline int hiSReg(int lowSreg) {
58 return (lowSreg == INVALID_SREG) ? INVALID_SREG : lowSreg + 1;
59}
60
61
62static inline bool liveOut(CompilationUnit *cUnit, int sReg)
63{
64 //TODO: fully implement
65 return true;
66}
67
68static inline int getSrcSSAName(MIR *mir, int num)
69{
70 assert(mir->ssaRep->numUses > num);
71 return mir->ssaRep->uses[num];
72}
73
74extern RegLocation evalLoc(CompilationUnit *cUnit, RegLocation loc,
75 int regClass, bool update);
76/* Mark a temp register as dead. Does not affect allocation state. */
77extern void clobberReg(CompilationUnit *cUnit, int reg);
78
79extern RegLocation updateLoc(CompilationUnit *cUnit, RegLocation loc);
80
81/* see comments for updateLoc */
82extern RegLocation updateLocWide(CompilationUnit *cUnit, RegLocation loc);
83
84/* Clobber all of the temps that might be used by a handler. */
85extern void clobberHandlerRegs(CompilationUnit *cUnit);
86
87extern void markRegLive(CompilationUnit *cUnit, int reg, int sReg);
88
89extern void markRegDirty(CompilationUnit *cUnit, int reg);
90
91extern void markRegPair(CompilationUnit *cUnit, int lowReg, int highReg);
92
93extern void markRegClean(CompilationUnit *cUnit, int reg);
94
95extern void resetDef(CompilationUnit *cUnit, int reg);
96
97extern void resetDefLoc(CompilationUnit *cUnit, RegLocation rl);
98
99/* Set up temp & preserved register pools specialized by target */
100extern void initPool(RegisterInfo *regs, int *regNums, int num);
101
102/*
103 * Mark the beginning and end LIR of a def sequence. Note that
104 * on entry start points to the LIR prior to the beginning of the
105 * sequence.
106 */
107extern void markDef(CompilationUnit *cUnit, RegLocation rl,
108 LIR *start, LIR *finish);
109/*
110 * Mark the beginning and end LIR of a def sequence. Note that
111 * on entry start points to the LIR prior to the beginning of the
112 * sequence.
113 */
114extern void markDefWide(CompilationUnit *cUnit, RegLocation rl,
115 LIR *start, LIR *finish);
116
117extern RegLocation getSrcLocWide(CompilationUnit *cUnit, MIR *mir,
118 int low, int high);
119
120extern RegLocation getDestLocWide(CompilationUnit *cUnit, MIR *mir,
121 int low, int high);
122// Get the LocRecord associated with an SSA name use.
123extern RegLocation getSrcLoc(CompilationUnit *cUnit, MIR *mir, int num);
124
125// Get the LocRecord associated with an SSA name def.
126extern RegLocation getDestLoc(CompilationUnit *cUnit, MIR *mir, int num);
127
128extern RegLocation getReturnLocWide(CompilationUnit *cUnit);
129
130/* Clobber all regs that might be used by an external C call */
131extern void clobberCallRegs(CompilationUnit *cUnit);
132
133extern RegisterInfo *isTemp(CompilationUnit *cUnit, int reg);
134
135extern void markRegInUse(CompilationUnit *cUnit, int reg);
136
137extern int allocTemp(CompilationUnit *cUnit);
138
139extern int allocTempFloat(CompilationUnit *cUnit);
140
141//REDO: too many assumptions.
142extern int allocTempDouble(CompilationUnit *cUnit);
143
144extern void freeTemp(CompilationUnit *cUnit, int reg);
145
146extern void resetDefLocWide(CompilationUnit *cUnit, RegLocation rl);
147
148extern void resetDefTracking(CompilationUnit *cUnit);
149
150/* Kill the corresponding bit in the null-checked register list */
151extern void killNullCheckedLocation(CompilationUnit *cUnit, RegLocation loc);
152
153//FIXME - this needs to also check the preserved pool.
154extern RegisterInfo *isLive(CompilationUnit *cUnit, int reg);
155
156/* To be used when explicitly managing register use */
157extern void lockAllTemps(CompilationUnit *cUnit);
158
159extern void flushAllRegs(CompilationUnit *cUnit);
160
161extern RegLocation getReturnLocWideAlt(CompilationUnit *cUnit);
162
163extern RegLocation getReturnLoc(CompilationUnit *cUnit);
164
165extern RegLocation getReturnLocAlt(CompilationUnit *cUnit);
166
167/* Clobber any temp associated with an sReg. Could be in either class */
168extern void clobberSReg(CompilationUnit *cUnit, int sReg);
169
170/* Return a temp if one is available, -1 otherwise */
171extern int allocFreeTemp(CompilationUnit *cUnit);
172
173/*
174 * Similar to allocTemp(), 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 lockTemp(CompilationUnit *cUnit, int reg);
179
180extern RegLocation wideToNarrowLoc(CompilationUnit *cUnit, RegLocation rl);
181
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 resetRegPool(CompilationUnit *cUnit);
188
189extern void clobberAllRegs(CompilationUnit *cUnit);
190
191extern void resetDefTracking(CompilationUnit *cUnit);