optimizing_compiler.cc revision f635e63318447ca04731b265a86a573c9ed1737c
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <fstream> 18#include <stdint.h> 19 20#include "builder.h" 21#include "code_generator.h" 22#include "compilers.h" 23#include "driver/compiler_driver.h" 24#include "driver/dex_compilation_unit.h" 25#include "graph_visualizer.h" 26#include "nodes.h" 27#include "ssa_liveness_analysis.h" 28#include "utils/arena_allocator.h" 29 30namespace art { 31 32/** 33 * Used by the code generator, to allocate the code in a vector. 34 */ 35class CodeVectorAllocator FINAL : public CodeAllocator { 36 public: 37 CodeVectorAllocator() { } 38 39 virtual uint8_t* Allocate(size_t size) { 40 size_ = size; 41 memory_.resize(size); 42 return &memory_[0]; 43 } 44 45 size_t GetSize() const { return size_; } 46 const std::vector<uint8_t>& GetMemory() const { return memory_; } 47 48 private: 49 std::vector<uint8_t> memory_; 50 size_t size_; 51 52 DISALLOW_COPY_AND_ASSIGN(CodeVectorAllocator); 53}; 54 55/** 56 * If set to true, generates a file suitable for the c1visualizer tool and IRHydra. 57 */ 58static bool kIsVisualizerEnabled = false; 59 60/** 61 * Filter to apply to the visualizer. Methods whose name contain that filter will 62 * be in the file. 63 */ 64static const char* kStringFilter = ""; 65 66OptimizingCompiler::OptimizingCompiler(CompilerDriver* driver) : QuickCompiler(driver) { 67 if (kIsVisualizerEnabled) { 68 visualizer_output_.reset(new std::ofstream("art.cfg")); 69 } 70} 71 72CompiledMethod* OptimizingCompiler::TryCompile(const DexFile::CodeItem* code_item, 73 uint32_t access_flags, 74 InvokeType invoke_type, 75 uint16_t class_def_idx, 76 uint32_t method_idx, 77 jobject class_loader, 78 const DexFile& dex_file) const { 79 DexCompilationUnit dex_compilation_unit( 80 nullptr, class_loader, art::Runtime::Current()->GetClassLinker(), dex_file, code_item, 81 class_def_idx, method_idx, access_flags, 82 GetCompilerDriver()->GetVerifiedMethod(&dex_file, method_idx)); 83 84 // For testing purposes, we put a special marker on method names that should be compiled 85 // with this compiler. This makes sure we're not regressing. 86 bool shouldCompile = dex_compilation_unit.GetSymbol().find("00024opt_00024") != std::string::npos; 87 88 ArenaPool pool; 89 ArenaAllocator arena(&pool); 90 HGraphBuilder builder(&arena, &dex_compilation_unit, &dex_file); 91 92 HGraph* graph = builder.BuildGraph(*code_item); 93 if (graph == nullptr) { 94 if (shouldCompile) { 95 LOG(FATAL) << "Could not build graph in optimizing compiler"; 96 } 97 return nullptr; 98 } 99 HGraphVisualizer visualizer(visualizer_output_.get(), graph, kStringFilter, dex_compilation_unit); 100 visualizer.DumpGraph("builder"); 101 102 InstructionSet instruction_set = GetCompilerDriver()->GetInstructionSet(); 103 // The optimizing compiler currently does not have a Thumb2 assembler. 104 if (instruction_set == kThumb2) { 105 instruction_set = kArm; 106 } 107 CodeGenerator* codegen = CodeGenerator::Create(&arena, graph, instruction_set); 108 if (codegen == nullptr) { 109 if (shouldCompile) { 110 LOG(FATAL) << "Could not find code generator for optimizing compiler"; 111 } 112 return nullptr; 113 } 114 115 CodeVectorAllocator allocator; 116 codegen->Compile(&allocator); 117 118 std::vector<uint8_t> mapping_table; 119 codegen->BuildMappingTable(&mapping_table); 120 std::vector<uint8_t> vmap_table; 121 codegen->BuildVMapTable(&vmap_table); 122 std::vector<uint8_t> gc_map; 123 codegen->BuildNativeGCMap(&gc_map, dex_compilation_unit); 124 125 // Run these phases to get some test coverage. 126 graph->BuildDominatorTree(); 127 graph->TransformToSSA(); 128 visualizer.DumpGraph("ssa"); 129 130 graph->FindNaturalLoops(); 131 SsaLivenessAnalysis(*graph).Analyze(); 132 133 return new CompiledMethod(GetCompilerDriver(), 134 instruction_set, 135 allocator.GetMemory(), 136 codegen->GetFrameSize(), 137 codegen->GetCoreSpillMask(), 138 0, /* FPR spill mask, unused */ 139 mapping_table, 140 vmap_table, 141 gc_map, 142 nullptr); 143} 144 145} // namespace art 146