diff options
Diffstat (limited to 'compiler/optimizing/nodes.h')
| -rw-r--r-- | compiler/optimizing/nodes.h | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 1190fae914..9b8521d968 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -58,6 +58,7 @@ class SsaBuilder; static const int kDefaultNumberOfBlocks = 8; static const int kDefaultNumberOfSuccessors = 2; static const int kDefaultNumberOfPredecessors = 2; +static const int kDefaultNumberOfExceptionalPredecessors = 0; static const int kDefaultNumberOfDominatedBlocks = 1; static const int kDefaultNumberOfBackEdges = 1; @@ -210,7 +211,9 @@ class HGraph : public ArenaObject<kArenaAllocMisc> { void ComputeTryBlockInformation(); // Inline this graph in `outer_graph`, replacing the given `invoke` instruction. - void InlineInto(HGraph* outer_graph, HInvoke* invoke); + // Returns the instruction used to replace the invoke expression or null if the + // invoke is for a void method. + HInstruction* InlineInto(HGraph* outer_graph, HInvoke* invoke); // Need to add a couple of blocks to test if the loop body is entered and // put deoptimization instructions, etc. @@ -306,7 +309,12 @@ class HGraph : public ArenaObject<kArenaAllocMisc> { // already, it is created and inserted into the graph. This method is only for // integral types. HConstant* GetConstant(Primitive::Type type, int64_t value); + + // TODO: This is problematic for the consistency of reference type propagation + // because it can be created anytime after the pass and thus it will be left + // with an invalid type. HNullConstant* GetNullConstant(); + HIntConstant* GetIntConstant(int32_t value) { return CreateConstant(value, &cached_int_constants_); } @@ -557,6 +565,7 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { explicit HBasicBlock(HGraph* graph, uint32_t dex_pc = kNoDexPc) : graph_(graph), predecessors_(graph->GetArena(), kDefaultNumberOfPredecessors), + exceptional_predecessors_(graph->GetArena(), kDefaultNumberOfExceptionalPredecessors), successors_(graph->GetArena(), kDefaultNumberOfSuccessors), loop_information_(nullptr), dominator_(nullptr), @@ -571,6 +580,10 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { return predecessors_; } + const GrowableArray<HInstruction*>& GetExceptionalPredecessors() const { + return exceptional_predecessors_; + } + const GrowableArray<HBasicBlock*>& GetSuccessors() const { return successors_; } @@ -639,6 +652,8 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { HInstruction* GetLastPhi() const { return phis_.last_instruction_; } const HInstructionList& GetPhis() const { return phis_; } + void AddExceptionalPredecessor(HInstruction* exceptional_predecessor); + void AddSuccessor(HBasicBlock* block) { successors_.Add(block); block->predecessors_.Add(this); @@ -678,6 +693,10 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { predecessors_.Delete(block); } + void RemoveExceptionalPredecessor(HInstruction* instruction) { + exceptional_predecessors_.Delete(instruction); + } + void RemoveSuccessor(HBasicBlock* block) { successors_.Delete(block); } @@ -714,6 +733,15 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { return -1; } + size_t GetExceptionalPredecessorIndexOf(HInstruction* exceptional_predecessor) const { + for (size_t i = 0, e = exceptional_predecessors_.Size(); i < e; ++i) { + if (exceptional_predecessors_.Get(i) == exceptional_predecessor) { + return i; + } + } + return -1; + } + size_t GetSuccessorIndexOf(HBasicBlock* successor) const { for (size_t i = 0, e = successors_.Size(); i < e; ++i) { if (successors_.Get(i) == successor) { @@ -874,6 +902,7 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { private: HGraph* graph_; GrowableArray<HBasicBlock*> predecessors_; + GrowableArray<HInstruction*> exceptional_predecessors_; GrowableArray<HBasicBlock*> successors_; HInstructionList instructions_; HInstructionList phis_; @@ -1467,26 +1496,27 @@ class ReferenceTypeInfo : ValueObject { static ReferenceTypeInfo CreateInvalid() { return ReferenceTypeInfo(); } - static bool IsValidHandle(TypeHandle handle) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + static bool IsValidHandle(TypeHandle handle) SHARED_REQUIRES(Locks::mutator_lock_) { return handle.GetReference() != nullptr; } - bool IsValid() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + bool IsValid() const SHARED_REQUIRES(Locks::mutator_lock_) { return IsValidHandle(type_handle_); } bool IsExact() const { return is_exact_; } - bool IsObjectClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + + bool IsObjectClass() const SHARED_REQUIRES(Locks::mutator_lock_) { DCHECK(IsValid()); return GetTypeHandle()->IsObjectClass(); } - bool IsInterface() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + bool IsInterface() const SHARED_REQUIRES(Locks::mutator_lock_) { DCHECK(IsValid()); return GetTypeHandle()->IsInterface(); } Handle<mirror::Class> GetTypeHandle() const { return type_handle_; } - bool IsSupertypeOf(ReferenceTypeInfo rti) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + bool IsSupertypeOf(ReferenceTypeInfo rti) const SHARED_REQUIRES(Locks::mutator_lock_) { DCHECK(IsValid()); DCHECK(rti.IsValid()); return GetTypeHandle()->IsAssignableFrom(rti.GetTypeHandle().Get()); @@ -1495,7 +1525,7 @@ class ReferenceTypeInfo : ValueObject { // Returns true if the type information provide the same amount of details. // Note that it does not mean that the instructions have the same actual type // (because the type can be the result of a merge). - bool IsEqual(ReferenceTypeInfo rti) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + bool IsEqual(ReferenceTypeInfo rti) SHARED_REQUIRES(Locks::mutator_lock_) { if (!IsValid() && !rti.IsValid()) { // Invalid types are equal. return true; @@ -3589,7 +3619,7 @@ class HInstanceFieldGet : public HExpression<1> { const DexFile& dex_file) : HExpression( field_type, - SideEffects::SideEffects::FieldReadOfType(field_type, is_volatile)), + SideEffects::FieldReadOfType(field_type, is_volatile)), field_info_(field_offset, field_type, is_volatile, field_idx, dex_file) { SetRawInputAt(0, value); } @@ -4036,7 +4066,7 @@ class HStaticFieldGet : public HExpression<1> { const DexFile& dex_file) : HExpression( field_type, - SideEffects::SideEffects::FieldReadOfType(field_type, is_volatile)), + SideEffects::FieldReadOfType(field_type, is_volatile)), field_info_(field_offset, field_type, is_volatile, field_idx, dex_file) { SetRawInputAt(0, cls); } @@ -4184,7 +4214,8 @@ class HBoundType : public HExpression<1> { HBoundType(HInstruction* input, ReferenceTypeInfo upper_bound, bool upper_can_be_null) : HExpression(Primitive::kPrimNot, SideEffects::None()), upper_bound_(upper_bound), - upper_can_be_null_(upper_can_be_null) { + upper_can_be_null_(upper_can_be_null), + can_be_null_(upper_can_be_null) { DCHECK_EQ(input->GetType(), Primitive::kPrimNot); SetRawInputAt(0, input); SetReferenceTypeInfo(upper_bound_); |