diff options
Diffstat (limited to 'compiler/optimizing/nodes.h')
| -rw-r--r-- | compiler/optimizing/nodes.h | 131 |
1 files changed, 102 insertions, 29 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index fedad0c69a..7ed5bca947 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -25,6 +25,7 @@ #include "base/arena_containers.h" #include "base/arena_object.h" #include "base/array_ref.h" +#include "base/intrusive_forward_list.h" #include "base/iteration_range.h" #include "base/mutex.h" #include "base/quasi_atomic.h" @@ -45,7 +46,6 @@ #include "mirror/class.h" #include "mirror/method_type.h" #include "offsets.h" -#include "utils/intrusive_forward_list.h" namespace art { @@ -131,6 +131,7 @@ enum GraphAnalysisResult { kAnalysisFailThrowCatchLoop, kAnalysisFailAmbiguousArrayOp, kAnalysisFailIrreducibleLoopAndStringInit, + kAnalysisFailPhiEquivalentInOsr, kAnalysisSuccess, }; @@ -320,6 +321,8 @@ class HGraph : public ArenaObject<kArenaAllocGraph> { bool dead_reference_safe = false, bool debuggable = false, bool osr = false, + bool is_shared_jit_code = false, + bool baseline = false, int start_instruction_id = 0) : allocator_(allocator), arena_stack_(arena_stack), @@ -334,6 +337,7 @@ class HGraph : public ArenaObject<kArenaAllocGraph> { temporaries_vreg_slots_(0), has_bounds_checks_(false), has_try_catch_(false), + has_monitor_operations_(false), has_simd_(false), has_loops_(false), has_irreducible_loops_(false), @@ -355,7 +359,9 @@ class HGraph : public ArenaObject<kArenaAllocGraph> { art_method_(nullptr), inexact_object_rti_(ReferenceTypeInfo::CreateInvalid()), osr_(osr), - cha_single_implementation_list_(allocator->Adapter(kArenaAllocCHA)) { + baseline_(baseline), + cha_single_implementation_list_(allocator->Adapter(kArenaAllocCHA)), + is_shared_jit_code_(is_shared_jit_code) { blocks_.reserve(kDefaultNumberOfBlocks); } @@ -503,7 +509,7 @@ class HGraph : public ArenaObject<kArenaAllocGraph> { return reverse_post_order_; } - ArrayRef<HBasicBlock* const> GetReversePostOrderSkipEntryBlock() { + ArrayRef<HBasicBlock* const> GetReversePostOrderSkipEntryBlock() const { DCHECK(GetReversePostOrder()[0] == entry_block_); return ArrayRef<HBasicBlock* const>(GetReversePostOrder()).SubArray(1); } @@ -585,6 +591,12 @@ class HGraph : public ArenaObject<kArenaAllocGraph> { bool IsCompilingOsr() const { return osr_; } + bool IsCompilingBaseline() const { return baseline_; } + + bool IsCompilingForSharedJitCode() const { + return is_shared_jit_code_; + } + ArenaSet<ArtMethod*>& GetCHASingleImplementationList() { return cha_single_implementation_list_; } @@ -600,6 +612,9 @@ class HGraph : public ArenaObject<kArenaAllocGraph> { bool HasTryCatch() const { return has_try_catch_; } void SetHasTryCatch(bool value) { has_try_catch_ = value; } + bool HasMonitorOperations() const { return has_monitor_operations_; } + void SetHasMonitorOperations(bool value) { has_monitor_operations_ = value; } + bool HasSIMD() const { return has_simd_; } void SetHasSIMD(bool value) { has_simd_ = value; } @@ -696,6 +711,10 @@ class HGraph : public ArenaObject<kArenaAllocGraph> { // false positives. bool has_try_catch_; + // Flag whether there are any HMonitorOperation in the graph. If yes this will mandate + // DexRegisterMap to be present to allow deadlock analysis for non-debuggable code. + bool has_monitor_operations_; + // Flag whether SIMD instructions appear in the graph. If true, the // code generators may have to be more careful spilling the wider // contents of SIMD registers. @@ -771,9 +790,17 @@ class HGraph : public ArenaObject<kArenaAllocGraph> { // compiled code entries which the interpreter can directly jump to. const bool osr_; + // Whether we are compiling baseline (not running optimizations). This affects + // the code being generated. + const bool baseline_; + // List of methods that are assumed to have single implementation. ArenaSet<ArtMethod*> cha_single_implementation_list_; + // Whether we are JIT compiling in the shared region area, putting + // restrictions on, for example, how literals are being generated. + bool is_shared_jit_code_; + friend class SsaBuilder; // For caching constants. friend class SsaLivenessAnalysis; // For the linear order. friend class HInliner; // For the reverse post order. @@ -1099,7 +1126,7 @@ class HBasicBlock : public ArenaObject<kArenaAllocBasicBlock> { } // Insert `this` between `predecessor` and `successor. This method - // preserves the indicies, and will update the first edge found between + // preserves the indices, and will update the first edge found between // `predecessor` and `successor`. void InsertBetween(HBasicBlock* predecessor, HBasicBlock* successor) { size_t predecessor_index = successor->GetPredecessorIndexOf(predecessor); @@ -1438,6 +1465,7 @@ class HLoopInformationOutwardIterator : public ValueObject { M(Shr, BinaryOperation) \ M(StaticFieldGet, Instruction) \ M(StaticFieldSet, Instruction) \ + M(StringBuilderAppend, Instruction) \ M(UnresolvedInstanceFieldGet, Instruction) \ M(UnresolvedInstanceFieldSet, Instruction) \ M(UnresolvedStaticFieldGet, Instruction) \ @@ -1497,17 +1525,6 @@ class HLoopInformationOutwardIterator : public ValueObject { #define FOR_EACH_CONCRETE_INSTRUCTION_ARM64(M) -#ifndef ART_ENABLE_CODEGEN_mips -#define FOR_EACH_CONCRETE_INSTRUCTION_MIPS(M) -#else -#define FOR_EACH_CONCRETE_INSTRUCTION_MIPS(M) \ - M(MipsComputeBaseMethodAddress, Instruction) \ - M(MipsPackedSwitch, Instruction) \ - M(IntermediateArrayAddressIndex, Instruction) -#endif - -#define FOR_EACH_CONCRETE_INSTRUCTION_MIPS64(M) - #ifndef ART_ENABLE_CODEGEN_x86 #define FOR_EACH_CONCRETE_INSTRUCTION_X86(M) #else @@ -1520,7 +1537,7 @@ class HLoopInformationOutwardIterator : public ValueObject { #if defined(ART_ENABLE_CODEGEN_x86) || defined(ART_ENABLE_CODEGEN_x86_64) #define FOR_EACH_CONCRETE_INSTRUCTION_X86_COMMON(M) \ - M(X86AndNot, Instruction) \ + M(X86AndNot, Instruction) \ M(X86MaskOrResetLeastSetBit, Instruction) #else #define FOR_EACH_CONCRETE_INSTRUCTION_X86_COMMON(M) @@ -1533,8 +1550,6 @@ class HLoopInformationOutwardIterator : public ValueObject { FOR_EACH_CONCRETE_INSTRUCTION_SHARED(M) \ FOR_EACH_CONCRETE_INSTRUCTION_ARM(M) \ FOR_EACH_CONCRETE_INSTRUCTION_ARM64(M) \ - FOR_EACH_CONCRETE_INSTRUCTION_MIPS(M) \ - FOR_EACH_CONCRETE_INSTRUCTION_MIPS64(M) \ FOR_EACH_CONCRETE_INSTRUCTION_X86(M) \ FOR_EACH_CONCRETE_INSTRUCTION_X86_64(M) \ FOR_EACH_CONCRETE_INSTRUCTION_X86_COMMON(M) @@ -2137,12 +2152,13 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> { // If this instruction will do an implicit null check, return the `HNullCheck` associated // with it. Otherwise return null. HNullCheck* GetImplicitNullCheck() const { - // Find the first previous instruction which is not a move. - HInstruction* first_prev_not_move = GetPreviousDisregardingMoves(); - if (first_prev_not_move != nullptr && - first_prev_not_move->IsNullCheck() && - first_prev_not_move->IsEmittedAtUseSite()) { - return first_prev_not_move->AsNullCheck(); + // Go over previous non-move instructions that are emitted at use site. + HInstruction* prev_not_move = GetPreviousDisregardingMoves(); + while (prev_not_move != nullptr && prev_not_move->IsEmittedAtUseSite()) { + if (prev_not_move->IsNullCheck()) { + return prev_not_move->AsNullCheck(); + } + prev_not_move = prev_not_move->GetPreviousDisregardingMoves(); } return nullptr; } @@ -4775,7 +4791,16 @@ class HInvokeVirtual final : public HInvoke { case Intrinsics::kThreadCurrentThread: case Intrinsics::kStringBufferAppend: case Intrinsics::kStringBufferToString: - case Intrinsics::kStringBuilderAppend: + case Intrinsics::kStringBuilderAppendObject: + case Intrinsics::kStringBuilderAppendString: + case Intrinsics::kStringBuilderAppendCharSequence: + case Intrinsics::kStringBuilderAppendCharArray: + case Intrinsics::kStringBuilderAppendBoolean: + case Intrinsics::kStringBuilderAppendChar: + case Intrinsics::kStringBuilderAppendInt: + case Intrinsics::kStringBuilderAppendLong: + case Intrinsics::kStringBuilderAppendFloat: + case Intrinsics::kStringBuilderAppendDouble: case Intrinsics::kStringBuilderToString: return false; default: @@ -6880,6 +6905,57 @@ class HStaticFieldSet final : public HExpression<2> { const FieldInfo field_info_; }; +class HStringBuilderAppend final : public HVariableInputSizeInstruction { + public: + HStringBuilderAppend(HIntConstant* format, + uint32_t number_of_arguments, + ArenaAllocator* allocator, + uint32_t dex_pc) + : HVariableInputSizeInstruction( + kStringBuilderAppend, + DataType::Type::kReference, + // The runtime call may read memory from inputs. It never writes outside + // of the newly allocated result object (or newly allocated helper objects). + SideEffects::AllReads().Union(SideEffects::CanTriggerGC()), + dex_pc, + allocator, + number_of_arguments + /* format */ 1u, + kArenaAllocInvokeInputs) { + DCHECK_GE(number_of_arguments, 1u); // There must be something to append. + SetRawInputAt(FormatIndex(), format); + } + + void SetArgumentAt(size_t index, HInstruction* argument) { + DCHECK_LE(index, GetNumberOfArguments()); + SetRawInputAt(index, argument); + } + + // Return the number of arguments, excluding the format. + size_t GetNumberOfArguments() const { + DCHECK_GE(InputCount(), 1u); + return InputCount() - 1u; + } + + size_t FormatIndex() const { + return GetNumberOfArguments(); + } + + HIntConstant* GetFormat() { + return InputAt(FormatIndex())->AsIntConstant(); + } + + bool NeedsEnvironment() const override { return true; } + + bool CanThrow() const override { return true; } + + bool CanBeNull() const override { return false; } + + DECLARE_INSTRUCTION(StringBuilderAppend); + + protected: + DEFAULT_COPY_CONSTRUCTOR(StringBuilderAppend); +}; + class HUnresolvedInstanceFieldGet final : public HExpression<1> { public: HUnresolvedInstanceFieldGet(HInstruction* obj, @@ -7222,7 +7298,7 @@ class HInstanceOf final : public HTypeCheckInstruction { } static bool CanCallRuntime(TypeCheckKind check_kind) { - // Mips currently does runtime calls for any other checks. + // TODO: Re-evaluate now that mips codegen has been removed. return check_kind != TypeCheckKind::kExactCheck; } @@ -7789,9 +7865,6 @@ class HIntermediateAddress final : public HExpression<2> { #if defined(ART_ENABLE_CODEGEN_arm) || defined(ART_ENABLE_CODEGEN_arm64) #include "nodes_shared.h" #endif -#ifdef ART_ENABLE_CODEGEN_mips -#include "nodes_mips.h" -#endif #if defined(ART_ENABLE_CODEGEN_x86) || defined(ART_ENABLE_CODEGEN_x86_64) #include "nodes_x86.h" #endif |