summaryrefslogtreecommitdiff
path: root/compiler/optimizing/nodes.h
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/nodes.h')
-rw-r--r--compiler/optimizing/nodes.h71
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; }