diff options
author | Dragos Sbirlea <dragoss@google.com> | 2013-06-21 09:20:34 -0700 |
---|---|---|
committer | Dragos Sbirlea <dragoss@google.com> | 2013-07-22 10:19:07 -0700 |
commit | 0e260a32601fb1178e11837c460807071d489f82 (patch) | |
tree | 5b9d4ac485805f99e0ada0009bbe040cf0d523e9 /compiler/sea_ir/code_gen.h | |
parent | 49ed57499b918553e2d3db922ca2826dffa5bcd1 (diff) | |
download | android_art-0e260a32601fb1178e11837c460807071d489f82.tar.gz android_art-0e260a32601fb1178e11837c460807071d489f82.tar.bz2 android_art-0e260a32601fb1178e11837c460807071d489f82.zip |
Added code generation framework.
visitors.h: Contains only IR visitor declarations for now.
code_gen.h: Code generation vistor declaration (needs llvm).
code_gen.cc:Code generation visitor implementation (needs llvm).
instruction_nodes.h: Classes for each type of instruction; this
enables the visitor to visit each instruction differently and
corresponds to the sea of nodes paper.
sea_node.h : Moved base Sea IR Node to this separate header.
Replaced NO_REGISTER with enum (including RETURN_REGISTER)
sea.cc: Addded code generation call.
Set parent region for SignatureNodes.
Propagate method and class ids in IR generation routine.
Create InstructionNode subclasses.
*.mk: Updated to support the new files. Fixed some pre-existing formatting.
instruction_tools.h: Fixed double-define of NO_REGISTER to
refer to the new enum.
dex_instruction.cc: Added support for one more instruction in
HasRegXX and VRegXX functions.
Change-Id: I7c78f603e41df7bf9da5b77951b8485dd1b49200
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_ |