diff options
Diffstat (limited to 'compiler/optimizing/nodes.h')
-rw-r--r-- | compiler/optimizing/nodes.h | 98 |
1 files changed, 88 insertions, 10 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index d6dfeaede8..d98d2ad75f 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -56,6 +56,12 @@ class HInstructionList { void AddInstruction(HInstruction* instruction); void RemoveInstruction(HInstruction* instruction); + // Return true if `instruction1` is found before `instruction2` in + // this instruction list and false otherwise. Abort if none + // of these instructions is found. + bool FoundBefore(const HInstruction* instruction1, + const HInstruction* instruction2) const; + private: HInstruction* first_instruction_; HInstruction* last_instruction_; @@ -192,7 +198,8 @@ class HLoopInformation : public ArenaObject { HLoopInformation(HBasicBlock* header, HGraph* graph) : header_(header), back_edges_(graph->GetArena(), kDefaultNumberOfBackEdges), - blocks_(graph->GetArena(), graph->GetBlocks().Size(), false) {} + // Make bit vector growable, as the number of blocks may change. + blocks_(graph->GetArena(), graph->GetBlocks().Size(), true) {} HBasicBlock* GetHeader() const { return header_; @@ -331,6 +338,13 @@ class HBasicBlock : public ArenaObject { block->successors_.Add(this); } + void SwapPredecessors() { + DCHECK_EQ(predecessors_.Size(), 2u); + HBasicBlock* temp = predecessors_.Get(0); + predecessors_.Put(0, predecessors_.Get(1)); + predecessors_.Put(1, temp); + } + size_t GetPredecessorIndexOf(HBasicBlock* predecessor) { for (size_t i = 0, e = predecessors_.Size(); i < e; ++i) { if (predecessors_.Get(i) == predecessor) { @@ -352,6 +366,9 @@ class HBasicBlock : public ArenaObject { void AddInstruction(HInstruction* instruction); void RemoveInstruction(HInstruction* instruction); void InsertInstructionBefore(HInstruction* instruction, HInstruction* cursor); + // Replace instruction `initial` with `replacement` within this block. + void ReplaceAndRemoveInstructionWith(HInstruction* initial, + HInstruction* replacement); void AddPhi(HPhi* phi); void RemovePhi(HPhi* phi); @@ -448,19 +465,21 @@ class HBasicBlock : public ArenaObject { #define FOR_EACH_INSTRUCTION(M) \ FOR_EACH_CONCRETE_INSTRUCTION(M) \ - M(Constant) + M(Constant) \ + M(BinaryOperation) #define FORWARD_DECLARATION(type) class H##type; FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) #undef FORWARD_DECLARATION -#define DECLARE_INSTRUCTION(type) \ - virtual const char* DebugName() const { return #type; } \ - virtual H##type* As##type() { return this; } \ - virtual bool InstructionTypeEquals(HInstruction* other) const { \ - return other->Is##type(); \ - } \ - virtual void Accept(HGraphVisitor* visitor) \ +#define DECLARE_INSTRUCTION(type) \ + virtual const char* DebugName() const { return #type; } \ + virtual const H##type* As##type() const OVERRIDE { return this; } \ + virtual H##type* As##type() OVERRIDE { return this; } \ + virtual bool InstructionTypeEquals(HInstruction* other) const { \ + return other->Is##type(); \ + } \ + virtual void Accept(HGraphVisitor* visitor) template <typename T> class HUseListNode : public ArenaObject { @@ -502,6 +521,11 @@ class SideEffects : public ValueObject { return SideEffects(((1 << count) - 1) << kFlagChangesCount); } + bool HasSideEffects() const { + size_t all_bits_set = (1 << kFlagChangesCount) - 1; + return (flags_ & all_bits_set) != 0; + } + private: static constexpr int kFlagChangesSomething = 0; static constexpr int kFlagChangesCount = kFlagChangesSomething + 1; @@ -553,6 +577,7 @@ class HInstruction : public ArenaObject { virtual bool NeedsEnvironment() const { return false; } virtual bool IsControlFlow() const { return false; } + bool HasSideEffects() const { return side_effects_.HasSideEffects(); } void AddUseAt(HInstruction* user, size_t index) { uses_ = new (block_->GetGraph()->GetArena()) HUseListNode<HInstruction>(user, index, uses_); @@ -582,6 +607,10 @@ class HInstruction : public ArenaObject { return result; } + // Does this instruction dominate `other_instruction`? Aborts if + // this instruction and `other_instruction` are both phis. + bool Dominates(HInstruction* other_instruction) const; + int GetId() const { return id_; } void SetId(int id) { id_ = id; } @@ -607,7 +636,8 @@ class HInstruction : public ArenaObject { } #define INSTRUCTION_TYPE_CHECK(type) \ - bool Is##type() { return (As##type() != nullptr); } \ + bool Is##type() const { return (As##type() != nullptr); } \ + virtual const H##type* As##type() const { return nullptr; } \ virtual H##type* As##type() { return nullptr; } FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) @@ -984,6 +1014,17 @@ class HBinaryOperation : public HExpression<2> { virtual bool CanBeMoved() const { return true; } virtual bool InstructionDataEquals(HInstruction* other) const { return true; } + // Try to statically evaluate `operation` and return an HConstant + // containing the result of this evaluation. If `operation` cannot + // be evaluated as a constant, return nullptr. + HConstant* TryStaticEvaluation(ArenaAllocator* allocator) const; + + // Apply this operation to `x` and `y`. + virtual int32_t Evaluate(int32_t x, int32_t y) const = 0; + virtual int64_t Evaluate(int64_t x, int64_t y) const = 0; + + DECLARE_INSTRUCTION(BinaryOperation); + private: DISALLOW_COPY_AND_ASSIGN(HBinaryOperation); }; @@ -1010,6 +1051,9 @@ class HEqual : public HCondition { HEqual(HInstruction* first, HInstruction* second) : HCondition(first, second) {} + virtual int32_t Evaluate(int32_t x, int32_t y) const { return x == y; } + virtual int64_t Evaluate(int64_t x, int64_t y) const { return x == y; } + DECLARE_INSTRUCTION(Equal); virtual IfCondition GetCondition() const { @@ -1025,6 +1069,9 @@ class HNotEqual : public HCondition { HNotEqual(HInstruction* first, HInstruction* second) : HCondition(first, second) {} + virtual int32_t Evaluate(int32_t x, int32_t y) const { return x != y; } + virtual int64_t Evaluate(int64_t x, int64_t y) const { return x != y; } + DECLARE_INSTRUCTION(NotEqual); virtual IfCondition GetCondition() const { @@ -1040,6 +1087,9 @@ class HLessThan : public HCondition { HLessThan(HInstruction* first, HInstruction* second) : HCondition(first, second) {} + virtual int32_t Evaluate(int32_t x, int32_t y) const { return x < y; } + virtual int64_t Evaluate(int64_t x, int64_t y) const { return x < y; } + DECLARE_INSTRUCTION(LessThan); virtual IfCondition GetCondition() const { @@ -1055,6 +1105,9 @@ class HLessThanOrEqual : public HCondition { HLessThanOrEqual(HInstruction* first, HInstruction* second) : HCondition(first, second) {} + virtual int32_t Evaluate(int32_t x, int32_t y) const { return x <= y; } + virtual int64_t Evaluate(int64_t x, int64_t y) const { return x <= y; } + DECLARE_INSTRUCTION(LessThanOrEqual); virtual IfCondition GetCondition() const { @@ -1070,6 +1123,9 @@ class HGreaterThan : public HCondition { HGreaterThan(HInstruction* first, HInstruction* second) : HCondition(first, second) {} + virtual int32_t Evaluate(int32_t x, int32_t y) const { return x > y; } + virtual int64_t Evaluate(int64_t x, int64_t y) const { return x > y; } + DECLARE_INSTRUCTION(GreaterThan); virtual IfCondition GetCondition() const { @@ -1085,6 +1141,9 @@ class HGreaterThanOrEqual : public HCondition { HGreaterThanOrEqual(HInstruction* first, HInstruction* second) : HCondition(first, second) {} + virtual int32_t Evaluate(int32_t x, int32_t y) const { return x >= y; } + virtual int64_t Evaluate(int64_t x, int64_t y) const { return x >= y; } + DECLARE_INSTRUCTION(GreaterThanOrEqual); virtual IfCondition GetCondition() const { @@ -1106,6 +1165,19 @@ class HCompare : public HBinaryOperation { DCHECK_EQ(type, second->GetType()); } + virtual int32_t Evaluate(int32_t x, int32_t y) const { + return + x == y ? 0 : + x > y ? 1 : + -1; + } + virtual int64_t Evaluate(int64_t x, int64_t y) const { + return + x == y ? 0 : + x > y ? 1 : + -1; + } + DECLARE_INSTRUCTION(Compare); private: @@ -1322,6 +1394,9 @@ class HAdd : public HBinaryOperation { virtual bool IsCommutative() { return true; } + virtual int32_t Evaluate(int32_t x, int32_t y) const { return x + y; } + virtual int64_t Evaluate(int64_t x, int64_t y) const { return x + y; } + DECLARE_INSTRUCTION(Add); private: @@ -1335,6 +1410,9 @@ class HSub : public HBinaryOperation { virtual bool IsCommutative() { return false; } + virtual int32_t Evaluate(int32_t x, int32_t y) const { return x + y; } + virtual int64_t Evaluate(int64_t x, int64_t y) const { return x + y; } + DECLARE_INSTRUCTION(Sub); private: |