diff options
Diffstat (limited to 'compiler/optimizing/nodes.h')
| -rw-r--r-- | compiler/optimizing/nodes.h | 92 | 
1 files changed, 84 insertions, 8 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 41c2f17cd9..d90c1fb335 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 @@ -1161,6 +1162,7 @@ class HLoopInformationOutwardIterator : public ValueObject {    M(BoundsCheck, Instruction)                                           \    M(BoundType, Instruction)                                             \    M(CheckCast, Instruction)                                             \ +  M(ClassTableGet, Instruction)                                         \    M(ClearException, Instruction)                                        \    M(ClinitCheck, Instruction)                                           \    M(Compare, BinaryOperation)                                           \ @@ -1220,6 +1222,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)                                          \ @@ -1819,6 +1822,7 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> {          dex_pc_(dex_pc),          id_(-1),          ssa_index_(-1), +        emitted_at_use_site_(false),          environment_(nullptr),          locations_(nullptr),          live_interval_(nullptr), @@ -2081,6 +2085,9 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> {    // The caller must ensure that this is safe to do.    void RemoveEnvironmentUsers(); +  bool IsEmittedAtUseSite() const { return emitted_at_use_site_; } +  void MarkEmittedAtUseSite() { emitted_at_use_site_ = true; } +   protected:    virtual const HUserRecord<HInstruction*> InputRecordAt(size_t i) const = 0;    virtual void SetRawInputRecordAt(size_t index, const HUserRecord<HInstruction*>& input) = 0; @@ -2102,6 +2109,10 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> {    // When doing liveness analysis, instructions that have uses get an SSA index.    int ssa_index_; +  // If set, the machine code for this instruction is assumed to be generated by +  // its users. Used by liveness analysis to compute use positions accordingly. +  bool emitted_at_use_site_; +    // List of instructions that have this instruction as input.    HUseList<HInstruction*> uses_; @@ -2542,6 +2553,44 @@ class HCurrentMethod : public HExpression<0> {    DISALLOW_COPY_AND_ASSIGN(HCurrentMethod);  }; +// Fetches an ArtMethod from the virtual table or the interface method table +// of a class. +class HClassTableGet : public HExpression<1> { + public: +  enum TableKind { +    kVTable, +    kIMTable, +  }; +  HClassTableGet(HInstruction* cls, +                 Primitive::Type type, +                 TableKind kind, +                 size_t index, +                 uint32_t dex_pc) +      : HExpression(type, SideEffects::None(), dex_pc), +        index_(index), +        table_kind_(kind) { +    SetRawInputAt(0, cls); +  } + +  bool CanBeMoved() const OVERRIDE { return true; } +  bool InstructionDataEquals(HInstruction* other) const OVERRIDE { +    return other->AsClassTableGet()->GetIndex() == index_ && +        other->AsClassTableGet()->GetTableKind() == table_kind_; +  } + +  TableKind GetTableKind() const { return table_kind_; } +  size_t GetIndex() const { return index_; } + +  DECLARE_INSTRUCTION(ClassTableGet); + + private: +  // The index of the ArtMethod in the table. +  const size_t index_; +  const TableKind table_kind_; + +  DISALLOW_COPY_AND_ASSIGN(HClassTableGet); +}; +  // PackedSwitch (jump table). A block ending with a PackedSwitch instruction will  // have one successor for each entry in the switch table, and the final successor  // will be the block containing the next Dex opcode. @@ -2711,12 +2760,8 @@ class HCondition : public HBinaryOperation {   public:    HCondition(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc)        : HBinaryOperation(Primitive::kPrimBoolean, first, second, SideEffects::None(), dex_pc), -        needs_materialization_(true),          bias_(ComparisonBias::kNoBias) {} -  bool NeedsMaterialization() const { return needs_materialization_; } -  void ClearNeedsMaterialization() { needs_materialization_ = false; } -    // For code generation purposes, returns whether this instruction is just before    // `instruction`, and disregard moves in between.    bool IsBeforeWhenDisregardMoves(HInstruction* instruction) const; @@ -2748,10 +2793,6 @@ class HCondition : public HBinaryOperation {    }   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_; -    // Needed if we merge a HCompare into a HCondition.    ComparisonBias bias_; @@ -5586,6 +5627,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,  |