blob: 0f0b2f7af61a0a88fdf76e066aa583b18a906928 [file] [log] [blame]
Dragos Sbirlea0e260a32013-06-21 09:20:34 -07001/*
2 * Copyright (C) 2013 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_SEA_IR_CODE_GEN_H_
18#define ART_COMPILER_SEA_IR_CODE_GEN_H_
19
20#include "llvm/IR/IRBuilder.h"
21#include "llvm/IR/LLVMContext.h"
22#include "llvm/IR/Module.h"
23#include "llvm/Analysis/Verifier.h"
24#include "visitor.h"
25
26namespace sea_ir {
27// Abstracts away the containers we use to map SEA IR objects to LLVM IR objects.
28class CodeGenData {
29 public:
30 explicit CodeGenData(): context_(&llvm::getGlobalContext()), module_("sea_ir", *context_),
31 builder_(*context_), function_(), blocks_(), values_() { }
32 // Returns the llvm::BasicBlock* corresponding to the sea_ir::Region with id @region_id.
33 llvm::BasicBlock* GetBlock(int region_id) {
34 std::map<int, llvm::BasicBlock*>::iterator block_it = blocks_.find(region_id);
35 DCHECK(block_it != blocks_.end());
36 return block_it->second;
37 }
38 // Returns the llvm::BasicBlock* corresponding top the sea_ir::Region @region.
39 llvm::BasicBlock* GetBlock(Region* region) {
40 return GetBlock(region->Id());
41 }
42 // Records @block as corresponding to the sea_ir::Region with id @region_id.
43 void AddBlock(int region_id, llvm::BasicBlock* block) {
44 blocks_.insert(std::pair<int, llvm::BasicBlock*>(region_id, block));
45 }
46 // Records @block as corresponding to the sea_ir::Region with @region.
47 void AddBlock(Region* region, llvm::BasicBlock* block) {
48 AddBlock(region->Id(), block);
49 }
50
51 llvm::Value* GetValue(int instruction_id) {
52 std::map<int, llvm::Value*>::iterator value_it = values_.find(instruction_id);
53 DCHECK(value_it != values_.end());
54 return value_it->second;
55 }
56 // Returns the llvm::Value* corresponding to the output of @instruction.
57 llvm::Value* GetValue(InstructionNode* instruction) {
58 return GetValue(instruction->Id());
59 }
60 // Records @value as corresponding to the sea_ir::InstructionNode with id @instruction_id.
61 void AddValue(int instruction_id, llvm::Value* value) {
62 values_.insert(std::pair<int, llvm::Value*>(instruction_id, value));
63 }
64 // Records @value as corresponding to the sea_ir::InstructionNode @instruction.
65 void AddValue(InstructionNode* instruction, llvm::Value* value) {
66 AddValue(instruction->Id(), value);
67 }
68
69 llvm::LLVMContext* const context_;
70 llvm::Module module_;
71 llvm::IRBuilder<> builder_;
72 llvm::Function* function_;
73
74 private:
75 std::map<int, llvm::BasicBlock*> blocks_;
76 std::map<int, llvm::Value*> values_;
77};
78
79class CodeGenPassVisitor: public IRVisitor {
80 public:
81 explicit CodeGenPassVisitor(CodeGenData* cgd): llvm_data_(cgd) { }
82 CodeGenPassVisitor(): llvm_data_(new CodeGenData()) { }
83 // Initialize any data structure needed before the start of visiting.
84 virtual void Initialize(SeaGraph* graph);
85 CodeGenData* GetData() {
86 return llvm_data_;
87 }
88 void Write(std::string file) {
89 llvm_data_->module_.dump();
90 llvm::verifyFunction(*llvm_data_->function_);
91 }
92
93 protected:
94 CodeGenData* const llvm_data_;
95};
96
97class CodeGenPrepassVisitor: public CodeGenPassVisitor {
98 public:
99 void Visit(SeaGraph* graph);
100 void Visit(SignatureNode* region);
101 void Visit(Region* region);
102 void Visit(InstructionNode* instruction) { }
103 void Visit(ConstInstructionNode* instruction) { }
104 void Visit(ReturnInstructionNode* instruction) { }
105 void Visit(IfNeInstructionNode* instruction) { }
106 //void Visit(AddIntLitInstructionNode* instruction) { }
107 void Visit(MoveResultInstructionNode* instruction) { }
108 void Visit(InvokeStaticInstructionNode* instruction) { }
109 void Visit(AddIntInstructionNode* instruction) { }
110 void Visit(GotoInstructionNode* instruction) { }
111 void Visit(IfEqzInstructionNode* instruction) { }
112 void Visit(PhiInstructionNode* region);
113};
114
115class CodeGenPostpassVisitor: public CodeGenPassVisitor {
116 public:
117 explicit CodeGenPostpassVisitor(CodeGenData* code_gen_data): CodeGenPassVisitor(code_gen_data) { }
118 void Visit(SeaGraph* graph);
119 void Visit(SignatureNode* region);
120 void Visit(Region* region);
121 void Visit(InstructionNode* region) { }
122 void Visit(ConstInstructionNode* instruction) { }
123 void Visit(ReturnInstructionNode* instruction) { }
124 void Visit(IfNeInstructionNode* instruction) { }
125 //void Visit(AddIntLitInstructionNode* instruction) { }
126 void Visit(MoveResultInstructionNode* instruction) { }
127 void Visit(InvokeStaticInstructionNode* instruction) { }
128 void Visit(AddIntInstructionNode* instruction) { }
129 void Visit(GotoInstructionNode* instruction) { }
130 void Visit(IfEqzInstructionNode* instruction) { }
131 void Visit(PhiInstructionNode* region);
132};
133
134class CodeGenVisitor: public CodeGenPassVisitor {
135 public:
136 explicit CodeGenVisitor(CodeGenData* code_gen_data): CodeGenPassVisitor(code_gen_data) { }
137 void Visit(SeaGraph* graph);
138 void Visit(SignatureNode* region);
139 void Visit(Region* region);
140 void Visit(InstructionNode* region);
141 void Visit(ConstInstructionNode* instruction);
142 void Visit(ReturnInstructionNode* instruction);
143 void Visit(IfNeInstructionNode* instruction);
144 //void Visit(AddIntLitInstructionNode* instruction);
145 void Visit(MoveResultInstructionNode* instruction);
146 void Visit(InvokeStaticInstructionNode* instruction);
147 void Visit(AddIntInstructionNode* instruction);
148 void Visit(GotoInstructionNode* instruction);
149 void Visit(IfEqzInstructionNode* instruction);
150 void Visit(PhiInstructionNode* region) { }
151};
152} // end namespace sea_ir
153#endif // ART_COMPILER_SEA_IR_CODE_GEN_H_