diff options
Diffstat (limited to 'compiler/dex/mir_graph.h')
-rw-r--r-- | compiler/dex/mir_graph.h | 141 |
1 files changed, 113 insertions, 28 deletions
diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h index 2943b9d9b3..8d46c6d15f 100644 --- a/compiler/dex/mir_graph.h +++ b/compiler/dex/mir_graph.h @@ -217,6 +217,7 @@ struct CompilerTemp { enum CompilerTempType { kCompilerTempVR, // A virtual register temporary. kCompilerTempSpecialMethodPtr, // Temporary that keeps track of current method pointer. + kCompilerTempBackend, // Temporary that is used by backend. }; // When debug option enabled, records effectiveness of null and range check elimination. @@ -573,10 +574,26 @@ class MIRGraph { return current_code_item_->insns_; } + /** + * @brief Used to obtain the raw dex bytecode instruction pointer. + * @param m_unit_index The method index in MIRGraph (caused by having multiple methods). + * This is guaranteed to contain index 0 which is the base method being compiled. + * @return Returns the raw instruction pointer. + */ const uint16_t* GetInsns(int m_unit_index) const { return m_units_[m_unit_index]->GetCodeItem()->insns_; } + /** + * @brief Used to obtain the raw data table. + * @param mir sparse switch, packed switch, of fill-array-data + * @param table_offset The table offset from start of method. + * @return Returns the raw table pointer. + */ + const uint16_t* GetTable(MIR* mir, uint32_t table_offset) const { + return GetInsns(mir->m_unit_index) + mir->offset + table_offset; + } + unsigned int GetNumBlocks() const { return num_blocks_; } @@ -783,12 +800,12 @@ class MIRGraph { return num_reachable_blocks_; } - int GetUseCount(int vreg) const { - return use_counts_.Get(vreg); + int GetUseCount(int sreg) const { + return use_counts_.Get(sreg); } - int GetRawUseCount(int vreg) const { - return raw_use_counts_.Get(vreg); + int GetRawUseCount(int sreg) const { + return raw_use_counts_.Get(sreg); } int GetSSASubscript(int ssa_reg) const { @@ -844,9 +861,26 @@ class MIRGraph { * @return Returns the number of compiler temporaries. */ size_t GetNumUsedCompilerTemps() const { - size_t total_num_temps = compiler_temps_.Size(); - DCHECK_LE(num_non_special_compiler_temps_, total_num_temps); - return total_num_temps; + // Assume that the special temps will always be used. + return GetNumNonSpecialCompilerTemps() + max_available_special_compiler_temps_; + } + + /** + * @brief Used to obtain number of bytes needed for special temps. + * @details This space is always needed because temps have special location on stack. + * @return Returns number of bytes for the special temps. + */ + size_t GetNumBytesForSpecialTemps() const; + + /** + * @brief Used by backend as a hint for maximum number of bytes for non-special temps. + * @details Returns 4 bytes for each temp because that is the maximum amount needed + * for storing each temp. The BE could be smarter though and allocate a smaller + * spill region. + * @return Returns the maximum number of bytes needed for non-special temps. + */ + size_t GetMaximumBytesForNonSpecialTemps() const { + return GetNumNonSpecialCompilerTemps() * sizeof(uint32_t); } /** @@ -864,7 +898,9 @@ class MIRGraph { * @return Returns true if the max was set and false if failed to set. */ bool SetMaxAvailableNonSpecialCompilerTemps(size_t new_max) { - if (new_max < GetNumNonSpecialCompilerTemps()) { + // Make sure that enough temps still exist for backend and also that the + // new max can still keep around all of the already requested temps. + if (new_max < (GetNumNonSpecialCompilerTemps() + reserved_temps_for_backend_)) { return false; } else { max_available_non_special_compiler_temps_ = new_max; @@ -873,21 +909,12 @@ class MIRGraph { } /** - * @brief Provides the number of non-special compiler temps available. + * @brief Provides the number of non-special compiler temps available for use by ME. * @details Even if this returns zero, special compiler temps are guaranteed to be available. + * Additionally, this makes sure to not use any temps reserved for BE only. * @return Returns the number of available temps. */ - size_t GetNumAvailableNonSpecialCompilerTemps(); - - /** - * @brief Used to obtain an existing compiler temporary. - * @param index The index of the temporary which must be strictly less than the - * number of temporaries. - * @return Returns the temporary that was asked for. - */ - CompilerTemp* GetCompilerTemp(size_t index) const { - return compiler_temps_.Get(index); - } + size_t GetNumAvailableVRTemps(); /** * @brief Used to obtain the maximum number of compiler temporaries that can be requested. @@ -898,7 +925,22 @@ class MIRGraph { } /** + * @brief Used to signal that the compiler temps have been committed. + * @details This should be used once the number of temps can no longer change, + * such as after frame size is committed and cannot be changed. + */ + void CommitCompilerTemps() { + compiler_temps_committed_ = true; + } + + /** * @brief Used to obtain a new unique compiler temporary. + * @details Two things are done for convenience when allocating a new compiler + * temporary. The ssa register is automatically requested and the information + * about reg location is filled. This helps when the temp is requested post + * ssa initialization, such as when temps are requested by the backend. + * @warning If the temp requested will be used for ME and have multiple versions, + * the sreg provided by the temp will be invalidated on next ssa recalculation. * @param ct_type Type of compiler temporary requested. * @param wide Whether we should allocate a wide temporary. * @return Returns the newly created compiler temporary. @@ -940,8 +982,49 @@ class MIRGraph { } // Is this vreg in the in set? - bool IsInVReg(int vreg) { - return (vreg >= cu_->num_regs); + bool IsInVReg(uint32_t vreg) { + return (vreg >= GetFirstInVR()) && (vreg < GetFirstTempVR()); + } + + uint32_t GetNumOfCodeVRs() const { + return current_code_item_->registers_size_; + } + + uint32_t GetNumOfCodeAndTempVRs() const { + // Include all of the possible temps so that no structures overflow when initialized. + return GetNumOfCodeVRs() + GetMaxPossibleCompilerTemps(); + } + + uint32_t GetNumOfLocalCodeVRs() const { + // This also refers to the first "in" VR. + return GetNumOfCodeVRs() - current_code_item_->ins_size_; + } + + uint32_t GetNumOfInVRs() const { + return current_code_item_->ins_size_; + } + + uint32_t GetNumOfOutVRs() const { + return current_code_item_->outs_size_; + } + + uint32_t GetFirstInVR() const { + return GetNumOfLocalCodeVRs(); + } + + uint32_t GetFirstTempVR() const { + // Temp VRs immediately follow code VRs. + return GetNumOfCodeVRs(); + } + + uint32_t GetFirstSpecialTempVR() const { + // Special temps appear first in the ordering before non special temps. + return GetFirstTempVR(); + } + + uint32_t GetFirstNonSpecialTempVR() const { + // We always leave space for all the special temps before the non-special ones. + return GetFirstSpecialTempVR() + max_available_special_compiler_temps_; } void DumpCheckStats(); @@ -1187,7 +1270,7 @@ class MIRGraph { // Stack of the loop head indexes and recalculation flags for RepeatingTopologicalSortIterator. GrowableArray<std::pair<uint16_t, bool>>* topological_order_loop_head_stack_; int* i_dom_list_; - ArenaBitVector** def_block_matrix_; // num_dalvik_register x num_blocks. + ArenaBitVector** def_block_matrix_; // original num registers x num_blocks. std::unique_ptr<ScopedArenaAllocator> temp_scoped_alloc_; uint16_t* temp_insn_data_; uint32_t temp_bit_vector_size_; @@ -1216,11 +1299,13 @@ class MIRGraph { ArenaAllocator* arena_; int backward_branches_; int forward_branches_; - GrowableArray<CompilerTemp*> compiler_temps_; - size_t num_non_special_compiler_temps_; - size_t max_available_non_special_compiler_temps_; - size_t max_available_special_compiler_temps_; - bool punt_to_interpreter_; // Difficult or not worthwhile - just interpret. + size_t num_non_special_compiler_temps_; // Keeps track of allocated non-special compiler temps. These are VRs that are in compiler temp region on stack. + size_t max_available_non_special_compiler_temps_; // Keeps track of maximum available non-special temps. + size_t max_available_special_compiler_temps_; // Keeps track of maximum available special temps. + bool requested_backend_temp_; // Keeps track whether BE temps have been requested. + size_t reserved_temps_for_backend_; // Keeps track of the remaining temps that are reserved for BE. + bool compiler_temps_committed_; // Keeps track whether number of temps has been frozen (for example post frame size calculation). + bool punt_to_interpreter_; // Difficult or not worthwhile - just interpret. uint64_t merged_df_flags_; GrowableArray<MirIFieldLoweringInfo> ifield_lowering_infos_; GrowableArray<MirSFieldLoweringInfo> sfield_lowering_infos_; |