diff options
46 files changed, 707 insertions, 695 deletions
diff --git a/build/Android.libart-compiler.mk b/build/Android.libart-compiler.mk index 4452f05f52..b73a32961e 100644 --- a/build/Android.libart-compiler.mk +++ b/build/Android.libart-compiler.mk @@ -45,7 +45,6 @@ LIBART_COMPILER_SRC_FILES := \ src/compiler/dex/quick/x86/utility_x86.cc \ src/compiler/dex/portable/mir_to_gbc.cc \ src/compiler/dex/mir_dataflow.cc \ - src/compiler/dex/dataflow_iterator.cc \ src/compiler/dex/mir_optimization.cc \ src/compiler/dex/frontend.cc \ src/compiler/dex/mir_graph.cc \ diff --git a/src/compiler/dex/arena_bit_vector.cc b/src/compiler/dex/arena_bit_vector.cc index c858ea1563..1fbf7740ac 100644 --- a/src/compiler/dex/arena_bit_vector.cc +++ b/src/compiler/dex/arena_bit_vector.cc @@ -113,18 +113,6 @@ void ArenaBitVector::Union(const ArenaBitVector* src) { } } -// Are we equal to another bit vector? Note: expandability attributes must also match. -bool ArenaBitVector::Equal(const ArenaBitVector* src) { - if (storage_size_ != src->GetStorageSize() || - expandable_ != src->IsExpandable()) - return false; - - for (unsigned int idx = 0; idx < storage_size_; idx++) { - if (storage_[idx] != src->GetRawStorageWord(idx)) return false; - } - return true; -} - // Count the number of bits that are set. int ArenaBitVector::NumSetBits() { diff --git a/src/compiler/dex/arena_bit_vector.h b/src/compiler/dex/arena_bit_vector.h index a66147ba5f..a950e82498 100644 --- a/src/compiler/dex/arena_bit_vector.h +++ b/src/compiler/dex/arena_bit_vector.h @@ -99,13 +99,19 @@ class ArenaBitVector { void Copy(ArenaBitVector* src); void Intersect(const ArenaBitVector* src2); void Union(const ArenaBitVector* src); - bool Equal(const ArenaBitVector* src); + // Are we equal to another bit vector? Note: expandability attributes must also match. + bool Equal(const ArenaBitVector* src) { + return (storage_size_ == src->GetStorageSize()) && + (expandable_ == src->IsExpandable()) && + (memcmp(storage_, src->GetRawStorage(), storage_size_ * 4) == 0); + } int NumSetBits(); uint32_t GetStorageSize() const { return storage_size_; } bool IsExpandable() const { return expandable_; } uint32_t GetRawStorageWord(size_t idx) const { return storage_[idx]; } uint32_t* GetRawStorage() { return storage_; } + const uint32_t* GetRawStorage() const { return storage_; } private: ArenaAllocator* const arena_; diff --git a/src/compiler/dex/dataflow_iterator-inl.h b/src/compiler/dex/dataflow_iterator-inl.h new file mode 100644 index 0000000000..b20004decc --- /dev/null +++ b/src/compiler/dex/dataflow_iterator-inl.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_SRC_COMPILER_DEX_DATAFLOW_ITERATOR_INL_H_ +#define ART_SRC_COMPILER_DEX_DATAFLOW_ITERATOR_INL_H_ + +#include "dataflow_iterator.h" + +namespace art { + +inline BasicBlock* DataflowIterator::NextBody(bool had_change) { + changed_ |= had_change; + BasicBlock* res = NULL; + if (reverse_) { + if (is_iterative_ && changed_ && (idx_ < 0)) { + idx_ = start_idx_; + changed_ = false; + } + if (idx_ >= 0) { + int bb_id = block_id_list_->Get(idx_--); + res = mir_graph_->GetBasicBlock(bb_id); + } + } else { + if (is_iterative_ && changed_ && (idx_ >= end_idx_)) { + idx_ = start_idx_; + changed_ = false; + } + if (idx_ < end_idx_) { + int bb_id = block_id_list_->Get(idx_++); + res = mir_graph_->GetBasicBlock(bb_id); + } + } + return res; +} + +// AllNodes uses the existing GrowableArray iterator, so use different NextBody(). +inline BasicBlock* AllNodesIterator::NextBody(bool had_change) { + changed_ |= had_change; + BasicBlock* res = NULL; + bool keep_looking = true; + while (keep_looking) { + res = all_nodes_iterator_->Next(); + if (is_iterative_ && changed_ && (res == NULL)) { + all_nodes_iterator_->Reset(); + changed_ = false; + } else if ((res == NULL) || (!res->hidden)) { + keep_looking = false; + } + } + return res; +} + +} // namespace art + +#endif // ART_SRC_COMPILER_DEX_DATAFLOW_ITERATOR_INL_H_ diff --git a/src/compiler/dex/dataflow_iterator.cc b/src/compiler/dex/dataflow_iterator.cc deleted file mode 100644 index bb5b969925..0000000000 --- a/src/compiler/dex/dataflow_iterator.cc +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "dataflow_iterator.h" - -namespace art { - - BasicBlock* DataflowIterator::NextBody(bool had_change) { - changed_ |= had_change; - BasicBlock* res = NULL; - if (reverse_) { - if (is_iterative_ && changed_ && (idx_ < 0)) { - idx_ = start_idx_; - changed_ = false; - } - if (idx_ >= 0) { - int bb_id = block_id_list_->Get(idx_--); - res = mir_graph_->GetBasicBlock(bb_id); - } - } else { - if (is_iterative_ && changed_ && (idx_ >= end_idx_)) { - idx_ = start_idx_; - changed_ = false; - } - if (idx_ < end_idx_) { - int bb_id = block_id_list_->Get(idx_++); - res = mir_graph_->GetBasicBlock(bb_id); - } - } - return res; - } - - // AllNodes uses the existing GrowableArray iterator, so use different NextBody(). - BasicBlock* AllNodesIterator::NextBody(bool had_change) { - changed_ |= had_change; - BasicBlock* res = NULL; - bool keep_looking = true; - while (keep_looking) { - res = all_nodes_iterator_->Next(); - if (is_iterative_ && changed_ && (res == NULL)) { - all_nodes_iterator_->Reset(); - changed_ = false; - } else if ((res == NULL) || (!res->hidden)) { - keep_looking = false; - } - } - return res; - } - -} // namespace art diff --git a/src/compiler/dex/dataflow_iterator.h b/src/compiler/dex/dataflow_iterator.h index a4b38bd80f..12cbf9cadf 100644 --- a/src/compiler/dex/dataflow_iterator.h +++ b/src/compiler/dex/dataflow_iterator.h @@ -71,7 +71,7 @@ namespace art { idx_(0), changed_(false) {} - virtual BasicBlock* NextBody(bool had_change); + virtual BasicBlock* NextBody(bool had_change) ALWAYS_INLINE; MIRGraph* const mir_graph_; const bool is_iterative_; @@ -86,7 +86,6 @@ namespace art { class ReachableNodesIterator : public DataflowIterator { public: - ReachableNodesIterator(MIRGraph* mir_graph, bool is_iterative) : DataflowIterator(mir_graph, is_iterative, 0, mir_graph->GetNumReachableBlocks(), false) { @@ -97,7 +96,6 @@ namespace art { class PreOrderDfsIterator : public DataflowIterator { public: - PreOrderDfsIterator(MIRGraph* mir_graph, bool is_iterative) : DataflowIterator(mir_graph, is_iterative, 0, mir_graph->GetNumReachableBlocks(), false) { @@ -119,7 +117,6 @@ namespace art { class ReversePostOrderDfsIterator : public DataflowIterator { public: - ReversePostOrderDfsIterator(MIRGraph* mir_graph, bool is_iterative) : DataflowIterator(mir_graph, is_iterative, mir_graph->GetNumReachableBlocks() -1, 0, true) { @@ -130,7 +127,6 @@ namespace art { class PostOrderDOMIterator : public DataflowIterator { public: - PostOrderDOMIterator(MIRGraph* mir_graph, bool is_iterative) : DataflowIterator(mir_graph, is_iterative, 0, mir_graph->GetNumReachableBlocks(), false) { @@ -141,18 +137,17 @@ namespace art { class AllNodesIterator : public DataflowIterator { public: - AllNodesIterator(MIRGraph* mir_graph, bool is_iterative) : DataflowIterator(mir_graph, is_iterative, 0, 0, false) { all_nodes_iterator_ = new (mir_graph->GetArena()) GrowableArray<BasicBlock*>::Iterator (mir_graph->GetBlockList()); } - virtual void Reset() { + void Reset() { all_nodes_iterator_->Reset(); } - virtual BasicBlock* NextBody(bool had_change); + BasicBlock* NextBody(bool had_change) ALWAYS_INLINE; private: GrowableArray<BasicBlock*>::Iterator* all_nodes_iterator_; diff --git a/src/compiler/dex/frontend.cc b/src/compiler/dex/frontend.cc index ca751ab849..e015645584 100644 --- a/src/compiler/dex/frontend.cc +++ b/src/compiler/dex/frontend.cc @@ -18,7 +18,7 @@ #include "compiler/driver/compiler_driver.h" #include "compiler_internals.h" -#include "dataflow_iterator.h" +#include "dataflow_iterator-inl.h" #if defined(ART_USE_PORTABLE_COMPILER) #include "compiler/llvm/llvm_compilation_unit.h" #include "compiler/dex/portable/mir_to_gbc.h" diff --git a/src/compiler/dex/mir_dataflow.cc b/src/compiler/dex/mir_dataflow.cc index 0baf6308ae..79eac6d14c 100644 --- a/src/compiler/dex/mir_dataflow.cc +++ b/src/compiler/dex/mir_dataflow.cc @@ -16,7 +16,7 @@ #include "compiler_internals.h" #include "local_value_numbering.h" -#include "dataflow_iterator.h" +#include "dataflow_iterator-inl.h" namespace art { @@ -933,11 +933,6 @@ int MIRGraph::AddNewSReg(int v_reg) SetNumSSARegs(ssa_reg + 1); ssa_base_vregs_->Insert(v_reg); ssa_subscripts_->Insert(subscript); - std::string ssa_name(GetSSAName(ssa_reg)); - char* name = static_cast<char*>(arena_->NewMem(ssa_name.length() + 1, false, - ArenaAllocator::kAllocDFInfo)); - strncpy(name, ssa_name.c_str(), ssa_name.length() + 1); - ssa_strings_->Insert(name); DCHECK_EQ(ssa_base_vregs_->Size(), ssa_subscripts_->Size()); return ssa_reg; } @@ -1140,8 +1135,6 @@ void MIRGraph::CompilerInitializeSSAConversion() kGrowableArraySSAtoDalvikMap); ssa_subscripts_ = new (arena_) GrowableArray<int>(arena_, num_dalvik_reg + GetDefCount() + 128, kGrowableArraySSAtoDalvikMap); - ssa_strings_ = new (arena_) GrowableArray<char*>(arena_, num_dalvik_reg + GetDefCount() + 128, - kGrowableArraySSAtoDalvikMap); /* * Initial number of SSA registers is equal to the number of Dalvik * registers. @@ -1156,11 +1149,6 @@ void MIRGraph::CompilerInitializeSSAConversion() for (unsigned int i = 0; i < num_dalvik_reg; i++) { ssa_base_vregs_->Insert(i); ssa_subscripts_->Insert(0); - std::string ssa_name = GetSSAName(i); - char* name = static_cast<char*>(arena_->NewMem(ssa_name.length() + 1, true, - ArenaAllocator::kAllocDFInfo)); - strncpy(name, ssa_name.c_str(), ssa_name.length() + 1); - ssa_strings_->Insert(name); } /* diff --git a/src/compiler/dex/mir_graph.cc b/src/compiler/dex/mir_graph.cc index fe0f0c7c85..11e100dc61 100644 --- a/src/compiler/dex/mir_graph.cc +++ b/src/compiler/dex/mir_graph.cc @@ -77,7 +77,6 @@ MIRGraph::MIRGraph(CompilationUnit* cu, ArenaAllocator* arena) cu_(cu), ssa_base_vregs_(NULL), ssa_subscripts_(NULL), - ssa_strings_(NULL), vreg_to_ssa_map_(NULL), ssa_last_defs_(NULL), is_constant_v_(NULL), diff --git a/src/compiler/dex/mir_graph.h b/src/compiler/dex/mir_graph.h index 882a5088d7..2b1c21fd70 100644 --- a/src/compiler/dex/mir_graph.h +++ b/src/compiler/dex/mir_graph.h @@ -452,10 +452,6 @@ class MIRGraph { return ssa_subscripts_->Get(ssa_reg); } - const char* GetSSAString(int ssa_reg) const { - return ssa_strings_->Get(ssa_reg); - } - RegLocation GetRawSrc(MIR* mir, int num) { DCHECK(num < mir->ssa_rep->num_uses); @@ -628,7 +624,6 @@ class MIRGraph { CompilationUnit* const cu_; GrowableArray<int>* ssa_base_vregs_; GrowableArray<int>* ssa_subscripts_; - GrowableArray<char*>* ssa_strings_; // Map original Dalvik virtual reg i to the current SSA name. int* vreg_to_ssa_map_; // length == method->registers_size int* ssa_last_defs_; // length == method->registers_size diff --git a/src/compiler/dex/mir_optimization.cc b/src/compiler/dex/mir_optimization.cc index 74b13fe47e..d9c443e536 100644 --- a/src/compiler/dex/mir_optimization.cc +++ b/src/compiler/dex/mir_optimization.cc @@ -16,7 +16,7 @@ #include "compiler_internals.h" #include "local_value_numbering.h" -#include "dataflow_iterator.h" +#include "dataflow_iterator-inl.h" namespace art { diff --git a/src/compiler/dex/portable/mir_to_gbc.cc b/src/compiler/dex/portable/mir_to_gbc.cc index 6fccb47d9f..1f9c92a3d2 100644 --- a/src/compiler/dex/portable/mir_to_gbc.cc +++ b/src/compiler/dex/portable/mir_to_gbc.cc @@ -28,7 +28,7 @@ #include <llvm/Support/ToolOutputFile.h> #include "compiler/dex/compiler_internals.h" -#include "compiler/dex/dataflow_iterator.h" +#include "compiler/dex/dataflow_iterator-inl.h" #include "compiler/dex/frontend.h" #include "mir_to_gbc.h" @@ -1964,7 +1964,7 @@ void MirConverter::MethodMIR2Bitcode() ::llvm::Constant* imm_value = mir_graph_->reg_location_[i].wide ? irb_->getJLong(0) : irb_->getJInt(0); val = EmitConst(imm_value, mir_graph_->reg_location_[i]); - val->setName(mir_graph_->GetSSAString(i)); + val->setName(mir_graph_->GetSSAName(i)); llvm_values_.Insert(val); } else { // Recover previously-created argument values diff --git a/src/compiler/dex/quick/arm/assemble_arm.cc b/src/compiler/dex/quick/arm/assemble_arm.cc index 23a87dcec1..36038f7741 100644 --- a/src/compiler/dex/quick/arm/assemble_arm.cc +++ b/src/compiler/dex/quick/arm/assemble_arm.cc @@ -16,6 +16,7 @@ #include "arm_lir.h" #include "codegen_arm.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" namespace art { diff --git a/src/compiler/dex/quick/arm/call_arm.cc b/src/compiler/dex/quick/arm/call_arm.cc index 32d4ed680f..77e09b8e4e 100644 --- a/src/compiler/dex/quick/arm/call_arm.cc +++ b/src/compiler/dex/quick/arm/call_arm.cc @@ -18,6 +18,7 @@ #include "arm_lir.h" #include "codegen_arm.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" #include "oat/runtime/oat_support_entrypoints.h" namespace art { diff --git a/src/compiler/dex/quick/arm/codegen_arm.h b/src/compiler/dex/quick/arm/codegen_arm.h index 9e409e6772..60111d1d06 100644 --- a/src/compiler/dex/quick/arm/codegen_arm.h +++ b/src/compiler/dex/quick/arm/codegen_arm.h @@ -23,143 +23,142 @@ namespace art { class ArmMir2Lir : public Mir2Lir { public: - ArmMir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena); // Required for target - codegen helpers. - virtual bool SmallLiteralDivide(Instruction::Code dalvik_opcode, RegLocation rl_src, + bool SmallLiteralDivide(Instruction::Code dalvik_opcode, RegLocation rl_src, RegLocation rl_dest, int lit); - virtual int LoadHelper(int offset); - virtual LIR* LoadBaseDisp(int rBase, int displacement, int r_dest, OpSize size, int s_reg); - virtual LIR* LoadBaseDispWide(int rBase, int displacement, int r_dest_lo, int r_dest_hi, - int s_reg); - virtual LIR* LoadBaseIndexed(int rBase, int r_index, int r_dest, int scale, OpSize size); - virtual LIR* LoadBaseIndexedDisp(int rBase, int r_index, int scale, int displacement, - int r_dest, int r_dest_hi, OpSize size, int s_reg); - virtual LIR* LoadConstantNoClobber(int r_dest, int value); - virtual LIR* LoadConstantWide(int r_dest_lo, int r_dest_hi, int64_t value); - virtual LIR* StoreBaseDisp(int rBase, int displacement, int r_src, OpSize size); - virtual LIR* StoreBaseDispWide(int rBase, int displacement, int r_src_lo, int r_src_hi); - virtual LIR* StoreBaseIndexed(int rBase, int r_index, int r_src, int scale, OpSize size); - virtual LIR* StoreBaseIndexedDisp(int rBase, int r_index, int scale, int displacement, - int r_src, int r_src_hi, OpSize size, int s_reg); - virtual void MarkGCCard(int val_reg, int tgt_addr_reg); + int LoadHelper(int offset); + LIR* LoadBaseDisp(int rBase, int displacement, int r_dest, OpSize size, int s_reg); + LIR* LoadBaseDispWide(int rBase, int displacement, int r_dest_lo, int r_dest_hi, + int s_reg); + LIR* LoadBaseIndexed(int rBase, int r_index, int r_dest, int scale, OpSize size); + LIR* LoadBaseIndexedDisp(int rBase, int r_index, int scale, int displacement, + int r_dest, int r_dest_hi, OpSize size, int s_reg); + LIR* LoadConstantNoClobber(int r_dest, int value); + LIR* LoadConstantWide(int r_dest_lo, int r_dest_hi, int64_t value); + LIR* StoreBaseDisp(int rBase, int displacement, int r_src, OpSize size); + LIR* StoreBaseDispWide(int rBase, int displacement, int r_src_lo, int r_src_hi); + LIR* StoreBaseIndexed(int rBase, int r_index, int r_src, int scale, OpSize size); + LIR* StoreBaseIndexedDisp(int rBase, int r_index, int scale, int displacement, + int r_src, int r_src_hi, OpSize size, int s_reg); + void MarkGCCard(int val_reg, int tgt_addr_reg); // Required for target - register utilities. - virtual bool IsFpReg(int reg); - virtual bool SameRegType(int reg1, int reg2); - virtual int AllocTypedTemp(bool fp_hint, int reg_class); - virtual int AllocTypedTempPair(bool fp_hint, int reg_class); - virtual int S2d(int low_reg, int high_reg); - virtual int TargetReg(SpecialTargetRegister reg); - virtual RegisterInfo* GetRegInfo(int reg); - virtual RegLocation GetReturnAlt(); - virtual RegLocation GetReturnWideAlt(); - virtual RegLocation LocCReturn(); - virtual RegLocation LocCReturnDouble(); - virtual RegLocation LocCReturnFloat(); - virtual RegLocation LocCReturnWide(); - virtual uint32_t FpRegMask(); - virtual uint64_t GetRegMaskCommon(int reg); - virtual void AdjustSpillMask(); - virtual void ClobberCalleeSave(); - virtual void FlushReg(int reg); - virtual void FlushRegWide(int reg1, int reg2); - virtual void FreeCallTemps(); - virtual void FreeRegLocTemps(RegLocation rl_keep, RegLocation rl_free); - virtual void LockCallTemps(); - virtual void MarkPreservedSingle(int v_reg, int reg); - virtual void CompilerInitializeRegAlloc(); + bool IsFpReg(int reg); + bool SameRegType(int reg1, int reg2); + int AllocTypedTemp(bool fp_hint, int reg_class); + int AllocTypedTempPair(bool fp_hint, int reg_class); + int S2d(int low_reg, int high_reg); + int TargetReg(SpecialTargetRegister reg); + RegisterInfo* GetRegInfo(int reg); + RegLocation GetReturnAlt(); + RegLocation GetReturnWideAlt(); + RegLocation LocCReturn(); + RegLocation LocCReturnDouble(); + RegLocation LocCReturnFloat(); + RegLocation LocCReturnWide(); + uint32_t FpRegMask(); + uint64_t GetRegMaskCommon(int reg); + void AdjustSpillMask(); + void ClobberCalleeSave(); + void FlushReg(int reg); + void FlushRegWide(int reg1, int reg2); + void FreeCallTemps(); + void FreeRegLocTemps(RegLocation rl_keep, RegLocation rl_free); + void LockCallTemps(); + void MarkPreservedSingle(int v_reg, int reg); + void CompilerInitializeRegAlloc(); // Required for target - miscellaneous. - virtual AssemblerStatus AssembleInstructions(uintptr_t start_addr); - virtual void DumpResourceMask(LIR* lir, uint64_t mask, const char* prefix); - virtual void SetupTargetResourceMasks(LIR* lir); - virtual const char* GetTargetInstFmt(int opcode); - virtual const char* GetTargetInstName(int opcode); - virtual std::string BuildInsnString(const char* fmt, LIR* lir, unsigned char* base_addr); - virtual uint64_t GetPCUseDefEncoding(); - virtual uint64_t GetTargetInstFlags(int opcode); - virtual int GetInsnSize(LIR* lir); - virtual bool IsUnconditionalBranch(LIR* lir); + AssemblerStatus AssembleInstructions(uintptr_t start_addr); + void DumpResourceMask(LIR* lir, uint64_t mask, const char* prefix); + void SetupTargetResourceMasks(LIR* lir); + const char* GetTargetInstFmt(int opcode); + const char* GetTargetInstName(int opcode); + std::string BuildInsnString(const char* fmt, LIR* lir, unsigned char* base_addr); + uint64_t GetPCUseDefEncoding(); + uint64_t GetTargetInstFlags(int opcode); + int GetInsnSize(LIR* lir); + bool IsUnconditionalBranch(LIR* lir); // Required for target - Dalvik-level generators. - virtual void GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_src2); - virtual void GenArrayObjPut(int opt_flags, RegLocation rl_array, RegLocation rl_index, - RegLocation rl_src, int scale); - virtual void GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array, - RegLocation rl_index, RegLocation rl_dest, int scale); - virtual void GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, - RegLocation rl_index, RegLocation rl_src, int scale); - virtual void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_shift); - virtual void GenMulLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenAddLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenAndLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenArithOpDouble(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_src2); - virtual void GenArithOpFloat(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_src2); - virtual void GenCmpFP(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2); - virtual void GenConversion(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src); - virtual bool GenInlinedCas32(CallInfo* info, bool need_write_barrier); - virtual bool GenInlinedMinMaxInt(CallInfo* info, bool is_min); - virtual bool GenInlinedSqrt(CallInfo* info); - virtual void GenNegLong(RegLocation rl_dest, RegLocation rl_src); - virtual void GenOrLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenSubLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenXorLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual LIR* GenRegMemCheck(ConditionCode c_code, int reg1, int base, int offset, + void GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest, + RegLocation rl_src1, RegLocation rl_src2); + void GenArrayObjPut(int opt_flags, RegLocation rl_array, RegLocation rl_index, + RegLocation rl_src, int scale); + void GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array, + RegLocation rl_index, RegLocation rl_dest, int scale); + void GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, + RegLocation rl_index, RegLocation rl_src, int scale); + void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest, + RegLocation rl_src1, RegLocation rl_shift); + void GenMulLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + void GenAddLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + void GenAndLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + void GenArithOpDouble(Instruction::Code opcode, RegLocation rl_dest, + RegLocation rl_src1, RegLocation rl_src2); + void GenArithOpFloat(Instruction::Code opcode, RegLocation rl_dest, + RegLocation rl_src1, RegLocation rl_src2); + void GenCmpFP(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, + RegLocation rl_src2); + void GenConversion(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src); + bool GenInlinedCas32(CallInfo* info, bool need_write_barrier); + bool GenInlinedMinMaxInt(CallInfo* info, bool is_min); + bool GenInlinedSqrt(CallInfo* info); + void GenNegLong(RegLocation rl_dest, RegLocation rl_src); + void GenOrLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + void GenSubLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + void GenXorLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + LIR* GenRegMemCheck(ConditionCode c_code, int reg1, int base, int offset, ThrowKind kind); - virtual RegLocation GenDivRem(RegLocation rl_dest, int reg_lo, int reg_hi, bool is_div); - virtual RegLocation GenDivRemLit(RegLocation rl_dest, int reg_lo, int lit, bool is_div); - virtual void GenCmpLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenDivZeroCheck(int reg_lo, int reg_hi); - virtual void GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method); - virtual void GenExitSequence(); - virtual void GenFillArrayData(uint32_t table_offset, RegLocation rl_src); - virtual void GenFusedFPCmpBranch(BasicBlock* bb, MIR* mir, bool gt_bias, bool is_double); - virtual void GenFusedLongCmpBranch(BasicBlock* bb, MIR* mir); - virtual void GenSelect(BasicBlock* bb, MIR* mir); - virtual void GenMemBarrier(MemBarrierKind barrier_kind); - virtual void GenMonitorEnter(int opt_flags, RegLocation rl_src); - virtual void GenMonitorExit(int opt_flags, RegLocation rl_src); - virtual void GenMoveException(RegLocation rl_dest); - virtual void GenMultiplyByTwoBitMultiplier(RegLocation rl_src, RegLocation rl_result, int lit, + RegLocation GenDivRem(RegLocation rl_dest, int reg_lo, int reg_hi, bool is_div); + RegLocation GenDivRemLit(RegLocation rl_dest, int reg_lo, int lit, bool is_div); + void GenCmpLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + void GenDivZeroCheck(int reg_lo, int reg_hi); + void GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method); + void GenExitSequence(); + void GenFillArrayData(uint32_t table_offset, RegLocation rl_src); + void GenFusedFPCmpBranch(BasicBlock* bb, MIR* mir, bool gt_bias, bool is_double); + void GenFusedLongCmpBranch(BasicBlock* bb, MIR* mir); + void GenSelect(BasicBlock* bb, MIR* mir); + void GenMemBarrier(MemBarrierKind barrier_kind); + void GenMonitorEnter(int opt_flags, RegLocation rl_src); + void GenMonitorExit(int opt_flags, RegLocation rl_src); + void GenMoveException(RegLocation rl_dest); + void GenMultiplyByTwoBitMultiplier(RegLocation rl_src, RegLocation rl_result, int lit, int first_bit, int second_bit); - virtual void GenNegDouble(RegLocation rl_dest, RegLocation rl_src); - virtual void GenNegFloat(RegLocation rl_dest, RegLocation rl_src); - virtual void GenPackedSwitch(MIR* mir, uint32_t table_offset, RegLocation rl_src); - virtual void GenSparseSwitch(MIR* mir, uint32_t table_offset, RegLocation rl_src); - virtual void GenSpecialCase(BasicBlock* bb, MIR* mir, SpecialCaseHandler special_case); + void GenNegDouble(RegLocation rl_dest, RegLocation rl_src); + void GenNegFloat(RegLocation rl_dest, RegLocation rl_src); + void GenPackedSwitch(MIR* mir, uint32_t table_offset, RegLocation rl_src); + void GenSparseSwitch(MIR* mir, uint32_t table_offset, RegLocation rl_src); + void GenSpecialCase(BasicBlock* bb, MIR* mir, SpecialCaseHandler special_case); // Required for target - single operation generators. - virtual LIR* OpUnconditionalBranch(LIR* target); - virtual LIR* OpCmpBranch(ConditionCode cond, int src1, int src2, LIR* target); - virtual LIR* OpCmpImmBranch(ConditionCode cond, int reg, int check_value, LIR* target); - virtual LIR* OpCondBranch(ConditionCode cc, LIR* target); - virtual LIR* OpDecAndBranch(ConditionCode c_code, int reg, LIR* target); - virtual LIR* OpFpRegCopy(int r_dest, int r_src); - virtual LIR* OpIT(ConditionCode cond, const char* guide); - virtual LIR* OpMem(OpKind op, int rBase, int disp); - virtual LIR* OpPcRelLoad(int reg, LIR* target); - virtual LIR* OpReg(OpKind op, int r_dest_src); - virtual LIR* OpRegCopy(int r_dest, int r_src); - virtual LIR* OpRegCopyNoInsert(int r_dest, int r_src); - virtual LIR* OpRegImm(OpKind op, int r_dest_src1, int value); - virtual LIR* OpRegMem(OpKind op, int r_dest, int rBase, int offset); - virtual LIR* OpRegReg(OpKind op, int r_dest_src1, int r_src2); - virtual LIR* OpRegRegImm(OpKind op, int r_dest, int r_src1, int value); - virtual LIR* OpRegRegReg(OpKind op, int r_dest, int r_src1, int r_src2); - virtual LIR* OpTestSuspend(LIR* target); - virtual LIR* OpThreadMem(OpKind op, int thread_offset); - virtual LIR* OpVldm(int rBase, int count); - virtual LIR* OpVstm(int rBase, int count); - virtual void OpLea(int rBase, int reg1, int reg2, int scale, int offset); - virtual void OpRegCopyWide(int dest_lo, int dest_hi, int src_lo, int src_hi); - virtual void OpTlsCmp(int offset, int val); + LIR* OpUnconditionalBranch(LIR* target); + LIR* OpCmpBranch(ConditionCode cond, int src1, int src2, LIR* target); + LIR* OpCmpImmBranch(ConditionCode cond, int reg, int check_value, LIR* target); + LIR* OpCondBranch(ConditionCode cc, LIR* target); + LIR* OpDecAndBranch(ConditionCode c_code, int reg, LIR* target); + LIR* OpFpRegCopy(int r_dest, int r_src); + LIR* OpIT(ConditionCode cond, const char* guide); + LIR* OpMem(OpKind op, int rBase, int disp); + LIR* OpPcRelLoad(int reg, LIR* target); + LIR* OpReg(OpKind op, int r_dest_src); + LIR* OpRegCopy(int r_dest, int r_src); + LIR* OpRegCopyNoInsert(int r_dest, int r_src); + LIR* OpRegImm(OpKind op, int r_dest_src1, int value); + LIR* OpRegMem(OpKind op, int r_dest, int rBase, int offset); + LIR* OpRegReg(OpKind op, int r_dest_src1, int r_src2); + LIR* OpRegRegImm(OpKind op, int r_dest, int r_src1, int value); + LIR* OpRegRegReg(OpKind op, int r_dest, int r_src1, int r_src2); + LIR* OpTestSuspend(LIR* target); + LIR* OpThreadMem(OpKind op, int thread_offset); + LIR* OpVldm(int rBase, int count); + LIR* OpVstm(int rBase, int count); + void OpLea(int rBase, int reg1, int reg2, int scale, int offset); + void OpRegCopyWide(int dest_lo, int dest_hi, int src_lo, int src_hi); + void OpTlsCmp(int offset, int val); RegLocation ArgLoc(RegLocation loc); LIR* LoadBaseDispBody(int rBase, int displacement, int r_dest, int r_dest_hi, OpSize size, diff --git a/src/compiler/dex/quick/arm/fp_arm.cc b/src/compiler/dex/quick/arm/fp_arm.cc index 4bf8738949..cd71c0798b 100644 --- a/src/compiler/dex/quick/arm/fp_arm.cc +++ b/src/compiler/dex/quick/arm/fp_arm.cc @@ -16,6 +16,7 @@ #include "arm_lir.h" #include "codegen_arm.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" namespace art { diff --git a/src/compiler/dex/quick/arm/int_arm.cc b/src/compiler/dex/quick/arm/int_arm.cc index 586a3a49b5..110e9f4320 100644 --- a/src/compiler/dex/quick/arm/int_arm.cc +++ b/src/compiler/dex/quick/arm/int_arm.cc @@ -18,6 +18,7 @@ #include "arm_lir.h" #include "codegen_arm.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" #include "mirror/array.h" #include "oat/runtime/oat_support_entrypoints.h" diff --git a/src/compiler/dex/quick/arm/target_arm.cc b/src/compiler/dex/quick/arm/target_arm.cc index 0a05a3a431..ee127a8e17 100644 --- a/src/compiler/dex/quick/arm/target_arm.cc +++ b/src/compiler/dex/quick/arm/target_arm.cc @@ -19,6 +19,7 @@ #include "arm_lir.h" #include "codegen_arm.h" #include "compiler/dex/compiler_internals.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" namespace art { diff --git a/src/compiler/dex/quick/arm/utility_arm.cc b/src/compiler/dex/quick/arm/utility_arm.cc index c689f72436..ef0cc72a5c 100644 --- a/src/compiler/dex/quick/arm/utility_arm.cc +++ b/src/compiler/dex/quick/arm/utility_arm.cc @@ -16,7 +16,7 @@ #include "arm_lir.h" #include "codegen_arm.h" -#include "compiler/dex/quick/mir_to_lir.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" namespace art { diff --git a/src/compiler/dex/quick/codegen_util.cc b/src/compiler/dex/quick/codegen_util.cc index 517d1b5c03..ac2828c276 100644 --- a/src/compiler/dex/quick/codegen_util.cc +++ b/src/compiler/dex/quick/codegen_util.cc @@ -17,6 +17,7 @@ #include "compiler/dex/compiler_internals.h" #include "dex_file-inl.h" #include "gc_map.h" +#include "mir_to_lir-inl.h" #include "verifier/dex_gc_map.h" #include "verifier/method_verifier.h" @@ -112,81 +113,6 @@ void Mir2Lir::AnnotateDalvikRegAccess(LIR* lir, int reg_id, bool is_load, } /* - * Mark the corresponding bit(s). - */ -void Mir2Lir::SetupRegMask(uint64_t* mask, int reg) -{ - *mask |= GetRegMaskCommon(reg); -} - -/* - * Set up the proper fields in the resource mask - */ -void Mir2Lir::SetupResourceMasks(LIR* lir) -{ - int opcode = lir->opcode; - - if (opcode <= 0) { - lir->use_mask = lir->def_mask = 0; - return; - } - - uint64_t flags = GetTargetInstFlags(opcode); - - if (flags & NEEDS_FIXUP) { - lir->flags.pcRelFixup = true; - } - - /* Get the starting size of the instruction's template */ - lir->flags.size = GetInsnSize(lir); - - /* Set up the mask for resources that are updated */ - if (flags & (IS_LOAD | IS_STORE)) { - /* Default to heap - will catch specialized classes later */ - SetMemRefType(lir, flags & IS_LOAD, kHeapRef); - } - - /* - * Conservatively assume the branch here will call out a function that in - * turn will trash everything. - */ - if (flags & IS_BRANCH) { - lir->def_mask = lir->use_mask = ENCODE_ALL; - return; - } - - if (flags & REG_DEF0) { - SetupRegMask(&lir->def_mask, lir->operands[0]); - } - - if (flags & REG_DEF1) { - SetupRegMask(&lir->def_mask, lir->operands[1]); - } - - - if (flags & SETS_CCODES) { - lir->def_mask |= ENCODE_CCODE; - } - - if (flags & (REG_USE0 | REG_USE1 | REG_USE2 | REG_USE3)) { - int i; - - for (i = 0; i < 4; i++) { - if (flags & (1 << (kRegUse0 + i))) { - SetupRegMask(&lir->use_mask, lir->operands[i]); - } - } - } - - if (flags & USES_CCODES) { - lir->use_mask |= ENCODE_CCODE; - } - - // Handle target-specific actions - SetupTargetResourceMasks(lir); -} - -/* * Debugging macros */ #define DUMP_RESOURCE_MASK(X) @@ -361,99 +287,6 @@ void Mir2Lir::CodegenDump() DumpMappingTable("Dex2PC_MappingTable", descriptor, name, signature, dex2pc_mapping_table_); } - -LIR* Mir2Lir::RawLIR(int dalvik_offset, int opcode, int op0, - int op1, int op2, int op3, int op4, LIR* target) -{ - LIR* insn = static_cast<LIR*>(arena_->NewMem(sizeof(LIR), true, ArenaAllocator::kAllocLIR)); - insn->dalvik_offset = dalvik_offset; - insn->opcode = opcode; - insn->operands[0] = op0; - insn->operands[1] = op1; - insn->operands[2] = op2; - insn->operands[3] = op3; - insn->operands[4] = op4; - insn->target = target; - SetupResourceMasks(insn); - if ((opcode == kPseudoTargetLabel) || (opcode == kPseudoSafepointPC) || - (opcode == kPseudoExportedPC)) { - // Always make labels scheduling barriers - insn->use_mask = insn->def_mask = ENCODE_ALL; - } - return insn; -} - -/* - * The following are building blocks to construct low-level IRs with 0 - 4 - * operands. - */ -LIR* Mir2Lir::NewLIR0(int opcode) -{ - DCHECK(is_pseudo_opcode(opcode) || (GetTargetInstFlags(opcode) & NO_OPERAND)) - << GetTargetInstName(opcode) << " " << opcode << " " - << PrettyMethod(cu_->method_idx, *cu_->dex_file) << " " - << current_dalvik_offset_; - LIR* insn = RawLIR(current_dalvik_offset_, opcode); - AppendLIR(insn); - return insn; -} - -LIR* Mir2Lir::NewLIR1(int opcode, int dest) -{ - DCHECK(is_pseudo_opcode(opcode) || (GetTargetInstFlags(opcode) & IS_UNARY_OP)) - << GetTargetInstName(opcode) << " " << opcode << " " - << PrettyMethod(cu_->method_idx, *cu_->dex_file) << " " - << current_dalvik_offset_; - LIR* insn = RawLIR(current_dalvik_offset_, opcode, dest); - AppendLIR(insn); - return insn; -} - -LIR* Mir2Lir::NewLIR2(int opcode, int dest, int src1) -{ - DCHECK(is_pseudo_opcode(opcode) || (GetTargetInstFlags(opcode) & IS_BINARY_OP)) - << GetTargetInstName(opcode) << " " << opcode << " " - << PrettyMethod(cu_->method_idx, *cu_->dex_file) << " " - << current_dalvik_offset_; - LIR* insn = RawLIR(current_dalvik_offset_, opcode, dest, src1); - AppendLIR(insn); - return insn; -} - -LIR* Mir2Lir::NewLIR3(int opcode, int dest, int src1, int src2) -{ - DCHECK(is_pseudo_opcode(opcode) || (GetTargetInstFlags(opcode) & IS_TERTIARY_OP)) - << GetTargetInstName(opcode) << " " << opcode << " " - << PrettyMethod(cu_->method_idx, *cu_->dex_file) << " " - << current_dalvik_offset_; - LIR* insn = RawLIR(current_dalvik_offset_, opcode, dest, src1, src2); - AppendLIR(insn); - return insn; -} - -LIR* Mir2Lir::NewLIR4(int opcode, int dest, int src1, int src2, int info) -{ - DCHECK(is_pseudo_opcode(opcode) || (GetTargetInstFlags(opcode) & IS_QUAD_OP)) - << GetTargetInstName(opcode) << " " << opcode << " " - << PrettyMethod(cu_->method_idx, *cu_->dex_file) << " " - << current_dalvik_offset_; - LIR* insn = RawLIR(current_dalvik_offset_, opcode, dest, src1, src2, info); - AppendLIR(insn); - return insn; -} - -LIR* Mir2Lir::NewLIR5(int opcode, int dest, int src1, int src2, int info1, - int info2) -{ - DCHECK(is_pseudo_opcode(opcode) || (GetTargetInstFlags(opcode) & IS_QUIN_OP)) - << GetTargetInstName(opcode) << " " << opcode << " " - << PrettyMethod(cu_->method_idx, *cu_->dex_file) << " " - << current_dalvik_offset_; - LIR* insn = RawLIR(current_dalvik_offset_, opcode, dest, src1, src2, info1, info2); - AppendLIR(insn); - return insn; -} - /* * Search the existing constants in the literal pool for an exact or close match * within specified delta (greater or equal to 0). diff --git a/src/compiler/dex/quick/gen_common.cc b/src/compiler/dex/quick/gen_common.cc index 7275449830..75c9e300e9 100644 --- a/src/compiler/dex/quick/gen_common.cc +++ b/src/compiler/dex/quick/gen_common.cc @@ -16,6 +16,7 @@ #include "compiler/dex/compiler_ir.h" #include "compiler/dex/compiler_internals.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" #include "mirror/array.h" #include "oat/runtime/oat_support_entrypoints.h" diff --git a/src/compiler/dex/quick/gen_invoke.cc b/src/compiler/dex/quick/gen_invoke.cc index d74c33f91b..4b12bb407a 100644 --- a/src/compiler/dex/quick/gen_invoke.cc +++ b/src/compiler/dex/quick/gen_invoke.cc @@ -19,6 +19,7 @@ #include "invoke_type.h" #include "mirror/array.h" #include "mirror/string.h" +#include "mir_to_lir-inl.h" #include "oat/runtime/oat_support_entrypoints.h" #include "x86/codegen_x86.h" diff --git a/src/compiler/dex/quick/gen_loadstore.cc b/src/compiler/dex/quick/gen_loadstore.cc index 1cebd31d19..085f7f518c 100644 --- a/src/compiler/dex/quick/gen_loadstore.cc +++ b/src/compiler/dex/quick/gen_loadstore.cc @@ -16,6 +16,7 @@ #include "compiler/dex/compiler_ir.h" #include "compiler/dex/compiler_internals.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" #include "invoke_type.h" namespace art { diff --git a/src/compiler/dex/quick/mips/assemble_mips.cc b/src/compiler/dex/quick/mips/assemble_mips.cc index 5223a0ecfd..002a23e5ae 100644 --- a/src/compiler/dex/quick/mips/assemble_mips.cc +++ b/src/compiler/dex/quick/mips/assemble_mips.cc @@ -15,6 +15,7 @@ */ #include "codegen_mips.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" #include "mips_lir.h" namespace art { diff --git a/src/compiler/dex/quick/mips/call_mips.cc b/src/compiler/dex/quick/mips/call_mips.cc index b53d1e35a5..9f1d314b55 100644 --- a/src/compiler/dex/quick/mips/call_mips.cc +++ b/src/compiler/dex/quick/mips/call_mips.cc @@ -17,6 +17,7 @@ /* This file contains codegen for the Mips ISA */ #include "codegen_mips.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" #include "mips_lir.h" #include "oat/runtime/oat_support_entrypoints.h" diff --git a/src/compiler/dex/quick/mips/codegen_mips.h b/src/compiler/dex/quick/mips/codegen_mips.h index db262a8e96..9fa8f779fe 100644 --- a/src/compiler/dex/quick/mips/codegen_mips.h +++ b/src/compiler/dex/quick/mips/codegen_mips.h @@ -28,139 +28,139 @@ class MipsMir2Lir : public Mir2Lir { MipsMir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena); // Required for target - codegen utilities. - virtual bool SmallLiteralDivide(Instruction::Code dalvik_opcode, RegLocation rl_src, + bool SmallLiteralDivide(Instruction::Code dalvik_opcode, RegLocation rl_src, RegLocation rl_dest, int lit); - virtual int LoadHelper(int offset); - virtual LIR* LoadBaseDisp(int rBase, int displacement, int r_dest, OpSize size, int s_reg); - virtual LIR* LoadBaseDispWide(int rBase, int displacement, int r_dest_lo, int r_dest_hi, + int LoadHelper(int offset); + LIR* LoadBaseDisp(int rBase, int displacement, int r_dest, OpSize size, int s_reg); + LIR* LoadBaseDispWide(int rBase, int displacement, int r_dest_lo, int r_dest_hi, int s_reg); - virtual LIR* LoadBaseIndexed(int rBase, int r_index, int r_dest, int scale, OpSize size); - virtual LIR* LoadBaseIndexedDisp(int rBase, int r_index, int scale, int displacement, + LIR* LoadBaseIndexed(int rBase, int r_index, int r_dest, int scale, OpSize size); + LIR* LoadBaseIndexedDisp(int rBase, int r_index, int scale, int displacement, int r_dest, int r_dest_hi, OpSize size, int s_reg); - virtual LIR* LoadConstantNoClobber(int r_dest, int value); - virtual LIR* LoadConstantWide(int r_dest_lo, int r_dest_hi, int64_t value); - virtual LIR* StoreBaseDisp(int rBase, int displacement, int r_src, OpSize size); - virtual LIR* StoreBaseDispWide(int rBase, int displacement, int r_src_lo, int r_src_hi); - virtual LIR* StoreBaseIndexed(int rBase, int r_index, int r_src, int scale, OpSize size); - virtual LIR* StoreBaseIndexedDisp(int rBase, int r_index, int scale, int displacement, + LIR* LoadConstantNoClobber(int r_dest, int value); + LIR* LoadConstantWide(int r_dest_lo, int r_dest_hi, int64_t value); + LIR* StoreBaseDisp(int rBase, int displacement, int r_src, OpSize size); + LIR* StoreBaseDispWide(int rBase, int displacement, int r_src_lo, int r_src_hi); + LIR* StoreBaseIndexed(int rBase, int r_index, int r_src, int scale, OpSize size); + LIR* StoreBaseIndexedDisp(int rBase, int r_index, int scale, int displacement, int r_src, int r_src_hi, OpSize size, int s_reg); - virtual void MarkGCCard(int val_reg, int tgt_addr_reg); + void MarkGCCard(int val_reg, int tgt_addr_reg); // Required for target - register utilities. - virtual bool IsFpReg(int reg); - virtual bool SameRegType(int reg1, int reg2); - virtual int AllocTypedTemp(bool fp_hint, int reg_class); - virtual int AllocTypedTempPair(bool fp_hint, int reg_class); - virtual int S2d(int low_reg, int high_reg); - virtual int TargetReg(SpecialTargetRegister reg); - virtual RegisterInfo* GetRegInfo(int reg); - virtual RegLocation GetReturnAlt(); - virtual RegLocation GetReturnWideAlt(); - virtual RegLocation LocCReturn(); - virtual RegLocation LocCReturnDouble(); - virtual RegLocation LocCReturnFloat(); - virtual RegLocation LocCReturnWide(); - virtual uint32_t FpRegMask(); - virtual uint64_t GetRegMaskCommon(int reg); - virtual void AdjustSpillMask(); - virtual void ClobberCalleeSave(); - virtual void FlushReg(int reg); - virtual void FlushRegWide(int reg1, int reg2); - virtual void FreeCallTemps(); - virtual void FreeRegLocTemps(RegLocation rl_keep, RegLocation rl_free); - virtual void LockCallTemps(); - virtual void MarkPreservedSingle(int v_reg, int reg); - virtual void CompilerInitializeRegAlloc(); + bool IsFpReg(int reg); + bool SameRegType(int reg1, int reg2); + int AllocTypedTemp(bool fp_hint, int reg_class); + int AllocTypedTempPair(bool fp_hint, int reg_class); + int S2d(int low_reg, int high_reg); + int TargetReg(SpecialTargetRegister reg); + RegisterInfo* GetRegInfo(int reg); + RegLocation GetReturnAlt(); + RegLocation GetReturnWideAlt(); + RegLocation LocCReturn(); + RegLocation LocCReturnDouble(); + RegLocation LocCReturnFloat(); + RegLocation LocCReturnWide(); + uint32_t FpRegMask(); + uint64_t GetRegMaskCommon(int reg); + void AdjustSpillMask(); + void ClobberCalleeSave(); + void FlushReg(int reg); + void FlushRegWide(int reg1, int reg2); + void FreeCallTemps(); + void FreeRegLocTemps(RegLocation rl_keep, RegLocation rl_free); + void LockCallTemps(); + void MarkPreservedSingle(int v_reg, int reg); + void CompilerInitializeRegAlloc(); // Required for target - miscellaneous. - virtual AssemblerStatus AssembleInstructions(uintptr_t start_addr); - virtual void DumpResourceMask(LIR* lir, uint64_t mask, const char* prefix); - virtual void SetupTargetResourceMasks(LIR* lir); - virtual const char* GetTargetInstFmt(int opcode); - virtual const char* GetTargetInstName(int opcode); - virtual std::string BuildInsnString(const char* fmt, LIR* lir, unsigned char* base_addr); - virtual uint64_t GetPCUseDefEncoding(); - virtual uint64_t GetTargetInstFlags(int opcode); - virtual int GetInsnSize(LIR* lir); - virtual bool IsUnconditionalBranch(LIR* lir); + AssemblerStatus AssembleInstructions(uintptr_t start_addr); + void DumpResourceMask(LIR* lir, uint64_t mask, const char* prefix); + void SetupTargetResourceMasks(LIR* lir); + const char* GetTargetInstFmt(int opcode); + const char* GetTargetInstName(int opcode); + std::string BuildInsnString(const char* fmt, LIR* lir, unsigned char* base_addr); + uint64_t GetPCUseDefEncoding(); + uint64_t GetTargetInstFlags(int opcode); + int GetInsnSize(LIR* lir); + bool IsUnconditionalBranch(LIR* lir); // Required for target - Dalvik-level generators. - virtual void GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest, + void GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenArrayObjPut(int opt_flags, RegLocation rl_array, RegLocation rl_index, + void GenArrayObjPut(int opt_flags, RegLocation rl_array, RegLocation rl_index, RegLocation rl_src, int scale); - virtual void GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array, + void GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array, RegLocation rl_index, RegLocation rl_dest, int scale); - virtual void GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, + void GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, RegLocation rl_index, RegLocation rl_src, int scale); - virtual void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest, + void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_shift); - virtual void GenMulLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenAddLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenAndLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenArithOpDouble(Instruction::Code opcode, RegLocation rl_dest, + void GenMulLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + void GenAddLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + void GenAndLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + void GenArithOpDouble(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenArithOpFloat(Instruction::Code opcode, RegLocation rl_dest, + void GenArithOpFloat(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenCmpFP(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, + void GenCmpFP(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenConversion(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src); - virtual bool GenInlinedCas32(CallInfo* info, bool need_write_barrier); - virtual bool GenInlinedMinMaxInt(CallInfo* info, bool is_min); - virtual bool GenInlinedSqrt(CallInfo* info); - virtual void GenNegLong(RegLocation rl_dest, RegLocation rl_src); - virtual void GenOrLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenSubLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenXorLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual LIR* GenRegMemCheck(ConditionCode c_code, int reg1, int base, int offset, + void GenConversion(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src); + bool GenInlinedCas32(CallInfo* info, bool need_write_barrier); + bool GenInlinedMinMaxInt(CallInfo* info, bool is_min); + bool GenInlinedSqrt(CallInfo* info); + void GenNegLong(RegLocation rl_dest, RegLocation rl_src); + void GenOrLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + void GenSubLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + void GenXorLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + LIR* GenRegMemCheck(ConditionCode c_code, int reg1, int base, int offset, ThrowKind kind); - virtual RegLocation GenDivRem(RegLocation rl_dest, int reg_lo, int reg_hi, bool is_div); - virtual RegLocation GenDivRemLit(RegLocation rl_dest, int reg_lo, int lit, bool is_div); - virtual void GenCmpLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenDivZeroCheck(int reg_lo, int reg_hi); - virtual void GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method); - virtual void GenExitSequence(); - virtual void GenFillArrayData(uint32_t table_offset, RegLocation rl_src); - virtual void GenFusedFPCmpBranch(BasicBlock* bb, MIR* mir, bool gt_bias, bool is_double); - virtual void GenFusedLongCmpBranch(BasicBlock* bb, MIR* mir); - virtual void GenSelect(BasicBlock* bb, MIR* mir); - virtual void GenMemBarrier(MemBarrierKind barrier_kind); - virtual void GenMonitorEnter(int opt_flags, RegLocation rl_src); - virtual void GenMonitorExit(int opt_flags, RegLocation rl_src); - virtual void GenMoveException(RegLocation rl_dest); - virtual void GenMultiplyByTwoBitMultiplier(RegLocation rl_src, RegLocation rl_result, int lit, + RegLocation GenDivRem(RegLocation rl_dest, int reg_lo, int reg_hi, bool is_div); + RegLocation GenDivRemLit(RegLocation rl_dest, int reg_lo, int lit, bool is_div); + void GenCmpLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + void GenDivZeroCheck(int reg_lo, int reg_hi); + void GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method); + void GenExitSequence(); + void GenFillArrayData(uint32_t table_offset, RegLocation rl_src); + void GenFusedFPCmpBranch(BasicBlock* bb, MIR* mir, bool gt_bias, bool is_double); + void GenFusedLongCmpBranch(BasicBlock* bb, MIR* mir); + void GenSelect(BasicBlock* bb, MIR* mir); + void GenMemBarrier(MemBarrierKind barrier_kind); + void GenMonitorEnter(int opt_flags, RegLocation rl_src); + void GenMonitorExit(int opt_flags, RegLocation rl_src); + void GenMoveException(RegLocation rl_dest); + void GenMultiplyByTwoBitMultiplier(RegLocation rl_src, RegLocation rl_result, int lit, int first_bit, int second_bit); - virtual void GenNegDouble(RegLocation rl_dest, RegLocation rl_src); - virtual void GenNegFloat(RegLocation rl_dest, RegLocation rl_src); - virtual void GenPackedSwitch(MIR* mir, uint32_t table_offset, RegLocation rl_src); - virtual void GenSparseSwitch(MIR* mir, uint32_t table_offset, RegLocation rl_src); - virtual void GenSpecialCase(BasicBlock* bb, MIR* mir, SpecialCaseHandler special_case); + void GenNegDouble(RegLocation rl_dest, RegLocation rl_src); + void GenNegFloat(RegLocation rl_dest, RegLocation rl_src); + void GenPackedSwitch(MIR* mir, uint32_t table_offset, RegLocation rl_src); + void GenSparseSwitch(MIR* mir, uint32_t table_offset, RegLocation rl_src); + void GenSpecialCase(BasicBlock* bb, MIR* mir, SpecialCaseHandler special_case); // Required for target - single operation generators. - virtual LIR* OpUnconditionalBranch(LIR* target); - virtual LIR* OpCmpBranch(ConditionCode cond, int src1, int src2, LIR* target); - virtual LIR* OpCmpImmBranch(ConditionCode cond, int reg, int check_value, LIR* target); - virtual LIR* OpCondBranch(ConditionCode cc, LIR* target); - virtual LIR* OpDecAndBranch(ConditionCode c_code, int reg, LIR* target); - virtual LIR* OpFpRegCopy(int r_dest, int r_src); - virtual LIR* OpIT(ConditionCode cond, const char* guide); - virtual LIR* OpMem(OpKind op, int rBase, int disp); - virtual LIR* OpPcRelLoad(int reg, LIR* target); - virtual LIR* OpReg(OpKind op, int r_dest_src); - virtual LIR* OpRegCopy(int r_dest, int r_src); - virtual LIR* OpRegCopyNoInsert(int r_dest, int r_src); - virtual LIR* OpRegImm(OpKind op, int r_dest_src1, int value); - virtual LIR* OpRegMem(OpKind op, int r_dest, int rBase, int offset); - virtual LIR* OpRegReg(OpKind op, int r_dest_src1, int r_src2); - virtual LIR* OpRegRegImm(OpKind op, int r_dest, int r_src1, int value); - virtual LIR* OpRegRegReg(OpKind op, int r_dest, int r_src1, int r_src2); - virtual LIR* OpTestSuspend(LIR* target); - virtual LIR* OpThreadMem(OpKind op, int thread_offset); - virtual LIR* OpVldm(int rBase, int count); - virtual LIR* OpVstm(int rBase, int count); - virtual void OpLea(int rBase, int reg1, int reg2, int scale, int offset); - virtual void OpRegCopyWide(int dest_lo, int dest_hi, int src_lo, int src_hi); - virtual void OpTlsCmp(int offset, int val); + LIR* OpUnconditionalBranch(LIR* target); + LIR* OpCmpBranch(ConditionCode cond, int src1, int src2, LIR* target); + LIR* OpCmpImmBranch(ConditionCode cond, int reg, int check_value, LIR* target); + LIR* OpCondBranch(ConditionCode cc, LIR* target); + LIR* OpDecAndBranch(ConditionCode c_code, int reg, LIR* target); + LIR* OpFpRegCopy(int r_dest, int r_src); + LIR* OpIT(ConditionCode cond, const char* guide); + LIR* OpMem(OpKind op, int rBase, int disp); + LIR* OpPcRelLoad(int reg, LIR* target); + LIR* OpReg(OpKind op, int r_dest_src); + LIR* OpRegCopy(int r_dest, int r_src); + LIR* OpRegCopyNoInsert(int r_dest, int r_src); + LIR* OpRegImm(OpKind op, int r_dest_src1, int value); + LIR* OpRegMem(OpKind op, int r_dest, int rBase, int offset); + LIR* OpRegReg(OpKind op, int r_dest_src1, int r_src2); + LIR* OpRegRegImm(OpKind op, int r_dest, int r_src1, int value); + LIR* OpRegRegReg(OpKind op, int r_dest, int r_src1, int r_src2); + LIR* OpTestSuspend(LIR* target); + LIR* OpThreadMem(OpKind op, int thread_offset); + LIR* OpVldm(int rBase, int count); + LIR* OpVstm(int rBase, int count); + void OpLea(int rBase, int reg1, int reg2, int scale, int offset); + void OpRegCopyWide(int dest_lo, int dest_hi, int src_lo, int src_hi); + void OpTlsCmp(int offset, int val); LIR* LoadBaseDispBody(int rBase, int displacement, int r_dest, int r_dest_hi, OpSize size, int s_reg); diff --git a/src/compiler/dex/quick/mips/fp_mips.cc b/src/compiler/dex/quick/mips/fp_mips.cc index 5ddec00e80..f384da1a5b 100644 --- a/src/compiler/dex/quick/mips/fp_mips.cc +++ b/src/compiler/dex/quick/mips/fp_mips.cc @@ -16,6 +16,7 @@ #include "codegen_mips.h" #include "mips_lir.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" #include "oat/runtime/oat_support_entrypoints.h" namespace art { diff --git a/src/compiler/dex/quick/mips/int_mips.cc b/src/compiler/dex/quick/mips/int_mips.cc index fbff397bd9..fe9e83f879 100644 --- a/src/compiler/dex/quick/mips/int_mips.cc +++ b/src/compiler/dex/quick/mips/int_mips.cc @@ -17,6 +17,7 @@ /* This file contains codegen for the Mips ISA */ #include "codegen_mips.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" #include "mips_lir.h" #include "mirror/array.h" #include "oat/runtime/oat_support_entrypoints.h" diff --git a/src/compiler/dex/quick/mips/target_mips.cc b/src/compiler/dex/quick/mips/target_mips.cc index 46a625e83f..356104c86c 100644 --- a/src/compiler/dex/quick/mips/target_mips.cc +++ b/src/compiler/dex/quick/mips/target_mips.cc @@ -16,6 +16,7 @@ #include "codegen_mips.h" #include "compiler/dex/compiler_internals.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" #include "mips_lir.h" #include <string> diff --git a/src/compiler/dex/quick/mips/utility_mips.cc b/src/compiler/dex/quick/mips/utility_mips.cc index 5f9f8c58a7..257b0f6cb2 100644 --- a/src/compiler/dex/quick/mips/utility_mips.cc +++ b/src/compiler/dex/quick/mips/utility_mips.cc @@ -15,6 +15,7 @@ */ #include "codegen_mips.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" #include "mips_lir.h" namespace art { diff --git a/src/compiler/dex/quick/mir_to_lir-inl.h b/src/compiler/dex/quick/mir_to_lir-inl.h new file mode 100644 index 0000000000..f7546924c8 --- /dev/null +++ b/src/compiler/dex/quick/mir_to_lir-inl.h @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_SRC_COMPILER_DEX_QUICK_MIR_TO_LIR_INL_H_ +#define ART_SRC_COMPILER_DEX_QUICK_MIR_TO_LIR_INL_H_ + +#include "mir_to_lir.h" + +#include "compiler/dex/compiler_internals.h" + +namespace art { + +/* Mark a temp register as dead. Does not affect allocation state. */ +inline void Mir2Lir::ClobberBody(RegisterInfo* p) { + if (p->is_temp) { + DCHECK(!(p->live && p->dirty)) << "Live & dirty temp in clobber"; + p->live = false; + p->s_reg = INVALID_SREG; + p->def_start = NULL; + p->def_end = NULL; + if (p->pair) { + p->pair = false; + Clobber(p->partner); + } + } +} + +inline LIR* Mir2Lir::RawLIR(int dalvik_offset, int opcode, int op0, + int op1, int op2, int op3, int op4, LIR* target) { + LIR* insn = static_cast<LIR*>(arena_->NewMem(sizeof(LIR), true, ArenaAllocator::kAllocLIR)); + insn->dalvik_offset = dalvik_offset; + insn->opcode = opcode; + insn->operands[0] = op0; + insn->operands[1] = op1; + insn->operands[2] = op2; + insn->operands[3] = op3; + insn->operands[4] = op4; + insn->target = target; + SetupResourceMasks(insn); + if ((opcode == kPseudoTargetLabel) || (opcode == kPseudoSafepointPC) || + (opcode == kPseudoExportedPC)) { + // Always make labels scheduling barriers + insn->use_mask = insn->def_mask = ENCODE_ALL; + } + return insn; +} + +/* + * The following are building blocks to construct low-level IRs with 0 - 4 + * operands. + */ +inline LIR* Mir2Lir::NewLIR0(int opcode) { + DCHECK(is_pseudo_opcode(opcode) || (GetTargetInstFlags(opcode) & NO_OPERAND)) + << GetTargetInstName(opcode) << " " << opcode << " " + << PrettyMethod(cu_->method_idx, *cu_->dex_file) << " " + << current_dalvik_offset_; + LIR* insn = RawLIR(current_dalvik_offset_, opcode); + AppendLIR(insn); + return insn; +} + +inline LIR* Mir2Lir::NewLIR1(int opcode, int dest) { + DCHECK(is_pseudo_opcode(opcode) || (GetTargetInstFlags(opcode) & IS_UNARY_OP)) + << GetTargetInstName(opcode) << " " << opcode << " " + << PrettyMethod(cu_->method_idx, *cu_->dex_file) << " " + << current_dalvik_offset_; + LIR* insn = RawLIR(current_dalvik_offset_, opcode, dest); + AppendLIR(insn); + return insn; +} + +inline LIR* Mir2Lir::NewLIR2(int opcode, int dest, int src1) { + DCHECK(is_pseudo_opcode(opcode) || (GetTargetInstFlags(opcode) & IS_BINARY_OP)) + << GetTargetInstName(opcode) << " " << opcode << " " + << PrettyMethod(cu_->method_idx, *cu_->dex_file) << " " + << current_dalvik_offset_; + LIR* insn = RawLIR(current_dalvik_offset_, opcode, dest, src1); + AppendLIR(insn); + return insn; +} + +inline LIR* Mir2Lir::NewLIR3(int opcode, int dest, int src1, int src2) { + DCHECK(is_pseudo_opcode(opcode) || (GetTargetInstFlags(opcode) & IS_TERTIARY_OP)) + << GetTargetInstName(opcode) << " " << opcode << " " + << PrettyMethod(cu_->method_idx, *cu_->dex_file) << " " + << current_dalvik_offset_; + LIR* insn = RawLIR(current_dalvik_offset_, opcode, dest, src1, src2); + AppendLIR(insn); + return insn; +} + +inline LIR* Mir2Lir::NewLIR4(int opcode, int dest, int src1, int src2, int info) { + DCHECK(is_pseudo_opcode(opcode) || (GetTargetInstFlags(opcode) & IS_QUAD_OP)) + << GetTargetInstName(opcode) << " " << opcode << " " + << PrettyMethod(cu_->method_idx, *cu_->dex_file) << " " + << current_dalvik_offset_; + LIR* insn = RawLIR(current_dalvik_offset_, opcode, dest, src1, src2, info); + AppendLIR(insn); + return insn; +} + +inline LIR* Mir2Lir::NewLIR5(int opcode, int dest, int src1, int src2, int info1, + int info2) { + DCHECK(is_pseudo_opcode(opcode) || (GetTargetInstFlags(opcode) & IS_QUIN_OP)) + << GetTargetInstName(opcode) << " " << opcode << " " + << PrettyMethod(cu_->method_idx, *cu_->dex_file) << " " + << current_dalvik_offset_; + LIR* insn = RawLIR(current_dalvik_offset_, opcode, dest, src1, src2, info1, info2); + AppendLIR(insn); + return insn; +} + +/* + * Mark the corresponding bit(s). + */ +inline void Mir2Lir::SetupRegMask(uint64_t* mask, int reg) { + *mask |= GetRegMaskCommon(reg); +} + +/* + * Set up the proper fields in the resource mask + */ +inline void Mir2Lir::SetupResourceMasks(LIR* lir) { + int opcode = lir->opcode; + + if (opcode <= 0) { + lir->use_mask = lir->def_mask = 0; + return; + } + + uint64_t flags = GetTargetInstFlags(opcode); + + if (flags & NEEDS_FIXUP) { + lir->flags.pcRelFixup = true; + } + + /* Get the starting size of the instruction's template */ + lir->flags.size = GetInsnSize(lir); + + /* Set up the mask for resources that are updated */ + if (flags & (IS_LOAD | IS_STORE)) { + /* Default to heap - will catch specialized classes later */ + SetMemRefType(lir, flags & IS_LOAD, kHeapRef); + } + + /* + * Conservatively assume the branch here will call out a function that in + * turn will trash everything. + */ + if (flags & IS_BRANCH) { + lir->def_mask = lir->use_mask = ENCODE_ALL; + return; + } + + if (flags & REG_DEF0) { + SetupRegMask(&lir->def_mask, lir->operands[0]); + } + + if (flags & REG_DEF1) { + SetupRegMask(&lir->def_mask, lir->operands[1]); + } + + + if (flags & SETS_CCODES) { + lir->def_mask |= ENCODE_CCODE; + } + + if (flags & (REG_USE0 | REG_USE1 | REG_USE2 | REG_USE3)) { + int i; + + for (i = 0; i < 4; i++) { + if (flags & (1 << (kRegUse0 + i))) { + SetupRegMask(&lir->use_mask, lir->operands[i]); + } + } + } + + if (flags & USES_CCODES) { + lir->use_mask |= ENCODE_CCODE; + } + + // Handle target-specific actions + SetupTargetResourceMasks(lir); +} + +} // namespace art + +#endif // ART_SRC_COMPILER_DEX_QUICK_MIR_TO_LIR_INL_H_ diff --git a/src/compiler/dex/quick/mir_to_lir.cc b/src/compiler/dex/quick/mir_to_lir.cc index 481078d7d5..49d715c3ca 100644 --- a/src/compiler/dex/quick/mir_to_lir.cc +++ b/src/compiler/dex/quick/mir_to_lir.cc @@ -14,10 +14,10 @@ * limitations under the License. */ -#include "object_utils.h" - #include "compiler/dex/compiler_internals.h" -#include "compiler/dex/dataflow_iterator.h" +#include "compiler/dex/dataflow_iterator-inl.h" +#include "mir_to_lir-inl.h" +#include "object_utils.h" namespace art { diff --git a/src/compiler/dex/quick/mir_to_lir.h b/src/compiler/dex/quick/mir_to_lir.h index 9a4f5d0ae4..5e5beaf5de 100644 --- a/src/compiler/dex/quick/mir_to_lir.h +++ b/src/compiler/dex/quick/mir_to_lir.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef ART_SRC_COMPILER_DEX_QUICK_CODEGEN_H_ -#define ART_SRC_COMPILER_DEX_QUICK_CODEGEN_H_ +#ifndef ART_SRC_COMPILER_DEX_QUICK_MIR_TO_LIR_H_ +#define ART_SRC_COMPILER_DEX_QUICK_MIR_TO_LIR_H_ #include "invoke_type.h" #include "compiled_method.h" @@ -314,8 +314,10 @@ class Mir2Lir : public Backend { void DumpRegPool(RegisterInfo* p, int num_regs); void DumpCoreRegPool(); void DumpFpRegPool(); - void ClobberBody(RegisterInfo* p); - void Clobber(int reg); + /* Mark a temp register as dead. Does not affect allocation state. */ + void Clobber(int reg) { + ClobberBody(GetRegInfo(reg)); + } void ClobberSRegBody(RegisterInfo* p, int num_regs, int s_reg); void ClobberSReg(int s_reg); int SRegToPMap(int s_reg); @@ -339,7 +341,6 @@ class Mir2Lir : public Backend { RegisterInfo* IsPromoted(int reg); bool IsDirty(int reg); void LockTemp(int reg); - void ResetDefBody(RegisterInfo* p); void ResetDef(int reg); void NullifyRange(LIR *start, LIR *finish, int s_reg1, int s_reg2); void MarkDef(RegLocation rl, LIR *start, LIR *finish); @@ -689,11 +690,6 @@ class Mir2Lir : public Backend { // Temp workaround void Workaround7250540(RegLocation rl_dest, int value); - // TODO: add accessors for these. - LIR* literal_list_; // Constants. - LIR* method_literal_list_; // Method literals requiring patching. - LIR* code_literal_list_; // Code literals requiring patching. - protected: Mir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena); @@ -701,6 +697,20 @@ class Mir2Lir : public Backend { return cu_; } + private: + void ClobberBody(RegisterInfo* p); + void ResetDefBody(RegisterInfo* p) { + p->def_start = NULL; + p->def_end = NULL; + } + + public: + // TODO: add accessors for these. + LIR* literal_list_; // Constants. + LIR* method_literal_list_; // Method literals requiring patching. + LIR* code_literal_list_; // Code literals requiring patching. + + protected: CompilationUnit* const cu_; MIRGraph* const mir_graph_; GrowableArray<SwitchTable*> switch_tables_; @@ -757,4 +767,4 @@ class Mir2Lir : public Backend { } // namespace art -#endif // ART_SRC_COMPILER_DEX_QUICK_CODEGEN_H_ +#endif //ART_SRC_COMPILER_DEX_QUICK_MIR_TO_LIR_H_ diff --git a/src/compiler/dex/quick/ralloc_util.cc b/src/compiler/dex/quick/ralloc_util.cc index 30ed1b7db2..8e0dba3a4f 100644 --- a/src/compiler/dex/quick/ralloc_util.cc +++ b/src/compiler/dex/quick/ralloc_util.cc @@ -18,6 +18,7 @@ #include "compiler/dex/compiler_ir.h" #include "compiler/dex/compiler_internals.h" +#include "mir_to_lir-inl.h" namespace art { @@ -84,28 +85,6 @@ void Mir2Lir::DumpFpRegPool() DumpRegPool(reg_pool_->FPRegs, reg_pool_->num_fp_regs); } -/* Mark a temp register as dead. Does not affect allocation state. */ -void Mir2Lir::ClobberBody(RegisterInfo* p) -{ - if (p->is_temp) { - DCHECK(!(p->live && p->dirty)) << "Live & dirty temp in clobber"; - p->live = false; - p->s_reg = INVALID_SREG; - p->def_start = NULL; - p->def_end = NULL; - if (p->pair) { - p->pair = false; - Clobber(p->partner); - } - } -} - -/* Mark a temp register as dead. Does not affect allocation state. */ -void Mir2Lir::Clobber(int reg) -{ - ClobberBody(GetRegInfo(reg)); -} - void Mir2Lir::ClobberSRegBody(RegisterInfo* p, int num_regs, int s_reg) { int i; @@ -555,12 +534,6 @@ void Mir2Lir::LockTemp(int reg) LOG(FATAL) << "Tried to lock a non-existant temp: r" << reg; } -void Mir2Lir::ResetDefBody(RegisterInfo* p) -{ - p->def_start = NULL; - p->def_end = NULL; -} - void Mir2Lir::ResetDef(int reg) { ResetDefBody(GetRegInfo(reg)); diff --git a/src/compiler/dex/quick/x86/assemble_x86.cc b/src/compiler/dex/quick/x86/assemble_x86.cc index f7c1594908..83dabe6c9a 100644 --- a/src/compiler/dex/quick/x86/assemble_x86.cc +++ b/src/compiler/dex/quick/x86/assemble_x86.cc @@ -15,6 +15,7 @@ */ #include "codegen_x86.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" #include "x86_lir.h" namespace art { diff --git a/src/compiler/dex/quick/x86/call_x86.cc b/src/compiler/dex/quick/x86/call_x86.cc index 614a72d6c2..1e37b2f7f0 100644 --- a/src/compiler/dex/quick/x86/call_x86.cc +++ b/src/compiler/dex/quick/x86/call_x86.cc @@ -17,6 +17,7 @@ /* This file contains codegen for the X86 ISA */ #include "codegen_x86.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" #include "x86_lir.h" namespace art { diff --git a/src/compiler/dex/quick/x86/codegen_x86.h b/src/compiler/dex/quick/x86/codegen_x86.h index 99e5148f9b..9050656071 100644 --- a/src/compiler/dex/quick/x86/codegen_x86.h +++ b/src/compiler/dex/quick/x86/codegen_x86.h @@ -28,139 +28,139 @@ class X86Mir2Lir : public Mir2Lir { X86Mir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena); // Required for target - codegen helpers. - virtual bool SmallLiteralDivide(Instruction::Code dalvik_opcode, RegLocation rl_src, + bool SmallLiteralDivide(Instruction::Code dalvik_opcode, RegLocation rl_src, RegLocation rl_dest, int lit); - virtual int LoadHelper(int offset); - virtual LIR* LoadBaseDisp(int rBase, int displacement, int r_dest, OpSize size, int s_reg); - virtual LIR* LoadBaseDispWide(int rBase, int displacement, int r_dest_lo, int r_dest_hi, + int LoadHelper(int offset); + LIR* LoadBaseDisp(int rBase, int displacement, int r_dest, OpSize size, int s_reg); + LIR* LoadBaseDispWide(int rBase, int displacement, int r_dest_lo, int r_dest_hi, int s_reg); - virtual LIR* LoadBaseIndexed(int rBase, int r_index, int r_dest, int scale, OpSize size); - virtual LIR* LoadBaseIndexedDisp(int rBase, int r_index, int scale, int displacement, + LIR* LoadBaseIndexed(int rBase, int r_index, int r_dest, int scale, OpSize size); + LIR* LoadBaseIndexedDisp(int rBase, int r_index, int scale, int displacement, int r_dest, int r_dest_hi, OpSize size, int s_reg); - virtual LIR* LoadConstantNoClobber(int r_dest, int value); - virtual LIR* LoadConstantWide(int r_dest_lo, int r_dest_hi, int64_t value); - virtual LIR* StoreBaseDisp(int rBase, int displacement, int r_src, OpSize size); - virtual LIR* StoreBaseDispWide(int rBase, int displacement, int r_src_lo, int r_src_hi); - virtual LIR* StoreBaseIndexed(int rBase, int r_index, int r_src, int scale, OpSize size); - virtual LIR* StoreBaseIndexedDisp(int rBase, int r_index, int scale, int displacement, + LIR* LoadConstantNoClobber(int r_dest, int value); + LIR* LoadConstantWide(int r_dest_lo, int r_dest_hi, int64_t value); + LIR* StoreBaseDisp(int rBase, int displacement, int r_src, OpSize size); + LIR* StoreBaseDispWide(int rBase, int displacement, int r_src_lo, int r_src_hi); + LIR* StoreBaseIndexed(int rBase, int r_index, int r_src, int scale, OpSize size); + LIR* StoreBaseIndexedDisp(int rBase, int r_index, int scale, int displacement, int r_src, int r_src_hi, OpSize size, int s_reg); - virtual void MarkGCCard(int val_reg, int tgt_addr_reg); + void MarkGCCard(int val_reg, int tgt_addr_reg); // Required for target - register utilities. - virtual bool IsFpReg(int reg); - virtual bool SameRegType(int reg1, int reg2); - virtual int AllocTypedTemp(bool fp_hint, int reg_class); - virtual int AllocTypedTempPair(bool fp_hint, int reg_class); - virtual int S2d(int low_reg, int high_reg); - virtual int TargetReg(SpecialTargetRegister reg); - virtual RegisterInfo* GetRegInfo(int reg); - virtual RegLocation GetReturnAlt(); - virtual RegLocation GetReturnWideAlt(); - virtual RegLocation LocCReturn(); - virtual RegLocation LocCReturnDouble(); - virtual RegLocation LocCReturnFloat(); - virtual RegLocation LocCReturnWide(); - virtual uint32_t FpRegMask(); - virtual uint64_t GetRegMaskCommon(int reg); - virtual void AdjustSpillMask(); - virtual void ClobberCalleeSave(); - virtual void FlushReg(int reg); - virtual void FlushRegWide(int reg1, int reg2); - virtual void FreeCallTemps(); - virtual void FreeRegLocTemps(RegLocation rl_keep, RegLocation rl_free); - virtual void LockCallTemps(); - virtual void MarkPreservedSingle(int v_reg, int reg); - virtual void CompilerInitializeRegAlloc(); + bool IsFpReg(int reg); + bool SameRegType(int reg1, int reg2); + int AllocTypedTemp(bool fp_hint, int reg_class); + int AllocTypedTempPair(bool fp_hint, int reg_class); + int S2d(int low_reg, int high_reg); + int TargetReg(SpecialTargetRegister reg); + RegisterInfo* GetRegInfo(int reg); + RegLocation GetReturnAlt(); + RegLocation GetReturnWideAlt(); + RegLocation LocCReturn(); + RegLocation LocCReturnDouble(); + RegLocation LocCReturnFloat(); + RegLocation LocCReturnWide(); + uint32_t FpRegMask(); + uint64_t GetRegMaskCommon(int reg); + void AdjustSpillMask(); + void ClobberCalleeSave(); + void FlushReg(int reg); + void FlushRegWide(int reg1, int reg2); + void FreeCallTemps(); + void FreeRegLocTemps(RegLocation rl_keep, RegLocation rl_free); + void LockCallTemps(); + void MarkPreservedSingle(int v_reg, int reg); + void CompilerInitializeRegAlloc(); // Required for target - miscellaneous. - virtual AssemblerStatus AssembleInstructions(uintptr_t start_addr); - virtual void DumpResourceMask(LIR* lir, uint64_t mask, const char* prefix); - virtual void SetupTargetResourceMasks(LIR* lir); - virtual const char* GetTargetInstFmt(int opcode); - virtual const char* GetTargetInstName(int opcode); - virtual std::string BuildInsnString(const char* fmt, LIR* lir, unsigned char* base_addr); - virtual uint64_t GetPCUseDefEncoding(); - virtual uint64_t GetTargetInstFlags(int opcode); - virtual int GetInsnSize(LIR* lir); - virtual bool IsUnconditionalBranch(LIR* lir); + AssemblerStatus AssembleInstructions(uintptr_t start_addr); + void DumpResourceMask(LIR* lir, uint64_t mask, const char* prefix); + void SetupTargetResourceMasks(LIR* lir); + const char* GetTargetInstFmt(int opcode); + const char* GetTargetInstName(int opcode); + std::string BuildInsnString(const char* fmt, LIR* lir, unsigned char* base_addr); + uint64_t GetPCUseDefEncoding(); + uint64_t GetTargetInstFlags(int opcode); + int GetInsnSize(LIR* lir); + bool IsUnconditionalBranch(LIR* lir); // Required for target - Dalvik-level generators. - virtual void GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest, + void GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenArrayObjPut(int opt_flags, RegLocation rl_array, + void GenArrayObjPut(int opt_flags, RegLocation rl_array, RegLocation rl_index, RegLocation rl_src, int scale); - virtual void GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array, + void GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array, RegLocation rl_index, RegLocation rl_dest, int scale); - virtual void GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, + void GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, RegLocation rl_index, RegLocation rl_src, int scale); - virtual void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest, + void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_shift); - virtual void GenMulLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenAddLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenAndLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenArithOpDouble(Instruction::Code opcode, RegLocation rl_dest, + void GenMulLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + void GenAddLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + void GenAndLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + void GenArithOpDouble(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenArithOpFloat(Instruction::Code opcode, RegLocation rl_dest, + void GenArithOpFloat(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenCmpFP(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, + void GenCmpFP(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenConversion(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src); - virtual bool GenInlinedCas32(CallInfo* info, bool need_write_barrier); - virtual bool GenInlinedMinMaxInt(CallInfo* info, bool is_min); - virtual bool GenInlinedSqrt(CallInfo* info); - virtual void GenNegLong(RegLocation rl_dest, RegLocation rl_src); - virtual void GenOrLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenSubLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenXorLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual LIR* GenRegMemCheck(ConditionCode c_code, int reg1, int base, int offset, + void GenConversion(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src); + bool GenInlinedCas32(CallInfo* info, bool need_write_barrier); + bool GenInlinedMinMaxInt(CallInfo* info, bool is_min); + bool GenInlinedSqrt(CallInfo* info); + void GenNegLong(RegLocation rl_dest, RegLocation rl_src); + void GenOrLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + void GenSubLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + void GenXorLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + LIR* GenRegMemCheck(ConditionCode c_code, int reg1, int base, int offset, ThrowKind kind); - virtual RegLocation GenDivRem(RegLocation rl_dest, int reg_lo, int reg_hi, bool is_div); - virtual RegLocation GenDivRemLit(RegLocation rl_dest, int reg_lo, int lit, bool is_div); - virtual void GenCmpLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); - virtual void GenDivZeroCheck(int reg_lo, int reg_hi); - virtual void GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method); - virtual void GenExitSequence(); - virtual void GenFillArrayData(uint32_t table_offset, RegLocation rl_src); - virtual void GenFusedFPCmpBranch(BasicBlock* bb, MIR* mir, bool gt_bias, bool is_double); - virtual void GenFusedLongCmpBranch(BasicBlock* bb, MIR* mir); - virtual void GenSelect(BasicBlock* bb, MIR* mir); - virtual void GenMemBarrier(MemBarrierKind barrier_kind); - virtual void GenMonitorEnter(int opt_flags, RegLocation rl_src); - virtual void GenMonitorExit(int opt_flags, RegLocation rl_src); - virtual void GenMoveException(RegLocation rl_dest); - virtual void GenMultiplyByTwoBitMultiplier(RegLocation rl_src, RegLocation rl_result, + RegLocation GenDivRem(RegLocation rl_dest, int reg_lo, int reg_hi, bool is_div); + RegLocation GenDivRemLit(RegLocation rl_dest, int reg_lo, int lit, bool is_div); + void GenCmpLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); + void GenDivZeroCheck(int reg_lo, int reg_hi); + void GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method); + void GenExitSequence(); + void GenFillArrayData(uint32_t table_offset, RegLocation rl_src); + void GenFusedFPCmpBranch(BasicBlock* bb, MIR* mir, bool gt_bias, bool is_double); + void GenFusedLongCmpBranch(BasicBlock* bb, MIR* mir); + void GenSelect(BasicBlock* bb, MIR* mir); + void GenMemBarrier(MemBarrierKind barrier_kind); + void GenMonitorEnter(int opt_flags, RegLocation rl_src); + void GenMonitorExit(int opt_flags, RegLocation rl_src); + void GenMoveException(RegLocation rl_dest); + void GenMultiplyByTwoBitMultiplier(RegLocation rl_src, RegLocation rl_result, int lit, int first_bit, int second_bit); - virtual void GenNegDouble(RegLocation rl_dest, RegLocation rl_src); - virtual void GenNegFloat(RegLocation rl_dest, RegLocation rl_src); - virtual void GenPackedSwitch(MIR* mir, uint32_t table_offset, RegLocation rl_src); - virtual void GenSparseSwitch(MIR* mir, uint32_t table_offset, RegLocation rl_src); - virtual void GenSpecialCase(BasicBlock* bb, MIR* mir, SpecialCaseHandler special_case); + void GenNegDouble(RegLocation rl_dest, RegLocation rl_src); + void GenNegFloat(RegLocation rl_dest, RegLocation rl_src); + void GenPackedSwitch(MIR* mir, uint32_t table_offset, RegLocation rl_src); + void GenSparseSwitch(MIR* mir, uint32_t table_offset, RegLocation rl_src); + void GenSpecialCase(BasicBlock* bb, MIR* mir, SpecialCaseHandler special_case); // Single operation generators. - virtual LIR* OpUnconditionalBranch(LIR* target); - virtual LIR* OpCmpBranch(ConditionCode cond, int src1, int src2, LIR* target); - virtual LIR* OpCmpImmBranch(ConditionCode cond, int reg, int check_value, LIR* target); - virtual LIR* OpCondBranch(ConditionCode cc, LIR* target); - virtual LIR* OpDecAndBranch(ConditionCode c_code, int reg, LIR* target); - virtual LIR* OpFpRegCopy(int r_dest, int r_src); - virtual LIR* OpIT(ConditionCode cond, const char* guide); - virtual LIR* OpMem(OpKind op, int rBase, int disp); - virtual LIR* OpPcRelLoad(int reg, LIR* target); - virtual LIR* OpReg(OpKind op, int r_dest_src); - virtual LIR* OpRegCopy(int r_dest, int r_src); - virtual LIR* OpRegCopyNoInsert(int r_dest, int r_src); - virtual LIR* OpRegImm(OpKind op, int r_dest_src1, int value); - virtual LIR* OpRegMem(OpKind op, int r_dest, int rBase, int offset); - virtual LIR* OpRegReg(OpKind op, int r_dest_src1, int r_src2); - virtual LIR* OpRegRegImm(OpKind op, int r_dest, int r_src1, int value); - virtual LIR* OpRegRegReg(OpKind op, int r_dest, int r_src1, int r_src2); - virtual LIR* OpTestSuspend(LIR* target); - virtual LIR* OpThreadMem(OpKind op, int thread_offset); - virtual LIR* OpVldm(int rBase, int count); - virtual LIR* OpVstm(int rBase, int count); - virtual void OpLea(int rBase, int reg1, int reg2, int scale, int offset); - virtual void OpRegCopyWide(int dest_lo, int dest_hi, int src_lo, int src_hi); - virtual void OpTlsCmp(int offset, int val); + LIR* OpUnconditionalBranch(LIR* target); + LIR* OpCmpBranch(ConditionCode cond, int src1, int src2, LIR* target); + LIR* OpCmpImmBranch(ConditionCode cond, int reg, int check_value, LIR* target); + LIR* OpCondBranch(ConditionCode cc, LIR* target); + LIR* OpDecAndBranch(ConditionCode c_code, int reg, LIR* target); + LIR* OpFpRegCopy(int r_dest, int r_src); + LIR* OpIT(ConditionCode cond, const char* guide); + LIR* OpMem(OpKind op, int rBase, int disp); + LIR* OpPcRelLoad(int reg, LIR* target); + LIR* OpReg(OpKind op, int r_dest_src); + LIR* OpRegCopy(int r_dest, int r_src); + LIR* OpRegCopyNoInsert(int r_dest, int r_src); + LIR* OpRegImm(OpKind op, int r_dest_src1, int value); + LIR* OpRegMem(OpKind op, int r_dest, int rBase, int offset); + LIR* OpRegReg(OpKind op, int r_dest_src1, int r_src2); + LIR* OpRegRegImm(OpKind op, int r_dest, int r_src1, int value); + LIR* OpRegRegReg(OpKind op, int r_dest, int r_src1, int r_src2); + LIR* OpTestSuspend(LIR* target); + LIR* OpThreadMem(OpKind op, int thread_offset); + LIR* OpVldm(int rBase, int count); + LIR* OpVstm(int rBase, int count); + void OpLea(int rBase, int reg1, int reg2, int scale, int offset); + void OpRegCopyWide(int dest_lo, int dest_hi, int src_lo, int src_hi); + void OpTlsCmp(int offset, int val); void OpRegThreadMem(OpKind op, int r_dest, int thread_offset); void SpillCoreRegs(); diff --git a/src/compiler/dex/quick/x86/fp_x86.cc b/src/compiler/dex/quick/x86/fp_x86.cc index db2cf289d8..3341e28ce5 100644 --- a/src/compiler/dex/quick/x86/fp_x86.cc +++ b/src/compiler/dex/quick/x86/fp_x86.cc @@ -15,6 +15,7 @@ */ #include "codegen_x86.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" #include "x86_lir.h" namespace art { diff --git a/src/compiler/dex/quick/x86/int_x86.cc b/src/compiler/dex/quick/x86/int_x86.cc index b2ee949f22..fffb900ec9 100644 --- a/src/compiler/dex/quick/x86/int_x86.cc +++ b/src/compiler/dex/quick/x86/int_x86.cc @@ -18,6 +18,7 @@ #include "codegen_x86.h" #include "mirror/array.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" #include "x86_lir.h" namespace art { diff --git a/src/compiler/dex/quick/x86/target_x86.cc b/src/compiler/dex/quick/x86/target_x86.cc index e6a49f8ce3..9110b704b8 100644 --- a/src/compiler/dex/quick/x86/target_x86.cc +++ b/src/compiler/dex/quick/x86/target_x86.cc @@ -16,6 +16,7 @@ #include "codegen_x86.h" #include "compiler/dex/compiler_internals.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" #include "x86_lir.h" #include <string> diff --git a/src/compiler/dex/quick/x86/utility_x86.cc b/src/compiler/dex/quick/x86/utility_x86.cc index 45c0e9cb41..82466d496b 100644 --- a/src/compiler/dex/quick/x86/utility_x86.cc +++ b/src/compiler/dex/quick/x86/utility_x86.cc @@ -15,6 +15,7 @@ */ #include "codegen_x86.h" +#include "compiler/dex/quick/mir_to_lir-inl.h" #include "x86_lir.h" namespace art { diff --git a/src/compiler/dex/ssa_transformation.cc b/src/compiler/dex/ssa_transformation.cc index a90d705c6f..41820720d8 100644 --- a/src/compiler/dex/ssa_transformation.cc +++ b/src/compiler/dex/ssa_transformation.cc @@ -15,7 +15,7 @@ */ #include "compiler_internals.h" -#include "dataflow_iterator.h" +#include "dataflow_iterator-inl.h" #define NOTVISITED (-1) diff --git a/src/compiler/dex/vreg_analysis.cc b/src/compiler/dex/vreg_analysis.cc index c260933b3e..b941140b00 100644 --- a/src/compiler/dex/vreg_analysis.cc +++ b/src/compiler/dex/vreg_analysis.cc @@ -15,7 +15,7 @@ */ #include "compiler_internals.h" -#include "dataflow_iterator.h" +#include "compiler/dex/dataflow_iterator-inl.h" namespace art { diff --git a/src/output_stream_test.cc b/src/output_stream_test.cc index 0e02825ff8..c9e0edefcd 100644 --- a/src/output_stream_test.cc +++ b/src/output_stream_test.cc @@ -25,7 +25,7 @@ class OutputStreamTest : public CommonTest { protected: void CheckOffset(off_t expected) { off_t actual = output_stream_->Seek(0, kSeekCurrent); - CHECK_EQ(expected, actual); + EXPECT_EQ(expected, actual); } void SetOutputStream(OutputStream& output_stream) { @@ -33,16 +33,16 @@ class OutputStreamTest : public CommonTest { } void GenerateTestOutput() { - CHECK_EQ(3, output_stream_->Seek(3, kSeekCurrent)); + EXPECT_EQ(3, output_stream_->Seek(3, kSeekCurrent)); CheckOffset(3); - CHECK_EQ(2, output_stream_->Seek(2, kSeekSet)); + EXPECT_EQ(2, output_stream_->Seek(2, kSeekSet)); CheckOffset(2); uint8_t buf[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - CHECK(output_stream_->WriteFully(buf, 2)); + EXPECT_TRUE(output_stream_->WriteFully(buf, 2)); CheckOffset(4); - CHECK_EQ(6, output_stream_->Seek(2, kSeekEnd)); + EXPECT_EQ(6, output_stream_->Seek(2, kSeekEnd)); CheckOffset(6); - CHECK(output_stream_->WriteFully(buf, 4)); + EXPECT_TRUE(output_stream_->WriteFully(buf, 4)); CheckOffset(10); } @@ -50,8 +50,8 @@ class OutputStreamTest : public CommonTest { uint8_t expected[] = { 0, 0, 1, 2, 0, 0, 1, 2, 3, 4 }; - CHECK_EQ(sizeof(expected), actual.size()); - CHECK_EQ(0, memcmp(expected, &actual[0], actual.size())); + EXPECT_EQ(sizeof(expected), actual.size()); + EXPECT_EQ(0, memcmp(expected, &actual[0], actual.size())); } OutputStream* output_stream_; @@ -63,10 +63,10 @@ TEST_F(OutputStreamTest, File) { SetOutputStream(output_stream); GenerateTestOutput(); UniquePtr<File> in(OS::OpenFile(tmp.GetFilename().c_str(), false)); - CHECK(in.get() != NULL); + EXPECT_TRUE(in.get() != NULL); std::vector<uint8_t> actual(in->GetLength()); bool readSuccess = in->ReadFully(&actual[0], actual.size()); - CHECK(readSuccess); + EXPECT_TRUE(readSuccess); CheckTestOutput(actual); } diff --git a/src/vector_output_stream.cc b/src/vector_output_stream.cc index 96154ee92b..e5ff729036 100644 --- a/src/vector_output_stream.cc +++ b/src/vector_output_stream.cc @@ -16,8 +16,6 @@ #include "vector_output_stream.h" -#include <string.h> - #include "base/logging.h" namespace art { @@ -25,14 +23,6 @@ namespace art { VectorOutputStream::VectorOutputStream(const std::string& location, std::vector<uint8_t>& vector) : OutputStream(location), offset_(vector.size()), vector_(vector) {} -bool VectorOutputStream::WriteFully(const void* buffer, int64_t byte_count) { - off_t new_offset = offset_ + byte_count; - EnsureCapacity(new_offset); - memcpy(&vector_[offset_], buffer, byte_count); - offset_ = new_offset; - return true; -} - off_t VectorOutputStream::Seek(off_t offset, Whence whence) { CHECK(whence == kSeekSet || whence == kSeekCurrent || whence == kSeekEnd) << whence; off_t new_offset = 0; @@ -55,10 +45,4 @@ off_t VectorOutputStream::Seek(off_t offset, Whence whence) { return offset_; } -void VectorOutputStream::EnsureCapacity(off_t new_offset) { - if (new_offset > static_cast<off_t>(vector_.size())) { - vector_.resize(new_offset); - } -} - } // namespace art diff --git a/src/vector_output_stream.h b/src/vector_output_stream.h index a99128e6f3..3546c8d577 100644 --- a/src/vector_output_stream.h +++ b/src/vector_output_stream.h @@ -20,6 +20,7 @@ #include "output_stream.h" #include <string> +#include <string.h> #include <vector> namespace art { @@ -30,12 +31,28 @@ class VectorOutputStream : public OutputStream { virtual ~VectorOutputStream() {} - virtual bool WriteFully(const void* buffer, int64_t byte_count); + bool WriteFully(const void* buffer, int64_t byte_count) { + if (static_cast<size_t>(offset_) == vector_.size()) { + const uint8_t* start = reinterpret_cast<const uint8_t*>(buffer); + vector_.insert(vector_.end(), &start[0], &start[byte_count]); + offset_ += byte_count; + } else { + off_t new_offset = offset_ + byte_count; + EnsureCapacity(new_offset); + memcpy(&vector_[offset_], buffer, byte_count); + offset_ = new_offset; + } + return true; + } - virtual off_t Seek(off_t offset, Whence whence); + off_t Seek(off_t offset, Whence whence); private: - void EnsureCapacity(off_t new_offset); + void EnsureCapacity(off_t new_offset) { + if (new_offset > static_cast<off_t>(vector_.size())) { + vector_.resize(new_offset); + } + } off_t offset_; std::vector<uint8_t>& vector_; |