blob: 24dcab613151adc0d6641f564a661e9752ac1730 [file] [log] [blame]
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +00001/*
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
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +000020#include "globals.h"
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +000021#include "instruction_set.h"
22#include "memory_region.h"
23#include "nodes.h"
24#include "utils/assembler.h"
25
26namespace art {
27
Nicolas Geoffray92cf83e2014-03-18 17:59:20 +000028class DexCompilationUnit;
29
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +000030class CodeAllocator {
31 public:
32 CodeAllocator() { }
33 virtual ~CodeAllocator() { }
34
35 virtual uint8_t* Allocate(size_t size) = 0;
36
37 private:
38 DISALLOW_COPY_AND_ASSIGN(CodeAllocator);
39};
40
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +000041struct PcInfo {
42 uint32_t dex_pc;
43 uintptr_t native_pc;
44};
45
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +000046/**
47 * A Location is an abstraction over the potential location
48 * of an instruction. It could be in register or stack.
49 */
50class Location : public ValueObject {
51 public:
52 template<typename T>
53 T reg() const { return static_cast<T>(reg_); }
54
55 Location() : reg_(kInvalid) { }
56 explicit Location(uword reg) : reg_(reg) { }
57
58 static Location RegisterLocation(uword reg) {
59 return Location(reg);
60 }
61
62 bool IsValid() const { return reg_ != kInvalid; }
63
64 Location(const Location& other) : reg_(other.reg_) { }
65
66 Location& operator=(const Location& other) {
67 reg_ = other.reg_;
68 return *this;
69 }
70
71 private:
72 // The target register for that location.
73 // TODO: Support stack location.
74 uword reg_;
75 static const uword kInvalid = -1;
76};
77
78/**
79 * The code generator computes LocationSummary for each instruction so that
80 * the instruction itself knows what code to generate: where to find the inputs
81 * and where to place the result.
82 *
83 * The intent is to have the code for generating the instruction independent of
84 * register allocation. A register allocator just has to provide a LocationSummary.
85 */
86class LocationSummary : public ArenaObject {
87 public:
88 explicit LocationSummary(HInstruction* instruction)
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +000089 : inputs(instruction->GetBlock()->GetGraph()->GetArena(), instruction->InputCount()),
90 temps(instruction->GetBlock()->GetGraph()->GetArena(), 0) {
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +000091 inputs.SetSize(instruction->InputCount());
92 for (int i = 0; i < instruction->InputCount(); i++) {
93 inputs.Put(i, Location());
94 }
95 }
96
97 void SetInAt(uint32_t at, Location location) {
98 inputs.Put(at, location);
99 }
100
101 Location InAt(uint32_t at) const {
102 return inputs.Get(at);
103 }
104
105 void SetOut(Location location) {
106 output = Location(location);
107 }
108
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +0000109 void AddTemp(Location location) {
110 temps.Add(location);
111 }
112
113 Location GetTemp(uint32_t at) const {
114 return temps.Get(at);
115 }
116
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000117 Location Out() const { return output; }
118
119 private:
120 GrowableArray<Location> inputs;
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +0000121 GrowableArray<Location> temps;
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000122 Location output;
123
124 DISALLOW_COPY_AND_ASSIGN(LocationSummary);
125};
126
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000127class CodeGenerator : public ArenaObject {
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +0000128 public:
129 // Compiles the graph to executable instructions. Returns whether the compilation
130 // succeeded.
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000131 void Compile(CodeAllocator* allocator);
132 static CodeGenerator* Create(ArenaAllocator* allocator,
133 HGraph* graph,
134 InstructionSet instruction_set);
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +0000135
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000136 HGraph* GetGraph() const { return graph_; }
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +0000137
138 Label* GetLabelOf(HBasicBlock* block) const;
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000139 bool GoesToNextBlock(HBasicBlock* current, HBasicBlock* next) const;
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +0000140
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +0000141 virtual void GenerateFrameEntry() = 0;
142 virtual void GenerateFrameExit() = 0;
143 virtual void Bind(Label* label) = 0;
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000144 virtual void Move(HInstruction* instruction, Location location) = 0;
145 virtual void Push(HInstruction* instruction, Location location) = 0;
146 virtual HGraphVisitor* GetLocationBuilder() = 0;
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000147 virtual HGraphVisitor* GetInstructionVisitor() = 0;
148 virtual Assembler* GetAssembler() = 0;
149
150 uint32_t GetFrameSize() const { return frame_size_; }
151 void SetFrameSize(uint32_t size) { frame_size_ = size; }
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +0000152 uint32_t GetCoreSpillMask() const { return core_spill_mask_; }
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000153
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +0000154 void RecordPcInfo(uint32_t dex_pc) {
155 struct PcInfo pc_info;
156 pc_info.dex_pc = dex_pc;
157 pc_info.native_pc = GetAssembler()->CodeSize();
158 pc_infos_.Add(pc_info);
159 }
160
161 void BuildMappingTable(std::vector<uint8_t>* vector) const;
162 void BuildVMapTable(std::vector<uint8_t>* vector) const;
Nicolas Geoffray92cf83e2014-03-18 17:59:20 +0000163 void BuildNativeGCMap(
164 std::vector<uint8_t>* vector, const DexCompilationUnit& dex_compilation_unit) const;
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000165
166 protected:
167 explicit CodeGenerator(HGraph* graph)
168 : frame_size_(0),
169 graph_(graph),
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +0000170 block_labels_(graph->GetArena(), 0),
171 pc_infos_(graph->GetArena(), 32) {
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000172 block_labels_.SetSize(graph->GetBlocks()->Size());
173 }
174 ~CodeGenerator() { }
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +0000175
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +0000176 // Frame size required for this method.
177 uint32_t frame_size_;
178 uint32_t core_spill_mask_;
179
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000180 private:
181 void InitLocations(HInstruction* instruction);
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +0000182 void CompileBlock(HBasicBlock* block);
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000183 void CompileEntryBlock();
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +0000184
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000185 HGraph* const graph_;
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +0000186
187 // Labels for each block that will be compiled.
188 GrowableArray<Label> block_labels_;
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +0000189 GrowableArray<PcInfo> pc_infos_;
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +0000190
191 DISALLOW_COPY_AND_ASSIGN(CodeGenerator);
192};
193
194} // namespace art
195
196#endif // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_H_