diff options
author | 2014-10-08 21:07:48 +0100 | |
---|---|---|
committer | 2014-10-09 15:21:57 +0100 | |
commit | 360231a056e796c36ffe62348507e904dc9efb9b (patch) | |
tree | a62ff73c11eaa6694649c98e4c2d872e89149b0c /compiler/optimizing/nodes.h | |
parent | 2072c465cfff077da257bdf14f1f1b2690c946c8 (diff) |
Fix code generation of materialized conditions.
Move the logic for knowing if a condition needs to be materialized
in an optimization pass (so that the information does not change
as a side effect of another optimization).
Also clean-up arm and x86_64 codegen:
- arm: ldr and str are for power-users when a constant is
in play. We should use LoadFromOffset and StoreToOffset.
- x86_64: fix misuses of movq instead of movl.
Change-Id: I01a03b91803624be2281a344a13ad5efbf4f3ef3
Diffstat (limited to 'compiler/optimizing/nodes.h')
-rw-r--r-- | compiler/optimizing/nodes.h | 126 |
1 files changed, 75 insertions, 51 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index fc5b06d0df..41713a401b 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -465,50 +465,51 @@ class HBasicBlock : public ArenaObject { DISALLOW_COPY_AND_ASSIGN(HBasicBlock); }; -#define FOR_EACH_CONCRETE_INSTRUCTION(M) \ - M(Add) \ - M(Condition) \ - M(Equal) \ - M(NotEqual) \ - M(LessThan) \ - M(LessThanOrEqual) \ - M(GreaterThan) \ - M(GreaterThanOrEqual) \ - M(Exit) \ - M(Goto) \ - M(If) \ - M(IntConstant) \ - M(InvokeStatic) \ - M(InvokeVirtual) \ - M(LoadLocal) \ - M(Local) \ - M(LongConstant) \ - M(NewInstance) \ - M(Not) \ - M(ParameterValue) \ - M(ParallelMove) \ - M(Phi) \ - M(Return) \ - M(ReturnVoid) \ - M(StoreLocal) \ - M(Sub) \ - M(Compare) \ - M(InstanceFieldGet) \ - M(InstanceFieldSet) \ - M(ArrayGet) \ - M(ArraySet) \ - M(ArrayLength) \ - M(BoundsCheck) \ - M(NullCheck) \ - M(Temporary) \ - M(SuspendCheck) \ - -#define FOR_EACH_INSTRUCTION(M) \ - FOR_EACH_CONCRETE_INSTRUCTION(M) \ - M(Constant) \ - M(BinaryOperation) - -#define FORWARD_DECLARATION(type) class H##type; +#define FOR_EACH_CONCRETE_INSTRUCTION(M) \ + M(Add, BinaryOperation) \ + M(Condition, BinaryOperation) \ + M(Equal, Condition) \ + M(NotEqual, Condition) \ + M(LessThan, Condition) \ + M(LessThanOrEqual, Condition) \ + M(GreaterThan, Condition) \ + M(GreaterThanOrEqual, Condition) \ + M(Exit, Instruction) \ + M(Goto, Instruction) \ + M(If, Instruction) \ + M(IntConstant, Constant) \ + M(InvokeStatic, Invoke) \ + M(InvokeVirtual, Invoke) \ + M(LoadLocal, Instruction) \ + M(Local, Instruction) \ + M(LongConstant, Constant) \ + M(NewInstance, Instruction) \ + M(Not, Instruction) \ + M(ParameterValue, Instruction) \ + M(ParallelMove, Instruction) \ + M(Phi, Instruction) \ + M(Return, Instruction) \ + M(ReturnVoid, Instruction) \ + M(StoreLocal, Instruction) \ + M(Sub, BinaryOperation) \ + M(Compare, BinaryOperation) \ + M(InstanceFieldGet, Instruction) \ + M(InstanceFieldSet, Instruction) \ + M(ArrayGet, Instruction) \ + M(ArraySet, Instruction) \ + M(ArrayLength, Instruction) \ + M(BoundsCheck, Instruction) \ + M(NullCheck, Instruction) \ + M(Temporary, Instruction) \ + M(SuspendCheck, Instruction) \ + +#define FOR_EACH_INSTRUCTION(M) \ + FOR_EACH_CONCRETE_INSTRUCTION(M) \ + M(Constant, Instruction) \ + M(BinaryOperation, Instruction) \ + M(Invoke, Instruction) + +#define FORWARD_DECLARATION(type, super) class H##type; FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) #undef FORWARD_DECLARATION @@ -623,7 +624,7 @@ class HInstruction : public ArenaObject { virtual ~HInstruction() {} -#define DECLARE_KIND(type) k##type, +#define DECLARE_KIND(type, super) k##type, enum InstructionKind { FOR_EACH_INSTRUCTION(DECLARE_KIND) }; @@ -709,7 +710,7 @@ class HInstruction : public ArenaObject { return uses_ != nullptr && uses_->GetTail() == nullptr; } -#define INSTRUCTION_TYPE_CHECK(type) \ +#define INSTRUCTION_TYPE_CHECK(type, super) \ bool Is##type() const { return (As##type() != nullptr); } \ virtual const H##type* As##type() const { return nullptr; } \ virtual H##type* As##type() { return nullptr; } @@ -1118,13 +1119,13 @@ class HBinaryOperation : public HExpression<2> { class HCondition : public HBinaryOperation { public: HCondition(HInstruction* first, HInstruction* second) - : HBinaryOperation(Primitive::kPrimBoolean, first, second) {} + : HBinaryOperation(Primitive::kPrimBoolean, first, second), + needs_materialization_(true) {} virtual bool IsCommutative() { return true; } - // For register allocation purposes, returns whether this instruction needs to be - // materialized (that is, not just be in the processor flags). - bool NeedsMaterialization() const; + bool NeedsMaterialization() const { return needs_materialization_; } + void ClearNeedsMaterialization() { needs_materialization_ = false; } // For code generation purposes, returns whether this instruction is just before // `if_`, and disregard moves in between. @@ -1135,6 +1136,10 @@ class HCondition : public HBinaryOperation { virtual IfCondition GetCondition() const = 0; private: + // For register allocation purposes, returns whether this instruction needs to be + // materialized (that is, not just be in the processor flags). + bool needs_materialization_; + DISALLOW_COPY_AND_ASSIGN(HCondition); }; @@ -1437,6 +1442,8 @@ class HInvoke : public HInstruction { uint32_t GetDexPc() const { return dex_pc_; } + DECLARE_INSTRUCTION(Invoke); + protected: GrowableArray<HInstruction*> inputs_; const Primitive::Type return_type_; @@ -1954,7 +1961,7 @@ class HGraphVisitor : public ValueObject { HGraph* GetGraph() const { return graph_; } // Visit functions for instruction classes. -#define DECLARE_VISIT_INSTRUCTION(name) \ +#define DECLARE_VISIT_INSTRUCTION(name, super) \ virtual void Visit##name(H##name* instr) { VisitInstruction(instr); } FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) @@ -1967,6 +1974,23 @@ class HGraphVisitor : public ValueObject { DISALLOW_COPY_AND_ASSIGN(HGraphVisitor); }; +class HGraphDelegateVisitor : public HGraphVisitor { + public: + explicit HGraphDelegateVisitor(HGraph* graph) : HGraphVisitor(graph) {} + virtual ~HGraphDelegateVisitor() {} + + // Visit functions that delegate to to super class. +#define DECLARE_VISIT_INSTRUCTION(name, super) \ + virtual void Visit##name(H##name* instr) OVERRIDE { Visit##super(instr); } + + FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) + +#undef DECLARE_VISIT_INSTRUCTION + + private: + DISALLOW_COPY_AND_ASSIGN(HGraphDelegateVisitor); +}; + class HInsertionOrderIterator : public ValueObject { public: explicit HInsertionOrderIterator(const HGraph& graph) : graph_(graph), index_(0) {} |