optimizing_compiler.cc revision e50383288a75244255d3ecedcc79ffe9caf774cb
1b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray/* 2b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * Copyright (C) 2014 The Android Open Source Project 3b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * 4b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License"); 5b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * you may not use this file except in compliance with the License. 6b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * You may obtain a copy of the License at 7b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * 8b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * http://www.apache.org/licenses/LICENSE-2.0 9b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * 10b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * Unless required by applicable law or agreed to in writing, software 11b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS, 12b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * See the License for the specific language governing permissions and 14b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * limitations under the License. 15b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray */ 16b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 17f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray#include <fstream> 18787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray#include <stdint.h> 19787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray 20787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray#include "builder.h" 21787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray#include "code_generator.h" 22b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#include "compilers.h" 23787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray#include "driver/compiler_driver.h" 2492cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray#include "driver/dex_compilation_unit.h" 25f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray#include "graph_visualizer.h" 26787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray#include "nodes.h" 27a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray#include "register_allocator.h" 28804d09372cc3d80d537da1489da4a45e0e19aa5dNicolas Geoffray#include "ssa_liveness_analysis.h" 29787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray#include "utils/arena_allocator.h" 30b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 31b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffraynamespace art { 32b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 33787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray/** 34787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray * Used by the code generator, to allocate the code in a vector. 35787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray */ 36787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffrayclass CodeVectorAllocator FINAL : public CodeAllocator { 37787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray public: 38787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray CodeVectorAllocator() { } 39787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray 40787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray virtual uint8_t* Allocate(size_t size) { 41787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray size_ = size; 4292cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray memory_.resize(size); 43787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray return &memory_[0]; 44787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray } 45787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray 46787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray size_t GetSize() const { return size_; } 4792cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray const std::vector<uint8_t>& GetMemory() const { return memory_; } 48787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray 49787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray private: 50787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray std::vector<uint8_t> memory_; 51787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray size_t size_; 52787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray 53787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray DISALLOW_COPY_AND_ASSIGN(CodeVectorAllocator); 54787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray}; 55787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray 56f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray/** 57f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * If set to true, generates a file suitable for the c1visualizer tool and IRHydra. 58f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray */ 59f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffraystatic bool kIsVisualizerEnabled = false; 60f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 61f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray/** 62f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * Filter to apply to the visualizer. Methods whose name contain that filter will 63f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * be in the file. 64f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray */ 65f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffraystatic const char* kStringFilter = ""; 66f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 67f635e63318447ca04731b265a86a573c9ed1737cNicolas GeoffrayOptimizingCompiler::OptimizingCompiler(CompilerDriver* driver) : QuickCompiler(driver) { 68f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (kIsVisualizerEnabled) { 69f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray visualizer_output_.reset(new std::ofstream("art.cfg")); 70f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 71f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray} 72787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray 7372d32629303f8f39362a4099481f48646aed042fIan RogersCompiledMethod* OptimizingCompiler::TryCompile(const DexFile::CodeItem* code_item, 74b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray uint32_t access_flags, 75b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray InvokeType invoke_type, 76b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray uint16_t class_def_idx, 77b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray uint32_t method_idx, 78b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray jobject class_loader, 79b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray const DexFile& dex_file) const { 808fb5ce3a7e1dec587642f900be86729c10224174Nicolas Geoffray InstructionSet instruction_set = GetCompilerDriver()->GetInstructionSet(); 818fb5ce3a7e1dec587642f900be86729c10224174Nicolas Geoffray // The optimizing compiler currently does not have a Thumb2 assembler. 828fb5ce3a7e1dec587642f900be86729c10224174Nicolas Geoffray if (instruction_set == kThumb2) { 838fb5ce3a7e1dec587642f900be86729c10224174Nicolas Geoffray instruction_set = kArm; 848fb5ce3a7e1dec587642f900be86729c10224174Nicolas Geoffray } 858fb5ce3a7e1dec587642f900be86729c10224174Nicolas Geoffray 868fb5ce3a7e1dec587642f900be86729c10224174Nicolas Geoffray // Do not attempt to compile on architectures we do not support. 878fb5ce3a7e1dec587642f900be86729c10224174Nicolas Geoffray if (instruction_set != kX86 && instruction_set != kX86_64 && instruction_set != kArm) { 888fb5ce3a7e1dec587642f900be86729c10224174Nicolas Geoffray return nullptr; 898fb5ce3a7e1dec587642f900be86729c10224174Nicolas Geoffray } 908fb5ce3a7e1dec587642f900be86729c10224174Nicolas Geoffray 9192cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray DexCompilationUnit dex_compilation_unit( 9292cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray nullptr, class_loader, art::Runtime::Current()->GetClassLinker(), dex_file, code_item, 9372d32629303f8f39362a4099481f48646aed042fIan Rogers class_def_idx, method_idx, access_flags, 9472d32629303f8f39362a4099481f48646aed042fIan Rogers GetCompilerDriver()->GetVerifiedMethod(&dex_file, method_idx)); 9592cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray 968ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray // For testing purposes, we put a special marker on method names that should be compiled 978ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray // with this compiler. This makes sure we're not regressing. 988ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray bool shouldCompile = dex_compilation_unit.GetSymbol().find("00024opt_00024") != std::string::npos; 9986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray bool shouldOptimize = 10086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray dex_compilation_unit.GetSymbol().find("00024reg_00024") != std::string::npos; 1018ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray 102787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray ArenaPool pool; 103787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray ArenaAllocator arena(&pool); 104e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray HGraphBuilder builder(&arena, &dex_compilation_unit, &dex_file, GetCompilerDriver()); 105f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 106787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray HGraph* graph = builder.BuildGraph(*code_item); 107787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray if (graph == nullptr) { 1088ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray if (shouldCompile) { 1098ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray LOG(FATAL) << "Could not build graph in optimizing compiler"; 1108ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray } 111787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray return nullptr; 112787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray } 113787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray 114787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray CodeGenerator* codegen = CodeGenerator::Create(&arena, graph, instruction_set); 115787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray if (codegen == nullptr) { 1168ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray if (shouldCompile) { 1178ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray LOG(FATAL) << "Could not find code generator for optimizing compiler"; 1188ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray } 119787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray return nullptr; 120787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray } 121787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray 122a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray HGraphVisualizer visualizer( 123a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray visualizer_output_.get(), graph, kStringFilter, *codegen, dex_compilation_unit); 124a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray visualizer.DumpGraph("builder"); 125a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray 126787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray CodeVectorAllocator allocator; 12786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray 12886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray if (RegisterAllocator::CanAllocateRegistersFor(*graph, instruction_set)) { 12986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray graph->BuildDominatorTree(); 13086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray graph->TransformToSSA(); 13186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray visualizer.DumpGraph("ssa"); 13286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray 13386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray graph->FindNaturalLoops(); 13486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray SsaLivenessAnalysis liveness(*graph, codegen); 13586dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray liveness.Analyze(); 13686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray visualizer.DumpGraph(kLivenessPassName); 13786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray 13886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray RegisterAllocator register_allocator(graph->GetArena(), codegen, liveness); 13986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray register_allocator.AllocateRegisters(); 14086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray 14186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray visualizer.DumpGraph(kRegisterAllocatorPassName); 14286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray codegen->CompileOptimized(&allocator); 14386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } else if (shouldOptimize && RegisterAllocator::Supports(instruction_set)) { 14486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray LOG(FATAL) << "Could not allocate registers in optimizing compiler"; 14586dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } else { 14686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray codegen->CompileBaseline(&allocator); 14786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray 14886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray // Run these phases to get some test coverage. 14986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray graph->BuildDominatorTree(); 15086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray graph->TransformToSSA(); 15186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray visualizer.DumpGraph("ssa"); 15286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray graph->FindNaturalLoops(); 15386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray SsaLivenessAnalysis liveness(*graph, codegen); 15486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray liveness.Analyze(); 15586dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray visualizer.DumpGraph(kLivenessPassName); 15686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 157787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray 158787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray std::vector<uint8_t> mapping_table; 159787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray codegen->BuildMappingTable(&mapping_table); 160787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray std::vector<uint8_t> vmap_table; 161787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray codegen->BuildVMapTable(&vmap_table); 162787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray std::vector<uint8_t> gc_map; 16392cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray codegen->BuildNativeGCMap(&gc_map, dex_compilation_unit); 164787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray 16572d32629303f8f39362a4099481f48646aed042fIan Rogers return new CompiledMethod(GetCompilerDriver(), 166787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray instruction_set, 16792cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray allocator.GetMemory(), 168787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray codegen->GetFrameSize(), 1698ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray codegen->GetCoreSpillMask(), 170787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray 0, /* FPR spill mask, unused */ 171787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray mapping_table, 172787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray vmap_table, 173787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray gc_map, 174787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray nullptr); 175b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray} 176b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 177b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray} // namespace art 178