1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ART_COMPILER_SEA_IR_CODE_GEN_H_
#define ART_COMPILER_SEA_IR_CODE_GEN_H_
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Analysis/Verifier.h"
#include "visitor.h"
namespace sea_ir {
// Abstracts away the containers we use to map SEA IR objects to LLVM IR objects.
class CodeGenData {
public:
explicit CodeGenData(): context_(&llvm::getGlobalContext()), module_("sea_ir", *context_),
builder_(*context_), function_(), blocks_(), values_() { }
// Returns the llvm::BasicBlock* corresponding to the sea_ir::Region with id @region_id.
llvm::BasicBlock* GetBlock(int region_id) {
std::map<int, llvm::BasicBlock*>::iterator block_it = blocks_.find(region_id);
DCHECK(block_it != blocks_.end());
return block_it->second;
}
// Returns the llvm::BasicBlock* corresponding top the sea_ir::Region @region.
llvm::BasicBlock* GetBlock(Region* region) {
return GetBlock(region->Id());
}
// Records @block as corresponding to the sea_ir::Region with id @region_id.
void AddBlock(int region_id, llvm::BasicBlock* block) {
blocks_.insert(std::pair<int, llvm::BasicBlock*>(region_id, block));
}
// Records @block as corresponding to the sea_ir::Region with @region.
void AddBlock(Region* region, llvm::BasicBlock* block) {
AddBlock(region->Id(), block);
}
llvm::Value* GetValue(int instruction_id) {
std::map<int, llvm::Value*>::iterator value_it = values_.find(instruction_id);
DCHECK(value_it != values_.end());
return value_it->second;
}
// Returns the llvm::Value* corresponding to the output of @instruction.
llvm::Value* GetValue(InstructionNode* instruction) {
return GetValue(instruction->Id());
}
// Records @value as corresponding to the sea_ir::InstructionNode with id @instruction_id.
void AddValue(int instruction_id, llvm::Value* value) {
values_.insert(std::pair<int, llvm::Value*>(instruction_id, value));
}
// Records @value as corresponding to the sea_ir::InstructionNode @instruction.
void AddValue(InstructionNode* instruction, llvm::Value* value) {
AddValue(instruction->Id(), value);
}
llvm::LLVMContext* const context_;
llvm::Module module_;
llvm::IRBuilder<> builder_;
llvm::Function* function_;
private:
std::map<int, llvm::BasicBlock*> blocks_;
std::map<int, llvm::Value*> values_;
};
class CodeGenPassVisitor: public IRVisitor {
public:
explicit CodeGenPassVisitor(CodeGenData* cgd): llvm_data_(cgd) { }
CodeGenPassVisitor(): llvm_data_(new CodeGenData()) { }
// Initialize any data structure needed before the start of visiting.
virtual void Initialize(SeaGraph* graph);
CodeGenData* GetData() {
return llvm_data_;
}
void Write(std::string file) {
llvm_data_->module_.dump();
llvm::verifyFunction(*llvm_data_->function_);
}
protected:
CodeGenData* const llvm_data_;
};
class CodeGenPrepassVisitor: public CodeGenPassVisitor {
public:
void Visit(SeaGraph* graph);
void Visit(SignatureNode* region);
void Visit(Region* region);
void Visit(InstructionNode* instruction) { }
void Visit(ConstInstructionNode* instruction) { }
void Visit(ReturnInstructionNode* instruction) { }
void Visit(IfNeInstructionNode* instruction) { }
//void Visit(AddIntLitInstructionNode* instruction) { }
void Visit(MoveResultInstructionNode* instruction) { }
void Visit(InvokeStaticInstructionNode* instruction) { }
void Visit(AddIntInstructionNode* instruction) { }
void Visit(GotoInstructionNode* instruction) { }
void Visit(IfEqzInstructionNode* instruction) { }
void Visit(PhiInstructionNode* region);
};
class CodeGenPostpassVisitor: public CodeGenPassVisitor {
public:
explicit CodeGenPostpassVisitor(CodeGenData* code_gen_data): CodeGenPassVisitor(code_gen_data) { }
void Visit(SeaGraph* graph);
void Visit(SignatureNode* region);
void Visit(Region* region);
void Visit(InstructionNode* region) { }
void Visit(ConstInstructionNode* instruction) { }
void Visit(ReturnInstructionNode* instruction) { }
void Visit(IfNeInstructionNode* instruction) { }
//void Visit(AddIntLitInstructionNode* instruction) { }
void Visit(MoveResultInstructionNode* instruction) { }
void Visit(InvokeStaticInstructionNode* instruction) { }
void Visit(AddIntInstructionNode* instruction) { }
void Visit(GotoInstructionNode* instruction) { }
void Visit(IfEqzInstructionNode* instruction) { }
void Visit(PhiInstructionNode* region);
};
class CodeGenVisitor: public CodeGenPassVisitor {
public:
explicit CodeGenVisitor(CodeGenData* code_gen_data): CodeGenPassVisitor(code_gen_data) { }
void Visit(SeaGraph* graph);
void Visit(SignatureNode* region);
void Visit(Region* region);
void Visit(InstructionNode* region);
void Visit(ConstInstructionNode* instruction);
void Visit(ReturnInstructionNode* instruction);
void Visit(IfNeInstructionNode* instruction);
//void Visit(AddIntLitInstructionNode* instruction);
void Visit(MoveResultInstructionNode* instruction);
void Visit(InvokeStaticInstructionNode* instruction);
void Visit(AddIntInstructionNode* instruction);
void Visit(GotoInstructionNode* instruction);
void Visit(IfEqzInstructionNode* instruction);
void Visit(PhiInstructionNode* region) { }
};
} // end namespace sea_ir
#endif // ART_COMPILER_SEA_IR_CODE_GEN_H_
|