summaryrefslogtreecommitdiff
path: root/compiler/optimizing/builder.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/builder.cc')
-rw-r--r--compiler/optimizing/builder.cc58
1 files changed, 32 insertions, 26 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 8baf3c5f89..8418ab0a7e 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -64,10 +64,6 @@ class Temporaries : public ValueObject {
size_t index_;
};
-static bool IsTypeSupported(Primitive::Type type) {
- return type != Primitive::kPrimFloat && type != Primitive::kPrimDouble;
-}
-
void HGraphBuilder::InitializeLocals(uint16_t count) {
graph_->SetNumberOfVRegs(count);
locals_.SetSize(count);
@@ -78,10 +74,10 @@ void HGraphBuilder::InitializeLocals(uint16_t count) {
}
}
-bool HGraphBuilder::InitializeParameters(uint16_t number_of_parameters) {
+void HGraphBuilder::InitializeParameters(uint16_t number_of_parameters) {
// dex_compilation_unit_ is null only when unit testing.
if (dex_compilation_unit_ == nullptr) {
- return true;
+ return;
}
graph_->SetNumberOfInVRegs(number_of_parameters);
@@ -116,7 +112,6 @@ bool HGraphBuilder::InitializeParameters(uint16_t number_of_parameters) {
parameter_index++;
}
}
- return true;
}
template<typename T>
@@ -195,9 +190,7 @@ HGraph* HGraphBuilder::BuildGraph(const DexFile::CodeItem& code_item) {
}
}
- if (!InitializeParameters(code_item.ins_size_)) {
- return nullptr;
- }
+ InitializeParameters(code_item.ins_size_);
size_t dex_offset = 0;
while (code_ptr < code_end) {
@@ -464,9 +457,6 @@ bool HGraphBuilder::BuildInstanceFieldAccess(const Instruction& instruction,
}
Primitive::Type field_type = resolved_field->GetTypeAsPrimitiveType();
- if (!IsTypeSupported(field_type)) {
- return false;
- }
HInstruction* object = LoadLocal(obj_reg, Primitive::kPrimNot);
current_block_->AddInstruction(new (arena_) HNullCheck(object, dex_offset));
@@ -524,10 +514,6 @@ bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction,
return false;
}
- if (!IsTypeSupported(field_type)) {
- return false;
- }
-
HLoadClass* constant = new (arena_) HLoadClass(
storage_index, is_referrers_class, dex_offset);
current_block_->AddInstruction(constant);
@@ -582,8 +568,6 @@ void HGraphBuilder::BuildArrayAccess(const Instruction& instruction,
uint8_t array_reg = instruction.VRegB_23x();
uint8_t index_reg = instruction.VRegC_23x();
- DCHECK(IsTypeSupported(anticipated_type));
-
// We need one temporary for the null check, one for the index, and one for the length.
Temporaries temps(graph_, 3);
@@ -799,8 +783,7 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32
break;
}
- // TODO: these instructions are also used to move floating point values, so what is
- // the type (int or float)?
+ // Note that the SSA building will refine the types.
case Instruction::MOVE:
case Instruction::MOVE_FROM16:
case Instruction::MOVE_16: {
@@ -809,8 +792,7 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32
break;
}
- // TODO: these instructions are also used to move floating point values, so what is
- // the type (long or double)?
+ // Note that the SSA building will refine the types.
case Instruction::MOVE_WIDE:
case Instruction::MOVE_WIDE_FROM16:
case Instruction::MOVE_WIDE_16: {
@@ -884,7 +866,8 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32
uint32_t number_of_vreg_arguments = instruction.VRegA_35c();
uint32_t args[5];
instruction.GetVarArgs(args);
- if (!BuildInvoke(instruction, dex_offset, method_idx, number_of_vreg_arguments, false, args, -1)) {
+ if (!BuildInvoke(instruction, dex_offset, method_idx,
+ number_of_vreg_arguments, false, args, -1)) {
return false;
}
break;
@@ -1286,7 +1269,7 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32
return false;
}
current_block_->AddInstruction(
- new (arena_) HLoadClass(instruction.VRegB_21c(), is_referrers_class, dex_offset));
+ new (arena_) HLoadClass(type_index, is_referrers_class, dex_offset));
UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction());
break;
}
@@ -1308,11 +1291,34 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32
break;
}
+ case Instruction::INSTANCE_OF: {
+ uint16_t type_index = instruction.VRegC_22c();
+ bool type_known_final;
+ bool type_known_abstract;
+ bool is_referrers_class;
+ bool can_access = compiler_driver_->CanAccessTypeWithoutChecks(
+ dex_compilation_unit_->GetDexMethodIndex(), *dex_file_, type_index,
+ &type_known_final, &type_known_abstract, &is_referrers_class);
+ if (!can_access) {
+ return false;
+ }
+ HInstruction* object = LoadLocal(instruction.VRegB_22c(), Primitive::kPrimNot);
+ HLoadClass* cls = new (arena_) HLoadClass(type_index, is_referrers_class, dex_offset);
+ current_block_->AddInstruction(cls);
+ // The class needs a temporary before being used by the type check.
+ Temporaries temps(graph_, 1);
+ temps.Add(cls);
+ current_block_->AddInstruction(
+ new (arena_) HTypeCheck(object, cls, type_known_final, dex_offset));
+ UpdateLocal(instruction.VRegA_22c(), current_block_->GetLastInstruction());
+ break;
+ }
+
default:
return false;
}
return true;
-}
+} // NOLINT(readability/fn_size)
HIntConstant* HGraphBuilder::GetIntConstant0() {
if (constant0_ != nullptr) {