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