blob: ea4d6c109d932535e50aa6879a2def67831f153d [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
17#include "Dalvik.h"
18#include "CompilerInternals.h"
19#include "Dataflow.h"
20#include "codegen/Ralloc.h"
21
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080022namespace art {
23
buzbee31a4a6f2012-02-28 15:36:15 -080024bool setFp(CompilationUnit* cUnit, int index, bool isFP) {
Bill Buzbeea114add2012-05-03 15:00:40 -070025 bool change = false;
26 if (cUnit->regLocation[index].highWord) {
buzbee67bc2362011-10-11 18:08:40 -070027 return change;
Bill Buzbeea114add2012-05-03 15:00:40 -070028 }
29 if (isFP && !cUnit->regLocation[index].fp) {
30 cUnit->regLocation[index].fp = true;
31 cUnit->regLocation[index].defined = true;
32 change = true;
33 }
34 return change;
buzbee67bc2362011-10-11 18:08:40 -070035}
36
buzbee31a4a6f2012-02-28 15:36:15 -080037bool setCore(CompilationUnit* cUnit, int index, bool isCore) {
Bill Buzbeea114add2012-05-03 15:00:40 -070038 bool change = false;
39 if (cUnit->regLocation[index].highWord) {
buzbee03fa2632011-09-20 17:10:57 -070040 return change;
Bill Buzbeea114add2012-05-03 15:00:40 -070041 }
42 if (isCore && !cUnit->regLocation[index].defined) {
43 cUnit->regLocation[index].core = true;
44 cUnit->regLocation[index].defined = true;
45 change = true;
46 }
47 return change;
buzbee03fa2632011-09-20 17:10:57 -070048}
49
buzbeebff24652012-05-06 16:22:05 -070050bool setRef(CompilationUnit* cUnit, int index, bool isRef) {
51 bool change = false;
52 if (cUnit->regLocation[index].highWord) {
53 return change;
54 }
55 if (isRef && !cUnit->regLocation[index].defined) {
56 cUnit->regLocation[index].ref = true;
57 cUnit->regLocation[index].defined = true;
58 change = true;
59 }
60 return change;
61}
62
buzbee31a4a6f2012-02-28 15:36:15 -080063bool remapNames(CompilationUnit* cUnit, BasicBlock* bb)
buzbeec0ecd652011-09-25 18:11:54 -070064{
Bill Buzbeea114add2012-05-03 15:00:40 -070065 if (bb->blockType != kDalvikByteCode && bb->blockType != kEntryBlock &&
66 bb->blockType != kExitBlock)
buzbeec0ecd652011-09-25 18:11:54 -070067 return false;
Bill Buzbeea114add2012-05-03 15:00:40 -070068
69 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
70 SSARepresentation *ssaRep = mir->ssaRep;
71 if (ssaRep) {
72 for (int i = 0; i < ssaRep->numUses; i++) {
73 ssaRep->uses[i] = cUnit->phiAliasMap[ssaRep->uses[i]];
74 }
75 for (int i = 0; i < ssaRep->numDefs; i++) {
76 ssaRep->defs[i] = cUnit->phiAliasMap[ssaRep->defs[i]];
77 }
78 }
79 }
80 return false;
buzbeec0ecd652011-09-25 18:11:54 -070081}
82
buzbee769fde12012-01-05 17:35:23 -080083// Try to find the next move result which might have an FP target
buzbee52ed7762012-06-13 23:43:14 -070084SSARepresentation* findFPMoveResult(MIR* mir)
buzbee769fde12012-01-05 17:35:23 -080085{
Bill Buzbeea114add2012-05-03 15:00:40 -070086 SSARepresentation* res = NULL;
87 for (; mir; mir = mir->next) {
88 if ((mir->dalvikInsn.opcode == Instruction::MOVE_RESULT) ||
89 (mir->dalvikInsn.opcode == Instruction::MOVE_RESULT_WIDE)) {
90 res = mir->ssaRep;
91 break;
buzbee769fde12012-01-05 17:35:23 -080092 }
Bill Buzbeea114add2012-05-03 15:00:40 -070093 }
94 return res;
buzbee769fde12012-01-05 17:35:23 -080095}
96
buzbee67bf8852011-08-17 17:51:35 -070097/*
buzbee03fa2632011-09-20 17:10:57 -070098 * Infer types and sizes. We don't need to track change on sizes,
99 * as it doesn't propagate. We're guaranteed at least one pass through
100 * the cfg.
buzbee67bf8852011-08-17 17:51:35 -0700101 */
buzbee31a4a6f2012-02-28 15:36:15 -0800102bool inferTypeAndSize(CompilationUnit* cUnit, BasicBlock* bb)
buzbee67bf8852011-08-17 17:51:35 -0700103{
Bill Buzbeea114add2012-05-03 15:00:40 -0700104 MIR *mir;
105 bool changed = false; // Did anything change?
buzbee03fa2632011-09-20 17:10:57 -0700106
Bill Buzbeea114add2012-05-03 15:00:40 -0700107 if (bb->dataFlowInfo == NULL) return false;
108 if (bb->blockType != kDalvikByteCode && bb->blockType != kEntryBlock)
109 return false;
buzbee67bf8852011-08-17 17:51:35 -0700110
Bill Buzbeea114add2012-05-03 15:00:40 -0700111 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
112 SSARepresentation *ssaRep = mir->ssaRep;
113 if (ssaRep) {
114 int attrs = oatDataFlowAttributes[mir->dalvikInsn.opcode];
buzbee67bc2362011-10-11 18:08:40 -0700115
Bill Buzbeea114add2012-05-03 15:00:40 -0700116 // Handle defs
buzbeebff24652012-05-06 16:22:05 -0700117 if (attrs & DF_DA) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700118 if (attrs & DF_CORE_A) {
119 changed |= setCore(cUnit, ssaRep->defs[0], true);
buzbee67bf8852011-08-17 17:51:35 -0700120 }
buzbeebff24652012-05-06 16:22:05 -0700121 if (attrs & DF_REF_A) {
122 changed |= setRef(cUnit, ssaRep->defs[0], true);
123 }
124 if (attrs & DF_A_WIDE) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700125 cUnit->regLocation[ssaRep->defs[0]].wide = true;
126 cUnit->regLocation[ssaRep->defs[1]].highWord = true;
127 DCHECK_EQ(SRegToVReg(cUnit, ssaRep->defs[0])+1,
128 SRegToVReg(cUnit, ssaRep->defs[1]));
129 }
130 }
131
132 // Handles uses
133 int next = 0;
buzbeebff24652012-05-06 16:22:05 -0700134 if (attrs & DF_UA) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700135 if (attrs & DF_CORE_A) {
136 changed |= setCore(cUnit, ssaRep->uses[next], true);
137 }
buzbeebff24652012-05-06 16:22:05 -0700138 if (attrs & DF_REF_A) {
139 changed |= setRef(cUnit, ssaRep->uses[next], true);
140 }
141 if (attrs & DF_A_WIDE) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700142 cUnit->regLocation[ssaRep->uses[next]].wide = true;
143 cUnit->regLocation[ssaRep->uses[next + 1]].highWord = true;
144 DCHECK_EQ(SRegToVReg(cUnit, ssaRep->uses[next])+1,
145 SRegToVReg(cUnit, ssaRep->uses[next + 1]));
146 next += 2;
147 } else {
148 next++;
149 }
150 }
buzbeebff24652012-05-06 16:22:05 -0700151 if (attrs & DF_UB) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700152 if (attrs & DF_CORE_B) {
153 changed |= setCore(cUnit, ssaRep->uses[next], true);
154 }
buzbeebff24652012-05-06 16:22:05 -0700155 if (attrs & DF_REF_B) {
156 changed |= setRef(cUnit, ssaRep->uses[next], true);
157 }
158 if (attrs & DF_B_WIDE) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700159 cUnit->regLocation[ssaRep->uses[next]].wide = true;
160 cUnit->regLocation[ssaRep->uses[next + 1]].highWord = true;
161 DCHECK_EQ(SRegToVReg(cUnit, ssaRep->uses[next])+1,
162 SRegToVReg(cUnit, ssaRep->uses[next + 1]));
163 next += 2;
164 } else {
165 next++;
166 }
167 }
buzbeebff24652012-05-06 16:22:05 -0700168 if (attrs & DF_UC) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700169 if (attrs & DF_CORE_C) {
170 changed |= setCore(cUnit, ssaRep->uses[next], true);
171 }
buzbeebff24652012-05-06 16:22:05 -0700172 if (attrs & DF_REF_C) {
173 changed |= setRef(cUnit, ssaRep->uses[next], true);
174 }
175 if (attrs & DF_C_WIDE) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700176 cUnit->regLocation[ssaRep->uses[next]].wide = true;
177 cUnit->regLocation[ssaRep->uses[next + 1]].highWord = true;
178 DCHECK_EQ(SRegToVReg(cUnit, ssaRep->uses[next])+1,
179 SRegToVReg(cUnit, ssaRep->uses[next + 1]));
180 }
181 }
182
buzbeed5018892012-07-11 14:23:40 -0700183 // Special-case return handling
184 if ((mir->dalvikInsn.opcode == Instruction::RETURN) ||
185 (mir->dalvikInsn.opcode == Instruction::RETURN_WIDE) ||
186 (mir->dalvikInsn.opcode == Instruction::RETURN_OBJECT)) {
187 switch(cUnit->shorty[0]) {
188 case 'I':
189 changed |= setCore(cUnit, ssaRep->uses[0], true);
190 break;
191 case 'J':
192 changed |= setCore(cUnit, ssaRep->uses[0], true);
193 changed |= setCore(cUnit, ssaRep->uses[1], true);
194 cUnit->regLocation[ssaRep->uses[0]].wide = true;
195 cUnit->regLocation[ssaRep->uses[1]].highWord = true;
196 break;
197 case 'F':
198 changed |= setFp(cUnit, ssaRep->uses[0], true);
199 break;
200 case 'D':
201 changed |= setFp(cUnit, ssaRep->uses[0], true);
202 changed |= setFp(cUnit, ssaRep->uses[1], true);
203 cUnit->regLocation[ssaRep->uses[0]].wide = true;
204 cUnit->regLocation[ssaRep->uses[1]].highWord = true;
205 break;
206 case 'L':
207 changed |= setRef(cUnit, ssaRep->uses[0], true);
208 break;
209 default: break;
210 }
211 }
212
Bill Buzbeea114add2012-05-03 15:00:40 -0700213 // Special-case handling for format 35c/3rc invokes
214 Instruction::Code opcode = mir->dalvikInsn.opcode;
215 int flags = (static_cast<int>(opcode) >= kNumPackedOpcodes)
216 ? 0 : Instruction::Flags(mir->dalvikInsn.opcode);
217 if ((flags & Instruction::kInvoke) &&
218 (attrs & (DF_FORMAT_35C | DF_FORMAT_3RC))) {
219 DCHECK_EQ(next, 0);
220 int target_idx = mir->dalvikInsn.vB;
221 const char* shorty = oatGetShortyFromTargetIdx(cUnit, target_idx);
222 // Handle result type if floating point
223 if ((shorty[0] == 'F') || (shorty[0] == 'D')) {
224 // Find move-result that consumes this result
buzbee52ed7762012-06-13 23:43:14 -0700225 SSARepresentation* tgtRep = findFPMoveResult(mir->next);
Bill Buzbeea114add2012-05-03 15:00:40 -0700226 // Might be in next basic block
227 if (!tgtRep) {
buzbee52ed7762012-06-13 23:43:14 -0700228 tgtRep = findFPMoveResult(bb->fallThrough->firstMIRInsn);
Bill Buzbeea114add2012-05-03 15:00:40 -0700229 }
230 // Result might not be used at all, so no move-result
231 if (tgtRep) {
232 tgtRep->fpDef[0] = true;
233 changed |= setFp(cUnit, tgtRep->defs[0], true);
234 if (shorty[0] == 'D') {
235 tgtRep->fpDef[1] = true;
236 changed |= setFp(cUnit, tgtRep->defs[1], true);
237 }
238 }
239 }
240 int numUses = mir->dalvikInsn.vA;
buzbeebff24652012-05-06 16:22:05 -0700241 // If this is a non-static invoke, mark implicit "this"
Bill Buzbeea114add2012-05-03 15:00:40 -0700242 if (((mir->dalvikInsn.opcode != Instruction::INVOKE_STATIC) &&
243 (mir->dalvikInsn.opcode != Instruction::INVOKE_STATIC_RANGE))) {
244 cUnit->regLocation[ssaRep->uses[next]].defined = true;
buzbeebff24652012-05-06 16:22:05 -0700245 cUnit->regLocation[ssaRep->uses[next]].ref = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700246 next++;
247 }
248 uint32_t cpos = 1;
249 if (strlen(shorty) > 1) {
250 for (int i = next; i < numUses;) {
251 DCHECK_LT(cpos, strlen(shorty));
252 switch (shorty[cpos++]) {
253 case 'D':
254 ssaRep->fpUse[i] = true;
255 ssaRep->fpUse[i+1] = true;
256 cUnit->regLocation[ssaRep->uses[i]].wide = true;
257 cUnit->regLocation[ssaRep->uses[i+1]].highWord = true;
258 DCHECK_EQ(SRegToVReg(cUnit, ssaRep->uses[i])+1,
259 SRegToVReg(cUnit, ssaRep->uses[i+1]));
260 i++;
261 break;
262 case 'J':
263 cUnit->regLocation[ssaRep->uses[i]].wide = true;
264 cUnit->regLocation[ssaRep->uses[i+1]].highWord = true;
265 DCHECK_EQ(SRegToVReg(cUnit, ssaRep->uses[i])+1,
266 SRegToVReg(cUnit, ssaRep->uses[i+1]));
267 changed |= setCore(cUnit, ssaRep->uses[i],true);
268 i++;
269 break;
270 case 'F':
271 ssaRep->fpUse[i] = true;
272 break;
buzbeebff24652012-05-06 16:22:05 -0700273 case 'L':
274 changed |= setRef(cUnit,ssaRep->uses[i], true);
275 break;
Bill Buzbeea114add2012-05-03 15:00:40 -0700276 default:
277 changed |= setCore(cUnit,ssaRep->uses[i], true);
278 break;
279 }
280 i++;
281 }
282 }
283 }
284
285 for (int i=0; ssaRep->fpUse && i< ssaRep->numUses; i++) {
286 if (ssaRep->fpUse[i])
287 changed |= setFp(cUnit, ssaRep->uses[i], true);
288 }
289 for (int i=0; ssaRep->fpDef && i< ssaRep->numDefs; i++) {
290 if (ssaRep->fpDef[i])
291 changed |= setFp(cUnit, ssaRep->defs[i], true);
292 }
293 // Special-case handling for moves & Phi
294 if (attrs & (DF_IS_MOVE | DF_NULL_TRANSFER_N)) {
295 // If any of our inputs or outputs is defined, set all
296 bool definedFP = false;
297 bool definedCore = false;
buzbeebff24652012-05-06 16:22:05 -0700298 bool definedRef = false;
Bill Buzbeea114add2012-05-03 15:00:40 -0700299 definedFP |= (cUnit->regLocation[ssaRep->defs[0]].defined &&
300 cUnit->regLocation[ssaRep->defs[0]].fp);
301 definedCore |= (cUnit->regLocation[ssaRep->defs[0]].defined &&
302 cUnit->regLocation[ssaRep->defs[0]].core);
buzbeebff24652012-05-06 16:22:05 -0700303 definedRef |= (cUnit->regLocation[ssaRep->defs[0]].defined &&
304 cUnit->regLocation[ssaRep->defs[0]].ref);
Bill Buzbeea114add2012-05-03 15:00:40 -0700305 for (int i = 0; i < ssaRep->numUses; i++) {
306 definedFP |= (cUnit->regLocation[ssaRep->uses[i]].defined &&
307 cUnit->regLocation[ssaRep->uses[i]].fp);
308 definedCore |= (cUnit->regLocation[ssaRep->uses[i]].defined
309 && cUnit->regLocation[ssaRep->uses[i]].core);
buzbeebff24652012-05-06 16:22:05 -0700310 definedRef |= (cUnit->regLocation[ssaRep->uses[i]].defined
311 && cUnit->regLocation[ssaRep->uses[i]].ref);
Bill Buzbeea114add2012-05-03 15:00:40 -0700312 }
313 /*
314 * TODO: cleaner fix
315 * We don't normally expect to see a Dalvik register
316 * definition used both as a floating point and core
317 * value. However, the instruction rewriting that occurs
318 * during verification can eliminate some type information,
319 * leaving us confused. The real fix here is either to
320 * add explicit type information to Dalvik byte codes,
321 * or to recognize THROW_VERIFICATION_ERROR as
322 * an unconditional branch and support dead code elimination.
323 * As a workaround we can detect this situation and
324 * disable register promotion (which is the only thing that
325 * relies on distinctions between core and fp usages.
326 */
buzbeebff24652012-05-06 16:22:05 -0700327 if ((definedFP && (definedCore | definedRef)) &&
Bill Buzbeea114add2012-05-03 15:00:40 -0700328 ((cUnit->disableOpt & (1 << kPromoteRegs)) == 0)) {
329 LOG(WARNING) << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
330 << " op at block " << bb->id
buzbeebff24652012-05-06 16:22:05 -0700331 << " has both fp and core/ref uses for same def.";
Bill Buzbeea114add2012-05-03 15:00:40 -0700332 cUnit->disableOpt |= (1 << kPromoteRegs);
333 }
334 changed |= setFp(cUnit, ssaRep->defs[0], definedFP);
335 changed |= setCore(cUnit, ssaRep->defs[0], definedCore);
buzbeebff24652012-05-06 16:22:05 -0700336 changed |= setRef(cUnit, ssaRep->defs[0], definedRef);
Bill Buzbeea114add2012-05-03 15:00:40 -0700337 for (int i = 0; i < ssaRep->numUses; i++) {
338 changed |= setFp(cUnit, ssaRep->uses[i], definedFP);
339 changed |= setCore(cUnit, ssaRep->uses[i], definedCore);
buzbeebff24652012-05-06 16:22:05 -0700340 changed |= setRef(cUnit, ssaRep->uses[i], definedRef);
Bill Buzbeea114add2012-05-03 15:00:40 -0700341 }
342 }
buzbee67bf8852011-08-17 17:51:35 -0700343 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700344 }
345 return changed;
buzbee67bf8852011-08-17 17:51:35 -0700346}
347
348static const char* storageName[] = {" Frame ", "PhysReg", " Spill "};
349
buzbeedfd3d702011-08-28 12:56:51 -0700350void oatDumpRegLocTable(RegLocation* table, int count)
buzbee67bf8852011-08-17 17:51:35 -0700351{
Bill Buzbeea114add2012-05-03 15:00:40 -0700352 for (int i = 0; i < count; i++) {
353 LOG(INFO) << StringPrintf("Loc[%02d] : %s, %c %c %c %c %c %c%d %c%d S%d",
354 i, storageName[table[i].location], table[i].wide ? 'W' : 'N',
buzbeed5018892012-07-11 14:23:40 -0700355 table[i].defined ? 'D' : 'U',
356 table[i].fp ? 'F' : table[i].ref ? 'R' :'C',
Bill Buzbeea114add2012-05-03 15:00:40 -0700357 table[i].highWord ? 'H' : 'L', table[i].home ? 'h' : 't',
358 oatIsFpReg(table[i].lowReg) ? 's' : 'r',
359 table[i].lowReg & oatFpRegMask(),
360 oatIsFpReg(table[i].highReg) ? 's' : 'r',
361 table[i].highReg & oatFpRegMask(), table[i].sRegLow);
362 }
buzbee67bf8852011-08-17 17:51:35 -0700363}
364
buzbee6969d502012-06-15 16:40:31 -0700365void oatDumpRegLoc(RegLocation loc) {
366 oatDumpRegLocTable(&loc, 1);
367}
368
buzbee2cfc6392012-05-07 14:51:40 -0700369static const RegLocation freshLoc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0,
370 INVALID_REG, INVALID_REG, INVALID_SREG,
371 INVALID_SREG};
buzbee67bf8852011-08-17 17:51:35 -0700372
buzbeead8f15e2012-06-18 14:49:45 -0700373int oatComputeFrameSize(CompilationUnit* cUnit) {
374 /* Figure out the frame size */
375 static const uint32_t kAlignMask = kStackAlignment - 1;
376 uint32_t size = (cUnit->numCoreSpills + cUnit->numFPSpills +
377 1 /* filler word */ + cUnit->numRegs + cUnit->numOuts +
378 cUnit->numCompilerTemps + 1 /* curMethod* */)
379 * sizeof(uint32_t);
380 /* Align and set */
381 return (size + kAlignMask) & ~(kAlignMask);
382}
383
buzbee67bf8852011-08-17 17:51:35 -0700384/*
385 * Simple register allocation. Some Dalvik virtual registers may
386 * be promoted to physical registers. Most of the work for temp
Ian Rogersb5d09b22012-03-06 22:14:17 -0800387 * allocation is done on the fly. We also do some initialization and
buzbee67bf8852011-08-17 17:51:35 -0700388 * type inference here.
389 */
390void oatSimpleRegAlloc(CompilationUnit* cUnit)
391{
Bill Buzbeea114add2012-05-03 15:00:40 -0700392 int i;
393 RegLocation* loc;
buzbee67bf8852011-08-17 17:51:35 -0700394
Bill Buzbeea114add2012-05-03 15:00:40 -0700395 /* Allocate the location map */
396 loc = (RegLocation*)oatNew(cUnit, cUnit->numSSARegs * sizeof(*loc), true,
397 kAllocRegAlloc);
398 for (i=0; i< cUnit->numSSARegs; i++) {
399 loc[i] = freshLoc;
400 loc[i].sRegLow = i;
buzbee2cfc6392012-05-07 14:51:40 -0700401 loc[i].isConst = oatIsBitSet(cUnit->isConstantV, i);
Bill Buzbeea114add2012-05-03 15:00:40 -0700402 }
403
404 /* Patch up the locations for Method* and the compiler temps */
405 loc[cUnit->methodSReg].location = kLocCompilerTemp;
406 loc[cUnit->methodSReg].defined = true;
407 for (i = 0; i < cUnit->numCompilerTemps; i++) {
408 CompilerTemp* ct = (CompilerTemp*)cUnit->compilerTemps.elemList[i];
409 loc[ct->sReg].location = kLocCompilerTemp;
410 loc[ct->sReg].defined = true;
411 }
412
413 cUnit->regLocation = loc;
414
415 /* Allocation the promotion map */
416 int numRegs = cUnit->numDalvikRegisters;
417 cUnit->promotionMap =
418 (PromotionMap*)oatNew(cUnit, (numRegs + cUnit->numCompilerTemps + 1) *
419 sizeof(cUnit->promotionMap[0]), true,
420 kAllocRegAlloc);
421
422 /* Add types of incoming arguments based on signature */
423 int numIns = cUnit->numIns;
424 if (numIns > 0) {
425 int sReg = numRegs - numIns;
426 if ((cUnit->access_flags & kAccStatic) == 0) {
427 // For non-static, skip past "this"
428 cUnit->regLocation[sReg].defined = true;
buzbeebff24652012-05-06 16:22:05 -0700429 cUnit->regLocation[sReg].ref = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700430 sReg++;
buzbee67bf8852011-08-17 17:51:35 -0700431 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700432 const char* shorty = cUnit->shorty;
433 int shorty_len = strlen(shorty);
434 for (int i = 1; i < shorty_len; i++) {
435 switch (shorty[i]) {
436 case 'D':
437 cUnit->regLocation[sReg].wide = true;
438 cUnit->regLocation[sReg+1].highWord = true;
439 cUnit->regLocation[sReg+1].fp = true;
440 DCHECK_EQ(SRegToVReg(cUnit, sReg)+1, SRegToVReg(cUnit, sReg+1));
441 cUnit->regLocation[sReg].fp = true;
442 cUnit->regLocation[sReg].defined = true;
443 sReg++;
444 break;
445 case 'J':
446 cUnit->regLocation[sReg].wide = true;
447 cUnit->regLocation[sReg+1].highWord = true;
448 DCHECK_EQ(SRegToVReg(cUnit, sReg)+1, SRegToVReg(cUnit, sReg+1));
449 cUnit->regLocation[sReg].core = true;
450 cUnit->regLocation[sReg].defined = true;
451 sReg++;
buzbeed5018892012-07-11 14:23:40 -0700452 break;
453 case 'F':
454 cUnit->regLocation[sReg].fp = true;
455 cUnit->regLocation[sReg].defined = true;
456 break;
457 case 'L':
458 cUnit->regLocation[sReg].ref = true;
459 cUnit->regLocation[sReg].defined = true;
460 break;
461 default:
462 cUnit->regLocation[sReg].core = true;
463 cUnit->regLocation[sReg].defined = true;
464 break;
buzbeee9a72f62011-09-04 17:59:07 -0700465 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700466 sReg++;
467 }
468 }
469
buzbee2cfc6392012-05-07 14:51:40 -0700470#if defined(ART_USE_QUICK_COMPILER)
471 if (!cUnit->genBitcode) {
472 /* Remap names */
473 oatDataFlowAnalysisDispatcher(cUnit, remapNames,
474 kPreOrderDFSTraversal,
475 false /* isIterative */);
476 }
477#else
Bill Buzbeea114add2012-05-03 15:00:40 -0700478 /* Remap names */
479 oatDataFlowAnalysisDispatcher(cUnit, remapNames,
480 kPreOrderDFSTraversal,
481 false /* isIterative */);
buzbee2cfc6392012-05-07 14:51:40 -0700482#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700483
484 /* Do type & size inference pass */
485 oatDataFlowAnalysisDispatcher(cUnit, inferTypeAndSize,
486 kPreOrderDFSTraversal,
487 true /* isIterative */);
488
489 /*
490 * Set the sRegLow field to refer to the pre-SSA name of the
491 * base Dalvik virtual register. Once we add a better register
492 * allocator, remove this remapping.
493 */
494 for (i=0; i < cUnit->numSSARegs; i++) {
495 if (cUnit->regLocation[i].location != kLocCompilerTemp) {
buzbee2cfc6392012-05-07 14:51:40 -0700496 int origSReg = cUnit->regLocation[i].sRegLow;
497 cUnit->regLocation[i].origSReg = origSReg;
498 cUnit->regLocation[i].sRegLow = SRegToVReg(cUnit, origSReg);
buzbeee9a72f62011-09-04 17:59:07 -0700499 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700500 }
buzbeee9a72f62011-09-04 17:59:07 -0700501
Bill Buzbeea114add2012-05-03 15:00:40 -0700502 cUnit->coreSpillMask = 0;
503 cUnit->fpSpillMask = 0;
504 cUnit->numCoreSpills = 0;
buzbeec0ecd652011-09-25 18:11:54 -0700505
Bill Buzbeea114add2012-05-03 15:00:40 -0700506 oatDoPromotion(cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700507
buzbeead8f15e2012-06-18 14:49:45 -0700508 /* Get easily-accessable post-promotion copy of RegLocation for Method* */
509 cUnit->methodLoc = cUnit->regLocation[cUnit->methodSReg];
510
Bill Buzbeea114add2012-05-03 15:00:40 -0700511 if (cUnit->printMe && !(cUnit->disableOpt & (1 << kPromoteRegs))) {
512 LOG(INFO) << "After Promotion";
513 oatDumpRegLocTable(cUnit->regLocation, cUnit->numSSARegs);
514 }
buzbee67bf8852011-08-17 17:51:35 -0700515
buzbeead8f15e2012-06-18 14:49:45 -0700516 /* Set the frame size */
517 cUnit->frameSize = oatComputeFrameSize(cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700518}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800519
520} // namespace art