diff options
Diffstat (limited to 'compiler/optimizing/nodes.h')
| -rw-r--r-- | compiler/optimizing/nodes.h | 137 |
1 files changed, 128 insertions, 9 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 3e4028ed7f..30d869d026 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -17,6 +17,7 @@ #ifndef ART_COMPILER_OPTIMIZING_NODES_H_ #define ART_COMPILER_OPTIMIZING_NODES_H_ +#include "entrypoints/quick/quick_entrypoints_enum.h" #include "invoke_type.h" #include "locations.h" #include "offsets.h" @@ -72,6 +73,15 @@ class HInstructionList { bool FoundBefore(const HInstruction* instruction1, const HInstruction* instruction2) const; + bool IsEmpty() const { return first_instruction_ == nullptr; } + void Clear() { first_instruction_ = last_instruction_ = nullptr; } + + // Update the block of all instructions to be `block`. + void SetBlockOfInstructions(HBasicBlock* block) const; + + void AddAfter(HInstruction* cursor, const HInstructionList& instruction_list); + void Add(const HInstructionList& instruction_list); + private: HInstruction* first_instruction_; HInstruction* last_instruction_; @@ -240,6 +250,10 @@ class HLoopInformation : public ArenaObject<kArenaAllocMisc> { return header_; } + void SetHeader(HBasicBlock* block) { + header_ = block; + } + HSuspendCheck* GetSuspendCheck() const { return suspend_check_; } void SetSuspendCheck(HSuspendCheck* check) { suspend_check_ = check; } bool HasSuspendCheck() const { return suspend_check_ != nullptr; } @@ -287,6 +301,8 @@ class HLoopInformation : public ArenaObject<kArenaAllocMisc> { const ArenaBitVector& GetBlocks() const { return blocks_; } + void Add(HBasicBlock* block); + private: // Internal recursive implementation of `Populate`. void PopulateRecursive(HBasicBlock* block); @@ -350,6 +366,7 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { } HGraph* GetGraph() const { return graph_; } + void SetGraph(HGraph* graph) { graph_ = graph; } int GetBlockId() const { return block_id_; } void SetBlockId(int id) { block_id_ = id; } @@ -357,6 +374,16 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { HBasicBlock* GetDominator() const { return dominator_; } void SetDominator(HBasicBlock* dominator) { dominator_ = dominator; } void AddDominatedBlock(HBasicBlock* block) { dominated_blocks_.Add(block); } + void ReplaceDominatedBlock(HBasicBlock* existing, HBasicBlock* new_block) { + for (size_t i = 0, e = dominated_blocks_.Size(); i < e; ++i) { + if (dominated_blocks_.Get(i) == existing) { + dominated_blocks_.Put(i, new_block); + return; + } + } + LOG(FATAL) << "Unreachable"; + UNREACHABLE(); + } int NumberOfBackEdges() const { return loop_information_ == nullptr @@ -383,10 +410,22 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { successors_.Put(successor_index, new_block); } + void ReplacePredecessor(HBasicBlock* existing, HBasicBlock* new_block) { + size_t predecessor_index = GetPredecessorIndexOf(existing); + DCHECK_NE(predecessor_index, static_cast<size_t>(-1)); + existing->RemoveSuccessor(this); + new_block->successors_.Add(this); + predecessors_.Put(predecessor_index, new_block); + } + void RemovePredecessor(HBasicBlock* block) { predecessors_.Delete(block); } + void RemoveSuccessor(HBasicBlock* block) { + successors_.Delete(block); + } + void ClearAllPredecessors() { predecessors_.Reset(); } @@ -421,6 +460,26 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { return -1; } + // Split the block into two blocks just after `cursor`. Returns the newly + // created block. Note that this method just updates raw block information, + // like predecessors, successors, dominators, and instruction list. It does not + // update the graph, reverse post order, loop information, nor make sure the + // blocks are consistent (for example ending with a control flow instruction). + HBasicBlock* SplitAfter(HInstruction* cursor); + + // Merge `other` at the end of `this`. Successors and dominated blocks of + // `other` are changed to be successors and dominated blocks of `this`. Note + // that this method does not update the graph, reverse post order, loop + // information, nor make sure the blocks are consistent (for example ending + // with a control flow instruction). + void MergeWith(HBasicBlock* other); + + // Replace `this` with `other`. Predecessors, successors, and dominated blocks + // of `this` are moved to `other`. + // Note that this method does not update the graph, reverse post order, loop + // information, nor make sure the blocks are consistent (for example ending + void ReplaceWith(HBasicBlock* other); + void AddInstruction(HInstruction* instruction); void RemoveInstruction(HInstruction* instruction); void InsertInstructionBefore(HInstruction* instruction, HInstruction* cursor); @@ -445,8 +504,9 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { return loop_information_; } - // Set the loop_information_ on this block. This method overrides the current + // Set the loop_information_ on this block. Overrides the current // loop_information if it is an outer loop of the passed loop information. + // Note that this method is called while creating the loop information. void SetInLoop(HLoopInformation* info) { if (IsLoopHeader()) { // Nothing to do. This just means `info` is an outer loop. @@ -464,6 +524,11 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { } } + // Raw update of the loop information. + void SetLoopInformation(HLoopInformation* info) { + loop_information_ = info; + } + bool IsInLoop() const { return loop_information_ != nullptr; } // Returns wheter this block dominates the blocked passed as parameter. @@ -481,7 +546,7 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { void SetIsCatchBlock() { is_catch_block_ = true; } private: - HGraph* const graph_; + HGraph* graph_; GrowableArray<HBasicBlock*> predecessors_; GrowableArray<HBasicBlock*> successors_; HInstructionList instructions_; @@ -899,8 +964,8 @@ class HInstruction : public ArenaObject<kArenaAllocMisc> { void ReplaceWith(HInstruction* instruction); void ReplaceInput(HInstruction* replacement, size_t index); - // Insert `this` instruction in `cursor`'s graph, just before `cursor`. - void InsertBefore(HInstruction* cursor); + // Move `this` instruction before `cursor`. + void MoveBefore(HInstruction* cursor); #define INSTRUCTION_TYPE_CHECK(type, super) \ bool Is##type() const { return (As##type() != nullptr); } \ @@ -1794,10 +1859,11 @@ class HInvokeInterface : public HInvoke { class HNewInstance : public HExpression<0> { public: - HNewInstance(uint32_t dex_pc, uint16_t type_index) + HNewInstance(uint32_t dex_pc, uint16_t type_index, QuickEntrypointEnum entrypoint) : HExpression(Primitive::kPrimNot, SideEffects::None()), dex_pc_(dex_pc), - type_index_(type_index) {} + type_index_(type_index), + entrypoint_(entrypoint) {} uint32_t GetDexPc() const { return dex_pc_; } uint16_t GetTypeIndex() const { return type_index_; } @@ -1812,11 +1878,14 @@ class HNewInstance : public HExpression<0> { bool CanBeNull() const OVERRIDE { return false; } + QuickEntrypointEnum GetEntrypoint() const { return entrypoint_; } + DECLARE_INSTRUCTION(NewInstance); private: const uint32_t dex_pc_; const uint16_t type_index_; + const QuickEntrypointEnum entrypoint_; DISALLOW_COPY_AND_ASSIGN(HNewInstance); }; @@ -1837,10 +1906,14 @@ class HNeg : public HUnaryOperation { class HNewArray : public HExpression<1> { public: - HNewArray(HInstruction* length, uint32_t dex_pc, uint16_t type_index) + HNewArray(HInstruction* length, + uint32_t dex_pc, + uint16_t type_index, + QuickEntrypointEnum entrypoint) : HExpression(Primitive::kPrimNot, SideEffects::None()), dex_pc_(dex_pc), - type_index_(type_index) { + type_index_(type_index), + entrypoint_(entrypoint) { SetRawInputAt(0, length); } @@ -1852,11 +1925,14 @@ class HNewArray : public HExpression<1> { bool CanBeNull() const OVERRIDE { return false; } + QuickEntrypointEnum GetEntrypoint() const { return entrypoint_; } + DECLARE_INSTRUCTION(NewArray); private: const uint32_t dex_pc_; const uint16_t type_index_; + const QuickEntrypointEnum entrypoint_; DISALLOW_COPY_AND_ASSIGN(HNewArray); }; @@ -2168,6 +2244,8 @@ class HTypeConversion : public HExpression<1> { DISALLOW_COPY_AND_ASSIGN(HTypeConversion); }; +static constexpr uint32_t kNoRegNumber = -1; + class HPhi : public HInstruction { public: HPhi(ArenaAllocator* arena, uint32_t reg_number, size_t number_of_inputs, Primitive::Type type) @@ -2562,6 +2640,12 @@ class HLoadClass : public HExpression<0> { return MustGenerateClinitCheck() || !is_referrers_class_; } + bool CanThrow() const OVERRIDE { + // May call runtime and and therefore can throw. + // TODO: finer grain decision. + return !is_referrers_class_; + } + DECLARE_INSTRUCTION(LoadClass); private: @@ -2726,12 +2810,14 @@ class HThrow : public HTemplateInstruction<1> { bool NeedsEnvironment() const OVERRIDE { return true; } + bool CanThrow() const OVERRIDE { return true; } + uint32_t GetDexPc() const { return dex_pc_; } DECLARE_INSTRUCTION(Throw); private: - uint32_t dex_pc_; + const uint32_t dex_pc_; DISALLOW_COPY_AND_ASSIGN(HThrow); }; @@ -3063,6 +3149,39 @@ class HPostOrderIterator : public ValueObject { DISALLOW_COPY_AND_ASSIGN(HPostOrderIterator); }; +// Iterator over the blocks that art part of the loop. Includes blocks part +// of an inner loop. The order in which the blocks are iterated is on their +// block id. +class HBlocksInLoopIterator : public ValueObject { + public: + explicit HBlocksInLoopIterator(const HLoopInformation& info) + : blocks_in_loop_(info.GetBlocks()), + blocks_(info.GetHeader()->GetGraph()->GetBlocks()), + index_(0) { + if (!blocks_in_loop_.IsBitSet(index_)) { + Advance(); + } + } + + bool Done() const { return index_ == blocks_.Size(); } + HBasicBlock* Current() const { return blocks_.Get(index_); } + void Advance() { + ++index_; + for (size_t e = blocks_.Size(); index_ < e; ++index_) { + if (blocks_in_loop_.IsBitSet(index_)) { + break; + } + } + } + + private: + const BitVector& blocks_in_loop_; + const GrowableArray<HBasicBlock*>& blocks_; + size_t index_; + + DISALLOW_COPY_AND_ASSIGN(HBlocksInLoopIterator); +}; + } // namespace art #endif // ART_COMPILER_OPTIMIZING_NODES_H_ |