diff options
author | 2015-12-14 11:44:01 +0000 | |
---|---|---|
committer | 2016-01-28 15:50:27 +0000 | |
commit | 74eb1b264691c4eb399d0858015a7fc13c476ac6 (patch) | |
tree | 0b6fc4f3003d50bf6c388601013cdfc606e53859 /compiler/optimizing/nodes.h | |
parent | 75fd2a8ab9b4aff59308034da26eb4986d10fa9e (diff) |
ART: Implement HSelect
This patch adds a new HIR instruction to Optimizing. HSelect returns
one of two inputs based on the outcome of a condition.
This is only initial implementation which:
- defines the new instruction,
- repurposes BooleanSimplifier to emit it,
- extends InstructionSimplifier to statically resolve it,
- updates existing code and tests accordingly.
Code generators currently emit fallback if/then/else code and will be
updated in follow-up CLs to use platform-specific conditional moves
when possible.
Change-Id: Ib61b17146487ebe6b55350c2b589f0b971dcaaee
Diffstat (limited to 'compiler/optimizing/nodes.h')
-rw-r--r-- | compiler/optimizing/nodes.h | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 922696bb5d..4de3f8abb5 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -1011,6 +1011,7 @@ class HBasicBlock : public ArenaObject<kArenaAllocBasicBlock> { // Replace instruction `initial` with `replacement` within this block. void ReplaceAndRemoveInstructionWith(HInstruction* initial, HInstruction* replacement); + void MoveInstructionBefore(HInstruction* insn, HInstruction* cursor); void AddPhi(HPhi* phi); void InsertPhiAfter(HPhi* instruction, HPhi* cursor); // RemoveInstruction and RemovePhi delete a given instruction from the respective @@ -1220,6 +1221,7 @@ class HLoopInformationOutwardIterator : public ValueObject { M(UnresolvedInstanceFieldSet, Instruction) \ M(UnresolvedStaticFieldGet, Instruction) \ M(UnresolvedStaticFieldSet, Instruction) \ + M(Select, Instruction) \ M(StoreLocal, Instruction) \ M(Sub, BinaryOperation) \ M(SuspendCheck, Instruction) \ @@ -5586,6 +5588,41 @@ class HMonitorOperation : public HTemplateInstruction<1> { DISALLOW_COPY_AND_ASSIGN(HMonitorOperation); }; +class HSelect : public HExpression<3> { + public: + HSelect(HInstruction* condition, + HInstruction* true_value, + HInstruction* false_value, + uint32_t dex_pc) + : HExpression(HPhi::ToPhiType(true_value->GetType()), SideEffects::None(), dex_pc) { + DCHECK_EQ(HPhi::ToPhiType(true_value->GetType()), HPhi::ToPhiType(false_value->GetType())); + + // First input must be `true_value` or `false_value` to allow codegens to + // use the SameAsFirstInput allocation policy. We make it `false_value`, so + // that architectures which implement HSelect as a conditional move also + // will not need to invert the condition. + SetRawInputAt(0, false_value); + SetRawInputAt(1, true_value); + SetRawInputAt(2, condition); + } + + HInstruction* GetFalseValue() const { return InputAt(0); } + HInstruction* GetTrueValue() const { return InputAt(1); } + HInstruction* GetCondition() const { return InputAt(2); } + + bool CanBeMoved() const OVERRIDE { return true; } + bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { return true; } + + bool CanBeNull() const OVERRIDE { + return GetTrueValue()->CanBeNull() || GetFalseValue()->CanBeNull(); + } + + DECLARE_INSTRUCTION(Select); + + private: + DISALLOW_COPY_AND_ASSIGN(HSelect); +}; + class MoveOperands : public ArenaObject<kArenaAllocMoveOperands> { public: MoveOperands(Location source, |