codegen_util.cc revision 6e07183e822a32856da9eb60006989496e06a9cc
1/*
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 "mir_to_lir-inl.h"
18
19#include "base/bit_vector-inl.h"
20#include "dex/mir_graph.h"
21#include "driver/compiler_driver.h"
22#include "driver/compiler_options.h"
23#include "driver/dex_compilation_unit.h"
24#include "dex_file-inl.h"
25#include "gc_map.h"
26#include "gc_map_builder.h"
27#include "mapping_table.h"
28#include "dex/quick/dex_file_method_inliner.h"
29#include "dex/quick/dex_file_to_method_inliner_map.h"
30#include "dex/verification_results.h"
31#include "dex/verified_method.h"
32#include "verifier/dex_gc_map.h"
33#include "verifier/method_verifier.h"
34#include "vmap_table.h"
35
36namespace art {
37
38namespace {
39
40/* Dump a mapping table */
41template <typename It>
42void DumpMappingTable(const char* table_name, const char* descriptor, const char* name,
43                      const Signature& signature, uint32_t size, It first) {
44  if (size != 0) {
45    std::string line(StringPrintf("\n  %s %s%s_%s_table[%u] = {", table_name,
46                     descriptor, name, signature.ToString().c_str(), size));
47    std::replace(line.begin(), line.end(), ';', '_');
48    LOG(INFO) << line;
49    for (uint32_t i = 0; i != size; ++i) {
50      line = StringPrintf("    {0x%05x, 0x%04x},", first.NativePcOffset(), first.DexPc());
51      ++first;
52      LOG(INFO) << line;
53    }
54    LOG(INFO) <<"  };\n\n";
55  }
56}
57
58}  // anonymous namespace
59
60bool Mir2Lir::IsInexpensiveConstant(RegLocation rl_src) {
61  bool res = false;
62  if (rl_src.is_const) {
63    if (rl_src.wide) {
64      // For wide registers, check whether we're the high partner. In that case we need to switch
65      // to the lower one for the correct value.
66      if (rl_src.high_word) {
67        rl_src.high_word = false;
68        rl_src.s_reg_low--;
69        rl_src.orig_sreg--;
70      }
71      if (rl_src.fp) {
72        res = InexpensiveConstantDouble(mir_graph_->ConstantValueWide(rl_src));
73      } else {
74        res = InexpensiveConstantLong(mir_graph_->ConstantValueWide(rl_src));
75      }
76    } else {
77      if (rl_src.fp) {
78        res = InexpensiveConstantFloat(mir_graph_->ConstantValue(rl_src));
79      } else {
80        res = InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src));
81      }
82    }
83  }
84  return res;
85}
86
87void Mir2Lir::MarkSafepointPC(LIR* inst) {
88  DCHECK(!inst->flags.use_def_invalid);
89  inst->u.m.def_mask = &kEncodeAll;
90  LIR* safepoint_pc = NewLIR0(kPseudoSafepointPC);
91  DCHECK(safepoint_pc->u.m.def_mask->Equals(kEncodeAll));
92  DCHECK(current_mir_ != nullptr || (current_dalvik_offset_ == 0 && safepoints_.empty()));
93  safepoints_.emplace_back(safepoint_pc, current_mir_);
94}
95
96void Mir2Lir::MarkSafepointPCAfter(LIR* after) {
97  DCHECK(!after->flags.use_def_invalid);
98  after->u.m.def_mask = &kEncodeAll;
99  // As NewLIR0 uses Append, we need to create the LIR by hand.
100  LIR* safepoint_pc = RawLIR(current_dalvik_offset_, kPseudoSafepointPC);
101  if (after->next == nullptr) {
102    DCHECK_EQ(after, last_lir_insn_);
103    AppendLIR(safepoint_pc);
104  } else {
105    InsertLIRAfter(after, safepoint_pc);
106  }
107  DCHECK(safepoint_pc->u.m.def_mask->Equals(kEncodeAll));
108  DCHECK(current_mir_ != nullptr || (current_dalvik_offset_ == 0 && safepoints_.empty()));
109  safepoints_.emplace_back(safepoint_pc, current_mir_);
110}
111
112/* Remove a LIR from the list. */
113void Mir2Lir::UnlinkLIR(LIR* lir) {
114  if (UNLIKELY(lir == first_lir_insn_)) {
115    first_lir_insn_ = lir->next;
116    if (lir->next != nullptr) {
117      lir->next->prev = nullptr;
118    } else {
119      DCHECK(lir->next == nullptr);
120      DCHECK(lir == last_lir_insn_);
121      last_lir_insn_ = nullptr;
122    }
123  } else if (lir == last_lir_insn_) {
124    last_lir_insn_ = lir->prev;
125    lir->prev->next = nullptr;
126  } else if ((lir->prev != nullptr) && (lir->next != nullptr)) {
127    lir->prev->next = lir->next;
128    lir->next->prev = lir->prev;
129  }
130}
131
132/* Convert an instruction to a NOP */
133void Mir2Lir::NopLIR(LIR* lir) {
134  lir->flags.is_nop = true;
135  if (!cu_->verbose) {
136    UnlinkLIR(lir);
137  }
138}
139
140void Mir2Lir::SetMemRefType(LIR* lir, bool is_load, int mem_type) {
141  DCHECK(GetTargetInstFlags(lir->opcode) & (IS_LOAD | IS_STORE));
142  DCHECK(!lir->flags.use_def_invalid);
143  // TODO: Avoid the extra Arena allocation!
144  const ResourceMask** mask_ptr;
145  ResourceMask mask;
146  if (is_load) {
147    mask_ptr = &lir->u.m.use_mask;
148  } else {
149    mask_ptr = &lir->u.m.def_mask;
150  }
151  mask = **mask_ptr;
152  /* Clear out the memref flags */
153  mask.ClearBits(kEncodeMem);
154  /* ..and then add back the one we need */
155  switch (mem_type) {
156    case ResourceMask::kLiteral:
157      DCHECK(is_load);
158      mask.SetBit(ResourceMask::kLiteral);
159      break;
160    case ResourceMask::kDalvikReg:
161      mask.SetBit(ResourceMask::kDalvikReg);
162      break;
163    case ResourceMask::kHeapRef:
164      mask.SetBit(ResourceMask::kHeapRef);
165      break;
166    case ResourceMask::kMustNotAlias:
167      /* Currently only loads can be marked as kMustNotAlias */
168      DCHECK(!(GetTargetInstFlags(lir->opcode) & IS_STORE));
169      mask.SetBit(ResourceMask::kMustNotAlias);
170      break;
171    default:
172      LOG(FATAL) << "Oat: invalid memref kind - " << mem_type;
173  }
174  *mask_ptr = mask_cache_.GetMask(mask);
175}
176
177/*
178 * Mark load/store instructions that access Dalvik registers through the stack.
179 */
180void Mir2Lir::AnnotateDalvikRegAccess(LIR* lir, int reg_id, bool is_load,
181                                      bool is64bit) {
182  DCHECK((is_load ? lir->u.m.use_mask : lir->u.m.def_mask)->Intersection(kEncodeMem).Equals(
183      kEncodeDalvikReg));
184
185  /*
186   * Store the Dalvik register id in alias_info. Mark the MSB if it is a 64-bit
187   * access.
188   */
189  lir->flags.alias_info = ENCODE_ALIAS_INFO(reg_id, is64bit);
190}
191
192/*
193 * Debugging macros
194 */
195#define DUMP_RESOURCE_MASK(X)
196
197/* Pretty-print a LIR instruction */
198void Mir2Lir::DumpLIRInsn(LIR* lir, unsigned char* base_addr) {
199  int offset = lir->offset;
200  int dest = lir->operands[0];
201  const bool dump_nop = (cu_->enable_debug & (1 << kDebugShowNops));
202
203  /* Handle pseudo-ops individually, and all regular insns as a group */
204  switch (lir->opcode) {
205    case kPseudoMethodEntry:
206      LOG(INFO) << "-------- method entry "
207                << PrettyMethod(cu_->method_idx, *cu_->dex_file);
208      break;
209    case kPseudoMethodExit:
210      LOG(INFO) << "-------- Method_Exit";
211      break;
212    case kPseudoBarrier:
213      LOG(INFO) << "-------- BARRIER";
214      break;
215    case kPseudoEntryBlock:
216      LOG(INFO) << "-------- entry offset: 0x" << std::hex << dest;
217      break;
218    case kPseudoDalvikByteCodeBoundary:
219      if (lir->operands[0] == 0) {
220         // NOTE: only used for debug listings.
221         lir->operands[0] = WrapPointer(ArenaStrdup("No instruction string"));
222      }
223      LOG(INFO) << "-------- dalvik offset: 0x" << std::hex
224                << lir->dalvik_offset << " @ "
225                << UnwrapPointer<char>(lir->operands[0]);
226      break;
227    case kPseudoExitBlock:
228      LOG(INFO) << "-------- exit offset: 0x" << std::hex << dest;
229      break;
230    case kPseudoPseudoAlign4:
231      LOG(INFO) << reinterpret_cast<uintptr_t>(base_addr) + offset << " (0x" << std::hex
232                << offset << "): .align4";
233      break;
234    case kPseudoEHBlockLabel:
235      LOG(INFO) << "Exception_Handling:";
236      break;
237    case kPseudoTargetLabel:
238    case kPseudoNormalBlockLabel:
239      LOG(INFO) << "L" << reinterpret_cast<void*>(lir) << ":";
240      break;
241    case kPseudoThrowTarget:
242      LOG(INFO) << "LT" << reinterpret_cast<void*>(lir) << ":";
243      break;
244    case kPseudoIntrinsicRetry:
245      LOG(INFO) << "IR" << reinterpret_cast<void*>(lir) << ":";
246      break;
247    case kPseudoSuspendTarget:
248      LOG(INFO) << "LS" << reinterpret_cast<void*>(lir) << ":";
249      break;
250    case kPseudoSafepointPC:
251      LOG(INFO) << "LsafepointPC_0x" << std::hex << lir->offset << "_" << lir->dalvik_offset << ":";
252      break;
253    case kPseudoExportedPC:
254      LOG(INFO) << "LexportedPC_0x" << std::hex << lir->offset << "_" << lir->dalvik_offset << ":";
255      break;
256    case kPseudoCaseLabel:
257      LOG(INFO) << "LC" << reinterpret_cast<void*>(lir) << ": Case target 0x"
258                << std::hex << lir->operands[0] << "|" << std::dec <<
259        lir->operands[0];
260      break;
261    default:
262      if (lir->flags.is_nop && !dump_nop) {
263        break;
264      } else {
265        std::string op_name(BuildInsnString(GetTargetInstName(lir->opcode),
266                                               lir, base_addr));
267        std::string op_operands(BuildInsnString(GetTargetInstFmt(lir->opcode),
268                                                    lir, base_addr));
269        LOG(INFO) << StringPrintf("%5p: %-9s%s%s",
270                                  base_addr + offset,
271                                  op_name.c_str(), op_operands.c_str(),
272                                  lir->flags.is_nop ? "(nop)" : "");
273      }
274      break;
275  }
276
277  if (lir->u.m.use_mask && (!lir->flags.is_nop || dump_nop)) {
278    DUMP_RESOURCE_MASK(DumpResourceMask(lir, *lir->u.m.use_mask, "use"));
279  }
280  if (lir->u.m.def_mask && (!lir->flags.is_nop || dump_nop)) {
281    DUMP_RESOURCE_MASK(DumpResourceMask(lir, *lir->u.m.def_mask, "def"));
282  }
283}
284
285void Mir2Lir::DumpPromotionMap() {
286  uint32_t num_regs = mir_graph_->GetNumOfCodeAndTempVRs();
287  for (uint32_t i = 0; i < num_regs; i++) {
288    PromotionMap v_reg_map = promotion_map_[i];
289    std::string buf;
290    if (v_reg_map.fp_location == kLocPhysReg) {
291      StringAppendF(&buf, " : s%d", RegStorage::RegNum(v_reg_map.fp_reg));
292    }
293
294    std::string buf3;
295    if (i < mir_graph_->GetNumOfCodeVRs()) {
296      StringAppendF(&buf3, "%02d", i);
297    } else if (i == mir_graph_->GetNumOfCodeVRs()) {
298      buf3 = "Method*";
299    } else {
300      uint32_t diff = i - mir_graph_->GetNumOfCodeVRs();
301      StringAppendF(&buf3, "ct%d", diff);
302    }
303
304    LOG(INFO) << StringPrintf("V[%s] -> %s%d%s", buf3.c_str(),
305                              v_reg_map.core_location == kLocPhysReg ?
306                              "r" : "SP+", v_reg_map.core_location == kLocPhysReg ?
307                              v_reg_map.core_reg : SRegOffset(i),
308                              buf.c_str());
309  }
310}
311
312void Mir2Lir::UpdateLIROffsets() {
313  // Only used for code listings.
314  size_t offset = 0;
315  for (LIR* lir = first_lir_insn_; lir != nullptr; lir = lir->next) {
316    lir->offset = offset;
317    if (!lir->flags.is_nop && !IsPseudoLirOp(lir->opcode)) {
318      offset += GetInsnSize(lir);
319    } else if (lir->opcode == kPseudoPseudoAlign4) {
320      offset += (offset & 0x2);
321    }
322  }
323}
324
325void Mir2Lir::MarkGCCard(int opt_flags, RegStorage val_reg, RegStorage tgt_addr_reg) {
326  DCHECK(val_reg.Valid());
327  DCHECK_EQ(val_reg.Is64Bit(), cu_->target64);
328  if ((opt_flags & MIR_STORE_NON_NULL_VALUE) != 0) {
329    UnconditionallyMarkGCCard(tgt_addr_reg);
330  } else {
331    LIR* branch_over = OpCmpImmBranch(kCondEq, val_reg, 0, nullptr);
332    UnconditionallyMarkGCCard(tgt_addr_reg);
333    LIR* target = NewLIR0(kPseudoTargetLabel);
334    branch_over->target = target;
335  }
336}
337
338/* Dump instructions and constant pool contents */
339void Mir2Lir::CodegenDump() {
340  LOG(INFO) << "Dumping LIR insns for "
341            << PrettyMethod(cu_->method_idx, *cu_->dex_file);
342  LIR* lir_insn;
343  int insns_size = mir_graph_->GetNumDalvikInsns();
344
345  LOG(INFO) << "Regs (excluding ins) : " << mir_graph_->GetNumOfLocalCodeVRs();
346  LOG(INFO) << "Ins          : " << mir_graph_->GetNumOfInVRs();
347  LOG(INFO) << "Outs         : " << mir_graph_->GetNumOfOutVRs();
348  LOG(INFO) << "CoreSpills       : " << num_core_spills_;
349  LOG(INFO) << "FPSpills       : " << num_fp_spills_;
350  LOG(INFO) << "CompilerTemps    : " << mir_graph_->GetNumUsedCompilerTemps();
351  LOG(INFO) << "Frame size       : " << frame_size_;
352  LOG(INFO) << "code size is " << total_size_ <<
353    " bytes, Dalvik size is " << insns_size * 2;
354  LOG(INFO) << "expansion factor: "
355            << static_cast<float>(total_size_) / static_cast<float>(insns_size * 2);
356  DumpPromotionMap();
357  UpdateLIROffsets();
358  for (lir_insn = first_lir_insn_; lir_insn != nullptr; lir_insn = lir_insn->next) {
359    DumpLIRInsn(lir_insn, 0);
360  }
361  for (lir_insn = literal_list_; lir_insn != nullptr; lir_insn = lir_insn->next) {
362    LOG(INFO) << StringPrintf("%x (%04x): .word (%#x)", lir_insn->offset, lir_insn->offset,
363                              lir_insn->operands[0]);
364  }
365
366  const DexFile::MethodId& method_id =
367      cu_->dex_file->GetMethodId(cu_->method_idx);
368  const Signature signature = cu_->dex_file->GetMethodSignature(method_id);
369  const char* name = cu_->dex_file->GetMethodName(method_id);
370  const char* descriptor(cu_->dex_file->GetMethodDeclaringClassDescriptor(method_id));
371
372  // Dump mapping tables
373  if (!encoded_mapping_table_.empty()) {
374    MappingTable table(&encoded_mapping_table_[0]);
375    DumpMappingTable("PC2Dex_MappingTable", descriptor, name, signature,
376                     table.PcToDexSize(), table.PcToDexBegin());
377    DumpMappingTable("Dex2PC_MappingTable", descriptor, name, signature,
378                     table.DexToPcSize(), table.DexToPcBegin());
379  }
380}
381
382/*
383 * Search the existing constants in the literal pool for an exact or close match
384 * within specified delta (greater or equal to 0).
385 */
386LIR* Mir2Lir::ScanLiteralPool(LIR* data_target, int value, unsigned int delta) {
387  while (data_target) {
388    if ((static_cast<unsigned>(value - data_target->operands[0])) <= delta)
389      return data_target;
390    data_target = data_target->next;
391  }
392  return nullptr;
393}
394
395/* Search the existing constants in the literal pool for an exact wide match */
396LIR* Mir2Lir::ScanLiteralPoolWide(LIR* data_target, int val_lo, int val_hi) {
397  bool lo_match = false;
398  LIR* lo_target = nullptr;
399  while (data_target) {
400    if (lo_match && (data_target->operands[0] == val_hi)) {
401      // Record high word in case we need to expand this later.
402      lo_target->operands[1] = val_hi;
403      return lo_target;
404    }
405    lo_match = false;
406    if (data_target->operands[0] == val_lo) {
407      lo_match = true;
408      lo_target = data_target;
409    }
410    data_target = data_target->next;
411  }
412  return nullptr;
413}
414
415/* Search the existing constants in the literal pool for an exact method match */
416LIR* Mir2Lir::ScanLiteralPoolMethod(LIR* data_target, const MethodReference& method) {
417  while (data_target) {
418    if (static_cast<uint32_t>(data_target->operands[0]) == method.dex_method_index &&
419        UnwrapPointer<DexFile>(data_target->operands[1]) == method.dex_file) {
420      return data_target;
421    }
422    data_target = data_target->next;
423  }
424  return nullptr;
425}
426
427/* Search the existing constants in the literal pool for an exact class match */
428LIR* Mir2Lir::ScanLiteralPoolClass(LIR* data_target, const DexFile& dex_file, uint32_t type_idx) {
429  while (data_target) {
430    if (static_cast<uint32_t>(data_target->operands[0]) == type_idx &&
431        UnwrapPointer<DexFile>(data_target->operands[1]) == &dex_file) {
432      return data_target;
433    }
434    data_target = data_target->next;
435  }
436  return nullptr;
437}
438
439/*
440 * The following are building blocks to insert constants into the pool or
441 * instruction streams.
442 */
443
444/* Add a 32-bit constant to the constant pool */
445LIR* Mir2Lir::AddWordData(LIR* *constant_list_p, int value) {
446  /* Add the constant to the literal pool */
447  if (constant_list_p) {
448    LIR* new_value = static_cast<LIR*>(arena_->Alloc(sizeof(LIR), kArenaAllocData));
449    new_value->operands[0] = value;
450    new_value->next = *constant_list_p;
451    *constant_list_p = new_value;
452    estimated_native_code_size_ += sizeof(value);
453    return new_value;
454  }
455  return nullptr;
456}
457
458/* Add a 64-bit constant to the constant pool or mixed with code */
459LIR* Mir2Lir::AddWideData(LIR* *constant_list_p, int val_lo, int val_hi) {
460  AddWordData(constant_list_p, val_hi);
461  return AddWordData(constant_list_p, val_lo);
462}
463
464/**
465 * @brief Push a compressed reference which needs patching at link/patchoat-time.
466 * @details This needs to be kept consistent with the code which actually does the patching in
467 *   oat_writer.cc and in the patchoat tool.
468 */
469static void PushUnpatchedReference(CodeBuffer* buf) {
470  // Note that we can safely initialize the patches to zero. The code deduplication mechanism takes
471  // the patches into account when determining whether two pieces of codes are functionally
472  // equivalent.
473  Push32(buf, UINT32_C(0));
474}
475
476static void AlignBuffer(CodeBuffer* buf, size_t offset) {
477  DCHECK_LE(buf->size(), offset);
478  buf->insert(buf->end(), offset - buf->size(), 0u);
479}
480
481/* Write the literal pool to the output stream */
482void Mir2Lir::InstallLiteralPools() {
483  AlignBuffer(&code_buffer_, data_offset_);
484  LIR* data_lir = literal_list_;
485  while (data_lir != nullptr) {
486    Push32(&code_buffer_, data_lir->operands[0]);
487    data_lir = NEXT_LIR(data_lir);
488  }
489  // TODO: patches_.reserve() as needed.
490  // Push code and method literals, record offsets for the compiler to patch.
491  data_lir = code_literal_list_;
492  while (data_lir != nullptr) {
493    uint32_t target_method_idx = data_lir->operands[0];
494    const DexFile* target_dex_file = UnwrapPointer<DexFile>(data_lir->operands[1]);
495    patches_.push_back(LinkerPatch::CodePatch(code_buffer_.size(),
496                                              target_dex_file, target_method_idx));
497    PushUnpatchedReference(&code_buffer_);
498    data_lir = NEXT_LIR(data_lir);
499  }
500  data_lir = method_literal_list_;
501  while (data_lir != nullptr) {
502    uint32_t target_method_idx = data_lir->operands[0];
503    const DexFile* target_dex_file = UnwrapPointer<DexFile>(data_lir->operands[1]);
504    patches_.push_back(LinkerPatch::MethodPatch(code_buffer_.size(),
505                                                target_dex_file, target_method_idx));
506    PushUnpatchedReference(&code_buffer_);
507    data_lir = NEXT_LIR(data_lir);
508  }
509  // Push class literals.
510  data_lir = class_literal_list_;
511  while (data_lir != nullptr) {
512    uint32_t target_type_idx = data_lir->operands[0];
513    const DexFile* class_dex_file = UnwrapPointer<DexFile>(data_lir->operands[1]);
514    patches_.push_back(LinkerPatch::TypePatch(code_buffer_.size(),
515                                              class_dex_file, target_type_idx));
516    PushUnpatchedReference(&code_buffer_);
517    data_lir = NEXT_LIR(data_lir);
518  }
519}
520
521/* Write the switch tables to the output stream */
522void Mir2Lir::InstallSwitchTables() {
523  for (Mir2Lir::SwitchTable* tab_rec : switch_tables_) {
524    AlignBuffer(&code_buffer_, tab_rec->offset);
525    /*
526     * For Arm, our reference point is the address of the bx
527     * instruction that does the launch, so we have to subtract
528     * the auto pc-advance.  For other targets the reference point
529     * is a label, so we can use the offset as-is.
530     */
531    int bx_offset = INVALID_OFFSET;
532    switch (cu_->instruction_set) {
533      case kThumb2:
534        DCHECK(tab_rec->anchor->flags.fixup != kFixupNone);
535        bx_offset = tab_rec->anchor->offset + 4;
536        break;
537      case kX86:
538        bx_offset = 0;
539        break;
540      case kX86_64:
541        // RIP relative to switch table.
542        bx_offset = tab_rec->offset;
543        break;
544      case kArm64:
545      case kMips:
546      case kMips64:
547        bx_offset = tab_rec->anchor->offset;
548        break;
549      default: LOG(FATAL) << "Unexpected instruction set: " << cu_->instruction_set;
550    }
551    if (cu_->verbose) {
552      LOG(INFO) << "Switch table for offset 0x" << std::hex << bx_offset;
553    }
554    if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) {
555      DCHECK(tab_rec->switch_mir != nullptr);
556      BasicBlock* bb = mir_graph_->GetBasicBlock(tab_rec->switch_mir->bb);
557      DCHECK(bb != nullptr);
558      int elems = 0;
559      for (SuccessorBlockInfo* successor_block_info : bb->successor_blocks) {
560        int key = successor_block_info->key;
561        int target = successor_block_info->block;
562        LIR* boundary_lir = InsertCaseLabel(target, key);
563        DCHECK(boundary_lir != nullptr);
564        int disp = boundary_lir->offset - bx_offset;
565        Push32(&code_buffer_, key);
566        Push32(&code_buffer_, disp);
567        if (cu_->verbose) {
568          LOG(INFO) << "  Case[" << elems << "] key: 0x"
569                    << std::hex << key << ", disp: 0x"
570                    << std::hex << disp;
571        }
572        elems++;
573      }
574      DCHECK_EQ(elems, tab_rec->table[1]);
575    } else {
576      DCHECK_EQ(static_cast<int>(tab_rec->table[0]),
577                static_cast<int>(Instruction::kPackedSwitchSignature));
578      DCHECK(tab_rec->switch_mir != nullptr);
579      BasicBlock* bb = mir_graph_->GetBasicBlock(tab_rec->switch_mir->bb);
580      DCHECK(bb != nullptr);
581      int elems = 0;
582      int low_key = s4FromSwitchData(&tab_rec->table[2]);
583      for (SuccessorBlockInfo* successor_block_info : bb->successor_blocks) {
584        int key = successor_block_info->key;
585        DCHECK_EQ(elems + low_key, key);
586        int target = successor_block_info->block;
587        LIR* boundary_lir = InsertCaseLabel(target, key);
588        DCHECK(boundary_lir != nullptr);
589        int disp = boundary_lir->offset - bx_offset;
590        Push32(&code_buffer_, disp);
591        if (cu_->verbose) {
592          LOG(INFO) << "  Case[" << elems << "] disp: 0x"
593                    << std::hex << disp;
594        }
595        elems++;
596      }
597      DCHECK_EQ(elems, tab_rec->table[1]);
598    }
599  }
600}
601
602/* Write the fill array dta to the output stream */
603void Mir2Lir::InstallFillArrayData() {
604  for (Mir2Lir::FillArrayData* tab_rec : fill_array_data_) {
605    AlignBuffer(&code_buffer_, tab_rec->offset);
606    for (int i = 0; i < (tab_rec->size + 1) / 2; i++) {
607      code_buffer_.push_back(tab_rec->table[i] & 0xFF);
608      code_buffer_.push_back((tab_rec->table[i] >> 8) & 0xFF);
609    }
610  }
611}
612
613static int AssignLiteralOffsetCommon(LIR* lir, CodeOffset offset) {
614  for (; lir != nullptr; lir = lir->next) {
615    lir->offset = offset;
616    offset += 4;
617  }
618  return offset;
619}
620
621static int AssignLiteralPointerOffsetCommon(LIR* lir, CodeOffset offset,
622                                            unsigned int element_size) {
623  // Align to natural pointer size.
624  offset = RoundUp(offset, element_size);
625  for (; lir != nullptr; lir = lir->next) {
626    lir->offset = offset;
627    offset += element_size;
628  }
629  return offset;
630}
631
632// Make sure we have a code address for every declared catch entry
633bool Mir2Lir::VerifyCatchEntries() {
634  MappingTable table(&encoded_mapping_table_[0]);
635  std::vector<uint32_t> dex_pcs;
636  dex_pcs.reserve(table.DexToPcSize());
637  for (auto it = table.DexToPcBegin(), end = table.DexToPcEnd(); it != end; ++it) {
638    dex_pcs.push_back(it.DexPc());
639  }
640  // Sort dex_pcs, so that we can quickly check it against the ordered mir_graph_->catches_.
641  std::sort(dex_pcs.begin(), dex_pcs.end());
642
643  bool success = true;
644  auto it = dex_pcs.begin(), end = dex_pcs.end();
645  for (uint32_t dex_pc : mir_graph_->catches_) {
646    while (it != end && *it < dex_pc) {
647      LOG(INFO) << "Unexpected catch entry @ dex pc 0x" << std::hex << *it;
648      ++it;
649      success = false;
650    }
651    if (it == end || *it > dex_pc) {
652      LOG(INFO) << "Missing native PC for catch entry @ 0x" << std::hex << dex_pc;
653      success = false;
654    } else {
655      ++it;
656    }
657  }
658  if (!success) {
659    LOG(INFO) << "Bad dex2pcMapping table in " << PrettyMethod(cu_->method_idx, *cu_->dex_file);
660    LOG(INFO) << "Entries @ decode: " << mir_graph_->catches_.size() << ", Entries in table: "
661              << table.DexToPcSize();
662  }
663  return success;
664}
665
666
667void Mir2Lir::CreateMappingTables() {
668  bool generate_src_map = cu_->compiler_driver->GetCompilerOptions().GetIncludeDebugSymbols();
669
670  uint32_t pc2dex_data_size = 0u;
671  uint32_t pc2dex_entries = 0u;
672  uint32_t pc2dex_offset = 0u;
673  uint32_t pc2dex_dalvik_offset = 0u;
674  uint32_t pc2dex_src_entries = 0u;
675  uint32_t dex2pc_data_size = 0u;
676  uint32_t dex2pc_entries = 0u;
677  uint32_t dex2pc_offset = 0u;
678  uint32_t dex2pc_dalvik_offset = 0u;
679  for (LIR* tgt_lir = first_lir_insn_; tgt_lir != nullptr; tgt_lir = NEXT_LIR(tgt_lir)) {
680    pc2dex_src_entries++;
681    if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) {
682      pc2dex_entries += 1;
683      DCHECK(pc2dex_offset <= tgt_lir->offset);
684      pc2dex_data_size += UnsignedLeb128Size(tgt_lir->offset - pc2dex_offset);
685      pc2dex_data_size += SignedLeb128Size(static_cast<int32_t>(tgt_lir->dalvik_offset) -
686                                           static_cast<int32_t>(pc2dex_dalvik_offset));
687      pc2dex_offset = tgt_lir->offset;
688      pc2dex_dalvik_offset = tgt_lir->dalvik_offset;
689    }
690    if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) {
691      dex2pc_entries += 1;
692      DCHECK(dex2pc_offset <= tgt_lir->offset);
693      dex2pc_data_size += UnsignedLeb128Size(tgt_lir->offset - dex2pc_offset);
694      dex2pc_data_size += SignedLeb128Size(static_cast<int32_t>(tgt_lir->dalvik_offset) -
695                                           static_cast<int32_t>(dex2pc_dalvik_offset));
696      dex2pc_offset = tgt_lir->offset;
697      dex2pc_dalvik_offset = tgt_lir->dalvik_offset;
698    }
699  }
700
701  if (generate_src_map) {
702    src_mapping_table_.reserve(pc2dex_src_entries);
703  }
704
705  uint32_t total_entries = pc2dex_entries + dex2pc_entries;
706  uint32_t hdr_data_size = UnsignedLeb128Size(total_entries) + UnsignedLeb128Size(pc2dex_entries);
707  uint32_t data_size = hdr_data_size + pc2dex_data_size + dex2pc_data_size;
708  encoded_mapping_table_.resize(data_size);
709  uint8_t* write_pos = &encoded_mapping_table_[0];
710  write_pos = EncodeUnsignedLeb128(write_pos, total_entries);
711  write_pos = EncodeUnsignedLeb128(write_pos, pc2dex_entries);
712  DCHECK_EQ(static_cast<size_t>(write_pos - &encoded_mapping_table_[0]), hdr_data_size);
713  uint8_t* write_pos2 = write_pos + pc2dex_data_size;
714
715  pc2dex_offset = 0u;
716  pc2dex_dalvik_offset = 0u;
717  dex2pc_offset = 0u;
718  dex2pc_dalvik_offset = 0u;
719  for (LIR* tgt_lir = first_lir_insn_; tgt_lir != nullptr; tgt_lir = NEXT_LIR(tgt_lir)) {
720    if (generate_src_map && !tgt_lir->flags.is_nop) {
721      src_mapping_table_.push_back(SrcMapElem({tgt_lir->offset,
722              static_cast<int32_t>(tgt_lir->dalvik_offset)}));
723    }
724    if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) {
725      DCHECK(pc2dex_offset <= tgt_lir->offset);
726      write_pos = EncodeUnsignedLeb128(write_pos, tgt_lir->offset - pc2dex_offset);
727      write_pos = EncodeSignedLeb128(write_pos, static_cast<int32_t>(tgt_lir->dalvik_offset) -
728                                     static_cast<int32_t>(pc2dex_dalvik_offset));
729      pc2dex_offset = tgt_lir->offset;
730      pc2dex_dalvik_offset = tgt_lir->dalvik_offset;
731    }
732    if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) {
733      DCHECK(dex2pc_offset <= tgt_lir->offset);
734      write_pos2 = EncodeUnsignedLeb128(write_pos2, tgt_lir->offset - dex2pc_offset);
735      write_pos2 = EncodeSignedLeb128(write_pos2, static_cast<int32_t>(tgt_lir->dalvik_offset) -
736                                      static_cast<int32_t>(dex2pc_dalvik_offset));
737      dex2pc_offset = tgt_lir->offset;
738      dex2pc_dalvik_offset = tgt_lir->dalvik_offset;
739    }
740  }
741  DCHECK_EQ(static_cast<size_t>(write_pos - &encoded_mapping_table_[0]),
742            hdr_data_size + pc2dex_data_size);
743  DCHECK_EQ(static_cast<size_t>(write_pos2 - &encoded_mapping_table_[0]), data_size);
744
745  if (kIsDebugBuild) {
746    CHECK(VerifyCatchEntries());
747
748    // Verify the encoded table holds the expected data.
749    MappingTable table(&encoded_mapping_table_[0]);
750    CHECK_EQ(table.TotalSize(), total_entries);
751    CHECK_EQ(table.PcToDexSize(), pc2dex_entries);
752    auto it = table.PcToDexBegin();
753    auto it2 = table.DexToPcBegin();
754    for (LIR* tgt_lir = first_lir_insn_; tgt_lir != nullptr; tgt_lir = NEXT_LIR(tgt_lir)) {
755      if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) {
756        CHECK_EQ(tgt_lir->offset, it.NativePcOffset());
757        CHECK_EQ(tgt_lir->dalvik_offset, it.DexPc());
758        ++it;
759      }
760      if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) {
761        CHECK_EQ(tgt_lir->offset, it2.NativePcOffset());
762        CHECK_EQ(tgt_lir->dalvik_offset, it2.DexPc());
763        ++it2;
764      }
765    }
766    CHECK(it == table.PcToDexEnd());
767    CHECK(it2 == table.DexToPcEnd());
768  }
769}
770
771void Mir2Lir::CreateNativeGcMap() {
772  if (UNLIKELY((cu_->disable_opt & (1u << kPromoteRegs)) != 0u)) {
773    // If we're not promoting to physical registers, it's safe to use the verifier's notion of
774    // references. (We disable register promotion when type inference finds a type conflict and
775    // in that the case we defer to the verifier to avoid using the compiler's conflicting info.)
776    CreateNativeGcMapWithoutRegisterPromotion();
777    return;
778  }
779
780  ArenaBitVector* references = new (arena_) ArenaBitVector(arena_, mir_graph_->GetNumSSARegs(),
781                                                           false);
782
783  // Calculate max native offset and max reference vreg.
784  MIR* prev_mir = nullptr;
785  int max_ref_vreg = -1;
786  CodeOffset max_native_offset = 0u;
787  for (const auto& entry : safepoints_) {
788    uint32_t native_offset = entry.first->offset;
789    max_native_offset = std::max(max_native_offset, native_offset);
790    MIR* mir = entry.second;
791    UpdateReferenceVRegs(mir, prev_mir, references);
792    max_ref_vreg = std::max(max_ref_vreg, references->GetHighestBitSet());
793    prev_mir = mir;
794  }
795
796#if defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)
797  static constexpr bool kLittleEndian = true;
798#else
799  static constexpr bool kLittleEndian = false;
800#endif
801
802  // Build the GC map.
803  uint32_t reg_width = static_cast<uint32_t>((max_ref_vreg + 8) / 8);
804  GcMapBuilder native_gc_map_builder(&native_gc_map_,
805                                     safepoints_.size(),
806                                     max_native_offset, reg_width);
807  if (kLittleEndian) {
808    for (const auto& entry : safepoints_) {
809      uint32_t native_offset = entry.first->offset;
810      MIR* mir = entry.second;
811      UpdateReferenceVRegs(mir, prev_mir, references);
812      // For little-endian, the bytes comprising the bit vector's raw storage are what we need.
813      native_gc_map_builder.AddEntry(native_offset,
814                                     reinterpret_cast<const uint8_t*>(references->GetRawStorage()));
815      prev_mir = mir;
816    }
817  } else {
818    ArenaVector<uint8_t> references_buffer(arena_->Adapter());
819    references_buffer.resize(reg_width);
820    for (const auto& entry : safepoints_) {
821      uint32_t native_offset = entry.first->offset;
822      MIR* mir = entry.second;
823      UpdateReferenceVRegs(mir, prev_mir, references);
824      // Big-endian or unknown endianness, manually translate the bit vector data.
825      const auto* raw_storage = references->GetRawStorage();
826      for (size_t i = 0; i != reg_width; ++i) {
827        references_buffer[i] = static_cast<uint8_t>(
828            raw_storage[i / sizeof(raw_storage[0])] >> (8u * (i % sizeof(raw_storage[0]))));
829      }
830      native_gc_map_builder.AddEntry(native_offset, &references_buffer[0]);
831      prev_mir = mir;
832    }
833  }
834}
835
836void Mir2Lir::CreateNativeGcMapWithoutRegisterPromotion() {
837  DCHECK(!encoded_mapping_table_.empty());
838  MappingTable mapping_table(&encoded_mapping_table_[0]);
839  uint32_t max_native_offset = 0;
840  for (auto it = mapping_table.PcToDexBegin(), end = mapping_table.PcToDexEnd(); it != end; ++it) {
841    uint32_t native_offset = it.NativePcOffset();
842    if (native_offset > max_native_offset) {
843      max_native_offset = native_offset;
844    }
845  }
846  MethodReference method_ref(cu_->dex_file, cu_->method_idx);
847  const std::vector<uint8_t>& gc_map_raw =
848      mir_graph_->GetCurrentDexCompilationUnit()->GetVerifiedMethod()->GetDexGcMap();
849  verifier::DexPcToReferenceMap dex_gc_map(&(gc_map_raw)[0]);
850  DCHECK_EQ(gc_map_raw.size(), dex_gc_map.RawSize());
851  // Compute native offset to references size.
852  GcMapBuilder native_gc_map_builder(&native_gc_map_,
853                                     mapping_table.PcToDexSize(),
854                                     max_native_offset, dex_gc_map.RegWidth());
855
856  for (auto it = mapping_table.PcToDexBegin(), end = mapping_table.PcToDexEnd(); it != end; ++it) {
857    uint32_t native_offset = it.NativePcOffset();
858    uint32_t dex_pc = it.DexPc();
859    const uint8_t* references = dex_gc_map.FindBitMap(dex_pc, false);
860    CHECK(references != nullptr) << "Missing ref for dex pc 0x" << std::hex << dex_pc <<
861        ": " << PrettyMethod(cu_->method_idx, *cu_->dex_file);
862    native_gc_map_builder.AddEntry(native_offset, references);
863  }
864
865  // Maybe not necessary, but this could help prevent errors where we access the verified method
866  // after it has been deleted.
867  mir_graph_->GetCurrentDexCompilationUnit()->ClearVerifiedMethod();
868}
869
870/* Determine the offset of each literal field */
871int Mir2Lir::AssignLiteralOffset(CodeOffset offset) {
872  offset = AssignLiteralOffsetCommon(literal_list_, offset);
873  constexpr unsigned int ptr_size = sizeof(uint32_t);
874  static_assert(ptr_size >= sizeof(mirror::HeapReference<mirror::Object>),
875                "Pointer size cannot hold a heap reference");
876  offset = AssignLiteralPointerOffsetCommon(code_literal_list_, offset, ptr_size);
877  offset = AssignLiteralPointerOffsetCommon(method_literal_list_, offset, ptr_size);
878  offset = AssignLiteralPointerOffsetCommon(class_literal_list_, offset, ptr_size);
879  return offset;
880}
881
882int Mir2Lir::AssignSwitchTablesOffset(CodeOffset offset) {
883  for (Mir2Lir::SwitchTable* tab_rec : switch_tables_) {
884    tab_rec->offset = offset;
885    if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) {
886      offset += tab_rec->table[1] * (sizeof(int) * 2);
887    } else {
888      DCHECK_EQ(static_cast<int>(tab_rec->table[0]),
889                static_cast<int>(Instruction::kPackedSwitchSignature));
890      offset += tab_rec->table[1] * sizeof(int);
891    }
892  }
893  return offset;
894}
895
896int Mir2Lir::AssignFillArrayDataOffset(CodeOffset offset) {
897  for (Mir2Lir::FillArrayData* tab_rec : fill_array_data_) {
898    tab_rec->offset = offset;
899    offset += tab_rec->size;
900    // word align
901    offset = RoundUp(offset, 4);
902  }
903  return offset;
904}
905
906/*
907 * Insert a kPseudoCaseLabel at the beginning of the Dalvik
908 * offset vaddr if pretty-printing, otherise use the standard block
909 * label.  The selected label will be used to fix up the case
910 * branch table during the assembly phase.  All resource flags
911 * are set to prevent code motion.  KeyVal is just there for debugging.
912 */
913LIR* Mir2Lir::InsertCaseLabel(uint32_t bbid, int keyVal) {
914  LIR* boundary_lir = &block_label_list_[bbid];
915  LIR* res = boundary_lir;
916  if (cu_->verbose) {
917    // Only pay the expense if we're pretty-printing.
918    LIR* new_label = static_cast<LIR*>(arena_->Alloc(sizeof(LIR), kArenaAllocLIR));
919    BasicBlock* bb = mir_graph_->GetBasicBlock(bbid);
920    DCHECK(bb != nullptr);
921    new_label->dalvik_offset = bb->start_offset;
922    new_label->opcode = kPseudoCaseLabel;
923    new_label->operands[0] = keyVal;
924    new_label->flags.fixup = kFixupLabel;
925    DCHECK(!new_label->flags.use_def_invalid);
926    new_label->u.m.def_mask = &kEncodeAll;
927    InsertLIRAfter(boundary_lir, new_label);
928  }
929  return res;
930}
931
932void Mir2Lir::DumpSparseSwitchTable(const uint16_t* table) {
933  /*
934   * Sparse switch data format:
935   *  ushort ident = 0x0200   magic value
936   *  ushort size       number of entries in the table; > 0
937   *  int keys[size]      keys, sorted low-to-high; 32-bit aligned
938   *  int targets[size]     branch targets, relative to switch opcode
939   *
940   * Total size is (2+size*4) 16-bit code units.
941   */
942  uint16_t ident = table[0];
943  int entries = table[1];
944  const int32_t* keys = reinterpret_cast<const int32_t*>(&table[2]);
945  const int32_t* targets = &keys[entries];
946  LOG(INFO) <<  "Sparse switch table - ident:0x" << std::hex << ident
947            << ", entries: " << std::dec << entries;
948  for (int i = 0; i < entries; i++) {
949    LOG(INFO) << "  Key[" << keys[i] << "] -> 0x" << std::hex << targets[i];
950  }
951}
952
953void Mir2Lir::DumpPackedSwitchTable(const uint16_t* table) {
954  /*
955   * Packed switch data format:
956   *  ushort ident = 0x0100   magic value
957   *  ushort size       number of entries in the table
958   *  int first_key       first (and lowest) switch case value
959   *  int targets[size]     branch targets, relative to switch opcode
960   *
961   * Total size is (4+size*2) 16-bit code units.
962   */
963  uint16_t ident = table[0];
964  const int32_t* targets = reinterpret_cast<const int32_t*>(&table[4]);
965  int entries = table[1];
966  int low_key = s4FromSwitchData(&table[2]);
967  LOG(INFO) << "Packed switch table - ident:0x" << std::hex << ident
968            << ", entries: " << std::dec << entries << ", low_key: " << low_key;
969  for (int i = 0; i < entries; i++) {
970    LOG(INFO) << "  Key[" << (i + low_key) << "] -> 0x" << std::hex
971              << targets[i];
972  }
973}
974
975/* Set up special LIR to mark a Dalvik byte-code instruction start for pretty printing */
976void Mir2Lir::MarkBoundary(DexOffset offset, const char* inst_str) {
977  UNUSED(offset);
978  // NOTE: only used for debug listings.
979  NewLIR1(kPseudoDalvikByteCodeBoundary, WrapPointer(ArenaStrdup(inst_str)));
980}
981
982// Convert relation of src1/src2 to src2/src1
983ConditionCode Mir2Lir::FlipComparisonOrder(ConditionCode before) {
984  ConditionCode res;
985  switch (before) {
986    case kCondEq: res = kCondEq; break;
987    case kCondNe: res = kCondNe; break;
988    case kCondLt: res = kCondGt; break;
989    case kCondGt: res = kCondLt; break;
990    case kCondLe: res = kCondGe; break;
991    case kCondGe: res = kCondLe; break;
992    default:
993      LOG(FATAL) << "Unexpected ccode " << before;
994      UNREACHABLE();
995  }
996  return res;
997}
998
999ConditionCode Mir2Lir::NegateComparison(ConditionCode before) {
1000  ConditionCode res;
1001  switch (before) {
1002    case kCondEq: res = kCondNe; break;
1003    case kCondNe: res = kCondEq; break;
1004    case kCondLt: res = kCondGe; break;
1005    case kCondGt: res = kCondLe; break;
1006    case kCondLe: res = kCondGt; break;
1007    case kCondGe: res = kCondLt; break;
1008    default:
1009      LOG(FATAL) << "Unexpected ccode " << before;
1010      UNREACHABLE();
1011  }
1012  return res;
1013}
1014
1015// TODO: move to mir_to_lir.cc
1016Mir2Lir::Mir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena)
1017    : literal_list_(nullptr),
1018      method_literal_list_(nullptr),
1019      class_literal_list_(nullptr),
1020      code_literal_list_(nullptr),
1021      first_fixup_(nullptr),
1022      arena_(arena),
1023      cu_(cu),
1024      mir_graph_(mir_graph),
1025      switch_tables_(arena->Adapter(kArenaAllocSwitchTable)),
1026      fill_array_data_(arena->Adapter(kArenaAllocFillArrayData)),
1027      tempreg_info_(arena->Adapter()),
1028      reginfo_map_(arena->Adapter()),
1029      pointer_storage_(arena->Adapter()),
1030      data_offset_(0),
1031      total_size_(0),
1032      block_label_list_(nullptr),
1033      promotion_map_(nullptr),
1034      current_dalvik_offset_(0),
1035      current_mir_(nullptr),
1036      estimated_native_code_size_(0),
1037      reg_pool_(nullptr),
1038      live_sreg_(0),
1039      code_buffer_(mir_graph->GetArena()->Adapter()),
1040      encoded_mapping_table_(mir_graph->GetArena()->Adapter()),
1041      core_vmap_table_(mir_graph->GetArena()->Adapter()),
1042      fp_vmap_table_(mir_graph->GetArena()->Adapter()),
1043      native_gc_map_(mir_graph->GetArena()->Adapter()),
1044      patches_(mir_graph->GetArena()->Adapter()),
1045      num_core_spills_(0),
1046      num_fp_spills_(0),
1047      frame_size_(0),
1048      core_spill_mask_(0),
1049      fp_spill_mask_(0),
1050      first_lir_insn_(nullptr),
1051      last_lir_insn_(nullptr),
1052      slow_paths_(arena->Adapter(kArenaAllocSlowPaths)),
1053      mem_ref_type_(ResourceMask::kHeapRef),
1054      mask_cache_(arena),
1055      safepoints_(arena->Adapter()),
1056      in_to_reg_storage_mapping_(arena) {
1057  switch_tables_.reserve(4);
1058  fill_array_data_.reserve(4);
1059  tempreg_info_.reserve(20);
1060  reginfo_map_.reserve(RegStorage::kMaxRegs);
1061  pointer_storage_.reserve(128);
1062  slow_paths_.reserve(32);
1063  // Reserve pointer id 0 for nullptr.
1064  size_t null_idx = WrapPointer<void>(nullptr);
1065  DCHECK_EQ(null_idx, 0U);
1066}
1067
1068void Mir2Lir::Materialize() {
1069  cu_->NewTimingSplit("RegisterAllocation");
1070  CompilerInitializeRegAlloc();  // Needs to happen after SSA naming
1071
1072  /* Allocate Registers using simple local allocation scheme */
1073  SimpleRegAlloc();
1074
1075  /* First try the custom light codegen for special cases. */
1076  DCHECK(cu_->compiler_driver->GetMethodInlinerMap() != nullptr);
1077  bool special_worked = cu_->compiler_driver->GetMethodInlinerMap()->GetMethodInliner(cu_->dex_file)
1078      ->GenSpecial(this, cu_->method_idx);
1079
1080  /* Take normal path for converting MIR to LIR only if the special codegen did not succeed. */
1081  if (special_worked == false) {
1082    MethodMIR2LIR();
1083  }
1084
1085  /* Method is not empty */
1086  if (first_lir_insn_) {
1087    /* Convert LIR into machine code. */
1088    AssembleLIR();
1089
1090    if ((cu_->enable_debug & (1 << kDebugCodegenDump)) != 0) {
1091      CodegenDump();
1092    }
1093  }
1094}
1095
1096CompiledMethod* Mir2Lir::GetCompiledMethod() {
1097  // Combine vmap tables - core regs, then fp regs - into vmap_table.
1098  Leb128EncodingVector vmap_encoder;
1099  if (frame_size_ > 0) {
1100    // Prefix the encoded data with its size.
1101    size_t size = core_vmap_table_.size() + 1 /* marker */ + fp_vmap_table_.size();
1102    vmap_encoder.Reserve(size + 1u);  // All values are likely to be one byte in ULEB128 (<128).
1103    vmap_encoder.PushBackUnsigned(size);
1104    // Core regs may have been inserted out of order - sort first.
1105    std::sort(core_vmap_table_.begin(), core_vmap_table_.end());
1106    for (size_t i = 0 ; i < core_vmap_table_.size(); ++i) {
1107      // Copy, stripping out the phys register sort key.
1108      vmap_encoder.PushBackUnsigned(
1109          ~(-1 << VREG_NUM_WIDTH) & (core_vmap_table_[i] + VmapTable::kEntryAdjustment));
1110    }
1111    // Push a marker to take place of lr.
1112    vmap_encoder.PushBackUnsigned(VmapTable::kAdjustedFpMarker);
1113    if (cu_->instruction_set == kThumb2) {
1114      // fp regs already sorted.
1115      for (uint32_t i = 0; i < fp_vmap_table_.size(); i++) {
1116        vmap_encoder.PushBackUnsigned(fp_vmap_table_[i] + VmapTable::kEntryAdjustment);
1117      }
1118    } else {
1119      // For other platforms regs may have been inserted out of order - sort first.
1120      std::sort(fp_vmap_table_.begin(), fp_vmap_table_.end());
1121      for (size_t i = 0 ; i < fp_vmap_table_.size(); ++i) {
1122        // Copy, stripping out the phys register sort key.
1123        vmap_encoder.PushBackUnsigned(
1124            ~(-1 << VREG_NUM_WIDTH) & (fp_vmap_table_[i] + VmapTable::kEntryAdjustment));
1125      }
1126    }
1127  } else {
1128    DCHECK_EQ(POPCOUNT(core_spill_mask_), 0);
1129    DCHECK_EQ(POPCOUNT(fp_spill_mask_), 0);
1130    DCHECK_EQ(core_vmap_table_.size(), 0u);
1131    DCHECK_EQ(fp_vmap_table_.size(), 0u);
1132    vmap_encoder.PushBackUnsigned(0u);  // Size is 0.
1133  }
1134
1135  // Sort patches by literal offset for better deduplication.
1136  std::sort(patches_.begin(), patches_.end(), [](const LinkerPatch& lhs, const LinkerPatch& rhs) {
1137    return lhs.LiteralOffset() < rhs.LiteralOffset();
1138  });
1139
1140  std::unique_ptr<std::vector<uint8_t>> cfi_info(
1141      cu_->compiler_driver->GetCompilerOptions().GetGenerateGDBInformation() ?
1142          ReturnFrameDescriptionEntry() :
1143          nullptr);
1144  ArrayRef<const uint8_t> cfi_ref;
1145  if (cfi_info.get() != nullptr) {
1146    cfi_ref = ArrayRef<const uint8_t>(*cfi_info);
1147  }
1148  return CompiledMethod::SwapAllocCompiledMethod(
1149      cu_->compiler_driver, cu_->instruction_set,
1150      ArrayRef<const uint8_t>(code_buffer_),
1151      frame_size_, core_spill_mask_, fp_spill_mask_,
1152      &src_mapping_table_,
1153      ArrayRef<const uint8_t>(encoded_mapping_table_),
1154      ArrayRef<const uint8_t>(vmap_encoder.GetData()),
1155      ArrayRef<const uint8_t>(native_gc_map_),
1156      cfi_ref,
1157      ArrayRef<LinkerPatch>(patches_));
1158}
1159
1160size_t Mir2Lir::GetMaxPossibleCompilerTemps() const {
1161  // Chose a reasonably small value in order to contain stack growth.
1162  // Backends that are smarter about spill region can return larger values.
1163  const size_t max_compiler_temps = 10;
1164  return max_compiler_temps;
1165}
1166
1167size_t Mir2Lir::GetNumBytesForCompilerTempSpillRegion() {
1168  // By default assume that the Mir2Lir will need one slot for each temporary.
1169  // If the backend can better determine temps that have non-overlapping ranges and
1170  // temps that do not need spilled, it can actually provide a small region.
1171  mir_graph_->CommitCompilerTemps();
1172  return mir_graph_->GetNumBytesForSpecialTemps() + mir_graph_->GetMaximumBytesForNonSpecialTemps();
1173}
1174
1175int Mir2Lir::ComputeFrameSize() {
1176  /* Figure out the frame size */
1177  uint32_t size = num_core_spills_ * GetBytesPerGprSpillLocation(cu_->instruction_set)
1178                  + num_fp_spills_ * GetBytesPerFprSpillLocation(cu_->instruction_set)
1179                  + sizeof(uint32_t)  // Filler.
1180                  + mir_graph_->GetNumOfLocalCodeVRs()  * sizeof(uint32_t)
1181                  + mir_graph_->GetNumOfOutVRs() * sizeof(uint32_t)
1182                  + GetNumBytesForCompilerTempSpillRegion();
1183  /* Align and set */
1184  return RoundUp(size, kStackAlignment);
1185}
1186
1187/*
1188 * Append an LIR instruction to the LIR list maintained by a compilation
1189 * unit
1190 */
1191void Mir2Lir::AppendLIR(LIR* lir) {
1192  if (first_lir_insn_ == nullptr) {
1193    DCHECK(last_lir_insn_ == nullptr);
1194    last_lir_insn_ = first_lir_insn_ = lir;
1195    lir->prev = lir->next = nullptr;
1196  } else {
1197    last_lir_insn_->next = lir;
1198    lir->prev = last_lir_insn_;
1199    lir->next = nullptr;
1200    last_lir_insn_ = lir;
1201  }
1202}
1203
1204/*
1205 * Insert an LIR instruction before the current instruction, which cannot be the
1206 * first instruction.
1207 *
1208 * prev_lir <-> new_lir <-> current_lir
1209 */
1210void Mir2Lir::InsertLIRBefore(LIR* current_lir, LIR* new_lir) {
1211  DCHECK(current_lir->prev != nullptr);
1212  LIR *prev_lir = current_lir->prev;
1213
1214  prev_lir->next = new_lir;
1215  new_lir->prev = prev_lir;
1216  new_lir->next = current_lir;
1217  current_lir->prev = new_lir;
1218}
1219
1220/*
1221 * Insert an LIR instruction after the current instruction, which cannot be the
1222 * last instruction.
1223 *
1224 * current_lir -> new_lir -> old_next
1225 */
1226void Mir2Lir::InsertLIRAfter(LIR* current_lir, LIR* new_lir) {
1227  new_lir->prev = current_lir;
1228  new_lir->next = current_lir->next;
1229  current_lir->next = new_lir;
1230  new_lir->next->prev = new_lir;
1231}
1232
1233bool Mir2Lir::PartiallyIntersects(RegLocation rl_src, RegLocation rl_dest) {
1234  DCHECK(rl_src.wide);
1235  DCHECK(rl_dest.wide);
1236  return (abs(mir_graph_->SRegToVReg(rl_src.s_reg_low) - mir_graph_->SRegToVReg(rl_dest.s_reg_low)) == 1);
1237}
1238
1239bool Mir2Lir::Intersects(RegLocation rl_src, RegLocation rl_dest) {
1240  DCHECK(rl_src.wide);
1241  DCHECK(rl_dest.wide);
1242  return (abs(mir_graph_->SRegToVReg(rl_src.s_reg_low) - mir_graph_->SRegToVReg(rl_dest.s_reg_low)) <= 1);
1243}
1244
1245LIR *Mir2Lir::OpCmpMemImmBranch(ConditionCode cond, RegStorage temp_reg, RegStorage base_reg,
1246                                int offset, int check_value, LIR* target, LIR** compare) {
1247  // Handle this for architectures that can't compare to memory.
1248  LIR* inst = Load32Disp(base_reg, offset, temp_reg);
1249  if (compare != nullptr) {
1250    *compare = inst;
1251  }
1252  LIR* branch = OpCmpImmBranch(cond, temp_reg, check_value, target);
1253  return branch;
1254}
1255
1256void Mir2Lir::AddSlowPath(LIRSlowPath* slowpath) {
1257  slow_paths_.push_back(slowpath);
1258  ResetDefTracking();
1259}
1260
1261void Mir2Lir::LoadCodeAddress(const MethodReference& target_method, InvokeType type,
1262                              SpecialTargetRegister symbolic_reg) {
1263  LIR* data_target = ScanLiteralPoolMethod(code_literal_list_, target_method);
1264  if (data_target == nullptr) {
1265    data_target = AddWordData(&code_literal_list_, target_method.dex_method_index);
1266    data_target->operands[1] = WrapPointer(const_cast<DexFile*>(target_method.dex_file));
1267    // NOTE: The invoke type doesn't contribute to the literal identity. In fact, we can have
1268    // the same method invoked with kVirtual, kSuper and kInterface but the class linker will
1269    // resolve these invokes to the same method, so we don't care which one we record here.
1270    data_target->operands[2] = type;
1271  }
1272  // Loads a code pointer. Code from oat file can be mapped anywhere.
1273  OpPcRelLoad(TargetPtrReg(symbolic_reg), data_target);
1274  DCHECK_NE(cu_->instruction_set, kMips) << reinterpret_cast<void*>(data_target);
1275  DCHECK_NE(cu_->instruction_set, kMips64) << reinterpret_cast<void*>(data_target);
1276}
1277
1278void Mir2Lir::LoadMethodAddress(const MethodReference& target_method, InvokeType type,
1279                                SpecialTargetRegister symbolic_reg) {
1280  LIR* data_target = ScanLiteralPoolMethod(method_literal_list_, target_method);
1281  if (data_target == nullptr) {
1282    data_target = AddWordData(&method_literal_list_, target_method.dex_method_index);
1283    data_target->operands[1] = WrapPointer(const_cast<DexFile*>(target_method.dex_file));
1284    // NOTE: The invoke type doesn't contribute to the literal identity. In fact, we can have
1285    // the same method invoked with kVirtual, kSuper and kInterface but the class linker will
1286    // resolve these invokes to the same method, so we don't care which one we record here.
1287    data_target->operands[2] = type;
1288  }
1289  // Loads an ArtMethod pointer, which is a reference as it lives in the heap.
1290  OpPcRelLoad(TargetReg(symbolic_reg, kRef), data_target);
1291  DCHECK_NE(cu_->instruction_set, kMips) << reinterpret_cast<void*>(data_target);
1292  DCHECK_NE(cu_->instruction_set, kMips64) << reinterpret_cast<void*>(data_target);
1293}
1294
1295void Mir2Lir::LoadClassType(const DexFile& dex_file, uint32_t type_idx,
1296                            SpecialTargetRegister symbolic_reg) {
1297  // Use the literal pool and a PC-relative load from a data word.
1298  LIR* data_target = ScanLiteralPoolClass(class_literal_list_, dex_file, type_idx);
1299  if (data_target == nullptr) {
1300    data_target = AddWordData(&class_literal_list_, type_idx);
1301    data_target->operands[1] = WrapPointer(const_cast<DexFile*>(&dex_file));
1302  }
1303  // Loads a Class pointer, which is a reference as it lives in the heap.
1304  OpPcRelLoad(TargetReg(symbolic_reg, kRef), data_target);
1305}
1306
1307std::vector<uint8_t>* Mir2Lir::ReturnFrameDescriptionEntry() {
1308  // Default case is to do nothing.
1309  return nullptr;
1310}
1311
1312RegLocation Mir2Lir::NarrowRegLoc(RegLocation loc) {
1313  if (loc.location == kLocPhysReg) {
1314    DCHECK(!loc.reg.Is32Bit());
1315    if (loc.reg.IsPair()) {
1316      RegisterInfo* info_lo = GetRegInfo(loc.reg.GetLow());
1317      RegisterInfo* info_hi = GetRegInfo(loc.reg.GetHigh());
1318      info_lo->SetIsWide(false);
1319      info_hi->SetIsWide(false);
1320      loc.reg = info_lo->GetReg();
1321    } else {
1322      RegisterInfo* info = GetRegInfo(loc.reg);
1323      RegisterInfo* info_new = info->FindMatchingView(RegisterInfo::k32SoloStorageMask);
1324      DCHECK(info_new != nullptr);
1325      if (info->IsLive() && (info->SReg() == loc.s_reg_low)) {
1326        info->MarkDead();
1327        info_new->MarkLive(loc.s_reg_low);
1328      }
1329      loc.reg = info_new->GetReg();
1330    }
1331    DCHECK(loc.reg.Valid());
1332  }
1333  loc.wide = false;
1334  return loc;
1335}
1336
1337void Mir2Lir::GenMachineSpecificExtendedMethodMIR(BasicBlock* bb, MIR* mir) {
1338  UNUSED(bb, mir);
1339  LOG(FATAL) << "Unknown MIR opcode not supported on this architecture";
1340  UNREACHABLE();
1341}
1342
1343void Mir2Lir::InitReferenceVRegs(BasicBlock* bb, BitVector* references) {
1344  // Mark the references coming from the first predecessor.
1345  DCHECK(bb != nullptr);
1346  DCHECK(bb->block_type == kEntryBlock || !bb->predecessors.empty());
1347  BasicBlock* first_bb =
1348      (bb->block_type == kEntryBlock) ? bb : mir_graph_->GetBasicBlock(bb->predecessors[0]);
1349  DCHECK(first_bb != nullptr);
1350  DCHECK(first_bb->data_flow_info != nullptr);
1351  DCHECK(first_bb->data_flow_info->vreg_to_ssa_map_exit != nullptr);
1352  const int32_t* first_vreg_to_ssa_map = first_bb->data_flow_info->vreg_to_ssa_map_exit;
1353  references->ClearAllBits();
1354  for (uint32_t vreg = 0, num_vregs = mir_graph_->GetNumOfCodeVRs(); vreg != num_vregs; ++vreg) {
1355    int32_t sreg = first_vreg_to_ssa_map[vreg];
1356    if (sreg != INVALID_SREG && mir_graph_->reg_location_[sreg].ref &&
1357        !mir_graph_->IsConstantNullRef(mir_graph_->reg_location_[sreg])) {
1358      references->SetBit(vreg);
1359    }
1360  }
1361  // Unmark the references that are merging with a different value.
1362  for (size_t i = 1u, num_pred = bb->predecessors.size(); i < num_pred; ++i) {
1363    BasicBlock* pred_bb = mir_graph_->GetBasicBlock(bb->predecessors[i]);
1364    DCHECK(pred_bb != nullptr);
1365    DCHECK(pred_bb->data_flow_info != nullptr);
1366    DCHECK(pred_bb->data_flow_info->vreg_to_ssa_map_exit != nullptr);
1367    const int32_t* pred_vreg_to_ssa_map = pred_bb->data_flow_info->vreg_to_ssa_map_exit;
1368    for (uint32_t vreg : references->Indexes()) {
1369      if (first_vreg_to_ssa_map[vreg] != pred_vreg_to_ssa_map[vreg]) {
1370        // NOTE: The BitVectorSet::IndexIterator will not check the pointed-to bit again,
1371        // so clearing the bit has no effect on the iterator.
1372        references->ClearBit(vreg);
1373      }
1374    }
1375  }
1376  if (bb->block_type != kEntryBlock && bb->first_mir_insn != nullptr &&
1377      static_cast<int>(bb->first_mir_insn->dalvikInsn.opcode) == kMirOpCheckPart2) {
1378    // In Mir2Lir::MethodBlockCodeGen() we have artificially moved the throwing
1379    // instruction to the previous block. However, the MIRGraph data used above
1380    // doesn't reflect that, so we still need to process that MIR insn here.
1381    DCHECK_EQ(bb->predecessors.size(), 1u);
1382    BasicBlock* pred_bb = mir_graph_->GetBasicBlock(bb->predecessors[0]);
1383    DCHECK(pred_bb != nullptr);
1384    DCHECK(pred_bb->last_mir_insn != nullptr);
1385    UpdateReferenceVRegsLocal(nullptr, pred_bb->last_mir_insn, references);
1386  }
1387}
1388
1389bool Mir2Lir::UpdateReferenceVRegsLocal(MIR* mir, MIR* prev_mir, BitVector* references) {
1390  DCHECK(mir == nullptr || mir->bb == prev_mir->bb);
1391  DCHECK(prev_mir != nullptr);
1392  while (prev_mir != nullptr) {
1393    if (prev_mir == mir) {
1394      return true;
1395    }
1396    const size_t num_defs = prev_mir->ssa_rep->num_defs;
1397    const int32_t* defs = prev_mir->ssa_rep->defs;
1398    if (num_defs == 1u && mir_graph_->reg_location_[defs[0]].ref &&
1399        !mir_graph_->IsConstantNullRef(mir_graph_->reg_location_[defs[0]])) {
1400      references->SetBit(mir_graph_->SRegToVReg(defs[0]));
1401    } else {
1402      for (size_t i = 0u; i != num_defs; ++i) {
1403        references->ClearBit(mir_graph_->SRegToVReg(defs[i]));
1404      }
1405    }
1406    prev_mir = prev_mir->next;
1407  }
1408  return false;
1409}
1410
1411void Mir2Lir::UpdateReferenceVRegs(MIR* mir, MIR* prev_mir, BitVector* references) {
1412  if (mir == nullptr) {
1413    // Safepoint in entry sequence.
1414    InitReferenceVRegs(mir_graph_->GetEntryBlock(), references);
1415    return;
1416  }
1417  if (IsInstructionReturn(mir->dalvikInsn.opcode) ||
1418      mir->dalvikInsn.opcode == Instruction::RETURN_VOID_NO_BARRIER) {
1419    references->ClearAllBits();
1420    if (mir->dalvikInsn.opcode == Instruction::RETURN_OBJECT) {
1421      references->SetBit(mir_graph_->SRegToVReg(mir->ssa_rep->uses[0]));
1422    }
1423    return;
1424  }
1425  if (prev_mir != nullptr && mir->bb == prev_mir->bb &&
1426      UpdateReferenceVRegsLocal(mir, prev_mir, references)) {
1427    return;
1428  }
1429  BasicBlock* bb = mir_graph_->GetBasicBlock(mir->bb);
1430  DCHECK(bb != nullptr);
1431  InitReferenceVRegs(bb, references);
1432  bool success = UpdateReferenceVRegsLocal(mir, bb->first_mir_insn, references);
1433  DCHECK(success) << "MIR @0x" << std::hex << mir->offset << " not in BB#" << std::dec << mir->bb;
1434}
1435
1436}  // namespace art
1437