diff options
Diffstat (limited to 'compiler/sea_ir/code_gen.h')
-rw-r--r-- | compiler/sea_ir/code_gen.h | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/compiler/sea_ir/code_gen.h b/compiler/sea_ir/code_gen.h new file mode 100644 index 0000000000..0f0b2f7af6 --- /dev/null +++ b/compiler/sea_ir/code_gen.h @@ -0,0 +1,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_ |