diff options
Diffstat (limited to 'compiler/optimizing/codegen_test_utils.h')
| -rw-r--r-- | compiler/optimizing/codegen_test_utils.h | 92 |
1 files changed, 79 insertions, 13 deletions
diff --git a/compiler/optimizing/codegen_test_utils.h b/compiler/optimizing/codegen_test_utils.h index 1b38acd8b0f..bcbcc12349a 100644 --- a/compiler/optimizing/codegen_test_utils.h +++ b/compiler/optimizing/codegen_test_utils.h @@ -28,6 +28,7 @@ #include "arch/x86/instruction_set_features_x86.h" #include "arch/x86/registers_x86.h" #include "arch/x86_64/instruction_set_features_x86_64.h" +#include "code_simulator.h" #include "code_simulator_container.h" #include "common_compiler_test.h" #include "graph_checker.h" @@ -78,6 +79,21 @@ class CodegenTargetConfig { }; #ifdef ART_ENABLE_CODEGEN_arm +// Special ARM code generator for codegen testing in a limited code +// generation environment (i.e. with no runtime support). +// +// Note: If we want to exercise certains HIR constructions +// (e.g. reference field load in Baker read barrier configuration) in +// codegen tests in the future, we should also: +// - save the Thread Register (R9) and possibly the Marking Register +// (R8) before entering the generated function (both registers are +// callee-save in AAPCS); +// - set these registers to meaningful values before or upon entering +// the generated function (so that generated code using them is +// correct); +// - restore their original values before leaving the generated +// function. + // Provide our own codegen, that ensures the C calling conventions // are preserved. Currently, ART and C do not match as R4 is caller-save // in ART, and callee-save in C. Alternatively, we could use or write @@ -99,6 +115,50 @@ class TestCodeGeneratorARMVIXL : public arm::CodeGeneratorARMVIXL { blocked_core_registers_[arm::R6] = false; blocked_core_registers_[arm::R7] = false; } + + void MaybeGenerateMarkingRegisterCheck(int code ATTRIBUTE_UNUSED, + Location temp_loc ATTRIBUTE_UNUSED) OVERRIDE { + // When turned on, the marking register checks in + // CodeGeneratorARMVIXL::MaybeGenerateMarkingRegisterCheck expects the + // Thread Register and the Marking Register to be set to + // meaningful values. This is not the case in codegen testing, so + // just disable them entirely here (by doing nothing in this + // method). + } +}; +#endif + +#ifdef ART_ENABLE_CODEGEN_arm64 +// Special ARM64 code generator for codegen testing in a limited code +// generation environment (i.e. with no runtime support). +// +// Note: If we want to exercise certains HIR constructions +// (e.g. reference field load in Baker read barrier configuration) in +// codegen tests in the future, we should also: +// - save the Thread Register (X19) and possibly the Marking Register +// (X20) before entering the generated function (both registers are +// callee-save in AAPCS64); +// - set these registers to meaningful values before or upon entering +// the generated function (so that generated code using them is +// correct); +// - restore their original values before leaving the generated +// function. +class TestCodeGeneratorARM64 : public arm64::CodeGeneratorARM64 { + public: + TestCodeGeneratorARM64(HGraph* graph, + const Arm64InstructionSetFeatures& isa_features, + const CompilerOptions& compiler_options) + : arm64::CodeGeneratorARM64(graph, isa_features, compiler_options) {} + + void MaybeGenerateMarkingRegisterCheck(int codem ATTRIBUTE_UNUSED, + Location temp_loc ATTRIBUTE_UNUSED) OVERRIDE { + // When turned on, the marking register checks in + // CodeGeneratorARM64::MaybeGenerateMarkingRegisterCheck expect the + // Thread Register and the Marking Register to be set to + // meaningful values. This is not the case in codegen testing, so + // just disable them entirely here (by doing nothing in this + // method). + } }; #endif @@ -235,10 +295,15 @@ static void RunCodeNoCheck(CodeGenerator* codegen, const std::function<void(HGraph*)>& hook_before_codegen, bool has_result, Expected expected) { - SsaLivenessAnalysis liveness(graph, codegen); - PrepareForRegisterAllocation(graph).Run(); - liveness.Analyze(); - RegisterAllocator::Create(graph->GetArena(), codegen, liveness)->AllocateRegisters(); + { + ScopedArenaAllocator local_allocator(graph->GetArenaStack()); + SsaLivenessAnalysis liveness(graph, codegen, &local_allocator); + PrepareForRegisterAllocation(graph).Run(); + liveness.Analyze(); + std::unique_ptr<RegisterAllocator> register_allocator = + RegisterAllocator::Create(&local_allocator, codegen, liveness); + register_allocator->AllocateRegisters(); + } hook_before_codegen(graph); InternalCodeAllocator allocator; codegen->Compile(&allocator); @@ -262,7 +327,8 @@ static void RunCode(CodegenTargetConfig target_config, bool has_result, Expected expected) { CompilerOptions compiler_options; - std::unique_ptr<CodeGenerator> codegen(target_config.CreateCodeGenerator(graph, compiler_options)); + std::unique_ptr<CodeGenerator> codegen(target_config.CreateCodeGenerator(graph, + compiler_options)); RunCode(codegen.get(), graph, hook_before_codegen, has_result, expected); } @@ -270,7 +336,7 @@ static void RunCode(CodegenTargetConfig target_config, CodeGenerator* create_codegen_arm_vixl32(HGraph* graph, const CompilerOptions& compiler_options) { std::unique_ptr<const ArmInstructionSetFeatures> features_arm( ArmInstructionSetFeatures::FromCppDefines()); - return new (graph->GetArena()) + return new (graph->GetAllocator()) TestCodeGeneratorARMVIXL(graph, *features_arm.get(), compiler_options); } #endif @@ -279,9 +345,8 @@ CodeGenerator* create_codegen_arm_vixl32(HGraph* graph, const CompilerOptions& c CodeGenerator* create_codegen_arm64(HGraph* graph, const CompilerOptions& compiler_options) { std::unique_ptr<const Arm64InstructionSetFeatures> features_arm64( Arm64InstructionSetFeatures::FromCppDefines()); - return new (graph->GetArena()) arm64::CodeGeneratorARM64(graph, - *features_arm64.get(), - compiler_options); + return new (graph->GetAllocator()) + TestCodeGeneratorARM64(graph, *features_arm64.get(), compiler_options); } #endif @@ -289,7 +354,8 @@ CodeGenerator* create_codegen_arm64(HGraph* graph, const CompilerOptions& compil CodeGenerator* create_codegen_x86(HGraph* graph, const CompilerOptions& compiler_options) { std::unique_ptr<const X86InstructionSetFeatures> features_x86( X86InstructionSetFeatures::FromCppDefines()); - return new (graph->GetArena()) TestCodeGeneratorX86(graph, *features_x86.get(), compiler_options); + return new (graph->GetAllocator()) TestCodeGeneratorX86( + graph, *features_x86.get(), compiler_options); } #endif @@ -297,7 +363,7 @@ CodeGenerator* create_codegen_x86(HGraph* graph, const CompilerOptions& compiler CodeGenerator* create_codegen_x86_64(HGraph* graph, const CompilerOptions& compiler_options) { std::unique_ptr<const X86_64InstructionSetFeatures> features_x86_64( X86_64InstructionSetFeatures::FromCppDefines()); - return new (graph->GetArena()) + return new (graph->GetAllocator()) x86_64::CodeGeneratorX86_64(graph, *features_x86_64.get(), compiler_options); } #endif @@ -306,7 +372,7 @@ CodeGenerator* create_codegen_x86_64(HGraph* graph, const CompilerOptions& compi CodeGenerator* create_codegen_mips(HGraph* graph, const CompilerOptions& compiler_options) { std::unique_ptr<const MipsInstructionSetFeatures> features_mips( MipsInstructionSetFeatures::FromCppDefines()); - return new (graph->GetArena()) + return new (graph->GetAllocator()) mips::CodeGeneratorMIPS(graph, *features_mips.get(), compiler_options); } #endif @@ -315,7 +381,7 @@ CodeGenerator* create_codegen_mips(HGraph* graph, const CompilerOptions& compile CodeGenerator* create_codegen_mips64(HGraph* graph, const CompilerOptions& compiler_options) { std::unique_ptr<const Mips64InstructionSetFeatures> features_mips64( Mips64InstructionSetFeatures::FromCppDefines()); - return new (graph->GetArena()) + return new (graph->GetAllocator()) mips64::CodeGeneratorMIPS64(graph, *features_mips64.get(), compiler_options); } #endif |
