• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 target independent register alloction support.
19  */
20 
21 #include "compiler/CompilerUtility.h"
22 #include "compiler/CompilerIR.h"
23 #include "compiler/Dataflow.h"
24 #include "compiler/codegen/arm/ArmLIR.h"
25 
26 /*
27  * Return most flexible allowed register class based on size.
28  * Bug: 2813841
29  * Must use a core register for data types narrower than word (due
30  * to possible unaligned load/store.
31  */
dvmCompilerRegClassBySize(OpSize size)32 static inline RegisterClass dvmCompilerRegClassBySize(OpSize size)
33 {
34     return (size == kUnsignedHalf ||
35             size == kSignedHalf ||
36             size == kUnsignedByte ||
37             size == kSignedByte ) ? kCoreReg : kAnyReg;
38 }
39 
dvmCompilerS2VReg(CompilationUnit * cUnit,int sReg)40 static inline int dvmCompilerS2VReg(CompilationUnit *cUnit, int sReg)
41 {
42     assert(sReg != INVALID_SREG);
43     return DECODE_REG(dvmConvertSSARegToDalvik(cUnit, sReg));
44 }
45 
46 /* Reset the tracker to unknown state */
dvmCompilerResetNullCheck(CompilationUnit * cUnit)47 static inline void dvmCompilerResetNullCheck(CompilationUnit *cUnit)
48 {
49     dvmClearAllBits(cUnit->regPool->nullCheckedRegs);
50 }
51 
52 /*
53  * Get the "real" sreg number associated with an sReg slot.  In general,
54  * sReg values passed through codegen are the SSA names created by
55  * dataflow analysis and refer to slot numbers in the cUnit->regLocation
56  * array.  However, renaming is accomplished by simply replacing RegLocation
57  * entries in the cUnit->reglocation[] array.  Therefore, when location
58  * records for operands are first created, we need to ask the locRecord
59  * identified by the dataflow pass what it's new name is.
60  */
61 
dvmCompilerSRegHi(int lowSreg)62 static inline int dvmCompilerSRegHi(int lowSreg) {
63     return (lowSreg == INVALID_SREG) ? INVALID_SREG : lowSreg + 1;
64 }
65 
66 
dvmCompilerLiveOut(CompilationUnit * cUnit,int sReg)67 static inline bool dvmCompilerLiveOut(CompilationUnit *cUnit, int sReg)
68 {
69     //TODO: fully implement
70     return true;
71 }
72 
dvmCompilerSSASrc(MIR * mir,int num)73 static inline int dvmCompilerSSASrc(MIR *mir, int num)
74 {
75     assert(mir->ssaRep->numUses > num);
76     return mir->ssaRep->uses[num];
77 }
78 
79 extern RegLocation dvmCompilerEvalLoc(CompilationUnit *cUnit, RegLocation loc,
80                                       int regClass, bool update);
81 /* Mark a temp register as dead.  Does not affect allocation state. */
82 extern void dvmCompilerClobber(CompilationUnit *cUnit, int reg);
83 
84 extern RegLocation dvmCompilerUpdateLoc(CompilationUnit *cUnit,
85                                         RegLocation loc);
86 
87 /* see comments for updateLoc */
88 extern RegLocation dvmCompilerUpdateLocWide(CompilationUnit *cUnit,
89                                             RegLocation loc);
90 
91 /* Clobber all of the temps that might be used by a handler. */
92 extern void dvmCompilerClobberHandlerRegs(CompilationUnit *cUnit);
93 
94 extern void dvmCompilerMarkLive(CompilationUnit *cUnit, int reg, int sReg);
95 
96 extern void dvmCompilerMarkDirty(CompilationUnit *cUnit, int reg);
97 
98 extern void dvmCompilerMarkPair(CompilationUnit *cUnit, int lowReg,
99                                 int highReg);
100 
101 extern void dvmCompilerMarkClean(CompilationUnit *cUnit, int reg);
102 
103 extern void dvmCompilerResetDef(CompilationUnit *cUnit, int reg);
104 
105 extern void dvmCompilerResetDefLoc(CompilationUnit *cUnit, RegLocation rl);
106 
107 /* Set up temp & preserved register pools specialized by target */
108 extern void dvmCompilerInitPool(RegisterInfo *regs, int *regNums, int num);
109 
110 /*
111  * Mark the beginning and end LIR of a def sequence.  Note that
112  * on entry start points to the LIR prior to the beginning of the
113  * sequence.
114  */
115 extern void dvmCompilerMarkDef(CompilationUnit *cUnit, RegLocation rl,
116                                LIR *start, LIR *finish);
117 /*
118  * Mark the beginning and end LIR of a def sequence.  Note that
119  * on entry start points to the LIR prior to the beginning of the
120  * sequence.
121  */
122 extern void dvmCompilerMarkDefWide(CompilationUnit *cUnit, RegLocation rl,
123                                    LIR *start, LIR *finish);
124 
125 extern RegLocation dvmCompilerGetSrcWide(CompilationUnit *cUnit, MIR *mir,
126                                          int low, int high);
127 
128 extern RegLocation dvmCompilerGetDestWide(CompilationUnit *cUnit, MIR *mir,
129                                           int low, int high);
130 // Get the LocRecord associated with an SSA name use.
131 extern RegLocation dvmCompilerGetSrc(CompilationUnit *cUnit, MIR *mir, int num);
132 
133 // Get the LocRecord associated with an SSA name def.
134 extern RegLocation dvmCompilerGetDest(CompilationUnit *cUnit, MIR *mir,
135                                       int num);
136 
137 extern RegLocation dvmCompilerGetReturnWide(CompilationUnit *cUnit);
138 
139 /* Clobber all regs that might be used by an external C call */
140 extern void dvmCompilerClobberCallRegs(CompilationUnit *cUnit);
141 
142 extern RegisterInfo *dvmCompilerIsTemp(CompilationUnit *cUnit, int reg);
143 
144 extern void dvmCompilerMarkInUse(CompilationUnit *cUnit, int reg);
145 
146 extern int dvmCompilerAllocTemp(CompilationUnit *cUnit);
147 
148 extern int dvmCompilerAllocTempFloat(CompilationUnit *cUnit);
149 
150 //REDO: too many assumptions.
151 extern int dvmCompilerAllocTempDouble(CompilationUnit *cUnit);
152 
153 extern void dvmCompilerFreeTemp(CompilationUnit *cUnit, int reg);
154 
155 extern void dvmCompilerResetDefLocWide(CompilationUnit *cUnit, RegLocation rl);
156 
157 extern void dvmCompilerResetDefTracking(CompilationUnit *cUnit);
158 
159 /* Kill the corresponding bit in the null-checked register list */
160 extern void dvmCompilerKillNullCheckedLoc(CompilationUnit *cUnit,
161                                           RegLocation loc);
162 
163 //FIXME - this needs to also check the preserved pool.
164 extern RegisterInfo *dvmCompilerIsLive(CompilationUnit *cUnit, int reg);
165 
166 /* To be used when explicitly managing register use */
167 extern void dvmCompilerLockAllTemps(CompilationUnit *cUnit);
168 
169 extern void dvmCompilerFlushAllRegs(CompilationUnit *cUnit);
170 
171 extern RegLocation dvmCompilerGetReturnWideAlt(CompilationUnit *cUnit);
172 
173 extern RegLocation dvmCompilerGetReturn(CompilationUnit *cUnit);
174 
175 extern RegLocation dvmCompilerGetReturnAlt(CompilationUnit *cUnit);
176 
177 /* Clobber any temp associated with an sReg.  Could be in either class */
178 extern void dvmCompilerClobberSReg(CompilationUnit *cUnit, int sReg);
179 
180 /* Return a temp if one is available, -1 otherwise */
181 extern int dvmCompilerAllocFreeTemp(CompilationUnit *cUnit);
182 
183 /*
184  * Similar to dvmCompilerAllocTemp(), but forces the allocation of a specific
185  * register.  No check is made to see if the register was previously
186  * allocated.  Use with caution.
187  */
188 extern void dvmCompilerLockTemp(CompilationUnit *cUnit, int reg);
189 
190 extern RegLocation dvmCompilerWideToNarrow(CompilationUnit *cUnit,
191                                            RegLocation rl);
192 
193 /*
194  * Free all allocated temps in the temp pools.  Note that this does
195  * not affect the "liveness" of a temp register, which will stay
196  * live until it is either explicitly killed or reallocated.
197  */
198 extern void dvmCompilerResetRegPool(CompilationUnit *cUnit);
199 
200 extern void dvmCompilerClobberAllRegs(CompilationUnit *cUnit);
201 
202 extern void dvmCompilerFlushRegWide(CompilationUnit *cUnit, int reg1, int reg2);
203 
204 extern void dvmCompilerFlushReg(CompilationUnit *cUnit, int reg);
205 
206 /*
207  * Architecture-dependent register allocation routines implemented in
208  * ${TARGET_ARCH}/${TARGET_ARCH_VARIANT}/Ralloc.c
209  */
210 extern int dvmCompilerAllocTypedTempPair(CompilationUnit *cUnit,
211                                          bool fpHint, int regClass);
212 
213 extern int dvmCompilerAllocTypedTemp(CompilationUnit *cUnit, bool fpHint,
214                                      int regClass);
215 
216 extern ArmLIR* dvmCompilerRegCopy(CompilationUnit *cUnit, int rDest, int rSrc);
217 
218 extern void dvmCompilerRegCopyWide(CompilationUnit *cUnit, int destLo,
219                                    int destHi, int srcLo, int srcHi);
220 
221 extern void dvmCompilerFlushRegImpl(CompilationUnit *cUnit, int rBase,
222                                     int displacement, int rSrc, OpSize size);
223 
224 extern void dvmCompilerFlushRegWideImpl(CompilationUnit *cUnit, int rBase,
225                                         int displacement, int rSrcLo,
226                                         int rSrcHi);
227