diff options
Diffstat (limited to 'compiler/optimizing/nodes.h')
-rw-r--r-- | compiler/optimizing/nodes.h | 71 |
1 files changed, 61 insertions, 10 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 66d5bfea32..d4382c6b4c 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -30,8 +30,8 @@ #include "base/transform_array_ref.h" #include "data_type.h" #include "deoptimization_kind.h" -#include "dex_file.h" -#include "dex_file_types.h" +#include "dex/dex_file.h" +#include "dex/dex_file_types.h" #include "entrypoints/quick/quick_entrypoints_enum.h" #include "handle.h" #include "handle_scope.h" @@ -423,6 +423,17 @@ class HGraph : public ArenaObject<kArenaAllocGraph> { void SplitCriticalEdge(HBasicBlock* block, HBasicBlock* successor); void OrderLoopHeaderPredecessors(HBasicBlock* header); + + // Transform a loop into a format with a single preheader. + // + // Each phi in the header should be split: original one in the header should only hold + // inputs reachable from the back edges and a single input from the preheader. The newly created + // phi in the preheader should collate the inputs from the original multiple incoming blocks. + // + // Loops in the graph typically have a single preheader, so this method is used to "repair" loops + // that no longer have this property. + void TransformLoopToSinglePreheaderFormat(HBasicBlock* header); + void SimplifyLoop(HBasicBlock* header); int32_t GetNextInstructionId() { @@ -4614,7 +4625,6 @@ class HInvokeInterface FINAL : public HInvoke { } uint32_t GetImtIndex() const { return imt_index_; } - uint32_t GetDexMethodIndex() const { return dex_method_index_; } DECLARE_INSTRUCTION(InvokeInterface); @@ -5787,10 +5797,10 @@ class HBoundsCheck FINAL : public HExpression<2> { HBoundsCheck(HInstruction* index, HInstruction* length, uint32_t dex_pc, - bool string_char_at = false) + bool is_string_char_at = false) : HExpression(index->GetType(), SideEffects::CanTriggerGC(), dex_pc) { DCHECK_EQ(DataType::Type::kInt32, DataType::Kind(index->GetType())); - SetPackedFlag<kFlagIsStringCharAt>(string_char_at); + SetPackedFlag<kFlagIsStringCharAt>(is_string_char_at); SetRawInputAt(0, index); SetRawInputAt(1, length); } @@ -6062,6 +6072,20 @@ class HLoadClass FINAL : public HInstruction { std::ostream& operator<<(std::ostream& os, HLoadClass::LoadKind rhs); // Note: defined outside class to see operator<<(., HLoadClass::LoadKind). +inline void HLoadClass::SetLoadKind(LoadKind load_kind) { + // The load kind should be determined before inserting the instruction to the graph. + DCHECK(GetBlock() == nullptr); + DCHECK(GetEnvironment() == nullptr); + SetPackedField<LoadKindField>(load_kind); + if (load_kind != LoadKind::kRuntimeCall && load_kind != LoadKind::kReferrersClass) { + special_input_ = HUserRecord<HInstruction*>(nullptr); + } + if (!NeedsEnvironment()) { + SetSideEffects(SideEffects::None()); + } +} + +// Note: defined outside class to see operator<<(., HLoadClass::LoadKind). inline void HLoadClass::AddSpecialInput(HInstruction* special_input) { // The special input is used for PC-relative loads on some architectures, // including literal pool loads, which are PC-relative too. @@ -6209,6 +6233,21 @@ class HLoadString FINAL : public HInstruction { std::ostream& operator<<(std::ostream& os, HLoadString::LoadKind rhs); // Note: defined outside class to see operator<<(., HLoadString::LoadKind). +inline void HLoadString::SetLoadKind(LoadKind load_kind) { + // The load kind should be determined before inserting the instruction to the graph. + DCHECK(GetBlock() == nullptr); + DCHECK(GetEnvironment() == nullptr); + DCHECK_EQ(GetLoadKind(), LoadKind::kRuntimeCall); + SetPackedField<LoadKindField>(load_kind); + if (load_kind != LoadKind::kRuntimeCall) { + special_input_ = HUserRecord<HInstruction*>(nullptr); + } + if (!NeedsEnvironment()) { + SetSideEffects(SideEffects::None()); + } +} + +// Note: defined outside class to see operator<<(., HLoadString::LoadKind). inline void HLoadString::AddSpecialInput(HInstruction* special_input) { // The special input is used for PC-relative loads on some architectures, // including literal pool loads, which are PC-relative too. @@ -6231,7 +6270,7 @@ class HClinitCheck FINAL : public HExpression<1> { HClinitCheck(HLoadClass* constant, uint32_t dex_pc) : HExpression( DataType::Type::kReference, - SideEffects::AllChanges(), // Assume write/read on all fields/arrays. + SideEffects::AllExceptGCDependency(), // Assume write/read on all fields/arrays. dex_pc) { SetRawInputAt(0, constant); } @@ -6562,7 +6601,7 @@ std::ostream& operator<<(std::ostream& os, TypeCheckKind rhs); class HInstanceOf FINAL : public HExpression<2> { public: HInstanceOf(HInstruction* object, - HLoadClass* constant, + HLoadClass* target_class, TypeCheckKind check_kind, uint32_t dex_pc) : HExpression(DataType::Type::kBool, @@ -6571,7 +6610,13 @@ class HInstanceOf FINAL : public HExpression<2> { SetPackedField<TypeCheckKindField>(check_kind); SetPackedFlag<kFlagMustDoNullCheck>(true); SetRawInputAt(0, object); - SetRawInputAt(1, constant); + SetRawInputAt(1, target_class); + } + + HLoadClass* GetTargetClass() const { + HInstruction* load_class = InputAt(1); + DCHECK(load_class->IsLoadClass()); + return load_class->AsLoadClass(); } bool IsClonable() const OVERRIDE { return true; } @@ -6665,14 +6710,20 @@ class HBoundType FINAL : public HExpression<1> { class HCheckCast FINAL : public HTemplateInstruction<2> { public: HCheckCast(HInstruction* object, - HLoadClass* constant, + HLoadClass* target_class, TypeCheckKind check_kind, uint32_t dex_pc) : HTemplateInstruction(SideEffects::CanTriggerGC(), dex_pc) { SetPackedField<TypeCheckKindField>(check_kind); SetPackedFlag<kFlagMustDoNullCheck>(true); SetRawInputAt(0, object); - SetRawInputAt(1, constant); + SetRawInputAt(1, target_class); + } + + HLoadClass* GetTargetClass() const { + HInstruction* load_class = InputAt(1); + DCHECK(load_class->IsLoadClass()); + return load_class->AsLoadClass(); } bool IsClonable() const OVERRIDE { return true; } |