blob: 29766e0ec396dd6d1105877871ed60db3c9b5249 [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
183 // Special-case handling for format 35c/3rc invokes
184 Instruction::Code opcode = mir->dalvikInsn.opcode;
185 int flags = (static_cast<int>(opcode) >= kNumPackedOpcodes)
186 ? 0 : Instruction::Flags(mir->dalvikInsn.opcode);
187 if ((flags & Instruction::kInvoke) &&
188 (attrs & (DF_FORMAT_35C | DF_FORMAT_3RC))) {
189 DCHECK_EQ(next, 0);
190 int target_idx = mir->dalvikInsn.vB;
191 const char* shorty = oatGetShortyFromTargetIdx(cUnit, target_idx);
192 // Handle result type if floating point
193 if ((shorty[0] == 'F') || (shorty[0] == 'D')) {
194 // Find move-result that consumes this result
buzbee52ed7762012-06-13 23:43:14 -0700195 SSARepresentation* tgtRep = findFPMoveResult(mir->next);
Bill Buzbeea114add2012-05-03 15:00:40 -0700196 // Might be in next basic block
197 if (!tgtRep) {
buzbee52ed7762012-06-13 23:43:14 -0700198 tgtRep = findFPMoveResult(bb->fallThrough->firstMIRInsn);
Bill Buzbeea114add2012-05-03 15:00:40 -0700199 }
200 // Result might not be used at all, so no move-result
201 if (tgtRep) {
202 tgtRep->fpDef[0] = true;
203 changed |= setFp(cUnit, tgtRep->defs[0], true);
204 if (shorty[0] == 'D') {
205 tgtRep->fpDef[1] = true;
206 changed |= setFp(cUnit, tgtRep->defs[1], true);
207 }
208 }
209 }
210 int numUses = mir->dalvikInsn.vA;
buzbeebff24652012-05-06 16:22:05 -0700211 // If this is a non-static invoke, mark implicit "this"
Bill Buzbeea114add2012-05-03 15:00:40 -0700212 if (((mir->dalvikInsn.opcode != Instruction::INVOKE_STATIC) &&
213 (mir->dalvikInsn.opcode != Instruction::INVOKE_STATIC_RANGE))) {
214 cUnit->regLocation[ssaRep->uses[next]].defined = true;
buzbeebff24652012-05-06 16:22:05 -0700215 cUnit->regLocation[ssaRep->uses[next]].ref = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700216 next++;
217 }
218 uint32_t cpos = 1;
219 if (strlen(shorty) > 1) {
220 for (int i = next; i < numUses;) {
221 DCHECK_LT(cpos, strlen(shorty));
222 switch (shorty[cpos++]) {
223 case 'D':
224 ssaRep->fpUse[i] = true;
225 ssaRep->fpUse[i+1] = true;
226 cUnit->regLocation[ssaRep->uses[i]].wide = true;
227 cUnit->regLocation[ssaRep->uses[i+1]].highWord = true;
228 DCHECK_EQ(SRegToVReg(cUnit, ssaRep->uses[i])+1,
229 SRegToVReg(cUnit, ssaRep->uses[i+1]));
230 i++;
231 break;
232 case 'J':
233 cUnit->regLocation[ssaRep->uses[i]].wide = true;
234 cUnit->regLocation[ssaRep->uses[i+1]].highWord = true;
235 DCHECK_EQ(SRegToVReg(cUnit, ssaRep->uses[i])+1,
236 SRegToVReg(cUnit, ssaRep->uses[i+1]));
237 changed |= setCore(cUnit, ssaRep->uses[i],true);
238 i++;
239 break;
240 case 'F':
241 ssaRep->fpUse[i] = true;
242 break;
buzbeebff24652012-05-06 16:22:05 -0700243 case 'L':
244 changed |= setRef(cUnit,ssaRep->uses[i], true);
245 break;
Bill Buzbeea114add2012-05-03 15:00:40 -0700246 default:
247 changed |= setCore(cUnit,ssaRep->uses[i], true);
248 break;
249 }
250 i++;
251 }
252 }
253 }
254
255 for (int i=0; ssaRep->fpUse && i< ssaRep->numUses; i++) {
256 if (ssaRep->fpUse[i])
257 changed |= setFp(cUnit, ssaRep->uses[i], true);
258 }
259 for (int i=0; ssaRep->fpDef && i< ssaRep->numDefs; i++) {
260 if (ssaRep->fpDef[i])
261 changed |= setFp(cUnit, ssaRep->defs[i], true);
262 }
263 // Special-case handling for moves & Phi
264 if (attrs & (DF_IS_MOVE | DF_NULL_TRANSFER_N)) {
265 // If any of our inputs or outputs is defined, set all
266 bool definedFP = false;
267 bool definedCore = false;
buzbeebff24652012-05-06 16:22:05 -0700268 bool definedRef = false;
Bill Buzbeea114add2012-05-03 15:00:40 -0700269 definedFP |= (cUnit->regLocation[ssaRep->defs[0]].defined &&
270 cUnit->regLocation[ssaRep->defs[0]].fp);
271 definedCore |= (cUnit->regLocation[ssaRep->defs[0]].defined &&
272 cUnit->regLocation[ssaRep->defs[0]].core);
buzbeebff24652012-05-06 16:22:05 -0700273 definedRef |= (cUnit->regLocation[ssaRep->defs[0]].defined &&
274 cUnit->regLocation[ssaRep->defs[0]].ref);
Bill Buzbeea114add2012-05-03 15:00:40 -0700275 for (int i = 0; i < ssaRep->numUses; i++) {
276 definedFP |= (cUnit->regLocation[ssaRep->uses[i]].defined &&
277 cUnit->regLocation[ssaRep->uses[i]].fp);
278 definedCore |= (cUnit->regLocation[ssaRep->uses[i]].defined
279 && cUnit->regLocation[ssaRep->uses[i]].core);
buzbeebff24652012-05-06 16:22:05 -0700280 definedRef |= (cUnit->regLocation[ssaRep->uses[i]].defined
281 && cUnit->regLocation[ssaRep->uses[i]].ref);
Bill Buzbeea114add2012-05-03 15:00:40 -0700282 }
283 /*
284 * TODO: cleaner fix
285 * We don't normally expect to see a Dalvik register
286 * definition used both as a floating point and core
287 * value. However, the instruction rewriting that occurs
288 * during verification can eliminate some type information,
289 * leaving us confused. The real fix here is either to
290 * add explicit type information to Dalvik byte codes,
291 * or to recognize THROW_VERIFICATION_ERROR as
292 * an unconditional branch and support dead code elimination.
293 * As a workaround we can detect this situation and
294 * disable register promotion (which is the only thing that
295 * relies on distinctions between core and fp usages.
296 */
buzbeebff24652012-05-06 16:22:05 -0700297 if ((definedFP && (definedCore | definedRef)) &&
Bill Buzbeea114add2012-05-03 15:00:40 -0700298 ((cUnit->disableOpt & (1 << kPromoteRegs)) == 0)) {
299 LOG(WARNING) << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
300 << " op at block " << bb->id
buzbeebff24652012-05-06 16:22:05 -0700301 << " has both fp and core/ref uses for same def.";
Bill Buzbeea114add2012-05-03 15:00:40 -0700302 cUnit->disableOpt |= (1 << kPromoteRegs);
303 }
304 changed |= setFp(cUnit, ssaRep->defs[0], definedFP);
305 changed |= setCore(cUnit, ssaRep->defs[0], definedCore);
buzbeebff24652012-05-06 16:22:05 -0700306 changed |= setRef(cUnit, ssaRep->defs[0], definedRef);
Bill Buzbeea114add2012-05-03 15:00:40 -0700307 for (int i = 0; i < ssaRep->numUses; i++) {
308 changed |= setFp(cUnit, ssaRep->uses[i], definedFP);
309 changed |= setCore(cUnit, ssaRep->uses[i], definedCore);
buzbeebff24652012-05-06 16:22:05 -0700310 changed |= setRef(cUnit, ssaRep->uses[i], definedRef);
Bill Buzbeea114add2012-05-03 15:00:40 -0700311 }
312 }
buzbee67bf8852011-08-17 17:51:35 -0700313 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700314 }
315 return changed;
buzbee67bf8852011-08-17 17:51:35 -0700316}
317
318static const char* storageName[] = {" Frame ", "PhysReg", " Spill "};
319
buzbeedfd3d702011-08-28 12:56:51 -0700320void oatDumpRegLocTable(RegLocation* table, int count)
buzbee67bf8852011-08-17 17:51:35 -0700321{
Bill Buzbeea114add2012-05-03 15:00:40 -0700322 for (int i = 0; i < count; i++) {
323 LOG(INFO) << StringPrintf("Loc[%02d] : %s, %c %c %c %c %c %c%d %c%d S%d",
324 i, storageName[table[i].location], table[i].wide ? 'W' : 'N',
325 table[i].defined ? 'D' : 'U', table[i].fp ? 'F' : 'C',
326 table[i].highWord ? 'H' : 'L', table[i].home ? 'h' : 't',
327 oatIsFpReg(table[i].lowReg) ? 's' : 'r',
328 table[i].lowReg & oatFpRegMask(),
329 oatIsFpReg(table[i].highReg) ? 's' : 'r',
330 table[i].highReg & oatFpRegMask(), table[i].sRegLow);
331 }
buzbee67bf8852011-08-17 17:51:35 -0700332}
333
buzbee6969d502012-06-15 16:40:31 -0700334void oatDumpRegLoc(RegLocation loc) {
335 oatDumpRegLocTable(&loc, 1);
336}
337
buzbee2cfc6392012-05-07 14:51:40 -0700338static const RegLocation freshLoc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0,
339 INVALID_REG, INVALID_REG, INVALID_SREG,
340 INVALID_SREG};
buzbee67bf8852011-08-17 17:51:35 -0700341
342/*
343 * Simple register allocation. Some Dalvik virtual registers may
344 * be promoted to physical registers. Most of the work for temp
Ian Rogersb5d09b22012-03-06 22:14:17 -0800345 * allocation is done on the fly. We also do some initialization and
buzbee67bf8852011-08-17 17:51:35 -0700346 * type inference here.
347 */
348void oatSimpleRegAlloc(CompilationUnit* cUnit)
349{
Bill Buzbeea114add2012-05-03 15:00:40 -0700350 int i;
351 RegLocation* loc;
buzbee67bf8852011-08-17 17:51:35 -0700352
Bill Buzbeea114add2012-05-03 15:00:40 -0700353 /* Allocate the location map */
354 loc = (RegLocation*)oatNew(cUnit, cUnit->numSSARegs * sizeof(*loc), true,
355 kAllocRegAlloc);
356 for (i=0; i< cUnit->numSSARegs; i++) {
357 loc[i] = freshLoc;
358 loc[i].sRegLow = i;
buzbee2cfc6392012-05-07 14:51:40 -0700359 loc[i].isConst = oatIsBitSet(cUnit->isConstantV, i);
Bill Buzbeea114add2012-05-03 15:00:40 -0700360 }
361
362 /* Patch up the locations for Method* and the compiler temps */
363 loc[cUnit->methodSReg].location = kLocCompilerTemp;
364 loc[cUnit->methodSReg].defined = true;
365 for (i = 0; i < cUnit->numCompilerTemps; i++) {
366 CompilerTemp* ct = (CompilerTemp*)cUnit->compilerTemps.elemList[i];
367 loc[ct->sReg].location = kLocCompilerTemp;
368 loc[ct->sReg].defined = true;
369 }
370
371 cUnit->regLocation = loc;
372
373 /* Allocation the promotion map */
374 int numRegs = cUnit->numDalvikRegisters;
375 cUnit->promotionMap =
376 (PromotionMap*)oatNew(cUnit, (numRegs + cUnit->numCompilerTemps + 1) *
377 sizeof(cUnit->promotionMap[0]), true,
378 kAllocRegAlloc);
379
380 /* Add types of incoming arguments based on signature */
381 int numIns = cUnit->numIns;
382 if (numIns > 0) {
383 int sReg = numRegs - numIns;
384 if ((cUnit->access_flags & kAccStatic) == 0) {
385 // For non-static, skip past "this"
386 cUnit->regLocation[sReg].defined = true;
buzbeebff24652012-05-06 16:22:05 -0700387 cUnit->regLocation[sReg].ref = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700388 sReg++;
buzbee67bf8852011-08-17 17:51:35 -0700389 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700390 const char* shorty = cUnit->shorty;
391 int shorty_len = strlen(shorty);
392 for (int i = 1; i < shorty_len; i++) {
393 switch (shorty[i]) {
394 case 'D':
395 cUnit->regLocation[sReg].wide = true;
396 cUnit->regLocation[sReg+1].highWord = true;
397 cUnit->regLocation[sReg+1].fp = true;
398 DCHECK_EQ(SRegToVReg(cUnit, sReg)+1, SRegToVReg(cUnit, sReg+1));
399 cUnit->regLocation[sReg].fp = true;
400 cUnit->regLocation[sReg].defined = true;
401 sReg++;
402 break;
403 case 'J':
404 cUnit->regLocation[sReg].wide = true;
405 cUnit->regLocation[sReg+1].highWord = true;
406 DCHECK_EQ(SRegToVReg(cUnit, sReg)+1, SRegToVReg(cUnit, sReg+1));
407 cUnit->regLocation[sReg].core = true;
408 cUnit->regLocation[sReg].defined = true;
409 sReg++;
410 break;
411 case 'F':
412 cUnit->regLocation[sReg].fp = true;
buzbee67bc2362011-10-11 18:08:40 -0700413 cUnit->regLocation[sReg].defined = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700414 break;
415 default:
buzbee67bc2362011-10-11 18:08:40 -0700416 cUnit->regLocation[sReg].core = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700417 cUnit->regLocation[sReg].defined = true;
418 break;
buzbeee9a72f62011-09-04 17:59:07 -0700419 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700420 sReg++;
421 }
422 }
423
buzbee2cfc6392012-05-07 14:51:40 -0700424#if defined(ART_USE_QUICK_COMPILER)
425 if (!cUnit->genBitcode) {
426 /* Remap names */
427 oatDataFlowAnalysisDispatcher(cUnit, remapNames,
428 kPreOrderDFSTraversal,
429 false /* isIterative */);
430 }
431#else
Bill Buzbeea114add2012-05-03 15:00:40 -0700432 /* Remap names */
433 oatDataFlowAnalysisDispatcher(cUnit, remapNames,
434 kPreOrderDFSTraversal,
435 false /* isIterative */);
buzbee2cfc6392012-05-07 14:51:40 -0700436#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700437
438 /* Do type & size inference pass */
439 oatDataFlowAnalysisDispatcher(cUnit, inferTypeAndSize,
440 kPreOrderDFSTraversal,
441 true /* isIterative */);
442
443 /*
444 * Set the sRegLow field to refer to the pre-SSA name of the
445 * base Dalvik virtual register. Once we add a better register
446 * allocator, remove this remapping.
447 */
448 for (i=0; i < cUnit->numSSARegs; i++) {
449 if (cUnit->regLocation[i].location != kLocCompilerTemp) {
buzbee2cfc6392012-05-07 14:51:40 -0700450 int origSReg = cUnit->regLocation[i].sRegLow;
451 cUnit->regLocation[i].origSReg = origSReg;
452 cUnit->regLocation[i].sRegLow = SRegToVReg(cUnit, origSReg);
buzbeee9a72f62011-09-04 17:59:07 -0700453 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700454 }
buzbeee9a72f62011-09-04 17:59:07 -0700455
Bill Buzbeea114add2012-05-03 15:00:40 -0700456 cUnit->coreSpillMask = 0;
457 cUnit->fpSpillMask = 0;
458 cUnit->numCoreSpills = 0;
buzbeec0ecd652011-09-25 18:11:54 -0700459
Bill Buzbeea114add2012-05-03 15:00:40 -0700460 oatDoPromotion(cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700461
Bill Buzbeea114add2012-05-03 15:00:40 -0700462 if (cUnit->printMe && !(cUnit->disableOpt & (1 << kPromoteRegs))) {
463 LOG(INFO) << "After Promotion";
464 oatDumpRegLocTable(cUnit->regLocation, cUnit->numSSARegs);
465 }
buzbee67bf8852011-08-17 17:51:35 -0700466
Bill Buzbeea114add2012-05-03 15:00:40 -0700467 /* Figure out the frame size */
468 static const uint32_t kAlignMask = kStackAlignment - 1;
469 uint32_t size = (cUnit->numCoreSpills + cUnit->numFPSpills +
470 1 /* filler word */ + cUnit->numRegs + cUnit->numOuts +
471 cUnit->numCompilerTemps + 1 /* curMethod* */)
472 * sizeof(uint32_t);
473 /* Align and set */
474 cUnit->frameSize = (size + kAlignMask) & ~(kAlignMask);
buzbee67bf8852011-08-17 17:51:35 -0700475}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800476
477} // namespace art