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
170e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea#include <llvm/Support/raw_ostream.h>
1890af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea
1990af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea#include "base/logging.h"
2090af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea#include "utils.h"
2190af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea
22bfaf44fa3366955a2bacb2c38c79b53df2434582Dragos Sbirlea#include "sea_ir/ir/sea.h"
23bfaf44fa3366955a2bacb2c38c79b53df2434582Dragos Sbirlea#include "sea_ir/code_gen/code_gen.h"
2490af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea#include "sea_ir/types/type_inference.h"
2590af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea#include "sea_ir/types/types.h"
260e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea
270e260a32601fb1178e11837c460807071d489f82Dragos Sbirleanamespace sea_ir {
280e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea
290e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenPrepassVisitor::Visit(PhiInstructionNode* phi) {
300e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  Region* r = phi->GetRegion();
310e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  const std::vector<Region*>* predecessors = r->GetPredecessors();
320e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  DCHECK(NULL != predecessors);
330e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  DCHECK_GT(predecessors->size(), 0u);
340e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::PHINode *llvm_phi  = llvm_data_->builder_.CreatePHI(
350e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea      llvm::Type::getInt32Ty(*llvm_data_->context_), predecessors->size(), phi->StringId());
360e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm_data_->AddValue(phi, llvm_phi);
370e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
380e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea
390e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenPassVisitor::Initialize(SeaGraph* graph) {
400e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  Region* root_region;
410e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  ordered_regions_.clear();
420e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  for (std::vector<Region*>::const_iterator cit = graph->GetRegions()->begin();
430e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea        cit != graph->GetRegions()->end(); cit++ ) {
440e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    if ((*cit)->GetIDominator() == (*cit)) {
450e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea      root_region = *cit;
460e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    }
470e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  }
480e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  ordered_regions_.push_back(root_region);
490e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  for (unsigned int id = 0; id < ordered_regions_.size(); id++) {
500e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    Region* current_region = ordered_regions_.at(id);
510e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    const std::set<Region*>* dominated_regions = current_region->GetIDominatedSet();
520e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    for (std::set<Region*>::const_iterator cit = dominated_regions->begin();
530e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea            cit != dominated_regions->end(); cit++ ) {
540e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea      ordered_regions_.push_back(*cit);
550e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    }
560e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  }
570e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
580e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea
5990af14d2743614e3e1453984b14258a6f145501dDragos Sbirleavoid CodeGenPostpassVisitor::Visit(SeaGraph* graph) { }
6090af14d2743614e3e1453984b14258a6f145501dDragos Sbirleavoid CodeGenVisitor::Visit(SeaGraph* graph) { }
610e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenPrepassVisitor::Visit(SeaGraph* graph) {
620e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::vector<SignatureNode*>* parameters = graph->GetParameterNodes();
6390af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea  // TODO: It may be better to extract correct types from dex
6490af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea  //       instead than from type inference.
650e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  DCHECK(parameters != NULL);
6690af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea  std::vector<llvm::Type*> parameter_types;
6790af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea  for (std::vector<SignatureNode*>::const_iterator param_iterator = parameters->begin();
6890af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea      param_iterator!= parameters->end(); param_iterator++) {
6990af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea    const Type* param_type = graph->ti_->type_data_.FindTypeOf((*param_iterator)->Id());
7090af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea    DCHECK(param_type->Equals(graph->ti_->type_cache_->Integer()))
7190af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea      << "Code generation for types other than integer not implemented.";
7290af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea    parameter_types.push_back(llvm::Type::getInt32Ty(*llvm_data_->context_));
7390af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea  }
740e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea
7590af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea  // TODO: Get correct function return type.
7690af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea  const Type* return_type = graph->ti_->type_data_.FindTypeOf(-1);
7790af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea  DCHECK(return_type->Equals(graph->ti_->type_cache_->Integer()))
7890af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea    << "Code generation for types other than integer not implemented.";
790e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::FunctionType *function_type = llvm::FunctionType::get(
800e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea      llvm::Type::getInt32Ty(*llvm_data_->context_),
810e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea      parameter_types, false);
8290af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea
830e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm_data_->function_ = llvm::Function::Create(function_type,
8490af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea      llvm::Function::ExternalLinkage, function_name_, &llvm_data_->module_);
850e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  unsigned param_id = 0;
860e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  for (llvm::Function::arg_iterator arg_it = llvm_data_->function_->arg_begin();
870e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea      param_id != llvm_data_->function_->arg_size(); ++arg_it, ++param_id) {
8890af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea    // TODO: The "+1" is because of the Method parameter on position 0.
890e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    DCHECK(parameters->size() > param_id) << "Insufficient parameters for function signature";
900e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    // Build parameter register name for LLVM IR clarity.
91db06306be76bcea3aabab2cecfb16ae2af542801Dragos Sbirlea    std::string arg_name = art::StringPrintf("r%d", parameters->at(param_id)->GetResultRegister());
920e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    arg_it->setName(arg_name);
930e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    SignatureNode* parameter = parameters->at(param_id);
940e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    llvm_data_->AddValue(parameter, arg_it);
950e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  }
960e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea
970e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::vector<Region*>* regions = &ordered_regions_;
980e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  DCHECK_GT(regions->size(), 0u);
990e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  // Then create all other basic blocks.
1000e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  for (std::vector<Region*>::const_iterator cit = regions->begin(); cit != regions->end(); cit++) {
1010e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    llvm::BasicBlock* new_basic_block = llvm::BasicBlock::Create(*llvm_data_->context_,
1020e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea        (*cit)->StringId(), llvm_data_->function_);
1030e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    llvm_data_->AddBlock((*cit), new_basic_block);
1040e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  }
1050e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
1060e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea
1070e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenPrepassVisitor::Visit(Region* region) {
1080e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm_data_->builder_.SetInsertPoint(llvm_data_->GetBlock(region));
1090e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
1100e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenPostpassVisitor::Visit(Region* region) {
1110e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm_data_->builder_.SetInsertPoint(llvm_data_->GetBlock(region));
1120e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
1130e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenVisitor::Visit(Region* region) {
1140e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm_data_->builder_.SetInsertPoint(llvm_data_->GetBlock(region));
1150e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
1160e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea
1170e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea
1180e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenVisitor::Visit(InstructionNode* instruction) {
1190e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::string instr = instruction->GetInstruction()->DumpString(NULL);
1207934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom  DCHECK(0);  // This whole function is useful only during development.
1210e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
1226547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea
1236547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirleavoid CodeGenVisitor::Visit(UnnamedConstInstructionNode* instruction) {
1246547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea  std::string instr = instruction->GetInstruction()->DumpString(NULL);
1256547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea  std::cout << "1.Instruction: " << instr << std::endl;
1266547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea  llvm_data_->AddValue(instruction,
1276547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea      llvm::ConstantInt::get(*llvm_data_->context_, llvm::APInt(32, instruction->GetConstValue())));
1286547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea}
1296547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea
1300e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenVisitor::Visit(ConstInstructionNode* instruction) {
1310e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::string instr = instruction->GetInstruction()->DumpString(NULL);
1320e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::cout << "1.Instruction: " << instr << std::endl;
1330e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm_data_->AddValue(instruction,
1340e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea      llvm::ConstantInt::get(*llvm_data_->context_, llvm::APInt(32, instruction->GetConstValue())));
1350e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
1360e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenVisitor::Visit(ReturnInstructionNode* instruction) {
1370e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::string instr = instruction->GetInstruction()->DumpString(NULL);
1380e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::cout << "2.Instruction: " << instr << std::endl;
139b40eddfc96b9ac235dea562e55ce2ad7b1cfb7c9Dragos Sbirlea  DCHECK_GT(instruction->GetSSAProducers().size(), 0u);
140b40eddfc96b9ac235dea562e55ce2ad7b1cfb7c9Dragos Sbirlea  llvm::Value* return_value = llvm_data_->GetValue(instruction->GetSSAProducers().at(0));
1410e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm_data_->builder_.CreateRet(return_value);
1420e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
1430e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenVisitor::Visit(IfNeInstructionNode* instruction) {
1440e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::string instr = instruction->GetInstruction()->DumpString(NULL);
1450e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::cout << "3.Instruction: " << instr << std::endl;
146b40eddfc96b9ac235dea562e55ce2ad7b1cfb7c9Dragos Sbirlea  std::vector<InstructionNode*> ssa_uses = instruction->GetSSAProducers();
1470e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  DCHECK_GT(ssa_uses.size(), 1u);
1480e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  InstructionNode* use_l = ssa_uses.at(0);
1490e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::Value* left = llvm_data_->GetValue(use_l);
1500e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea
1510e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  InstructionNode* use_r = ssa_uses.at(1);
1520e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::Value* right = llvm_data_->GetValue(use_r);
1530e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::Value* ifne = llvm_data_->builder_.CreateICmpNE(left, right, instruction->StringId());
1540e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  DCHECK(instruction->GetRegion() != NULL);
1550e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::vector<Region*>* successors = instruction->GetRegion()->GetSuccessors();
1560e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  DCHECK_GT(successors->size(), 0u);
1570e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::BasicBlock* then_block = llvm_data_->GetBlock(successors->at(0));
1580e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::BasicBlock* else_block = llvm_data_->GetBlock(successors->at(1));
1590e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea
1600e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm_data_->builder_.CreateCondBr(ifne, then_block, else_block);
1610e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
1620e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea
1630e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea/*
1640e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenVisitor::Visit(AddIntLitInstructionNode* instruction) {
1650e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::string instr = instruction->GetInstruction()->DumpString(NULL);
1660e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::cout << "4.Instruction: " << instr << std::endl;
1670e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::vector<InstructionNode*> ssa_uses = instruction->GetSSAUses();
1680e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  InstructionNode* use_l = ssa_uses.at(0);
1690e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::Value* left = llvm_data->GetValue(use_l);
1700e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::Value* right = llvm::ConstantInt::get(*llvm_data->context_,
1710e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea      llvm::APInt(32, instruction->GetConstValue()));
1720e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::Value* result = llvm_data->builder_.CreateAdd(left, right);
1730e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm_data->AddValue(instruction, result);
1740e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
1750e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea*/
1760e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenVisitor::Visit(MoveResultInstructionNode* instruction) {
1770e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::string instr = instruction->GetInstruction()->DumpString(NULL);
1780e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::cout << "5.Instruction: " << instr << std::endl;
1790e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  // TODO: Currently, this "mov" instruction is simulated by "res = return_register + 0".
1800e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  // This is inefficient, but should be optimized out by the coalescing phase of the reg alloc.
1810e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  // The TODO is to either ensure that this happens, or to
1820e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  // remove the move-result instructions completely from the IR
1830e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  // by merging them with the invoke-* instructions,
1840e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  // since their purpose of minimizing the number of opcodes in dex is
1850e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  // not relevant for the IR. (Will need to have different
1860e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  // instruction subclasses for functions and procedures.)
187b40eddfc96b9ac235dea562e55ce2ad7b1cfb7c9Dragos Sbirlea  std::vector<InstructionNode*> ssa_uses = instruction->GetSSAProducers();
1880e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  InstructionNode* use_l = ssa_uses.at(0);
1890e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::Value* left = llvm_data_->GetValue(use_l);
1900e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::Value* right = llvm::ConstantInt::get(*llvm_data_->context_, llvm::APInt(32, 0));
1910e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::Value* result = llvm_data_->builder_.CreateAdd(left, right);
1920e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm_data_->AddValue(instruction, result);
1930e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
1940e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenVisitor::Visit(InvokeStaticInstructionNode* invoke) {
1950e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::string instr = invoke->GetInstruction()->DumpString(NULL);
1960e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::cout << "6.Instruction: " << instr << std::endl;
19790af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea  // TODO: Build callee LLVM function name.
19890af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea  std::string symbol = "dex_";
19990af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea  symbol += art::MangleForJni(PrettyMethod(invoke->GetCalledMethodIndex(), dex_file_));
20090af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea  std::string function_name = "dex_int_00020Main_fibonacci_00028int_00029";
2010e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::Function *callee = llvm_data_->module_.getFunction(function_name);
2020e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  // TODO: Add proper checking of the matching between formal and actual signature.
2030e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  DCHECK(NULL != callee);
2040e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::vector<llvm::Value*> parameter_values;
205b40eddfc96b9ac235dea562e55ce2ad7b1cfb7c9Dragos Sbirlea  std::vector<InstructionNode*> parameter_sources = invoke->GetSSAProducers();
20690af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea  // TODO: Replace first parameter with Method argument instead of 0.
20790af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea  parameter_values.push_back(llvm::ConstantInt::get(*llvm_data_->context_, llvm::APInt(32, 0)));
2080e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  for (std::vector<InstructionNode*>::const_iterator cit = parameter_sources.begin();
2090e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea      cit != parameter_sources.end(); ++cit) {
2100e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    llvm::Value* parameter_value = llvm_data_->GetValue((*cit));
2110e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    DCHECK(NULL != parameter_value);
2120e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    parameter_values.push_back(parameter_value);
2130e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  }
2140e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::Value* return_value = llvm_data_->builder_.CreateCall(callee,
2150e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea      parameter_values, invoke->StringId());
2160e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm_data_->AddValue(invoke, return_value);
2170e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
2180e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenVisitor::Visit(AddIntInstructionNode* instruction) {
2190e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::string instr = instruction->GetInstruction()->DumpString(NULL);
2200e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::cout << "7.Instruction: " << instr << std::endl;
221b40eddfc96b9ac235dea562e55ce2ad7b1cfb7c9Dragos Sbirlea  std::vector<InstructionNode*> ssa_uses = instruction->GetSSAProducers();
2220e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  DCHECK_GT(ssa_uses.size(), 1u);
2230e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  InstructionNode* use_l = ssa_uses.at(0);
2240e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  InstructionNode* use_r = ssa_uses.at(1);
2250e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::Value* left = llvm_data_->GetValue(use_l);
2260e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::Value* right = llvm_data_->GetValue(use_r);
2270e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::Value* result = llvm_data_->builder_.CreateAdd(left, right);
2280e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm_data_->AddValue(instruction, result);
2290e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
2300e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenVisitor::Visit(GotoInstructionNode* instruction) {
2310e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::string instr = instruction->GetInstruction()->DumpString(NULL);
2320e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::cout << "8.Instruction: " << instr << std::endl;
2330e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::vector<sea_ir::Region*>* targets = instruction->GetRegion()->GetSuccessors();
2340e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  DCHECK_EQ(targets->size(), 1u);
2350e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::BasicBlock* target_block = llvm_data_->GetBlock(targets->at(0));
2360e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm_data_->builder_.CreateBr(target_block);
2370e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
2380e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenVisitor::Visit(IfEqzInstructionNode* instruction) {
2390e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::string instr = instruction->GetInstruction()->DumpString(NULL);
2400e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::cout << "9. Instruction: " << instr << "; Id: " <<instruction << std::endl;
241b40eddfc96b9ac235dea562e55ce2ad7b1cfb7c9Dragos Sbirlea  std::vector<InstructionNode*> ssa_uses = instruction->GetSSAProducers();
2420e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  DCHECK_GT(ssa_uses.size(), 0u);
2430e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  InstructionNode* use_l = ssa_uses.at(0);
2440e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::Value* left = llvm_data_->GetValue(use_l);
2450e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::Value* ifeqz = llvm_data_->builder_.CreateICmpEQ(left,
2460e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea      llvm::ConstantInt::get(*llvm_data_->context_, llvm::APInt::getNullValue(32)),
2470e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea      instruction->StringId());
2480e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  DCHECK(instruction->GetRegion() != NULL);
2490e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  std::vector<Region*>* successors = instruction->GetRegion()->GetSuccessors();
2500e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  DCHECK_GT(successors->size(), 0u);
2510e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::BasicBlock* then_block = llvm_data_->GetBlock(successors->at(0));
2520e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::BasicBlock* else_block = llvm_data_->GetBlock(successors->at(1));
2530e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm_data_->builder_.CreateCondBr(ifeqz, then_block, else_block);
2540e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
2550e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea
2560e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenPostpassVisitor::Visit(PhiInstructionNode* phi) {
25790af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea  std::cout << "10. Instruction: Phi(" << phi->GetRegisterNumber() << ")" << std::endl;
2580e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  Region* r = phi->GetRegion();
2590e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  const std::vector<Region*>* predecessors = r->GetPredecessors();
2600e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  DCHECK(NULL != predecessors);
2610e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  DCHECK_GT(predecessors->size(), 0u);
2620e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  // Prepass (CodeGenPrepassVisitor) should create the phi function value.
2630e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  llvm::PHINode* llvm_phi = (llvm::PHINode*) llvm_data_->GetValue(phi);
2640e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  int predecessor_pos = 0;
2650e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  for (std::vector<Region*>::const_iterator cit = predecessors->begin();
2660e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea      cit != predecessors->end(); ++cit) {
2670e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    std::vector<InstructionNode*>* defining_instructions = phi->GetSSAUses(predecessor_pos++);
2680e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    DCHECK_EQ(defining_instructions->size(), 1u);
2690e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    InstructionNode* defining_instruction = defining_instructions->at(0);
2700e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    DCHECK(NULL != defining_instruction);
2710e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    Region* incoming_region = *cit;
2720e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    llvm::BasicBlock* incoming_basic_block = llvm_data_->GetBlock(incoming_region);
2730e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    llvm::Value* incoming_value = llvm_data_->GetValue(defining_instruction);
2740e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea    llvm_phi->addIncoming(incoming_value, incoming_basic_block);
2750e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea  }
2760e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
2770e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea
2780e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenVisitor::Visit(SignatureNode* signature) {
279c16c5b4f7e984678ecdbc4b5319d5dbadfddb09dDragos Sbirlea  DCHECK_EQ(signature->GetDefinitions().size(), 1u) <<
280c16c5b4f7e984678ecdbc4b5319d5dbadfddb09dDragos Sbirlea      "Signature nodes must correspond to a single parameter register.";
2810e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
2820e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenPrepassVisitor::Visit(SignatureNode* signature) {
283c16c5b4f7e984678ecdbc4b5319d5dbadfddb09dDragos Sbirlea  DCHECK_EQ(signature->GetDefinitions().size(), 1u) <<
284c16c5b4f7e984678ecdbc4b5319d5dbadfddb09dDragos Sbirlea      "Signature nodes must correspond to a single parameter register.";
2850e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
2860e260a32601fb1178e11837c460807071d489f82Dragos Sbirleavoid CodeGenPostpassVisitor::Visit(SignatureNode* signature) {
287c16c5b4f7e984678ecdbc4b5319d5dbadfddb09dDragos Sbirlea  DCHECK_EQ(signature->GetDefinitions().size(), 1u) <<
288c16c5b4f7e984678ecdbc4b5319d5dbadfddb09dDragos Sbirlea      "Signature nodes must correspond to a single parameter register.";
2890e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea}
2900e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea
2917934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom}  // namespace sea_ir
292