10e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea/* 20e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea * Copyright (C) 2013 The Android Open Source Project 30e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea * 40e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea * Licensed under the Apache License, Version 2.0 (the "License"); 50e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea * you may not use this file except in compliance with the License. 60e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea * You may obtain a copy of the License at 70e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea * 80e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea * http://www.apache.org/licenses/LICENSE-2.0 90e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea * 100e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea * Unless required by applicable law or agreed to in writing, software 110e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea * distributed under the License is distributed on an "AS IS" BASIS, 120e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea * See the License for the specific language governing permissions and 140e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea * limitations under the License. 150e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea */ 160e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea 17bfaf44fa3366955a2bacb2c38c79b53df2434582Dragos Sbirlea#ifndef ART_COMPILER_SEA_IR_CODE_GEN_CODE_GEN_H_ 18bfaf44fa3366955a2bacb2c38c79b53df2434582Dragos Sbirlea#define ART_COMPILER_SEA_IR_CODE_GEN_CODE_GEN_H_ 190e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea 2090af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea#include "instruction_set.h" 21b40eddfc96b9ac235dea562e55ce2ad7b1cfb7c9Dragos Sbirlea#include "llvm/Analysis/Verifier.h" 220e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea#include "llvm/IR/IRBuilder.h" 230e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea#include "llvm/IR/LLVMContext.h" 240e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea#include "llvm/IR/Module.h" 250e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea#include "llvm/Analysis/Verifier.h" 26bfaf44fa3366955a2bacb2c38c79b53df2434582Dragos Sbirlea#include "sea_ir/ir/visitor.h" 270e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea 280e260a32601fb1178e11837c460807071d489f82Dragos Sbirleanamespace sea_ir { 290e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea// Abstracts away the containers we use to map SEA IR objects to LLVM IR objects. 300e260a32601fb1178e11837c460807071d489f82Dragos Sbirleaclass CodeGenData { 310e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea public: 320e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea explicit CodeGenData(): context_(&llvm::getGlobalContext()), module_("sea_ir", *context_), 330e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea builder_(*context_), function_(), blocks_(), values_() { } 340e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea // Returns the llvm::BasicBlock* corresponding to the sea_ir::Region with id @region_id. 350e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea llvm::BasicBlock* GetBlock(int region_id) { 360e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea std::map<int, llvm::BasicBlock*>::iterator block_it = blocks_.find(region_id); 370e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea DCHECK(block_it != blocks_.end()); 380e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea return block_it->second; 390e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea } 400e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea // Returns the llvm::BasicBlock* corresponding top the sea_ir::Region @region. 410e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea llvm::BasicBlock* GetBlock(Region* region) { 420e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea return GetBlock(region->Id()); 430e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea } 440e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea // Records @block as corresponding to the sea_ir::Region with id @region_id. 450e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void AddBlock(int region_id, llvm::BasicBlock* block) { 460e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea blocks_.insert(std::pair<int, llvm::BasicBlock*>(region_id, block)); 470e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea } 480e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea // Records @block as corresponding to the sea_ir::Region with @region. 490e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void AddBlock(Region* region, llvm::BasicBlock* block) { 500e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea AddBlock(region->Id(), block); 510e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea } 520e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea 530e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea llvm::Value* GetValue(int instruction_id) { 540e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea std::map<int, llvm::Value*>::iterator value_it = values_.find(instruction_id); 550e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea DCHECK(value_it != values_.end()); 560e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea return value_it->second; 570e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea } 580e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea // Returns the llvm::Value* corresponding to the output of @instruction. 590e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea llvm::Value* GetValue(InstructionNode* instruction) { 600e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea return GetValue(instruction->Id()); 610e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea } 620e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea // Records @value as corresponding to the sea_ir::InstructionNode with id @instruction_id. 630e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void AddValue(int instruction_id, llvm::Value* value) { 640e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea values_.insert(std::pair<int, llvm::Value*>(instruction_id, value)); 650e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea } 660e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea // Records @value as corresponding to the sea_ir::InstructionNode @instruction. 670e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void AddValue(InstructionNode* instruction, llvm::Value* value) { 680e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea AddValue(instruction->Id(), value); 690e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea } 7090af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea // Generates and returns in @elf the executable code corresponding to the llvm module 7190af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea // 7290af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea std::string GetElf(art::InstructionSet instruction_set); 730e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea 740e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea llvm::LLVMContext* const context_; 750e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea llvm::Module module_; 760e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea llvm::IRBuilder<> builder_; 770e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea llvm::Function* function_; 780e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea 790e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea private: 800e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea std::map<int, llvm::BasicBlock*> blocks_; 810e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea std::map<int, llvm::Value*> values_; 820e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}; 830e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea 840e260a32601fb1178e11837c460807071d489f82Dragos Sbirleaclass CodeGenPassVisitor: public IRVisitor { 850e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea public: 860e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea explicit CodeGenPassVisitor(CodeGenData* cgd): llvm_data_(cgd) { } 870e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea CodeGenPassVisitor(): llvm_data_(new CodeGenData()) { } 880e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea // Initialize any data structure needed before the start of visiting. 890e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea virtual void Initialize(SeaGraph* graph); 900e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea CodeGenData* GetData() { 910e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea return llvm_data_; 920e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea } 930e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Write(std::string file) { 940e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea llvm_data_->module_.dump(); 950e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea llvm::verifyFunction(*llvm_data_->function_); 960e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea } 970e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea 980e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea protected: 990e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea CodeGenData* const llvm_data_; 1000e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}; 1010e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea 1020e260a32601fb1178e11837c460807071d489f82Dragos Sbirleaclass CodeGenPrepassVisitor: public CodeGenPassVisitor { 1030e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea public: 10490af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea explicit CodeGenPrepassVisitor(const std::string& function_name): 10590af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea function_name_(function_name) { } 1060e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(SeaGraph* graph); 1070e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(SignatureNode* region); 1080e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(Region* region); 1090e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(InstructionNode* instruction) { } 1106547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea 1116547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea void Visit(UnnamedConstInstructionNode* instruction) { } 1120e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(ConstInstructionNode* instruction) { } 1130e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(ReturnInstructionNode* instruction) { } 1140e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(IfNeInstructionNode* instruction) { } 1157934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom // void Visit(AddIntLitInstructionNode* instruction) { } 1160e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(MoveResultInstructionNode* instruction) { } 1170e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(InvokeStaticInstructionNode* instruction) { } 1180e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(AddIntInstructionNode* instruction) { } 1190e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(GotoInstructionNode* instruction) { } 1200e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(IfEqzInstructionNode* instruction) { } 1210e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(PhiInstructionNode* region); 12290af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea 12390af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea private: 12490af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea std::string function_name_; 1250e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}; 1260e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea 1270e260a32601fb1178e11837c460807071d489f82Dragos Sbirleaclass CodeGenPostpassVisitor: public CodeGenPassVisitor { 1280e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea public: 1290e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea explicit CodeGenPostpassVisitor(CodeGenData* code_gen_data): CodeGenPassVisitor(code_gen_data) { } 1300e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(SeaGraph* graph); 1310e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(SignatureNode* region); 1320e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(Region* region); 1330e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(InstructionNode* region) { } 1346547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea void Visit(UnnamedConstInstructionNode* instruction) { } 1350e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(ConstInstructionNode* instruction) { } 1360e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(ReturnInstructionNode* instruction) { } 1370e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(IfNeInstructionNode* instruction) { } 1387934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom // void Visit(AddIntLitInstructionNode* instruction) { } 1390e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(MoveResultInstructionNode* instruction) { } 1400e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(InvokeStaticInstructionNode* instruction) { } 1410e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(AddIntInstructionNode* instruction) { } 1420e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(GotoInstructionNode* instruction) { } 1430e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(IfEqzInstructionNode* instruction) { } 1440e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(PhiInstructionNode* region); 1450e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}; 1460e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea 1470e260a32601fb1178e11837c460807071d489f82Dragos Sbirleaclass CodeGenVisitor: public CodeGenPassVisitor { 1480e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea public: 14990af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea explicit CodeGenVisitor(CodeGenData* code_gen_data, 15090af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea const art::DexFile& dex_file): CodeGenPassVisitor(code_gen_data), dex_file_(dex_file) { } 1510e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(SeaGraph* graph); 1520e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(SignatureNode* region); 1530e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(Region* region); 1540e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(InstructionNode* region); 1556547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea void Visit(UnnamedConstInstructionNode* instruction); 1560e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(ConstInstructionNode* instruction); 1570e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(ReturnInstructionNode* instruction); 1580e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(IfNeInstructionNode* instruction); 1590e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(MoveResultInstructionNode* instruction); 1600e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(InvokeStaticInstructionNode* instruction); 1610e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(AddIntInstructionNode* instruction); 1620e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(GotoInstructionNode* instruction); 1630e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(IfEqzInstructionNode* instruction); 1640e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea void Visit(PhiInstructionNode* region) { } 16590af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea 16690af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea private: 16790af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea std::string function_name_; 16890af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea const art::DexFile& dex_file_; 1690e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}; 1707934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom} // namespace sea_ir 171bfaf44fa3366955a2bacb2c38c79b53df2434582Dragos Sbirlea#endif // ART_COMPILER_SEA_IR_CODE_GEN_CODE_GEN_H_ 172