blob: e1689a68406b6262f2a314b045a2f155c3eca049 [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
buzbee31a4a6f2012-02-28 15:36:15 -080084SSARepresentation* findMoveResult(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) ||
buzbee15bf9802012-06-12 17:49:27 -070089 (mir->dalvikInsn.opcode == Instruction::MOVE_RESULT_OBJECT) ||
Bill Buzbeea114add2012-05-03 15:00:40 -070090 (mir->dalvikInsn.opcode == Instruction::MOVE_RESULT_WIDE)) {
91 res = mir->ssaRep;
92 break;
buzbee769fde12012-01-05 17:35:23 -080093 }
Bill Buzbeea114add2012-05-03 15:00:40 -070094 }
95 return res;
buzbee769fde12012-01-05 17:35:23 -080096}
97
buzbee67bf8852011-08-17 17:51:35 -070098/*
buzbee03fa2632011-09-20 17:10:57 -070099 * Infer types and sizes. We don't need to track change on sizes,
100 * as it doesn't propagate. We're guaranteed at least one pass through
101 * the cfg.
buzbee67bf8852011-08-17 17:51:35 -0700102 */
buzbee31a4a6f2012-02-28 15:36:15 -0800103bool inferTypeAndSize(CompilationUnit* cUnit, BasicBlock* bb)
buzbee67bf8852011-08-17 17:51:35 -0700104{
Bill Buzbeea114add2012-05-03 15:00:40 -0700105 MIR *mir;
106 bool changed = false; // Did anything change?
buzbee03fa2632011-09-20 17:10:57 -0700107
Bill Buzbeea114add2012-05-03 15:00:40 -0700108 if (bb->dataFlowInfo == NULL) return false;
109 if (bb->blockType != kDalvikByteCode && bb->blockType != kEntryBlock)
110 return false;
buzbee67bf8852011-08-17 17:51:35 -0700111
Bill Buzbeea114add2012-05-03 15:00:40 -0700112 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
113 SSARepresentation *ssaRep = mir->ssaRep;
114 if (ssaRep) {
115 int attrs = oatDataFlowAttributes[mir->dalvikInsn.opcode];
buzbee67bc2362011-10-11 18:08:40 -0700116
Bill Buzbeea114add2012-05-03 15:00:40 -0700117 // Handle defs
buzbeebff24652012-05-06 16:22:05 -0700118 if (attrs & DF_DA) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700119 if (attrs & DF_CORE_A) {
120 changed |= setCore(cUnit, ssaRep->defs[0], true);
buzbee67bf8852011-08-17 17:51:35 -0700121 }
buzbeebff24652012-05-06 16:22:05 -0700122 if (attrs & DF_REF_A) {
123 changed |= setRef(cUnit, ssaRep->defs[0], true);
124 }
125 if (attrs & DF_A_WIDE) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700126 cUnit->regLocation[ssaRep->defs[0]].wide = true;
127 cUnit->regLocation[ssaRep->defs[1]].highWord = true;
128 DCHECK_EQ(SRegToVReg(cUnit, ssaRep->defs[0])+1,
129 SRegToVReg(cUnit, ssaRep->defs[1]));
130 }
131 }
132
133 // Handles uses
134 int next = 0;
buzbeebff24652012-05-06 16:22:05 -0700135 if (attrs & DF_UA) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700136 if (attrs & DF_CORE_A) {
137 changed |= setCore(cUnit, ssaRep->uses[next], true);
138 }
buzbeebff24652012-05-06 16:22:05 -0700139 if (attrs & DF_REF_A) {
140 changed |= setRef(cUnit, ssaRep->uses[next], true);
141 }
142 if (attrs & DF_A_WIDE) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700143 cUnit->regLocation[ssaRep->uses[next]].wide = true;
144 cUnit->regLocation[ssaRep->uses[next + 1]].highWord = true;
145 DCHECK_EQ(SRegToVReg(cUnit, ssaRep->uses[next])+1,
146 SRegToVReg(cUnit, ssaRep->uses[next + 1]));
147 next += 2;
148 } else {
149 next++;
150 }
151 }
buzbeebff24652012-05-06 16:22:05 -0700152 if (attrs & DF_UB) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700153 if (attrs & DF_CORE_B) {
154 changed |= setCore(cUnit, ssaRep->uses[next], true);
155 }
buzbeebff24652012-05-06 16:22:05 -0700156 if (attrs & DF_REF_B) {
157 changed |= setRef(cUnit, ssaRep->uses[next], true);
158 }
159 if (attrs & DF_B_WIDE) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700160 cUnit->regLocation[ssaRep->uses[next]].wide = true;
161 cUnit->regLocation[ssaRep->uses[next + 1]].highWord = true;
162 DCHECK_EQ(SRegToVReg(cUnit, ssaRep->uses[next])+1,
163 SRegToVReg(cUnit, ssaRep->uses[next + 1]));
164 next += 2;
165 } else {
166 next++;
167 }
168 }
buzbeebff24652012-05-06 16:22:05 -0700169 if (attrs & DF_UC) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700170 if (attrs & DF_CORE_C) {
171 changed |= setCore(cUnit, ssaRep->uses[next], true);
172 }
buzbeebff24652012-05-06 16:22:05 -0700173 if (attrs & DF_REF_C) {
174 changed |= setRef(cUnit, ssaRep->uses[next], true);
175 }
176 if (attrs & DF_C_WIDE) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700177 cUnit->regLocation[ssaRep->uses[next]].wide = true;
178 cUnit->regLocation[ssaRep->uses[next + 1]].highWord = true;
179 DCHECK_EQ(SRegToVReg(cUnit, ssaRep->uses[next])+1,
180 SRegToVReg(cUnit, ssaRep->uses[next + 1]));
181 }
182 }
183
184 // Special-case handling for format 35c/3rc invokes
185 Instruction::Code opcode = mir->dalvikInsn.opcode;
186 int flags = (static_cast<int>(opcode) >= kNumPackedOpcodes)
187 ? 0 : Instruction::Flags(mir->dalvikInsn.opcode);
188 if ((flags & Instruction::kInvoke) &&
189 (attrs & (DF_FORMAT_35C | DF_FORMAT_3RC))) {
190 DCHECK_EQ(next, 0);
191 int target_idx = mir->dalvikInsn.vB;
192 const char* shorty = oatGetShortyFromTargetIdx(cUnit, target_idx);
193 // Handle result type if floating point
194 if ((shorty[0] == 'F') || (shorty[0] == 'D')) {
195 // Find move-result that consumes this result
196 SSARepresentation* tgtRep = findMoveResult(mir->next);
197 // Might be in next basic block
198 if (!tgtRep) {
199 tgtRep = findMoveResult(bb->fallThrough->firstMIRInsn);
200 }
201 // Result might not be used at all, so no move-result
202 if (tgtRep) {
203 tgtRep->fpDef[0] = true;
204 changed |= setFp(cUnit, tgtRep->defs[0], true);
205 if (shorty[0] == 'D') {
206 tgtRep->fpDef[1] = true;
207 changed |= setFp(cUnit, tgtRep->defs[1], true);
208 }
209 }
210 }
211 int numUses = mir->dalvikInsn.vA;
buzbeebff24652012-05-06 16:22:05 -0700212 // If this is a non-static invoke, mark implicit "this"
Bill Buzbeea114add2012-05-03 15:00:40 -0700213 if (((mir->dalvikInsn.opcode != Instruction::INVOKE_STATIC) &&
214 (mir->dalvikInsn.opcode != Instruction::INVOKE_STATIC_RANGE))) {
215 cUnit->regLocation[ssaRep->uses[next]].defined = true;
buzbeebff24652012-05-06 16:22:05 -0700216 cUnit->regLocation[ssaRep->uses[next]].ref = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700217 next++;
218 }
219 uint32_t cpos = 1;
220 if (strlen(shorty) > 1) {
221 for (int i = next; i < numUses;) {
222 DCHECK_LT(cpos, strlen(shorty));
223 switch (shorty[cpos++]) {
224 case 'D':
225 ssaRep->fpUse[i] = true;
226 ssaRep->fpUse[i+1] = true;
227 cUnit->regLocation[ssaRep->uses[i]].wide = true;
228 cUnit->regLocation[ssaRep->uses[i+1]].highWord = true;
229 DCHECK_EQ(SRegToVReg(cUnit, ssaRep->uses[i])+1,
230 SRegToVReg(cUnit, ssaRep->uses[i+1]));
231 i++;
232 break;
233 case 'J':
234 cUnit->regLocation[ssaRep->uses[i]].wide = true;
235 cUnit->regLocation[ssaRep->uses[i+1]].highWord = true;
236 DCHECK_EQ(SRegToVReg(cUnit, ssaRep->uses[i])+1,
237 SRegToVReg(cUnit, ssaRep->uses[i+1]));
238 changed |= setCore(cUnit, ssaRep->uses[i],true);
239 i++;
240 break;
241 case 'F':
242 ssaRep->fpUse[i] = true;
243 break;
buzbeebff24652012-05-06 16:22:05 -0700244 case 'L':
245 changed |= setRef(cUnit,ssaRep->uses[i], true);
246 break;
Bill Buzbeea114add2012-05-03 15:00:40 -0700247 default:
248 changed |= setCore(cUnit,ssaRep->uses[i], true);
249 break;
250 }
251 i++;
252 }
253 }
254 }
255
256 for (int i=0; ssaRep->fpUse && i< ssaRep->numUses; i++) {
257 if (ssaRep->fpUse[i])
258 changed |= setFp(cUnit, ssaRep->uses[i], true);
259 }
260 for (int i=0; ssaRep->fpDef && i< ssaRep->numDefs; i++) {
261 if (ssaRep->fpDef[i])
262 changed |= setFp(cUnit, ssaRep->defs[i], true);
263 }
264 // Special-case handling for moves & Phi
265 if (attrs & (DF_IS_MOVE | DF_NULL_TRANSFER_N)) {
266 // If any of our inputs or outputs is defined, set all
267 bool definedFP = false;
268 bool definedCore = false;
buzbeebff24652012-05-06 16:22:05 -0700269 bool definedRef = false;
Bill Buzbeea114add2012-05-03 15:00:40 -0700270 definedFP |= (cUnit->regLocation[ssaRep->defs[0]].defined &&
271 cUnit->regLocation[ssaRep->defs[0]].fp);
272 definedCore |= (cUnit->regLocation[ssaRep->defs[0]].defined &&
273 cUnit->regLocation[ssaRep->defs[0]].core);
buzbeebff24652012-05-06 16:22:05 -0700274 definedRef |= (cUnit->regLocation[ssaRep->defs[0]].defined &&
275 cUnit->regLocation[ssaRep->defs[0]].ref);
Bill Buzbeea114add2012-05-03 15:00:40 -0700276 for (int i = 0; i < ssaRep->numUses; i++) {
277 definedFP |= (cUnit->regLocation[ssaRep->uses[i]].defined &&
278 cUnit->regLocation[ssaRep->uses[i]].fp);
279 definedCore |= (cUnit->regLocation[ssaRep->uses[i]].defined
280 && cUnit->regLocation[ssaRep->uses[i]].core);
buzbeebff24652012-05-06 16:22:05 -0700281 definedRef |= (cUnit->regLocation[ssaRep->uses[i]].defined
282 && cUnit->regLocation[ssaRep->uses[i]].ref);
Bill Buzbeea114add2012-05-03 15:00:40 -0700283 }
284 /*
285 * TODO: cleaner fix
286 * We don't normally expect to see a Dalvik register
287 * definition used both as a floating point and core
288 * value. However, the instruction rewriting that occurs
289 * during verification can eliminate some type information,
290 * leaving us confused. The real fix here is either to
291 * add explicit type information to Dalvik byte codes,
292 * or to recognize THROW_VERIFICATION_ERROR as
293 * an unconditional branch and support dead code elimination.
294 * As a workaround we can detect this situation and
295 * disable register promotion (which is the only thing that
296 * relies on distinctions between core and fp usages.
297 */
buzbeebff24652012-05-06 16:22:05 -0700298 if ((definedFP && (definedCore | definedRef)) &&
Bill Buzbeea114add2012-05-03 15:00:40 -0700299 ((cUnit->disableOpt & (1 << kPromoteRegs)) == 0)) {
300 LOG(WARNING) << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
301 << " op at block " << bb->id
buzbeebff24652012-05-06 16:22:05 -0700302 << " has both fp and core/ref uses for same def.";
Bill Buzbeea114add2012-05-03 15:00:40 -0700303 cUnit->disableOpt |= (1 << kPromoteRegs);
304 }
305 changed |= setFp(cUnit, ssaRep->defs[0], definedFP);
306 changed |= setCore(cUnit, ssaRep->defs[0], definedCore);
buzbeebff24652012-05-06 16:22:05 -0700307 changed |= setRef(cUnit, ssaRep->defs[0], definedRef);
Bill Buzbeea114add2012-05-03 15:00:40 -0700308 for (int i = 0; i < ssaRep->numUses; i++) {
309 changed |= setFp(cUnit, ssaRep->uses[i], definedFP);
310 changed |= setCore(cUnit, ssaRep->uses[i], definedCore);
buzbeebff24652012-05-06 16:22:05 -0700311 changed |= setRef(cUnit, ssaRep->uses[i], definedRef);
Bill Buzbeea114add2012-05-03 15:00:40 -0700312 }
313 }
buzbee67bf8852011-08-17 17:51:35 -0700314 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700315 }
316 return changed;
buzbee67bf8852011-08-17 17:51:35 -0700317}
318
319static const char* storageName[] = {" Frame ", "PhysReg", " Spill "};
320
buzbeedfd3d702011-08-28 12:56:51 -0700321void oatDumpRegLocTable(RegLocation* table, int count)
buzbee67bf8852011-08-17 17:51:35 -0700322{
Bill Buzbeea114add2012-05-03 15:00:40 -0700323 for (int i = 0; i < count; i++) {
324 LOG(INFO) << StringPrintf("Loc[%02d] : %s, %c %c %c %c %c %c%d %c%d S%d",
325 i, storageName[table[i].location], table[i].wide ? 'W' : 'N',
326 table[i].defined ? 'D' : 'U', table[i].fp ? 'F' : 'C',
327 table[i].highWord ? 'H' : 'L', table[i].home ? 'h' : 't',
328 oatIsFpReg(table[i].lowReg) ? 's' : 'r',
329 table[i].lowReg & oatFpRegMask(),
330 oatIsFpReg(table[i].highReg) ? 's' : 'r',
331 table[i].highReg & oatFpRegMask(), table[i].sRegLow);
332 }
buzbee67bf8852011-08-17 17:51:35 -0700333}
334
buzbee2cfc6392012-05-07 14:51:40 -0700335static const RegLocation freshLoc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0,
336 INVALID_REG, INVALID_REG, INVALID_SREG,
337 INVALID_SREG};
buzbee67bf8852011-08-17 17:51:35 -0700338
339/*
340 * Simple register allocation. Some Dalvik virtual registers may
341 * be promoted to physical registers. Most of the work for temp
Ian Rogersb5d09b22012-03-06 22:14:17 -0800342 * allocation is done on the fly. We also do some initialization and
buzbee67bf8852011-08-17 17:51:35 -0700343 * type inference here.
344 */
345void oatSimpleRegAlloc(CompilationUnit* cUnit)
346{
Bill Buzbeea114add2012-05-03 15:00:40 -0700347 int i;
348 RegLocation* loc;
buzbee67bf8852011-08-17 17:51:35 -0700349
Bill Buzbeea114add2012-05-03 15:00:40 -0700350 /* Allocate the location map */
351 loc = (RegLocation*)oatNew(cUnit, cUnit->numSSARegs * sizeof(*loc), true,
352 kAllocRegAlloc);
353 for (i=0; i< cUnit->numSSARegs; i++) {
354 loc[i] = freshLoc;
355 loc[i].sRegLow = i;
buzbee2cfc6392012-05-07 14:51:40 -0700356 loc[i].isConst = oatIsBitSet(cUnit->isConstantV, i);
Bill Buzbeea114add2012-05-03 15:00:40 -0700357 }
358
359 /* Patch up the locations for Method* and the compiler temps */
360 loc[cUnit->methodSReg].location = kLocCompilerTemp;
361 loc[cUnit->methodSReg].defined = true;
362 for (i = 0; i < cUnit->numCompilerTemps; i++) {
363 CompilerTemp* ct = (CompilerTemp*)cUnit->compilerTemps.elemList[i];
364 loc[ct->sReg].location = kLocCompilerTemp;
365 loc[ct->sReg].defined = true;
366 }
367
368 cUnit->regLocation = loc;
369
370 /* Allocation the promotion map */
371 int numRegs = cUnit->numDalvikRegisters;
372 cUnit->promotionMap =
373 (PromotionMap*)oatNew(cUnit, (numRegs + cUnit->numCompilerTemps + 1) *
374 sizeof(cUnit->promotionMap[0]), true,
375 kAllocRegAlloc);
376
377 /* Add types of incoming arguments based on signature */
378 int numIns = cUnit->numIns;
379 if (numIns > 0) {
380 int sReg = numRegs - numIns;
381 if ((cUnit->access_flags & kAccStatic) == 0) {
382 // For non-static, skip past "this"
383 cUnit->regLocation[sReg].defined = true;
buzbeebff24652012-05-06 16:22:05 -0700384 cUnit->regLocation[sReg].ref = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700385 sReg++;
buzbee67bf8852011-08-17 17:51:35 -0700386 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700387 const char* shorty = cUnit->shorty;
388 int shorty_len = strlen(shorty);
389 for (int i = 1; i < shorty_len; i++) {
390 switch (shorty[i]) {
391 case 'D':
392 cUnit->regLocation[sReg].wide = true;
393 cUnit->regLocation[sReg+1].highWord = true;
394 cUnit->regLocation[sReg+1].fp = true;
395 DCHECK_EQ(SRegToVReg(cUnit, sReg)+1, SRegToVReg(cUnit, sReg+1));
396 cUnit->regLocation[sReg].fp = true;
397 cUnit->regLocation[sReg].defined = true;
398 sReg++;
399 break;
400 case 'J':
401 cUnit->regLocation[sReg].wide = true;
402 cUnit->regLocation[sReg+1].highWord = true;
403 DCHECK_EQ(SRegToVReg(cUnit, sReg)+1, SRegToVReg(cUnit, sReg+1));
404 cUnit->regLocation[sReg].core = true;
405 cUnit->regLocation[sReg].defined = true;
406 sReg++;
407 break;
408 case 'F':
409 cUnit->regLocation[sReg].fp = true;
buzbee67bc2362011-10-11 18:08:40 -0700410 cUnit->regLocation[sReg].defined = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700411 break;
412 default:
buzbee67bc2362011-10-11 18:08:40 -0700413 cUnit->regLocation[sReg].core = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700414 cUnit->regLocation[sReg].defined = true;
415 break;
buzbeee9a72f62011-09-04 17:59:07 -0700416 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700417 sReg++;
418 }
419 }
420
buzbee2cfc6392012-05-07 14:51:40 -0700421#if defined(ART_USE_QUICK_COMPILER)
422 if (!cUnit->genBitcode) {
423 /* Remap names */
424 oatDataFlowAnalysisDispatcher(cUnit, remapNames,
425 kPreOrderDFSTraversal,
426 false /* isIterative */);
427 }
428#else
Bill Buzbeea114add2012-05-03 15:00:40 -0700429 /* Remap names */
430 oatDataFlowAnalysisDispatcher(cUnit, remapNames,
431 kPreOrderDFSTraversal,
432 false /* isIterative */);
buzbee2cfc6392012-05-07 14:51:40 -0700433#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700434
435 /* Do type & size inference pass */
436 oatDataFlowAnalysisDispatcher(cUnit, inferTypeAndSize,
437 kPreOrderDFSTraversal,
438 true /* isIterative */);
439
440 /*
441 * Set the sRegLow field to refer to the pre-SSA name of the
442 * base Dalvik virtual register. Once we add a better register
443 * allocator, remove this remapping.
444 */
445 for (i=0; i < cUnit->numSSARegs; i++) {
446 if (cUnit->regLocation[i].location != kLocCompilerTemp) {
buzbee2cfc6392012-05-07 14:51:40 -0700447 int origSReg = cUnit->regLocation[i].sRegLow;
448 cUnit->regLocation[i].origSReg = origSReg;
449 cUnit->regLocation[i].sRegLow = SRegToVReg(cUnit, origSReg);
buzbeee9a72f62011-09-04 17:59:07 -0700450 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700451 }
buzbeee9a72f62011-09-04 17:59:07 -0700452
Bill Buzbeea114add2012-05-03 15:00:40 -0700453 cUnit->coreSpillMask = 0;
454 cUnit->fpSpillMask = 0;
455 cUnit->numCoreSpills = 0;
buzbeec0ecd652011-09-25 18:11:54 -0700456
Bill Buzbeea114add2012-05-03 15:00:40 -0700457 oatDoPromotion(cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700458
Bill Buzbeea114add2012-05-03 15:00:40 -0700459 if (cUnit->printMe && !(cUnit->disableOpt & (1 << kPromoteRegs))) {
460 LOG(INFO) << "After Promotion";
461 oatDumpRegLocTable(cUnit->regLocation, cUnit->numSSARegs);
462 }
buzbee67bf8852011-08-17 17:51:35 -0700463
Bill Buzbeea114add2012-05-03 15:00:40 -0700464 /* Figure out the frame size */
465 static const uint32_t kAlignMask = kStackAlignment - 1;
466 uint32_t size = (cUnit->numCoreSpills + cUnit->numFPSpills +
467 1 /* filler word */ + cUnit->numRegs + cUnit->numOuts +
468 cUnit->numCompilerTemps + 1 /* curMethod* */)
469 * sizeof(uint32_t);
470 /* Align and set */
471 cUnit->frameSize = (size + kAlignMask) & ~(kAlignMask);
buzbee67bf8852011-08-17 17:51:35 -0700472}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800473
474} // namespace art