summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/code_generator.cc65
-rw-r--r--compiler/optimizing/code_generator.h12
-rw-r--r--compiler/optimizing/code_generator_arm.cc2
-rw-r--r--compiler/optimizing/code_generator_arm64.cc1
-rw-r--r--compiler/optimizing/code_generator_mips.cc2
-rw-r--r--compiler/optimizing/code_generator_mips64.cc1
-rw-r--r--compiler/optimizing/code_generator_x86.cc5
-rw-r--r--compiler/optimizing/code_generator_x86_64.cc1
-rw-r--r--compiler/optimizing/licm_test.cc12
-rw-r--r--compiler/optimizing/nodes.h33
-rw-r--r--compiler/optimizing/optimizing_cfi_test.cc2
-rw-r--r--compiler/optimizing/optimizing_compiler.cc6
-rw-r--r--compiler/optimizing/side_effects_test.cc34
13 files changed, 91 insertions, 85 deletions
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc
index 953c0ae418..a771cc1567 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -552,59 +552,66 @@ void CodeGenerator::MaybeRecordStat(MethodCompilationStat compilation_stat, size
}
}
-CodeGenerator* CodeGenerator::Create(HGraph* graph,
- InstructionSet instruction_set,
- const InstructionSetFeatures& isa_features,
- const CompilerOptions& compiler_options,
- OptimizingCompilerStats* stats) {
+std::unique_ptr<CodeGenerator> CodeGenerator::Create(HGraph* graph,
+ InstructionSet instruction_set,
+ const InstructionSetFeatures& isa_features,
+ const CompilerOptions& compiler_options,
+ OptimizingCompilerStats* stats) {
+ ArenaAllocator* arena = graph->GetArena();
switch (instruction_set) {
#ifdef ART_ENABLE_CODEGEN_arm
case kArm:
case kThumb2: {
- return new arm::CodeGeneratorARM(graph,
- *isa_features.AsArmInstructionSetFeatures(),
- compiler_options,
- stats);
+ return std::unique_ptr<CodeGenerator>(
+ new (arena) arm::CodeGeneratorARM(graph,
+ *isa_features.AsArmInstructionSetFeatures(),
+ compiler_options,
+ stats));
}
#endif
#ifdef ART_ENABLE_CODEGEN_arm64
case kArm64: {
- return new arm64::CodeGeneratorARM64(graph,
- *isa_features.AsArm64InstructionSetFeatures(),
- compiler_options,
- stats);
+ return std::unique_ptr<CodeGenerator>(
+ new (arena) arm64::CodeGeneratorARM64(graph,
+ *isa_features.AsArm64InstructionSetFeatures(),
+ compiler_options,
+ stats));
}
#endif
#ifdef ART_ENABLE_CODEGEN_mips
case kMips: {
- return new mips::CodeGeneratorMIPS(graph,
- *isa_features.AsMipsInstructionSetFeatures(),
- compiler_options,
- stats);
+ return std::unique_ptr<CodeGenerator>(
+ new (arena) mips::CodeGeneratorMIPS(graph,
+ *isa_features.AsMipsInstructionSetFeatures(),
+ compiler_options,
+ stats));
}
#endif
#ifdef ART_ENABLE_CODEGEN_mips64
case kMips64: {
- return new mips64::CodeGeneratorMIPS64(graph,
- *isa_features.AsMips64InstructionSetFeatures(),
- compiler_options,
- stats);
+ return std::unique_ptr<CodeGenerator>(
+ new (arena) mips64::CodeGeneratorMIPS64(graph,
+ *isa_features.AsMips64InstructionSetFeatures(),
+ compiler_options,
+ stats));
}
#endif
#ifdef ART_ENABLE_CODEGEN_x86
case kX86: {
- return new x86::CodeGeneratorX86(graph,
- *isa_features.AsX86InstructionSetFeatures(),
- compiler_options,
- stats);
+ return std::unique_ptr<CodeGenerator>(
+ new (arena) x86::CodeGeneratorX86(graph,
+ *isa_features.AsX86InstructionSetFeatures(),
+ compiler_options,
+ stats));
}
#endif
#ifdef ART_ENABLE_CODEGEN_x86_64
case kX86_64: {
- return new x86_64::CodeGeneratorX86_64(graph,
- *isa_features.AsX86_64InstructionSetFeatures(),
- compiler_options,
- stats);
+ return std::unique_ptr<CodeGenerator>(
+ new (arena) x86_64::CodeGeneratorX86_64(graph,
+ *isa_features.AsX86_64InstructionSetFeatures(),
+ compiler_options,
+ stats));
}
#endif
default:
diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h
index 1a060b1f58..87832a2d9f 100644
--- a/compiler/optimizing/code_generator.h
+++ b/compiler/optimizing/code_generator.h
@@ -166,15 +166,15 @@ class FieldAccessCallingConvention {
DISALLOW_COPY_AND_ASSIGN(FieldAccessCallingConvention);
};
-class CodeGenerator {
+class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> {
public:
// Compiles the graph to executable instructions.
void Compile(CodeAllocator* allocator);
- static CodeGenerator* Create(HGraph* graph,
- InstructionSet instruction_set,
- const InstructionSetFeatures& isa_features,
- const CompilerOptions& compiler_options,
- OptimizingCompilerStats* stats = nullptr);
+ static std::unique_ptr<CodeGenerator> Create(HGraph* graph,
+ InstructionSet instruction_set,
+ const InstructionSetFeatures& isa_features,
+ const CompilerOptions& compiler_options,
+ OptimizingCompilerStats* stats = nullptr);
virtual ~CodeGenerator() {}
// Get the graph. This is the outermost graph, never the graph of a method being inlined.
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 3049128a87..45d23fe516 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -777,7 +777,7 @@ CodeGeneratorARM::CodeGeneratorARM(HGraph* graph,
location_builder_(graph, this),
instruction_visitor_(graph, this),
move_resolver_(graph->GetArena(), this),
- assembler_(),
+ assembler_(graph->GetArena()),
isa_features_(isa_features),
uint32_literals_(std::less<uint32_t>(),
graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index c978aaa81d..efe4c06d3f 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -904,6 +904,7 @@ CodeGeneratorARM64::CodeGeneratorARM64(HGraph* graph,
location_builder_(graph, this),
instruction_visitor_(graph, this),
move_resolver_(graph->GetArena(), this),
+ assembler_(graph->GetArena()),
isa_features_(isa_features),
uint32_literals_(std::less<uint32_t>(),
graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc
index 185397ccdf..12d1164d03 100644
--- a/compiler/optimizing/code_generator_mips.cc
+++ b/compiler/optimizing/code_generator_mips.cc
@@ -471,7 +471,7 @@ CodeGeneratorMIPS::CodeGeneratorMIPS(HGraph* graph,
location_builder_(graph, this),
instruction_visitor_(graph, this),
move_resolver_(graph->GetArena(), this),
- assembler_(&isa_features),
+ assembler_(graph->GetArena(), &isa_features),
isa_features_(isa_features) {
// Save RA (containing the return address) to mimic Quick.
AddAllocatedRegister(Location::RegisterLocation(RA));
diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc
index 246f5b7a65..56ac38ef84 100644
--- a/compiler/optimizing/code_generator_mips64.cc
+++ b/compiler/optimizing/code_generator_mips64.cc
@@ -417,6 +417,7 @@ CodeGeneratorMIPS64::CodeGeneratorMIPS64(HGraph* graph,
location_builder_(graph, this),
instruction_visitor_(graph, this),
move_resolver_(graph->GetArena(), this),
+ assembler_(graph->GetArena()),
isa_features_(isa_features) {
// Save RA (containing the return address) to mimic Quick.
AddAllocatedRegister(Location::RegisterLocation(RA));
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 304cf08b51..1a4e62eb25 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -795,13 +795,16 @@ CodeGeneratorX86::CodeGeneratorX86(HGraph* graph,
location_builder_(graph, this),
instruction_visitor_(graph, this),
move_resolver_(graph->GetArena(), this),
+ assembler_(graph->GetArena()),
isa_features_(isa_features),
method_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
relative_call_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
pc_relative_dex_cache_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
simple_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
string_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
- fixups_to_jump_tables_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)) {
+ constant_area_start_(-1),
+ fixups_to_jump_tables_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
+ method_address_offset_(-1) {
// Use a fake return address register to mimic Quick.
AddAllocatedRegister(Location::RegisterLocation(kFakeReturnRegister));
}
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 056b69baac..59cc4444f7 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -1007,6 +1007,7 @@ CodeGeneratorX86_64::CodeGeneratorX86_64(HGraph* graph,
location_builder_(graph, this),
instruction_visitor_(graph, this),
move_resolver_(graph->GetArena(), this),
+ assembler_(graph->GetArena()),
isa_features_(isa_features),
constant_area_start_(0),
method_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
diff --git a/compiler/optimizing/licm_test.cc b/compiler/optimizing/licm_test.cc
index d446539700..2a62643465 100644
--- a/compiler/optimizing/licm_test.cc
+++ b/compiler/optimizing/licm_test.cc
@@ -169,13 +169,11 @@ TEST_F(LICMTest, ArrayHoisting) {
BuildLoop();
// Populate the loop with instructions: set/get array with different types.
- // ArrayGet is typed as kPrimByte and ArraySet given a float value in order to
- // avoid SsaBuilder's typing of ambiguous array operations from reference type info.
HInstruction* get_array = new (&allocator_) HArrayGet(
- parameter_, int_constant_, Primitive::kPrimByte, 0);
+ parameter_, int_constant_, Primitive::kPrimInt, 0);
loop_body_->InsertInstructionBefore(get_array, loop_body_->GetLastInstruction());
HInstruction* set_array = new (&allocator_) HArraySet(
- parameter_, int_constant_, float_constant_, Primitive::kPrimShort, 0);
+ parameter_, int_constant_, float_constant_, Primitive::kPrimFloat, 0);
loop_body_->InsertInstructionBefore(set_array, loop_body_->GetLastInstruction());
EXPECT_EQ(get_array->GetBlock(), loop_body_);
@@ -189,13 +187,11 @@ TEST_F(LICMTest, NoArrayHoisting) {
BuildLoop();
// Populate the loop with instructions: set/get array with same types.
- // ArrayGet is typed as kPrimByte and ArraySet given a float value in order to
- // avoid SsaBuilder's typing of ambiguous array operations from reference type info.
HInstruction* get_array = new (&allocator_) HArrayGet(
- parameter_, int_constant_, Primitive::kPrimByte, 0);
+ parameter_, int_constant_, Primitive::kPrimFloat, 0);
loop_body_->InsertInstructionBefore(get_array, loop_body_->GetLastInstruction());
HInstruction* set_array = new (&allocator_) HArraySet(
- parameter_, get_array, float_constant_, Primitive::kPrimByte, 0);
+ parameter_, get_array, float_constant_, Primitive::kPrimFloat, 0);
loop_body_->InsertInstructionBefore(set_array, loop_body_->GetLastInstruction());
EXPECT_EQ(get_array->GetBlock(), loop_body_);
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index dc5a8fa9cb..6f3e536d05 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -1551,21 +1551,21 @@ class SideEffects : public ValueObject {
static SideEffects FieldWriteOfType(Primitive::Type type, bool is_volatile) {
return is_volatile
? AllWritesAndReads()
- : SideEffects(TypeFlagWithAlias(type, kFieldWriteOffset));
+ : SideEffects(TypeFlag(type, kFieldWriteOffset));
}
static SideEffects ArrayWriteOfType(Primitive::Type type) {
- return SideEffects(TypeFlagWithAlias(type, kArrayWriteOffset));
+ return SideEffects(TypeFlag(type, kArrayWriteOffset));
}
static SideEffects FieldReadOfType(Primitive::Type type, bool is_volatile) {
return is_volatile
? AllWritesAndReads()
- : SideEffects(TypeFlagWithAlias(type, kFieldReadOffset));
+ : SideEffects(TypeFlag(type, kFieldReadOffset));
}
static SideEffects ArrayReadOfType(Primitive::Type type) {
- return SideEffects(TypeFlagWithAlias(type, kArrayReadOffset));
+ return SideEffects(TypeFlag(type, kArrayReadOffset));
}
static SideEffects CanTriggerGC() {
@@ -1692,23 +1692,6 @@ class SideEffects : public ValueObject {
static constexpr uint64_t kAllReads =
((1ULL << (kLastBitForReads + 1 - kFieldReadOffset)) - 1) << kFieldReadOffset;
- // Work around the fact that HIR aliases I/F and J/D.
- // TODO: remove this interceptor once HIR types are clean
- static uint64_t TypeFlagWithAlias(Primitive::Type type, int offset) {
- switch (type) {
- case Primitive::kPrimInt:
- case Primitive::kPrimFloat:
- return TypeFlag(Primitive::kPrimInt, offset) |
- TypeFlag(Primitive::kPrimFloat, offset);
- case Primitive::kPrimLong:
- case Primitive::kPrimDouble:
- return TypeFlag(Primitive::kPrimLong, offset) |
- TypeFlag(Primitive::kPrimDouble, offset);
- default:
- return TypeFlag(type, offset);
- }
- }
-
// Translates type to bit flag.
static uint64_t TypeFlag(Primitive::Type type, int offset) {
CHECK_NE(type, Primitive::kPrimVoid);
@@ -5196,10 +5179,8 @@ class HArraySet : public HTemplateInstruction<3> {
uint32_t dex_pc,
SideEffects additional_side_effects = SideEffects::None())
: HTemplateInstruction(
- SideEffects::ArrayWriteOfType(expected_component_type).Union(
- SideEffectsForArchRuntimeCalls(value->GetType())).Union(
- additional_side_effects),
- dex_pc) {
+ SideEffectsForArchRuntimeCalls(value->GetType()).Union(additional_side_effects),
+ dex_pc) {
SetPackedField<ExpectedComponentTypeField>(expected_component_type);
SetPackedFlag<kFlagNeedsTypeCheck>(value->GetType() == Primitive::kPrimNot);
SetPackedFlag<kFlagValueCanBeNull>(true);
@@ -5207,6 +5188,8 @@ class HArraySet : public HTemplateInstruction<3> {
SetRawInputAt(0, array);
SetRawInputAt(1, index);
SetRawInputAt(2, value);
+ // We can now call component type logic to set correct type-based side effects.
+ AddSideEffects(SideEffects::ArrayWriteOfType(GetComponentType()));
}
bool NeedsEnvironment() const OVERRIDE {
diff --git a/compiler/optimizing/optimizing_cfi_test.cc b/compiler/optimizing/optimizing_cfi_test.cc
index 2b0d522b31..400686d236 100644
--- a/compiler/optimizing/optimizing_cfi_test.cc
+++ b/compiler/optimizing/optimizing_cfi_test.cc
@@ -54,7 +54,7 @@ class OptimizingCFITest : public CFITest {
isa_features_.reset(InstructionSetFeatures::FromVariant(isa, "default", &error));
graph_ = CreateGraph(&allocator_);
// Generate simple frame with some spills.
- code_gen_.reset(CodeGenerator::Create(graph_, isa, *isa_features_, opts_));
+ code_gen_ = CodeGenerator::Create(graph_, isa, *isa_features_, opts_);
code_gen_->GetAssembler()->cfi().SetEnabled(true);
const int frame_size = 64;
int core_reg = 0;
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index cad94c7ad7..3670ce2253 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -948,13 +948,11 @@ bool OptimizingCompiler::JitCompile(Thread* self,
info.frame_size_in_bytes = method_header->GetFrameSizeInBytes();
info.code_info = stack_map_size == 0 ? nullptr : stack_map_data;
info.cfi = ArrayRef<const uint8_t>(*codegen->GetAssembler()->cfi().data());
- ArrayRef<const uint8_t> elf_file = debug::WriteDebugElfFileForMethods(
+ std::vector<uint8_t> elf_file = debug::WriteDebugElfFileForMethods(
GetCompilerDriver()->GetInstructionSet(),
GetCompilerDriver()->GetInstructionSetFeatures(),
ArrayRef<const debug::MethodDebugInfo>(&info, 1));
- CreateJITCodeEntryForAddress(code_address,
- std::unique_ptr<const uint8_t[]>(elf_file.data()),
- elf_file.size());
+ CreateJITCodeEntryForAddress(code_address, std::move(elf_file));
}
Runtime::Current()->GetJit()->AddMemoryUsage(method, arena.BytesUsed());
diff --git a/compiler/optimizing/side_effects_test.cc b/compiler/optimizing/side_effects_test.cc
index 9bbc354290..b01bc1ca0d 100644
--- a/compiler/optimizing/side_effects_test.cc
+++ b/compiler/optimizing/side_effects_test.cc
@@ -148,19 +148,19 @@ TEST(SideEffectsTest, VolatileDependences) {
EXPECT_FALSE(any_write.MayDependOn(volatile_read));
}
-TEST(SideEffectsTest, SameWidthTypes) {
+TEST(SideEffectsTest, SameWidthTypesNoAlias) {
// Type I/F.
- testWriteAndReadDependence(
+ testNoWriteAndReadDependence(
SideEffects::FieldWriteOfType(Primitive::kPrimInt, /* is_volatile */ false),
SideEffects::FieldReadOfType(Primitive::kPrimFloat, /* is_volatile */ false));
- testWriteAndReadDependence(
+ testNoWriteAndReadDependence(
SideEffects::ArrayWriteOfType(Primitive::kPrimInt),
SideEffects::ArrayReadOfType(Primitive::kPrimFloat));
// Type L/D.
- testWriteAndReadDependence(
+ testNoWriteAndReadDependence(
SideEffects::FieldWriteOfType(Primitive::kPrimLong, /* is_volatile */ false),
SideEffects::FieldReadOfType(Primitive::kPrimDouble, /* is_volatile */ false));
- testWriteAndReadDependence(
+ testNoWriteAndReadDependence(
SideEffects::ArrayWriteOfType(Primitive::kPrimLong),
SideEffects::ArrayReadOfType(Primitive::kPrimDouble));
}
@@ -216,14 +216,32 @@ TEST(SideEffectsTest, BitStrings) {
"||||||L|",
SideEffects::FieldWriteOfType(Primitive::kPrimNot, false).ToString().c_str());
EXPECT_STREQ(
+ "||DFJISCBZL|DFJISCBZL||DFJISCBZL|DFJISCBZL|",
+ SideEffects::FieldWriteOfType(Primitive::kPrimNot, true).ToString().c_str());
+ EXPECT_STREQ(
"|||||Z||",
SideEffects::ArrayWriteOfType(Primitive::kPrimBoolean).ToString().c_str());
EXPECT_STREQ(
+ "|||||C||",
+ SideEffects::ArrayWriteOfType(Primitive::kPrimChar).ToString().c_str());
+ EXPECT_STREQ(
+ "|||||S||",
+ SideEffects::ArrayWriteOfType(Primitive::kPrimShort).ToString().c_str());
+ EXPECT_STREQ(
"|||B||||",
SideEffects::FieldReadOfType(Primitive::kPrimByte, false).ToString().c_str());
EXPECT_STREQ(
- "||DJ|||||", // note: DJ alias
+ "||D|||||",
SideEffects::ArrayReadOfType(Primitive::kPrimDouble).ToString().c_str());
+ EXPECT_STREQ(
+ "||J|||||",
+ SideEffects::ArrayReadOfType(Primitive::kPrimLong).ToString().c_str());
+ EXPECT_STREQ(
+ "||F|||||",
+ SideEffects::ArrayReadOfType(Primitive::kPrimFloat).ToString().c_str());
+ EXPECT_STREQ(
+ "||I|||||",
+ SideEffects::ArrayReadOfType(Primitive::kPrimInt).ToString().c_str());
SideEffects s = SideEffects::None();
s = s.Union(SideEffects::FieldWriteOfType(Primitive::kPrimChar, /* is_volatile */ false));
s = s.Union(SideEffects::FieldWriteOfType(Primitive::kPrimLong, /* is_volatile */ false));
@@ -231,9 +249,7 @@ TEST(SideEffectsTest, BitStrings) {
s = s.Union(SideEffects::FieldReadOfType(Primitive::kPrimInt, /* is_volatile */ false));
s = s.Union(SideEffects::ArrayReadOfType(Primitive::kPrimFloat));
s = s.Union(SideEffects::ArrayReadOfType(Primitive::kPrimDouble));
- EXPECT_STREQ(
- "||DFJI|FI||S|DJC|", // note: DJ/FI alias.
- s.ToString().c_str());
+ EXPECT_STREQ("||DF|I||S|JC|", s.ToString().c_str());
}
} // namespace art