blob: d4223f1ab14834f86cc7070ca2671c17b96a9def [file] [log] [blame]
buzbee311ca162013-02-28 15:56:43 -08001/*
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 "compiler_internals.h"
18#include "dataflow_iterator.h"
buzbee311ca162013-02-28 15:56:43 -080019
20namespace art {
21
buzbee1fd33462013-03-25 13:40:45 -070022bool MIRGraph::SetFp(int index, bool is_fp) {
buzbee311ca162013-02-28 15:56:43 -080023 bool change = false;
buzbee1fd33462013-03-25 13:40:45 -070024 if (is_fp && !reg_location_[index].fp) {
25 reg_location_[index].fp = true;
26 reg_location_[index].defined = true;
buzbee311ca162013-02-28 15:56:43 -080027 change = true;
28 }
29 return change;
30}
31
buzbee1fd33462013-03-25 13:40:45 -070032bool MIRGraph::SetCore(int index, bool is_core) {
buzbee311ca162013-02-28 15:56:43 -080033 bool change = false;
buzbee1fd33462013-03-25 13:40:45 -070034 if (is_core && !reg_location_[index].defined) {
35 reg_location_[index].core = true;
36 reg_location_[index].defined = true;
buzbee311ca162013-02-28 15:56:43 -080037 change = true;
38 }
39 return change;
40}
41
buzbee1fd33462013-03-25 13:40:45 -070042bool MIRGraph::SetRef(int index, bool is_ref) {
buzbee311ca162013-02-28 15:56:43 -080043 bool change = false;
buzbee1fd33462013-03-25 13:40:45 -070044 if (is_ref && !reg_location_[index].defined) {
45 reg_location_[index].ref = true;
46 reg_location_[index].defined = true;
buzbee311ca162013-02-28 15:56:43 -080047 change = true;
48 }
49 return change;
50}
51
buzbee1fd33462013-03-25 13:40:45 -070052bool MIRGraph::SetWide(int index, bool is_wide) {
buzbee311ca162013-02-28 15:56:43 -080053 bool change = false;
buzbee1fd33462013-03-25 13:40:45 -070054 if (is_wide && !reg_location_[index].wide) {
55 reg_location_[index].wide = true;
buzbee311ca162013-02-28 15:56:43 -080056 change = true;
57 }
58 return change;
59}
60
buzbee1fd33462013-03-25 13:40:45 -070061bool MIRGraph::SetHigh(int index, bool is_high) {
buzbee311ca162013-02-28 15:56:43 -080062 bool change = false;
buzbee1fd33462013-03-25 13:40:45 -070063 if (is_high && !reg_location_[index].high_word) {
64 reg_location_[index].high_word = true;
buzbee311ca162013-02-28 15:56:43 -080065 change = true;
66 }
67 return change;
68}
69
70/*
71 * Infer types and sizes. We don't need to track change on sizes,
72 * as it doesn't propagate. We're guaranteed at least one pass through
73 * the cfg.
74 */
75bool MIRGraph::InferTypeAndSize(BasicBlock* bb)
76{
77 MIR *mir;
78 bool changed = false; // Did anything change?
79
80 if (bb->data_flow_info == NULL) return false;
81 if (bb->block_type != kDalvikByteCode && bb->block_type != kEntryBlock)
82 return false;
83
84 for (mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
85 SSARepresentation *ssa_rep = mir->ssa_rep;
86 if (ssa_rep) {
buzbee1fd33462013-03-25 13:40:45 -070087 int attrs = oat_data_flow_attributes_[mir->dalvikInsn.opcode];
buzbee311ca162013-02-28 15:56:43 -080088
89 // Handle defs
90 if (attrs & DF_DA) {
91 if (attrs & DF_CORE_A) {
buzbee1fd33462013-03-25 13:40:45 -070092 changed |= SetCore(ssa_rep->defs[0], true);
buzbee311ca162013-02-28 15:56:43 -080093 }
94 if (attrs & DF_REF_A) {
buzbee1fd33462013-03-25 13:40:45 -070095 changed |= SetRef(ssa_rep->defs[0], true);
buzbee311ca162013-02-28 15:56:43 -080096 }
97 if (attrs & DF_A_WIDE) {
buzbee1fd33462013-03-25 13:40:45 -070098 reg_location_[ssa_rep->defs[0]].wide = true;
99 reg_location_[ssa_rep->defs[1]].wide = true;
100 reg_location_[ssa_rep->defs[1]].high_word = true;
buzbee311ca162013-02-28 15:56:43 -0800101 DCHECK_EQ(SRegToVReg(ssa_rep->defs[0])+1,
102 SRegToVReg(ssa_rep->defs[1]));
103 }
104 }
105
106 // Handles uses
107 int next = 0;
108 if (attrs & DF_UA) {
109 if (attrs & DF_CORE_A) {
buzbee1fd33462013-03-25 13:40:45 -0700110 changed |= SetCore(ssa_rep->uses[next], true);
buzbee311ca162013-02-28 15:56:43 -0800111 }
112 if (attrs & DF_REF_A) {
buzbee1fd33462013-03-25 13:40:45 -0700113 changed |= SetRef(ssa_rep->uses[next], true);
buzbee311ca162013-02-28 15:56:43 -0800114 }
115 if (attrs & DF_A_WIDE) {
buzbee1fd33462013-03-25 13:40:45 -0700116 reg_location_[ssa_rep->uses[next]].wide = true;
117 reg_location_[ssa_rep->uses[next + 1]].wide = true;
118 reg_location_[ssa_rep->uses[next + 1]].high_word = true;
buzbee311ca162013-02-28 15:56:43 -0800119 DCHECK_EQ(SRegToVReg(ssa_rep->uses[next])+1,
120 SRegToVReg(ssa_rep->uses[next + 1]));
121 next += 2;
122 } else {
123 next++;
124 }
125 }
126 if (attrs & DF_UB) {
127 if (attrs & DF_CORE_B) {
buzbee1fd33462013-03-25 13:40:45 -0700128 changed |= SetCore(ssa_rep->uses[next], true);
buzbee311ca162013-02-28 15:56:43 -0800129 }
130 if (attrs & DF_REF_B) {
buzbee1fd33462013-03-25 13:40:45 -0700131 changed |= SetRef(ssa_rep->uses[next], true);
buzbee311ca162013-02-28 15:56:43 -0800132 }
133 if (attrs & DF_B_WIDE) {
buzbee1fd33462013-03-25 13:40:45 -0700134 reg_location_[ssa_rep->uses[next]].wide = true;
135 reg_location_[ssa_rep->uses[next + 1]].wide = true;
136 reg_location_[ssa_rep->uses[next + 1]].high_word = true;
buzbee311ca162013-02-28 15:56:43 -0800137 DCHECK_EQ(SRegToVReg(ssa_rep->uses[next])+1,
138 SRegToVReg(ssa_rep->uses[next + 1]));
139 next += 2;
140 } else {
141 next++;
142 }
143 }
144 if (attrs & DF_UC) {
145 if (attrs & DF_CORE_C) {
buzbee1fd33462013-03-25 13:40:45 -0700146 changed |= SetCore(ssa_rep->uses[next], true);
buzbee311ca162013-02-28 15:56:43 -0800147 }
148 if (attrs & DF_REF_C) {
buzbee1fd33462013-03-25 13:40:45 -0700149 changed |= SetRef(ssa_rep->uses[next], true);
buzbee311ca162013-02-28 15:56:43 -0800150 }
151 if (attrs & DF_C_WIDE) {
buzbee1fd33462013-03-25 13:40:45 -0700152 reg_location_[ssa_rep->uses[next]].wide = true;
153 reg_location_[ssa_rep->uses[next + 1]].wide = true;
154 reg_location_[ssa_rep->uses[next + 1]].high_word = true;
buzbee311ca162013-02-28 15:56:43 -0800155 DCHECK_EQ(SRegToVReg(ssa_rep->uses[next])+1,
156 SRegToVReg(ssa_rep->uses[next + 1]));
157 }
158 }
159
160 // Special-case return handling
161 if ((mir->dalvikInsn.opcode == Instruction::RETURN) ||
162 (mir->dalvikInsn.opcode == Instruction::RETURN_WIDE) ||
163 (mir->dalvikInsn.opcode == Instruction::RETURN_OBJECT)) {
164 switch(cu_->shorty[0]) {
165 case 'I':
buzbee1fd33462013-03-25 13:40:45 -0700166 changed |= SetCore(ssa_rep->uses[0], true);
buzbee311ca162013-02-28 15:56:43 -0800167 break;
168 case 'J':
buzbee1fd33462013-03-25 13:40:45 -0700169 changed |= SetCore(ssa_rep->uses[0], true);
170 changed |= SetCore(ssa_rep->uses[1], true);
171 reg_location_[ssa_rep->uses[0]].wide = true;
172 reg_location_[ssa_rep->uses[1]].wide = true;
173 reg_location_[ssa_rep->uses[1]].high_word = true;
buzbee311ca162013-02-28 15:56:43 -0800174 break;
175 case 'F':
buzbee1fd33462013-03-25 13:40:45 -0700176 changed |= SetFp(ssa_rep->uses[0], true);
buzbee311ca162013-02-28 15:56:43 -0800177 break;
178 case 'D':
buzbee1fd33462013-03-25 13:40:45 -0700179 changed |= SetFp(ssa_rep->uses[0], true);
180 changed |= SetFp(ssa_rep->uses[1], true);
181 reg_location_[ssa_rep->uses[0]].wide = true;
182 reg_location_[ssa_rep->uses[1]].wide = true;
183 reg_location_[ssa_rep->uses[1]].high_word = true;
buzbee311ca162013-02-28 15:56:43 -0800184 break;
185 case 'L':
buzbee1fd33462013-03-25 13:40:45 -0700186 changed |= SetRef(ssa_rep->uses[0], true);
buzbee311ca162013-02-28 15:56:43 -0800187 break;
188 default: break;
189 }
190 }
191
192 // Special-case handling for format 35c/3rc invokes
193 Instruction::Code opcode = mir->dalvikInsn.opcode;
194 int flags = (static_cast<int>(opcode) >= kNumPackedOpcodes)
195 ? 0 : Instruction::FlagsOf(mir->dalvikInsn.opcode);
196 if ((flags & Instruction::kInvoke) &&
197 (attrs & (DF_FORMAT_35C | DF_FORMAT_3RC))) {
198 DCHECK_EQ(next, 0);
199 int target_idx = mir->dalvikInsn.vB;
buzbee1fd33462013-03-25 13:40:45 -0700200 const char* shorty = GetShortyFromTargetIdx(target_idx);
buzbee311ca162013-02-28 15:56:43 -0800201 // Handle result type if floating point
202 if ((shorty[0] == 'F') || (shorty[0] == 'D')) {
203 MIR* move_result_mir = FindMoveResult(bb, mir);
204 // Result might not be used at all, so no move-result
205 if (move_result_mir && (move_result_mir->dalvikInsn.opcode !=
206 Instruction::MOVE_RESULT_OBJECT)) {
207 SSARepresentation* tgt_rep = move_result_mir->ssa_rep;
208 DCHECK(tgt_rep != NULL);
209 tgt_rep->fp_def[0] = true;
buzbee1fd33462013-03-25 13:40:45 -0700210 changed |= SetFp(tgt_rep->defs[0], true);
buzbee311ca162013-02-28 15:56:43 -0800211 if (shorty[0] == 'D') {
212 tgt_rep->fp_def[1] = true;
buzbee1fd33462013-03-25 13:40:45 -0700213 changed |= SetFp(tgt_rep->defs[1], true);
buzbee311ca162013-02-28 15:56:43 -0800214 }
215 }
216 }
217 int num_uses = mir->dalvikInsn.vA;
218 // If this is a non-static invoke, mark implicit "this"
219 if (((mir->dalvikInsn.opcode != Instruction::INVOKE_STATIC) &&
220 (mir->dalvikInsn.opcode != Instruction::INVOKE_STATIC_RANGE))) {
buzbee1fd33462013-03-25 13:40:45 -0700221 reg_location_[ssa_rep->uses[next]].defined = true;
222 reg_location_[ssa_rep->uses[next]].ref = true;
buzbee311ca162013-02-28 15:56:43 -0800223 next++;
224 }
225 uint32_t cpos = 1;
226 if (strlen(shorty) > 1) {
227 for (int i = next; i < num_uses;) {
228 DCHECK_LT(cpos, strlen(shorty));
229 switch (shorty[cpos++]) {
230 case 'D':
231 ssa_rep->fp_use[i] = true;
232 ssa_rep->fp_use[i+1] = true;
buzbee1fd33462013-03-25 13:40:45 -0700233 reg_location_[ssa_rep->uses[i]].wide = true;
234 reg_location_[ssa_rep->uses[i+1]].wide = true;
235 reg_location_[ssa_rep->uses[i+1]].high_word = true;
buzbee311ca162013-02-28 15:56:43 -0800236 DCHECK_EQ(SRegToVReg(ssa_rep->uses[i])+1, SRegToVReg(ssa_rep->uses[i+1]));
237 i++;
238 break;
239 case 'J':
buzbee1fd33462013-03-25 13:40:45 -0700240 reg_location_[ssa_rep->uses[i]].wide = true;
241 reg_location_[ssa_rep->uses[i+1]].wide = true;
242 reg_location_[ssa_rep->uses[i+1]].high_word = true;
buzbee311ca162013-02-28 15:56:43 -0800243 DCHECK_EQ(SRegToVReg(ssa_rep->uses[i])+1, SRegToVReg(ssa_rep->uses[i+1]));
buzbee1fd33462013-03-25 13:40:45 -0700244 changed |= SetCore(ssa_rep->uses[i],true);
buzbee311ca162013-02-28 15:56:43 -0800245 i++;
246 break;
247 case 'F':
248 ssa_rep->fp_use[i] = true;
249 break;
250 case 'L':
buzbee1fd33462013-03-25 13:40:45 -0700251 changed |= SetRef(ssa_rep->uses[i], true);
buzbee311ca162013-02-28 15:56:43 -0800252 break;
253 default:
buzbee1fd33462013-03-25 13:40:45 -0700254 changed |= SetCore(ssa_rep->uses[i], true);
buzbee311ca162013-02-28 15:56:43 -0800255 break;
256 }
257 i++;
258 }
259 }
260 }
261
262 for (int i=0; ssa_rep->fp_use && i< ssa_rep->num_uses; i++) {
263 if (ssa_rep->fp_use[i])
buzbee1fd33462013-03-25 13:40:45 -0700264 changed |= SetFp(ssa_rep->uses[i], true);
buzbee311ca162013-02-28 15:56:43 -0800265 }
266 for (int i=0; ssa_rep->fp_def && i< ssa_rep->num_defs; i++) {
267 if (ssa_rep->fp_def[i])
buzbee1fd33462013-03-25 13:40:45 -0700268 changed |= SetFp(ssa_rep->defs[i], true);
buzbee311ca162013-02-28 15:56:43 -0800269 }
270 // Special-case handling for moves & Phi
271 if (attrs & (DF_IS_MOVE | DF_NULL_TRANSFER_N)) {
272 /*
273 * If any of our inputs or outputs is defined, set all.
274 * Some ugliness related to Phi nodes and wide values.
275 * The Phi set will include all low words or all high
276 * words, so we have to treat them specially.
277 */
278 bool is_phi = (static_cast<int>(mir->dalvikInsn.opcode) ==
279 kMirOpPhi);
buzbee1fd33462013-03-25 13:40:45 -0700280 RegLocation rl_temp = reg_location_[ssa_rep->defs[0]];
buzbee311ca162013-02-28 15:56:43 -0800281 bool defined_fp = rl_temp.defined && rl_temp.fp;
282 bool defined_core = rl_temp.defined && rl_temp.core;
283 bool defined_ref = rl_temp.defined && rl_temp.ref;
284 bool is_wide = rl_temp.wide || ((attrs & DF_A_WIDE) != 0);
285 bool is_high = is_phi && rl_temp.wide && rl_temp.high_word;
286 for (int i = 0; i < ssa_rep->num_uses;i++) {
buzbee1fd33462013-03-25 13:40:45 -0700287 rl_temp = reg_location_[ssa_rep->uses[i]];
buzbee311ca162013-02-28 15:56:43 -0800288 defined_fp |= rl_temp.defined && rl_temp.fp;
289 defined_core |= rl_temp.defined && rl_temp.core;
290 defined_ref |= rl_temp.defined && rl_temp.ref;
291 is_wide |= rl_temp.wide;
292 is_high |= is_phi && rl_temp.wide && rl_temp.high_word;
293 }
294 /*
295 * TODO: cleaner fix
296 * We don't normally expect to see a Dalvik register
297 * definition used both as a floating point and core
298 * value. However, the instruction rewriting that occurs
299 * during verification can eliminate some type information,
300 * leaving us confused. The real fix here is either to
301 * add explicit type information to Dalvik byte codes,
302 * or to recognize THROW_VERIFICATION_ERROR as
303 * an unconditional branch and support dead code elimination.
304 * As a workaround we can detect this situation and
305 * disable register promotion (which is the only thing that
306 * relies on distinctions between core and fp usages.
307 */
308 if ((defined_fp && (defined_core | defined_ref)) &&
309 ((cu_->disable_opt & (1 << kPromoteRegs)) == 0)) {
310 LOG(WARNING) << PrettyMethod(cu_->method_idx, *cu_->dex_file)
311 << " op at block " << bb->id
312 << " has both fp and core/ref uses for same def.";
313 cu_->disable_opt |= (1 << kPromoteRegs);
314 }
buzbee1fd33462013-03-25 13:40:45 -0700315 changed |= SetFp(ssa_rep->defs[0], defined_fp);
316 changed |= SetCore(ssa_rep->defs[0], defined_core);
317 changed |= SetRef(ssa_rep->defs[0], defined_ref);
318 changed |= SetWide(ssa_rep->defs[0], is_wide);
319 changed |= SetHigh(ssa_rep->defs[0], is_high);
buzbee311ca162013-02-28 15:56:43 -0800320 if (attrs & DF_A_WIDE) {
buzbee1fd33462013-03-25 13:40:45 -0700321 changed |= SetWide(ssa_rep->defs[1], true);
322 changed |= SetHigh(ssa_rep->defs[1], true);
buzbee311ca162013-02-28 15:56:43 -0800323 }
324 for (int i = 0; i < ssa_rep->num_uses; i++) {
buzbee1fd33462013-03-25 13:40:45 -0700325 changed |= SetFp(ssa_rep->uses[i], defined_fp);
326 changed |= SetCore(ssa_rep->uses[i], defined_core);
327 changed |= SetRef(ssa_rep->uses[i], defined_ref);
328 changed |= SetWide(ssa_rep->uses[i], is_wide);
329 changed |= SetHigh(ssa_rep->uses[i], is_high);
buzbee311ca162013-02-28 15:56:43 -0800330 }
331 if (attrs & DF_A_WIDE) {
332 DCHECK_EQ(ssa_rep->num_uses, 2);
buzbee1fd33462013-03-25 13:40:45 -0700333 changed |= SetWide(ssa_rep->uses[1], true);
334 changed |= SetHigh(ssa_rep->uses[1], true);
buzbee311ca162013-02-28 15:56:43 -0800335 }
336 }
337 }
338 }
339 return changed;
340}
341
342static const char* storage_name[] = {" Frame ", "PhysReg", " Spill "};
343
344void MIRGraph::DumpRegLocTable(RegLocation* table, int count)
345{
buzbee1fd33462013-03-25 13:40:45 -0700346 //FIXME: Quick-specific. Move to Quick (and make a generic version for MIRGraph?
347 Mir2Lir* cg = static_cast<Mir2Lir*>(cu_->cg.get());
buzbee311ca162013-02-28 15:56:43 -0800348 if (cg != NULL) {
349 for (int i = 0; i < count; i++) {
350 LOG(INFO) << StringPrintf("Loc[%02d] : %s, %c %c %c %c %c %c %c%d %c%d S%d",
351 table[i].orig_sreg, storage_name[table[i].location],
352 table[i].wide ? 'W' : 'N', table[i].defined ? 'D' : 'U',
353 table[i].fp ? 'F' : table[i].ref ? 'R' :'C',
354 table[i].is_const ? 'c' : 'n',
355 table[i].high_word ? 'H' : 'L', table[i].home ? 'h' : 't',
356 cg->IsFpReg(table[i].low_reg) ? 's' : 'r',
357 table[i].low_reg & cg->FpRegMask(),
358 cg->IsFpReg(table[i].high_reg) ? 's' : 'r',
359 table[i].high_reg & cg->FpRegMask(), table[i].s_reg_low);
360 }
361 } else {
362 // Either pre-regalloc or Portable.
363 for (int i = 0; i < count; i++) {
364 LOG(INFO) << StringPrintf("Loc[%02d] : %s, %c %c %c %c %c %c S%d",
365 table[i].orig_sreg, storage_name[table[i].location],
366 table[i].wide ? 'W' : 'N', table[i].defined ? 'D' : 'U',
367 table[i].fp ? 'F' : table[i].ref ? 'R' :'C',
368 table[i].is_const ? 'c' : 'n',
369 table[i].high_word ? 'H' : 'L', table[i].home ? 'h' : 't',
370 table[i].s_reg_low);
371 }
372 }
373}
374
375static const RegLocation fresh_loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0,
376 INVALID_REG, INVALID_REG, INVALID_SREG,
377 INVALID_SREG};
378
buzbee311ca162013-02-28 15:56:43 -0800379/*
380 * Simple register allocation. Some Dalvik virtual registers may
381 * be promoted to physical registers. Most of the work for temp
382 * allocation is done on the fly. We also do some initialization and
383 * type inference here.
384 */
385void MIRGraph::BuildRegLocations()
386{
387 int i;
388 RegLocation* loc;
389
390 /* Allocate the location map */
buzbee862a7602013-04-05 10:58:54 -0700391 loc = static_cast<RegLocation*>(arena_->NewMem(GetNumSSARegs() * sizeof(*loc), true,
392 ArenaAllocator::kAllocRegAlloc));
buzbee311ca162013-02-28 15:56:43 -0800393 for (i=0; i < GetNumSSARegs(); i++) {
394 loc[i] = fresh_loc;
395 loc[i].s_reg_low = i;
buzbee862a7602013-04-05 10:58:54 -0700396 loc[i].is_const = is_constant_v_->IsBitSet(i);
buzbee311ca162013-02-28 15:56:43 -0800397 }
398
399 /* Patch up the locations for Method* and the compiler temps */
buzbee1fd33462013-03-25 13:40:45 -0700400 loc[method_sreg_].location = kLocCompilerTemp;
401 loc[method_sreg_].defined = true;
buzbee311ca162013-02-28 15:56:43 -0800402 for (i = 0; i < cu_->num_compiler_temps; i++) {
buzbee862a7602013-04-05 10:58:54 -0700403 CompilerTemp* ct = compiler_temps_.Get(i);
buzbee311ca162013-02-28 15:56:43 -0800404 loc[ct->s_reg].location = kLocCompilerTemp;
405 loc[ct->s_reg].defined = true;
406 }
407
buzbee1fd33462013-03-25 13:40:45 -0700408 reg_location_ = loc;
buzbee311ca162013-02-28 15:56:43 -0800409
buzbee311ca162013-02-28 15:56:43 -0800410 int num_regs = cu_->num_dalvik_registers;
buzbee311ca162013-02-28 15:56:43 -0800411
412 /* Add types of incoming arguments based on signature */
413 int num_ins = cu_->num_ins;
414 if (num_ins > 0) {
415 int s_reg = num_regs - num_ins;
416 if ((cu_->access_flags & kAccStatic) == 0) {
417 // For non-static, skip past "this"
buzbee1fd33462013-03-25 13:40:45 -0700418 reg_location_[s_reg].defined = true;
419 reg_location_[s_reg].ref = true;
buzbee311ca162013-02-28 15:56:43 -0800420 s_reg++;
421 }
422 const char* shorty = cu_->shorty;
423 int shorty_len = strlen(shorty);
424 for (int i = 1; i < shorty_len; i++) {
425 switch (shorty[i]) {
426 case 'D':
buzbee1fd33462013-03-25 13:40:45 -0700427 reg_location_[s_reg].wide = true;
428 reg_location_[s_reg+1].high_word = true;
429 reg_location_[s_reg+1].fp = true;
buzbee311ca162013-02-28 15:56:43 -0800430 DCHECK_EQ(SRegToVReg(s_reg)+1, SRegToVReg(s_reg+1));
buzbee1fd33462013-03-25 13:40:45 -0700431 reg_location_[s_reg].fp = true;
432 reg_location_[s_reg].defined = true;
buzbee311ca162013-02-28 15:56:43 -0800433 s_reg++;
434 break;
435 case 'J':
buzbee1fd33462013-03-25 13:40:45 -0700436 reg_location_[s_reg].wide = true;
437 reg_location_[s_reg+1].high_word = true;
buzbee311ca162013-02-28 15:56:43 -0800438 DCHECK_EQ(SRegToVReg(s_reg)+1, SRegToVReg(s_reg+1));
buzbee1fd33462013-03-25 13:40:45 -0700439 reg_location_[s_reg].core = true;
440 reg_location_[s_reg].defined = true;
buzbee311ca162013-02-28 15:56:43 -0800441 s_reg++;
442 break;
443 case 'F':
buzbee1fd33462013-03-25 13:40:45 -0700444 reg_location_[s_reg].fp = true;
445 reg_location_[s_reg].defined = true;
buzbee311ca162013-02-28 15:56:43 -0800446 break;
447 case 'L':
buzbee1fd33462013-03-25 13:40:45 -0700448 reg_location_[s_reg].ref = true;
449 reg_location_[s_reg].defined = true;
buzbee311ca162013-02-28 15:56:43 -0800450 break;
451 default:
buzbee1fd33462013-03-25 13:40:45 -0700452 reg_location_[s_reg].core = true;
453 reg_location_[s_reg].defined = true;
buzbee311ca162013-02-28 15:56:43 -0800454 break;
455 }
456 s_reg++;
457 }
458 }
459
460 /* Do type & size inference pass */
buzbee0665fe02013-03-21 12:32:21 -0700461 PreOrderDfsIterator iter(this, true /* iterative */);
buzbee311ca162013-02-28 15:56:43 -0800462 bool change = false;
463 for (BasicBlock* bb = iter.Next(false); bb != NULL; bb = iter.Next(change)) {
464 change = InferTypeAndSize(bb);
465 }
466
467 /*
468 * Set the s_reg_low field to refer to the pre-SSA name of the
469 * base Dalvik virtual register. Once we add a better register
470 * allocator, remove this remapping.
471 */
472 for (i=0; i < GetNumSSARegs(); i++) {
buzbee1fd33462013-03-25 13:40:45 -0700473 if (reg_location_[i].location != kLocCompilerTemp) {
474 int orig_sreg = reg_location_[i].s_reg_low;
475 reg_location_[i].orig_sreg = orig_sreg;
476 reg_location_[i].s_reg_low = SRegToVReg(orig_sreg);
buzbee311ca162013-02-28 15:56:43 -0800477 }
478 }
479}
480
481} // namespace art