diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/code_generator_mips.cc | 124 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_mips.h | 1 | ||||
-rw-r--r-- | compiler/optimizing/nodes.cc | 21 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 1 | ||||
-rw-r--r-- | compiler/optimizing/nodes_arm.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/nodes_x86.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_cfi_test_expected.inc | 172 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_compiler.cc | 29 | ||||
-rw-r--r-- | compiler/optimizing/select_generator.cc | 4 |
9 files changed, 157 insertions, 199 deletions
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index 928d685fbe..ed0767ed52 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -665,6 +665,18 @@ void ParallelMoveResolverMIPS::Exchange(int index1, int index2, bool double_slot } } +void CodeGeneratorMIPS::ComputeSpillMask() { + core_spill_mask_ = allocated_registers_.GetCoreRegisters() & core_callee_save_mask_; + fpu_spill_mask_ = allocated_registers_.GetFloatingPointRegisters() & fpu_callee_save_mask_; + DCHECK_NE(core_spill_mask_, 0u) << "At least the return address register must be saved"; + // If there're FPU callee-saved registers and there's an odd number of GPR callee-saved + // registers, include the ZERO register to force alignment of FPU callee-saved registers + // within the stack frame. + if ((fpu_spill_mask_ != 0) && (POPCOUNT(core_spill_mask_) % 2 != 0)) { + core_spill_mask_ |= (1 << ZERO); + } +} + static dwarf::Reg DWARFReg(Register reg) { return dwarf::Reg::MipsCore(static_cast<int>(reg)); } @@ -694,105 +706,61 @@ void CodeGeneratorMIPS::GenerateFrameEntry() { } // Spill callee-saved registers. - // Note that their cumulative size is small and they can be indexed using - // 16-bit offsets. - - // TODO: increment/decrement SP in one step instead of two or remove this comment. - uint32_t ofs = FrameEntrySpillSize(); - bool unaligned_float = ofs & 0x7; - bool fpu_32bit = isa_features_.Is32BitFloatingPoint(); + uint32_t ofs = GetFrameSize(); __ IncreaseFrameSize(ofs); - for (int i = arraysize(kCoreCalleeSaves) - 1; i >= 0; --i) { - Register reg = kCoreCalleeSaves[i]; - if (allocated_registers_.ContainsCoreRegister(reg)) { - ofs -= kMipsWordSize; - __ Sw(reg, SP, ofs); + for (uint32_t mask = core_spill_mask_; mask != 0; ) { + Register reg = static_cast<Register>(MostSignificantBit(mask)); + mask ^= 1u << reg; + ofs -= kMipsWordSize; + // The ZERO register is only included for alignment. + if (reg != ZERO) { + __ StoreToOffset(kStoreWord, reg, SP, ofs); __ cfi().RelOffset(DWARFReg(reg), ofs); } } - for (int i = arraysize(kFpuCalleeSaves) - 1; i >= 0; --i) { - FRegister reg = kFpuCalleeSaves[i]; - if (allocated_registers_.ContainsFloatingPointRegister(reg)) { - ofs -= kMipsDoublewordSize; - // TODO: Change the frame to avoid unaligned accesses for fpu registers. - if (unaligned_float) { - if (fpu_32bit) { - __ Swc1(reg, SP, ofs); - __ Swc1(static_cast<FRegister>(reg + 1), SP, ofs + 4); - } else { - __ Mfhc1(TMP, reg); - __ Swc1(reg, SP, ofs); - __ Sw(TMP, SP, ofs + 4); - } - } else { - __ Sdc1(reg, SP, ofs); - } - // TODO: __ cfi().RelOffset(DWARFReg(reg), ofs); - } + for (uint32_t mask = fpu_spill_mask_; mask != 0; ) { + FRegister reg = static_cast<FRegister>(MostSignificantBit(mask)); + mask ^= 1u << reg; + ofs -= kMipsDoublewordSize; + __ StoreDToOffset(reg, SP, ofs); + // TODO: __ cfi().RelOffset(DWARFReg(reg), ofs); } - // Allocate the rest of the frame and store the current method pointer - // at its end. - - __ IncreaseFrameSize(GetFrameSize() - FrameEntrySpillSize()); - - static_assert(IsInt<16>(kCurrentMethodStackOffset), - "kCurrentMethodStackOffset must fit into int16_t"); - __ Sw(kMethodRegisterArgument, SP, kCurrentMethodStackOffset); + // Store the current method pointer. + __ StoreToOffset(kStoreWord, kMethodRegisterArgument, SP, kCurrentMethodStackOffset); } void CodeGeneratorMIPS::GenerateFrameExit() { __ cfi().RememberState(); if (!HasEmptyFrame()) { - // Deallocate the rest of the frame. - - __ DecreaseFrameSize(GetFrameSize() - FrameEntrySpillSize()); - // Restore callee-saved registers. - // Note that their cumulative size is small and they can be indexed using - // 16-bit offsets. - - // TODO: increment/decrement SP in one step instead of two or remove this comment. - - uint32_t ofs = 0; - bool unaligned_float = FrameEntrySpillSize() & 0x7; - bool fpu_32bit = isa_features_.Is32BitFloatingPoint(); - - for (size_t i = 0; i < arraysize(kFpuCalleeSaves); ++i) { - FRegister reg = kFpuCalleeSaves[i]; - if (allocated_registers_.ContainsFloatingPointRegister(reg)) { - if (unaligned_float) { - if (fpu_32bit) { - __ Lwc1(reg, SP, ofs); - __ Lwc1(static_cast<FRegister>(reg + 1), SP, ofs + 4); - } else { - __ Lwc1(reg, SP, ofs); - __ Lw(TMP, SP, ofs + 4); - __ Mthc1(TMP, reg); - } - } else { - __ Ldc1(reg, SP, ofs); - } - ofs += kMipsDoublewordSize; - // TODO: __ cfi().Restore(DWARFReg(reg)); - } - } - for (size_t i = 0; i < arraysize(kCoreCalleeSaves); ++i) { - Register reg = kCoreCalleeSaves[i]; - if (allocated_registers_.ContainsCoreRegister(reg)) { - __ Lw(reg, SP, ofs); - ofs += kMipsWordSize; + // For better instruction scheduling restore RA before other registers. + uint32_t ofs = GetFrameSize(); + for (uint32_t mask = core_spill_mask_; mask != 0; ) { + Register reg = static_cast<Register>(MostSignificantBit(mask)); + mask ^= 1u << reg; + ofs -= kMipsWordSize; + // The ZERO register is only included for alignment. + if (reg != ZERO) { + __ LoadFromOffset(kLoadWord, reg, SP, ofs); __ cfi().Restore(DWARFReg(reg)); } } - DCHECK_EQ(ofs, FrameEntrySpillSize()); - __ DecreaseFrameSize(ofs); + for (uint32_t mask = fpu_spill_mask_; mask != 0; ) { + FRegister reg = static_cast<FRegister>(MostSignificantBit(mask)); + mask ^= 1u << reg; + ofs -= kMipsDoublewordSize; + __ LoadDFromOffset(reg, SP, ofs); + // TODO: __ cfi().Restore(DWARFReg(reg)); + } + + __ DecreaseFrameSize(GetFrameSize()); } __ Jr(RA); diff --git a/compiler/optimizing/code_generator_mips.h b/compiler/optimizing/code_generator_mips.h index 435a869368..8c0bae628e 100644 --- a/compiler/optimizing/code_generator_mips.h +++ b/compiler/optimizing/code_generator_mips.h @@ -262,6 +262,7 @@ class CodeGeneratorMIPS : public CodeGenerator { OptimizingCompilerStats* stats = nullptr); virtual ~CodeGeneratorMIPS() {} + void ComputeSpillMask() OVERRIDE; void GenerateFrameEntry() OVERRIDE; void GenerateFrameExit() OVERRIDE; diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 150d6b029b..ae3c4b01e6 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -785,22 +785,6 @@ void HBasicBlock::ReplaceAndRemoveInstructionWith(HInstruction* initial, RemoveInstruction(initial); } -void HBasicBlock::MoveInstructionBefore(HInstruction* insn, HInstruction* cursor) { - DCHECK(!cursor->IsPhi()); - DCHECK(!insn->IsPhi()); - DCHECK(!insn->IsControlFlow()); - DCHECK(insn->CanBeMoved()); - DCHECK(!insn->HasSideEffects()); - - HBasicBlock* from_block = insn->GetBlock(); - HBasicBlock* to_block = cursor->GetBlock(); - DCHECK(from_block != to_block); - - from_block->RemoveInstruction(insn, /* ensure_safety */ false); - insn->SetBlock(to_block); - to_block->instructions_.InsertInstructionBefore(insn, cursor); -} - static void Add(HInstructionList* instruction_list, HBasicBlock* block, HInstruction* instruction) { @@ -1352,6 +1336,11 @@ std::ostream& operator<<(std::ostream& os, const HInstruction::InstructionKind& } void HInstruction::MoveBefore(HInstruction* cursor) { + DCHECK(!IsPhi()); + DCHECK(!IsControlFlow()); + DCHECK(CanBeMoved()); + DCHECK(!cursor->IsPhi()); + next_->previous_ = previous_; if (previous_ != nullptr) { previous_->next_ = next_; diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index da84afbb39..711a6c1b2d 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -1049,7 +1049,6 @@ class HBasicBlock : public ArenaObject<kArenaAllocBasicBlock> { // Replace instruction `initial` with `replacement` within this block. void ReplaceAndRemoveInstructionWith(HInstruction* initial, HInstruction* replacement); - void MoveInstructionBefore(HInstruction* insn, HInstruction* cursor); void AddPhi(HPhi* phi); void InsertPhiAfter(HPhi* instruction, HPhi* cursor); // RemoveInstruction and RemovePhi delete a given instruction from the respective diff --git a/compiler/optimizing/nodes_arm.h b/compiler/optimizing/nodes_arm.h index 371e8ef6bb..d9f9740e73 100644 --- a/compiler/optimizing/nodes_arm.h +++ b/compiler/optimizing/nodes_arm.h @@ -26,6 +26,8 @@ class HArmDexCacheArraysBase FINAL : public HExpression<0> { dex_file_(&dex_file), element_offset_(static_cast<size_t>(-1)) { } + bool CanBeMoved() const OVERRIDE { return true; } + void UpdateElementOffset(size_t element_offset) { // Use the lowest offset from the requested elements so that all offsets from // this base are non-negative because our assemblers emit negative-offset loads diff --git a/compiler/optimizing/nodes_x86.h b/compiler/optimizing/nodes_x86.h index c3696b5936..fa479760fe 100644 --- a/compiler/optimizing/nodes_x86.h +++ b/compiler/optimizing/nodes_x86.h @@ -26,6 +26,8 @@ class HX86ComputeBaseMethodAddress FINAL : public HExpression<0> { HX86ComputeBaseMethodAddress() : HExpression(Primitive::kPrimInt, SideEffects::None(), kNoDexPc) {} + bool CanBeMoved() const OVERRIDE { return true; } + DECLARE_INSTRUCTION(X86ComputeBaseMethodAddress); private: diff --git a/compiler/optimizing/optimizing_cfi_test_expected.inc b/compiler/optimizing/optimizing_cfi_test_expected.inc index fc66823b04..764160adce 100644 --- a/compiler/optimizing/optimizing_cfi_test_expected.inc +++ b/compiler/optimizing/optimizing_cfi_test_expected.inc @@ -140,53 +140,43 @@ static constexpr uint8_t expected_cfi_kX86_64[] = { // 0x0000002d: .cfi_def_cfa_offset: 64 static constexpr uint8_t expected_asm_kMips[] = { - 0xE4, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xBF, 0xAF, 0x14, 0x00, 0xB1, 0xAF, - 0x10, 0x00, 0xB0, 0xAF, 0x08, 0x00, 0xB6, 0xE7, 0x0C, 0x00, 0xB7, 0xE7, - 0x00, 0x00, 0xB4, 0xE7, 0x04, 0x00, 0xB5, 0xE7, 0xDC, 0xFF, 0xBD, 0x27, - 0x00, 0x00, 0xA4, 0xAF, 0x24, 0x00, 0xBD, 0x27, 0x00, 0x00, 0xB4, 0xC7, - 0x04, 0x00, 0xB5, 0xC7, 0x08, 0x00, 0xB6, 0xC7, 0x0C, 0x00, 0xB7, 0xC7, - 0x10, 0x00, 0xB0, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xBF, 0x8F, - 0x1C, 0x00, 0xBD, 0x27, 0x09, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, + 0xC0, 0xFF, 0xBD, 0x27, 0x3C, 0x00, 0xBF, 0xAF, 0x38, 0x00, 0xB1, 0xAF, + 0x34, 0x00, 0xB0, 0xAF, 0x28, 0x00, 0xB6, 0xF7, 0x20, 0x00, 0xB4, 0xF7, + 0x00, 0x00, 0xA4, 0xAF, 0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xB1, 0x8F, + 0x34, 0x00, 0xB0, 0x8F, 0x28, 0x00, 0xB6, 0xD7, 0x20, 0x00, 0xB4, 0xD7, + 0x40, 0x00, 0xBD, 0x27, 0x09, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, }; static constexpr uint8_t expected_cfi_kMips[] = { - 0x44, 0x0E, 0x1C, 0x44, 0x9F, 0x01, 0x44, 0x91, 0x02, 0x44, 0x90, 0x03, - 0x54, 0x0E, 0x40, 0x44, 0x0A, 0x44, 0x0E, 0x1C, 0x54, 0xD0, 0x44, 0xD1, - 0x44, 0xDF, 0x44, 0x0E, 0x00, 0x48, 0x0B, 0x0E, 0x40, + 0x44, 0x0E, 0x40, 0x44, 0x9F, 0x01, 0x44, 0x91, 0x02, 0x44, 0x90, 0x03, + 0x4C, 0x0A, 0x44, 0xDF, 0x44, 0xD1, 0x44, 0xD0, 0x4C, 0x0E, 0x00, 0x48, + 0x0B, 0x0E, 0x40, }; -// 0x00000000: addiu r29, r29, -28 -// 0x00000004: .cfi_def_cfa_offset: 28 -// 0x00000004: sw r31, +24(r29) +// 0x00000000: addiu r29, r29, -64 +// 0x00000004: .cfi_def_cfa_offset: 64 +// 0x00000004: sw r31, +60(r29) // 0x00000008: .cfi_offset: r31 at cfa-4 -// 0x00000008: sw r17, +20(r29) +// 0x00000008: sw r17, +56(r29) // 0x0000000c: .cfi_offset: r17 at cfa-8 -// 0x0000000c: sw r16, +16(r29) +// 0x0000000c: sw r16, +52(r29) // 0x00000010: .cfi_offset: r16 at cfa-12 -// 0x00000010: swc1 f22, +8(r29) -// 0x00000014: swc1 f23, +12(r29) -// 0x00000018: swc1 f20, +0(r29) -// 0x0000001c: swc1 f21, +4(r29) -// 0x00000020: addiu r29, r29, -36 -// 0x00000024: .cfi_def_cfa_offset: 64 -// 0x00000024: sw r4, +0(r29) -// 0x00000028: .cfi_remember_state -// 0x00000028: addiu r29, r29, 36 -// 0x0000002c: .cfi_def_cfa_offset: 28 -// 0x0000002c: lwc1 f20, +0(r29) -// 0x00000030: lwc1 f21, +4(r29) -// 0x00000034: lwc1 f22, +8(r29) -// 0x00000038: lwc1 f23, +12(r29) -// 0x0000003c: lw r16, +16(r29) -// 0x00000040: .cfi_restore: r16 -// 0x00000040: lw r17, +20(r29) -// 0x00000044: .cfi_restore: r17 -// 0x00000044: lw r31, +24(r29) -// 0x00000048: .cfi_restore: r31 -// 0x00000048: addiu r29, r29, 28 -// 0x0000004c: .cfi_def_cfa_offset: 0 -// 0x0000004c: jr r31 -// 0x00000050: nop -// 0x00000054: .cfi_restore_state -// 0x00000054: .cfi_def_cfa_offset: 64 +// 0x00000010: sdc1 f22, +40(r29) +// 0x00000014: sdc1 f20, +32(r29) +// 0x00000018: sw r4, +0(r29) +// 0x0000001c: .cfi_remember_state +// 0x0000001c: lw r31, +60(r29) +// 0x00000020: .cfi_restore: r31 +// 0x00000020: lw r17, +56(r29) +// 0x00000024: .cfi_restore: r17 +// 0x00000024: lw r16, +52(r29) +// 0x00000028: .cfi_restore: r16 +// 0x00000028: ldc1 f22, +40(r29) +// 0x0000002c: ldc1 f20, +32(r29) +// 0x00000030: addiu r29, r29, 64 +// 0x00000034: .cfi_def_cfa_offset: 0 +// 0x00000034: jr r31 +// 0x00000038: nop +// 0x0000003c: .cfi_restore_state +// 0x0000003c: .cfi_def_cfa_offset: 64 static constexpr uint8_t expected_asm_kMips64[] = { 0xD8, 0xFF, 0xBD, 0x67, 0x20, 0x00, 0xBF, 0xFF, 0x18, 0x00, 0xB1, 0xFF, @@ -349,75 +339,65 @@ static constexpr uint8_t expected_cfi_kThumb2_adjust[] = { // 0x00000098: .cfi_def_cfa_offset: 64 static constexpr uint8_t expected_asm_kMips_adjust_head[] = { - 0xE4, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xBF, 0xAF, 0x14, 0x00, 0xB1, 0xAF, - 0x10, 0x00, 0xB0, 0xAF, 0x08, 0x00, 0xB6, 0xE7, 0x0C, 0x00, 0xB7, 0xE7, - 0x00, 0x00, 0xB4, 0xE7, 0x04, 0x00, 0xB5, 0xE7, 0xDC, 0xFF, 0xBD, 0x27, + 0xC0, 0xFF, 0xBD, 0x27, 0x3C, 0x00, 0xBF, 0xAF, 0x38, 0x00, 0xB1, 0xAF, + 0x34, 0x00, 0xB0, 0xAF, 0x28, 0x00, 0xB6, 0xF7, 0x20, 0x00, 0xB4, 0xF7, 0x00, 0x00, 0xA4, 0xAF, 0x08, 0x00, 0x04, 0x14, 0xFC, 0xFF, 0xBD, 0x27, 0x00, 0x00, 0xBF, 0xAF, 0x00, 0x00, 0x10, 0x04, 0x02, 0x00, 0x01, 0x3C, 0x18, 0x00, 0x21, 0x34, 0x21, 0x08, 0x3F, 0x00, 0x00, 0x00, 0xBF, 0x8F, 0x09, 0x00, 0x20, 0x00, 0x04, 0x00, 0xBD, 0x27, }; static constexpr uint8_t expected_asm_kMips_adjust_tail[] = { - 0x24, 0x00, 0xBD, 0x27, 0x00, 0x00, 0xB4, 0xC7, 0x04, 0x00, 0xB5, 0xC7, - 0x08, 0x00, 0xB6, 0xC7, 0x0C, 0x00, 0xB7, 0xC7, 0x10, 0x00, 0xB0, 0x8F, - 0x14, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xBD, 0x27, + 0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xB1, 0x8F, 0x34, 0x00, 0xB0, 0x8F, + 0x28, 0x00, 0xB6, 0xD7, 0x20, 0x00, 0xB4, 0xD7, 0x40, 0x00, 0xBD, 0x27, 0x09, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, }; static constexpr uint8_t expected_cfi_kMips_adjust[] = { - 0x44, 0x0E, 0x1C, 0x44, 0x9F, 0x01, 0x44, 0x91, 0x02, 0x44, 0x90, 0x03, - 0x54, 0x0E, 0x40, 0x4C, 0x0E, 0x44, 0x60, 0x0E, 0x40, 0x04, 0x04, 0x00, - 0x02, 0x00, 0x0A, 0x44, 0x0E, 0x1C, 0x54, 0xD0, 0x44, 0xD1, 0x44, 0xDF, - 0x44, 0x0E, 0x00, 0x48, 0x0B, 0x0E, 0x40, + 0x44, 0x0E, 0x40, 0x44, 0x9F, 0x01, 0x44, 0x91, 0x02, 0x44, 0x90, 0x03, + 0x54, 0x0E, 0x44, 0x60, 0x0E, 0x40, 0x04, 0x04, 0x00, 0x02, 0x00, 0x0A, + 0x44, 0xDF, 0x44, 0xD1, 0x44, 0xD0, 0x4C, 0x0E, 0x00, 0x48, 0x0B, 0x0E, + 0x40, }; -// 0x00000000: addiu r29, r29, -28 -// 0x00000004: .cfi_def_cfa_offset: 28 -// 0x00000004: sw r31, +24(r29) +// 0x00000000: addiu r29, r29, -64 +// 0x00000004: .cfi_def_cfa_offset: 64 +// 0x00000004: sw r31, +60(r29) // 0x00000008: .cfi_offset: r31 at cfa-4 -// 0x00000008: sw r17, +20(r29) +// 0x00000008: sw r17, +56(r29) // 0x0000000c: .cfi_offset: r17 at cfa-8 -// 0x0000000c: sw r16, +16(r29) +// 0x0000000c: sw r16, +52(r29) // 0x00000010: .cfi_offset: r16 at cfa-12 -// 0x00000010: swc1 f22, +8(r29) -// 0x00000014: swc1 f23, +12(r29) -// 0x00000018: swc1 f20, +0(r29) -// 0x0000001c: swc1 f21, +4(r29) -// 0x00000020: addiu r29, r29, -36 -// 0x00000024: .cfi_def_cfa_offset: 64 -// 0x00000024: sw r4, +0(r29) -// 0x00000028: bne r0, r4, 0x0000004c ; +36 -// 0x0000002c: addiu r29, r29, -4 -// 0x00000030: .cfi_def_cfa_offset: 68 -// 0x00000030: sw r31, +0(r29) -// 0x00000034: bltzal r0, 0x00000038 ; +4 -// 0x00000038: lui r1, 0x20000 -// 0x0000003c: ori r1, r1, 24 -// 0x00000040: addu r1, r1, r31 -// 0x00000044: lw r31, +0(r29) -// 0x00000048: jr r1 -// 0x0000004c: addiu r29, r29, 4 -// 0x00000050: .cfi_def_cfa_offset: 64 -// 0x00000050: nop +// 0x00000010: sdc1 f22, +40(r29) +// 0x00000014: sdc1 f20, +32(r29) +// 0x00000018: sw r4, +0(r29) +// 0x0000001c: bne r0, r4, 0x00000040 ; +36 +// 0x00000020: addiu r29, r29, -4 +// 0x00000024: .cfi_def_cfa_offset: 68 +// 0x00000024: sw r31, +0(r29) +// 0x00000028: bltzal r0, 0x0000002c ; +4 +// 0x0000002c: lui r1, 0x20000 +// 0x00000030: ori r1, r1, 24 +// 0x00000034: addu r1, r1, r31 +// 0x00000038: lw r31, +0(r29) +// 0x0000003c: jr r1 +// 0x00000040: addiu r29, r29, 4 +// 0x00000044: .cfi_def_cfa_offset: 64 +// 0x00000044: nop // ... -// 0x00020050: nop -// 0x00020054: .cfi_remember_state -// 0x00020054: addiu r29, r29, 36 -// 0x00020058: .cfi_def_cfa_offset: 28 -// 0x00020058: lwc1 f20, +0(r29) -// 0x0002005c: lwc1 f21, +4(r29) -// 0x00020060: lwc1 f22, +8(r29) -// 0x00020064: lwc1 f23, +12(r29) -// 0x00020068: lw r16, +16(r29) -// 0x0002006c: .cfi_restore: r16 -// 0x0002006c: lw r17, +20(r29) -// 0x00020070: .cfi_restore: r17 -// 0x00020070: lw r31, +24(r29) -// 0x00020074: .cfi_restore: r31 -// 0x00020074: addiu r29, r29, 28 -// 0x00020078: .cfi_def_cfa_offset: 0 -// 0x00020078: jr r31 -// 0x0002007c: nop -// 0x00020080: .cfi_restore_state -// 0x00020080: .cfi_def_cfa_offset: 64 +// 0x00020044: nop +// 0x00020048: .cfi_remember_state +// 0x00020048: lw r31, +60(r29) +// 0x0002004c: .cfi_restore: r31 +// 0x0002004c: lw r17, +56(r29) +// 0x00020050: .cfi_restore: r17 +// 0x00020050: lw r16, +52(r29) +// 0x00020054: .cfi_restore: r16 +// 0x00020054: ldc1 f22, +40(r29) +// 0x00020058: ldc1 f20, +32(r29) +// 0x0002005c: addiu r29, r29, 64 +// 0x00020060: .cfi_def_cfa_offset: 0 +// 0x00020060: jr r31 +// 0x00020064: nop +// 0x00020068: .cfi_restore_state +// 0x00020068: .cfi_def_cfa_offset: 64 static constexpr uint8_t expected_asm_kMips64_adjust_head[] = { 0xD8, 0xFF, 0xBD, 0x67, 0x20, 0x00, 0xBF, 0xFF, 0x18, 0x00, 0xB1, 0xFF, diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 37197af460..c9a4bfe987 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -321,6 +321,7 @@ class OptimizingCompiler FINAL : public Compiler { jobject class_loader, const DexFile& dex_file, Handle<mirror::DexCache> dex_cache, + ArtMethod* method, bool osr) const; std::unique_ptr<OptimizingCompilerStats> compilation_stats_; @@ -614,6 +615,7 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, jobject class_loader, const DexFile& dex_file, Handle<mirror::DexCache> dex_cache, + ArtMethod* method, bool osr) const { MaybeRecordStat(MethodCompilationStat::kAttemptCompilation); CompilerDriver* compiler_driver = GetCompilerDriver(); @@ -679,17 +681,30 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, osr); const uint8_t* interpreter_metadata = nullptr; - { + if (method == nullptr) { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> loader(hs.NewHandle( soa.Decode<mirror::ClassLoader*>(class_loader))); - ArtMethod* art_method = compiler_driver->ResolveMethod( + method = compiler_driver->ResolveMethod( soa, dex_cache, loader, &dex_compilation_unit, method_idx, invoke_type); - // We may not get a method, for example if its class is erroneous. - if (art_method != nullptr) { - graph->SetArtMethod(art_method); - interpreter_metadata = art_method->GetQuickenedInfo(); + } + // For AOT compilation, we may not get a method, for example if its class is erroneous. + // JIT should always have a method. + DCHECK(Runtime::Current()->IsAotCompiler() || method != nullptr); + if (method != nullptr) { + graph->SetArtMethod(method); + ScopedObjectAccess soa(Thread::Current()); + interpreter_metadata = method->GetQuickenedInfo(); + uint16_t type_index = method->GetDeclaringClass()->GetDexTypeIndex(); + + // Update the dex cache if the type is not in it yet. Note that under AOT, + // the verifier must have set it, but under JIT, there's no guarantee, as we + // don't necessarily run the verifier. + // The compiler and the compiler driver assume the compiling class is + // in the dex cache. + if (dex_cache->GetResolvedType(type_index) == nullptr) { + dex_cache->SetResolvedType(type_index, method->GetDeclaringClass()); } } @@ -798,6 +813,7 @@ CompiledMethod* OptimizingCompiler::Compile(const DexFile::CodeItem* code_item, jclass_loader, dex_file, dex_cache, + nullptr, /* osr */ false)); if (codegen.get() != nullptr) { MaybeRecordStat(MethodCompilationStat::kCompiled); @@ -884,6 +900,7 @@ bool OptimizingCompiler::JitCompile(Thread* self, jclass_loader, *dex_file, dex_cache, + method, osr)); if (codegen.get() == nullptr) { return false; diff --git a/compiler/optimizing/select_generator.cc b/compiler/optimizing/select_generator.cc index e52476ea03..e409035d9d 100644 --- a/compiler/optimizing/select_generator.cc +++ b/compiler/optimizing/select_generator.cc @@ -96,10 +96,10 @@ void HSelectGenerator::Run() { // TODO(dbrazdil): This puts an instruction between If and its condition. // Implement moving of conditions to first users if possible. if (!true_block->IsSingleGoto()) { - true_block->MoveInstructionBefore(true_block->GetFirstInstruction(), if_instruction); + true_block->GetFirstInstruction()->MoveBefore(if_instruction); } if (!false_block->IsSingleGoto()) { - false_block->MoveInstructionBefore(false_block->GetFirstInstruction(), if_instruction); + false_block->GetFirstInstruction()->MoveBefore(if_instruction); } DCHECK(true_block->IsSingleGoto()); DCHECK(false_block->IsSingleGoto()); |