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