code_generator.h revision bab4ed7057799a4fadc6283108ab56f389d117d4
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#ifndef ART_COMPILER_OPTIMIZING_CODE_GENERATOR_H_ 18#define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_H_ 19 20#include "globals.h" 21#include "instruction_set.h" 22#include "memory_region.h" 23#include "nodes.h" 24#include "utils/assembler.h" 25 26namespace art { 27 28class CodeAllocator { 29 public: 30 CodeAllocator() { } 31 virtual ~CodeAllocator() { } 32 33 virtual uint8_t* Allocate(size_t size) = 0; 34 35 private: 36 DISALLOW_COPY_AND_ASSIGN(CodeAllocator); 37}; 38 39/** 40 * A Location is an abstraction over the potential location 41 * of an instruction. It could be in register or stack. 42 */ 43class Location : public ValueObject { 44 public: 45 template<typename T> 46 T reg() const { return static_cast<T>(reg_); } 47 48 Location() : reg_(kInvalid) { } 49 explicit Location(uword reg) : reg_(reg) { } 50 51 static Location RegisterLocation(uword reg) { 52 return Location(reg); 53 } 54 55 bool IsValid() const { return reg_ != kInvalid; } 56 57 Location(const Location& other) : reg_(other.reg_) { } 58 59 Location& operator=(const Location& other) { 60 reg_ = other.reg_; 61 return *this; 62 } 63 64 private: 65 // The target register for that location. 66 // TODO: Support stack location. 67 uword reg_; 68 static const uword kInvalid = -1; 69}; 70 71/** 72 * The code generator computes LocationSummary for each instruction so that 73 * the instruction itself knows what code to generate: where to find the inputs 74 * and where to place the result. 75 * 76 * The intent is to have the code for generating the instruction independent of 77 * register allocation. A register allocator just has to provide a LocationSummary. 78 */ 79class LocationSummary : public ArenaObject { 80 public: 81 explicit LocationSummary(HInstruction* instruction) 82 : inputs(instruction->block()->graph()->arena(), instruction->InputCount()) { 83 inputs.SetSize(instruction->InputCount()); 84 for (int i = 0; i < instruction->InputCount(); i++) { 85 inputs.Put(i, Location()); 86 } 87 } 88 89 void SetInAt(uint32_t at, Location location) { 90 inputs.Put(at, location); 91 } 92 93 Location InAt(uint32_t at) const { 94 return inputs.Get(at); 95 } 96 97 void SetOut(Location location) { 98 output = Location(location); 99 } 100 101 Location Out() const { return output; } 102 103 private: 104 GrowableArray<Location> inputs; 105 Location output; 106 107 DISALLOW_COPY_AND_ASSIGN(LocationSummary); 108}; 109 110class CodeGenerator : public HGraphVisitor { 111 public: 112 // Compiles the graph to executable instructions. Returns whether the compilation 113 // succeeded. 114 static bool CompileGraph(HGraph* graph, InstructionSet instruction_set, CodeAllocator* allocator); 115 116 Assembler* assembler() const { return assembler_; } 117 118 // Visit functions for instruction classes. 119#define DECLARE_VISIT_INSTRUCTION(name) \ 120 virtual void Visit##name(H##name* instr) = 0; 121 122 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) 123 124#undef DECLARE_VISIT_INSTRUCTION 125 126 protected: 127 CodeGenerator(Assembler* assembler, HGraph* graph) 128 : HGraphVisitor(graph), 129 frame_size_(0), 130 assembler_(assembler), 131 block_labels_(graph->arena(), 0) { 132 block_labels_.SetSize(graph->blocks()->Size()); 133 } 134 135 Label* GetLabelOf(HBasicBlock* block) const; 136 bool GoesToNextBlock(HBasicBlock* current, HBasicBlock* next) const; 137 138 // Frame size required for this method. 139 uint32_t frame_size_; 140 141 virtual void GenerateFrameEntry() = 0; 142 virtual void GenerateFrameExit() = 0; 143 virtual void Bind(Label* label) = 0; 144 virtual void Move(HInstruction* instruction, Location location) = 0; 145 virtual void Push(HInstruction* instruction, Location location) = 0; 146 virtual HGraphVisitor* GetLocationBuilder() = 0; 147 148 private: 149 void InitLocations(HInstruction* instruction); 150 void Compile(CodeAllocator* allocator); 151 void CompileBlock(HBasicBlock* block); 152 void CompileEntryBlock(); 153 154 Assembler* const assembler_; 155 156 // Labels for each block that will be compiled. 157 GrowableArray<Label> block_labels_; 158 159 DISALLOW_COPY_AND_ASSIGN(CodeGenerator); 160}; 161 162} // namespace art 163 164#endif // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_H_ 165