diff options
Diffstat (limited to 'compiler/optimizing/nodes.h')
| -rw-r--r-- | compiler/optimizing/nodes.h | 88 |
1 files changed, 70 insertions, 18 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 07ff8ba010..664cf18ad7 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -128,6 +128,7 @@ class HGraph : public ArenaObject<kArenaAllocMisc> { void SetExitBlock(HBasicBlock* block) { exit_block_ = block; } void AddBlock(HBasicBlock* block); + void AddConstant(HConstant* instruction); // Try building the SSA form of this graph, with dominance computation and loop // recognition. Returns whether it was successful in doing all these steps. @@ -154,6 +155,8 @@ class HGraph : public ArenaObject<kArenaAllocMisc> { // Inline this graph in `outer_graph`, replacing the given `invoke` instruction. void InlineInto(HGraph* outer_graph, HInvoke* invoke); + void MergeEmptyBranches(HBasicBlock* start_block, HBasicBlock* end_block); + void SplitCriticalEdge(HBasicBlock* block, HBasicBlock* successor); void SimplifyLoop(HBasicBlock* header); @@ -217,6 +220,8 @@ class HGraph : public ArenaObject<kArenaAllocMisc> { bool IsDebuggable() const { return debuggable_; } HNullConstant* GetNullConstant(); + HIntConstant* GetIntConstant0(); + HIntConstant* GetIntConstant1(); private: HBasicBlock* FindCommonDominator(HBasicBlock* first, HBasicBlock* second) const; @@ -267,6 +272,10 @@ class HGraph : public ArenaObject<kArenaAllocMisc> { // Cached null constant that might be created when building SSA form. HNullConstant* cached_null_constant_; + // Cached common constants often needed by optimization passes. + HIntConstant* cached_int_constant0_; + HIntConstant* cached_int_constant1_; + ART_FRIEND_TEST(GraphTest, IfSuccessorSimpleJoinBlock1); DISALLOW_COPY_AND_ASSIGN(HGraph); }; @@ -300,9 +309,9 @@ class HLoopInformation : public ArenaObject<kArenaAllocMisc> { back_edges_.Delete(back_edge); } - bool IsBackEdge(HBasicBlock* block) { + bool IsBackEdge(const HBasicBlock& block) const { for (size_t i = 0, e = back_edges_.Size(); i < e; ++i) { - if (back_edges_.Get(i) == block) return true; + if (back_edges_.Get(i) == &block) return true; } return false; } @@ -336,6 +345,7 @@ class HLoopInformation : public ArenaObject<kArenaAllocMisc> { const ArenaBitVector& GetBlocks() const { return blocks_; } void Add(HBasicBlock* block); + void Remove(HBasicBlock* block); private: // Internal recursive implementation of `Populate`. @@ -391,6 +401,8 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { return graph_->GetExitBlock() == this; } + bool IsSingleGoto() const; + void AddBackEdge(HBasicBlock* back_edge) { if (loop_information_ == nullptr) { loop_information_ = new (graph_->GetArena()) HLoopInformation(this, graph_); @@ -512,8 +524,16 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { // 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 + // with a control flow instruction). void ReplaceWith(HBasicBlock* other); + // Disconnects `this` from all its predecessors, successors and the dominator. + // It assumes that `this` does not dominate any blocks. + // 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 DisconnectFromAll(); + void AddInstruction(HInstruction* instruction); void InsertInstructionBefore(HInstruction* instruction, HInstruction* cursor); // Replace instruction `initial` with `replacement` within this block. @@ -582,6 +602,9 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { bool IsCatchBlock() const { return is_catch_block_; } void SetIsCatchBlock() { is_catch_block_ = true; } + bool EndsWithIf() const; + bool HasSinglePhi() const; + private: HGraph* graph_; GrowableArray<HBasicBlock*> predecessors_; @@ -604,6 +627,31 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { DISALLOW_COPY_AND_ASSIGN(HBasicBlock); }; +// Iterates over the LoopInformation of all loops which contain 'block' +// from the innermost to the outermost. +class HLoopInformationOutwardIterator : public ValueObject { + public: + explicit HLoopInformationOutwardIterator(const HBasicBlock& block) + : current_(block.GetLoopInformation()) {} + + bool Done() const { return current_ == nullptr; } + + void Advance() { + DCHECK(!Done()); + current_ = current_->GetHeader()->GetDominator()->GetLoopInformation(); + } + + HLoopInformation* Current() const { + DCHECK(!Done()); + return current_; + } + + private: + HLoopInformation* current_; + + DISALLOW_COPY_AND_ASSIGN(HLoopInformationOutwardIterator); +}; + #define FOR_EACH_CONCRETE_INSTRUCTION(M) \ M(Add, BinaryOperation) \ M(And, BinaryOperation) \ @@ -1200,8 +1248,6 @@ class HInstruction : public ArenaObject<kArenaAllocMisc> { return NeedsEnvironment() || IsLoadClass() || IsLoadString(); } - virtual bool NeedsDexCache() const { return false; } - protected: virtual const HUserRecord<HInstruction*> InputRecordAt(size_t i) const = 0; virtual void SetRawInputRecordAt(size_t index, const HUserRecord<HInstruction*>& input) = 0; @@ -1875,20 +1921,22 @@ class HFloatConstant : public HConstant { float GetValue() const { return value_; } bool InstructionDataEquals(HInstruction* other) const OVERRIDE { - return bit_cast<float, int32_t>(other->AsFloatConstant()->value_) == - bit_cast<float, int32_t>(value_); + return bit_cast<uint32_t, float>(other->AsFloatConstant()->value_) == + bit_cast<uint32_t, float>(value_); } size_t ComputeHashCode() const OVERRIDE { return static_cast<size_t>(GetValue()); } bool IsMinusOne() const OVERRIDE { - return bit_cast<uint32_t>(AsFloatConstant()->GetValue()) == bit_cast<uint32_t>((-1.0f)); + return bit_cast<uint32_t, float>(AsFloatConstant()->GetValue()) == + bit_cast<uint32_t, float>((-1.0f)); } bool IsZero() const OVERRIDE { return AsFloatConstant()->GetValue() == 0.0f; } bool IsOne() const OVERRIDE { - return bit_cast<uint32_t>(AsFloatConstant()->GetValue()) == bit_cast<uint32_t>(1.0f); + return bit_cast<uint32_t, float>(AsFloatConstant()->GetValue()) == + bit_cast<uint32_t, float>(1.0f); } DECLARE_INSTRUCTION(FloatConstant); @@ -1906,20 +1954,22 @@ class HDoubleConstant : public HConstant { double GetValue() const { return value_; } bool InstructionDataEquals(HInstruction* other) const OVERRIDE { - return bit_cast<double, int64_t>(other->AsDoubleConstant()->value_) == - bit_cast<double, int64_t>(value_); + return bit_cast<uint64_t, double>(other->AsDoubleConstant()->value_) == + bit_cast<uint64_t, double>(value_); } size_t ComputeHashCode() const OVERRIDE { return static_cast<size_t>(GetValue()); } bool IsMinusOne() const OVERRIDE { - return bit_cast<uint64_t>(AsDoubleConstant()->GetValue()) == bit_cast<uint64_t>((-1.0)); + return bit_cast<uint64_t, double>(AsDoubleConstant()->GetValue()) == + bit_cast<uint64_t, double>((-1.0)); } bool IsZero() const OVERRIDE { return AsDoubleConstant()->GetValue() == 0.0; } bool IsOne() const OVERRIDE { - return bit_cast<uint64_t>(AsDoubleConstant()->GetValue()) == bit_cast<uint64_t>(1.0); + return bit_cast<uint64_t, double>(AsDoubleConstant()->GetValue()) == + bit_cast<uint64_t, double>(1.0); } DECLARE_INSTRUCTION(DoubleConstant); @@ -2092,7 +2142,6 @@ class HInvokeStaticOrDirect : public HInvoke { InvokeType GetInvokeType() const { return invoke_type_; } bool IsRecursive() const { return is_recursive_; } - bool NeedsDexCache() const OVERRIDE { return !IsRecursive(); } DECLARE_INSTRUCTION(InvokeStaticOrDirect); @@ -2975,8 +3024,6 @@ class HLoadClass : public HExpression<0> { return loaded_class_rti_.IsExact(); } - bool NeedsDexCache() const OVERRIDE { return !is_referrers_class_; } - DECLARE_INSTRUCTION(LoadClass); private: @@ -3012,7 +3059,6 @@ class HLoadString : public HExpression<0> { // TODO: Can we deopt or debug when we resolve a string? bool NeedsEnvironment() const OVERRIDE { return false; } - bool NeedsDexCache() const OVERRIDE { return true; } DECLARE_INSTRUCTION(LoadString); @@ -3465,7 +3511,10 @@ class HInsertionOrderIterator : public ValueObject { class HReversePostOrderIterator : public ValueObject { public: - explicit HReversePostOrderIterator(const HGraph& graph) : graph_(graph), index_(0) {} + explicit HReversePostOrderIterator(const HGraph& graph) : graph_(graph), index_(0) { + // Check that reverse post order of the graph has been built. + DCHECK(!graph.GetReversePostOrder().IsEmpty()); + } bool Done() const { return index_ == graph_.GetReversePostOrder().Size(); } HBasicBlock* Current() const { return graph_.GetReversePostOrder().Get(index_); } @@ -3481,7 +3530,10 @@ class HReversePostOrderIterator : public ValueObject { class HPostOrderIterator : public ValueObject { public: explicit HPostOrderIterator(const HGraph& graph) - : graph_(graph), index_(graph_.GetReversePostOrder().Size()) {} + : graph_(graph), index_(graph_.GetReversePostOrder().Size()) { + // Check that reverse post order of the graph has been built. + DCHECK(!graph.GetReversePostOrder().IsEmpty()); + } bool Done() const { return index_ == 0; } HBasicBlock* Current() const { return graph_.GetReversePostOrder().Get(index_ - 1); } |