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