Get SEA fibonacci running in interpreter mode.

Android.mk: Added new file to build.
compile_driver.cc: Moved SE_IR usage test in the block
         protected by bool compile, which is enabled by
         adding a sepatate test in IsCnadidateForCompilation.
class_linker.cc: Added check in NeedsInterpreter to enable SEA_IR.
art_method-inl.h: DIsabled check in SEA_IR mode.
method_verifier.cc: Added check for SEA_IR mode.
method_verifier.h: Chenged IsCandidateForCompilation signature to
         allow testing the function name (for SEA_IR selective
         compilation).
dot_gen.h: Updated ART file API usage to altest version.
sea_ir/frontend.cc: Passing function symbol name to CompileMethod.
instruction_Nodes.h: Added  accessor for method index for
         InvokeStatic IR node.
sea.cc: Added additional IR SignatureNode for function calls (extra
         Method parameter). Fixed UnnamedConstant constant value.
sea.h: Passing function_name to GenerateLLVM.
type_inference_visitor.cc: Aded type for first (placeholder) method
         parameter.

Change-Id: I295858ea0761a3dffb36f35748d8b93d4919d6a9
diff --git a/compiler/Android.mk b/compiler/Android.mk
index 5caf688..c18462a 100644
--- a/compiler/Android.mk
+++ b/compiler/Android.mk
@@ -97,6 +97,7 @@
 	sea_ir/ir/instruction_tools.cc \
 	sea_ir/ir/sea.cc \
 	sea_ir/code_gen/code_gen.cc \
+	sea_ir/code_gen/code_gen_data.cc \
 	sea_ir/types/type_inference.cc \
 	sea_ir/types/type_inference_visitor.cc \
 	sea_ir/debug/dot_gen.cc
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 4659f7b..9d583fd 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -314,7 +314,7 @@
                                               uint32_t method_idx,
                                               jobject class_loader,
                                               const art::DexFile& dex_file);
-
+#ifdef ART_SEA_IR_MODE
 extern "C" art::CompiledMethod* SeaIrCompileMethod(art::CompilerDriver& compiler,
                                                    const art::DexFile::CodeItem* code_item,
                                                    uint32_t access_flags,
@@ -323,7 +323,7 @@
                                                    uint32_t method_idx,
                                                    jobject class_loader,
                                                    const art::DexFile& dex_file);
-
+#endif
 extern "C" art::CompiledMethod* ArtLLVMJniCompileMethod(art::CompilerDriver& driver,
                                                         uint32_t access_flags, uint32_t method_idx,
                                                         const art::DexFile& dex_file);
@@ -2230,16 +2230,15 @@
     CHECK(compiled_method != NULL);
   } else if ((access_flags & kAccAbstract) != 0) {
   } else {
-    bool compile = verifier::MethodVerifier::IsCandidateForCompilation(code_item, access_flags);
-#ifdef ART_SEA_IR_MODE
-    bool use_sea = Runtime::Current()->IsSeaIRMode();
-    use_sea = use_sea && (std::string::npos != PrettyMethod(method_idx, dex_file).find("fibonacci"));
-    if (use_sea) compile = true;
-#endif
+    MethodReference method_ref(&dex_file, method_idx);
+    bool compile = verifier::MethodVerifier::IsCandidateForCompilation(method_ref, access_flags);
 
     if (compile) {
       CompilerFn compiler = compiler_;
 #ifdef ART_SEA_IR_MODE
+      bool use_sea = Runtime::Current()->IsSeaIRMode();
+      use_sea = use_sea &&
+          (std::string::npos != PrettyMethod(method_idx, dex_file).find("fibonacci"));
       if (use_sea) {
         compiler = sea_ir_compiler_;
         LOG(INFO) << "Using SEA IR to compile..." << std::endl;
diff --git a/compiler/sea_ir/code_gen/code_gen.cc b/compiler/sea_ir/code_gen/code_gen.cc
index cb150e5..8d79c41 100644
--- a/compiler/sea_ir/code_gen/code_gen.cc
+++ b/compiler/sea_ir/code_gen/code_gen.cc
@@ -15,8 +15,14 @@
  */
 
 #include <llvm/Support/raw_ostream.h>
+
+#include "base/logging.h"
+#include "utils.h"
+
 #include "sea_ir/ir/sea.h"
 #include "sea_ir/code_gen/code_gen.h"
+#include "sea_ir/types/type_inference.h"
+#include "sea_ir/types/types.h"
 
 namespace sea_ir {
 
@@ -50,34 +56,36 @@
   }
 }
 
-void CodeGenPostpassVisitor::Visit(SeaGraph* graph) {
-  std::vector<SignatureNode*>* parameters = graph->GetParameterNodes();
-  std::cout << "=== SeaGraph ===" << parameters->size() << std::endl;
-}
-void CodeGenVisitor::Visit(SeaGraph* graph) {
-  std::vector<SignatureNode*>* parameters = graph->GetParameterNodes();
-  std::cout << "=== SeaGraph ===" << parameters->size() << std::endl;
-}
+void CodeGenPostpassVisitor::Visit(SeaGraph* graph) { }
+void CodeGenVisitor::Visit(SeaGraph* graph) { }
 void CodeGenPrepassVisitor::Visit(SeaGraph* graph) {
   std::vector<SignatureNode*>* parameters = graph->GetParameterNodes();
-  std::cout << "=== SeaGraph ===" << parameters->size() << std::endl;
-  // TODO: Extract correct types from dex for params and return value.
+  // TODO: It may be better to extract correct types from dex
+  //       instead than from type inference.
   DCHECK(parameters != NULL);
-  std::vector<llvm::Type*> parameter_types(parameters->size(),
-      llvm::Type::getInt32Ty(*llvm_data_->context_));
-  // Build llvm function name.
-  std::string function_name = art::StringPrintf(
-      "class=%d_method=%d", graph->class_def_idx_, graph->method_idx_);
+  std::vector<llvm::Type*> parameter_types;
+  for (std::vector<SignatureNode*>::const_iterator param_iterator = parameters->begin();
+      param_iterator!= parameters->end(); param_iterator++) {
+    const Type* param_type = graph->ti_->type_data_.FindTypeOf((*param_iterator)->Id());
+    DCHECK(param_type->Equals(graph->ti_->type_cache_->Integer()))
+      << "Code generation for types other than integer not implemented.";
+    parameter_types.push_back(llvm::Type::getInt32Ty(*llvm_data_->context_));
+  }
 
-  // Build llvm function type and parameters.
+  // TODO: Get correct function return type.
+  const Type* return_type = graph->ti_->type_data_.FindTypeOf(-1);
+  DCHECK(return_type->Equals(graph->ti_->type_cache_->Integer()))
+    << "Code generation for types other than integer not implemented.";
   llvm::FunctionType *function_type = llvm::FunctionType::get(
       llvm::Type::getInt32Ty(*llvm_data_->context_),
       parameter_types, false);
+
   llvm_data_->function_ = llvm::Function::Create(function_type,
-      llvm::Function::ExternalLinkage, function_name, &llvm_data_->module_);
+      llvm::Function::ExternalLinkage, function_name_, &llvm_data_->module_);
   unsigned param_id = 0;
   for (llvm::Function::arg_iterator arg_it = llvm_data_->function_->arg_begin();
       param_id != llvm_data_->function_->arg_size(); ++arg_it, ++param_id) {
+    // TODO: The "+1" is because of the Method parameter on position 0.
     DCHECK(parameters->size() > param_id) << "Insufficient parameters for function signature";
     // Build parameter register name for LLVM IR clarity.
     std::string arg_name = art::StringPrintf("r%d", parameters->at(param_id)->GetResultRegister());
@@ -97,15 +105,12 @@
 }
 
 void CodeGenPrepassVisitor::Visit(Region* region) {
-  std::cout << " == Region " << region->StringId() << " ==" << std::endl;
   llvm_data_->builder_.SetInsertPoint(llvm_data_->GetBlock(region));
 }
 void CodeGenPostpassVisitor::Visit(Region* region) {
-  std::cout << " == Region " << region->StringId() << " ==" << std::endl;
   llvm_data_->builder_.SetInsertPoint(llvm_data_->GetBlock(region));
 }
 void CodeGenVisitor::Visit(Region* region) {
-  std::cout << " == Region " << region->StringId() << " ==" << std::endl;
   llvm_data_->builder_.SetInsertPoint(llvm_data_->GetBlock(region));
 }
 
@@ -189,13 +194,17 @@
 void CodeGenVisitor::Visit(InvokeStaticInstructionNode* invoke) {
   std::string instr = invoke->GetInstruction()->DumpString(NULL);
   std::cout << "6.Instruction: " << instr << std::endl;
-  // TODO: Build callee llvm function name.
-  std::string function_name = art::StringPrintf("class=%d_method=%d", 0, 1);
+  // TODO: Build callee LLVM function name.
+  std::string symbol = "dex_";
+  symbol += art::MangleForJni(PrettyMethod(invoke->GetCalledMethodIndex(), dex_file_));
+  std::string function_name = "dex_int_00020Main_fibonacci_00028int_00029";
   llvm::Function *callee = llvm_data_->module_.getFunction(function_name);
   // TODO: Add proper checking of the matching between formal and actual signature.
   DCHECK(NULL != callee);
   std::vector<llvm::Value*> parameter_values;
   std::vector<InstructionNode*> parameter_sources = invoke->GetSSAProducers();
+  // TODO: Replace first parameter with Method argument instead of 0.
+  parameter_values.push_back(llvm::ConstantInt::get(*llvm_data_->context_, llvm::APInt(32, 0)));
   for (std::vector<InstructionNode*>::const_iterator cit = parameter_sources.begin();
       cit != parameter_sources.end(); ++cit) {
     llvm::Value* parameter_value = llvm_data_->GetValue((*cit));
@@ -245,7 +254,7 @@
 }
 
 void CodeGenPostpassVisitor::Visit(PhiInstructionNode* phi) {
-  std::cout << "Phi node for: " << phi->GetRegisterNumber() << std::endl;
+  std::cout << "10. Instruction: Phi(" << phi->GetRegisterNumber() << ")" << std::endl;
   Region* r = phi->GetRegion();
   const std::vector<Region*>* predecessors = r->GetPredecessors();
   DCHECK(NULL != predecessors);
@@ -267,17 +276,14 @@
 }
 
 void CodeGenVisitor::Visit(SignatureNode* signature) {
-  std::cout << "Signature: ;" << "Id:" << signature->StringId() << std::endl;
   DCHECK_EQ(signature->GetDefinitions().size(), 1u) <<
       "Signature nodes must correspond to a single parameter register.";
 }
 void CodeGenPrepassVisitor::Visit(SignatureNode* signature) {
-  std::cout << "Signature: ;" << "Id:" << signature->StringId() << std::endl;
   DCHECK_EQ(signature->GetDefinitions().size(), 1u) <<
       "Signature nodes must correspond to a single parameter register.";
 }
 void CodeGenPostpassVisitor::Visit(SignatureNode* signature) {
-  std::cout << "Signature: ;" << "Id:" << signature->StringId() << std::endl;
   DCHECK_EQ(signature->GetDefinitions().size(), 1u) <<
       "Signature nodes must correspond to a single parameter register.";
 }
diff --git a/compiler/sea_ir/code_gen/code_gen.h b/compiler/sea_ir/code_gen/code_gen.h
index b1bc4dc..544e9f0 100644
--- a/compiler/sea_ir/code_gen/code_gen.h
+++ b/compiler/sea_ir/code_gen/code_gen.h
@@ -17,6 +17,7 @@
 #ifndef ART_COMPILER_SEA_IR_CODE_GEN_CODE_GEN_H_
 #define ART_COMPILER_SEA_IR_CODE_GEN_CODE_GEN_H_
 
+#include "instruction_set.h"
 #include "llvm/Analysis/Verifier.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/LLVMContext.h"
@@ -66,6 +67,9 @@
   void AddValue(InstructionNode* instruction, llvm::Value* value) {
       AddValue(instruction->Id(), value);
   }
+  // Generates and returns in @elf the executable code corresponding to the llvm module
+  //
+  std::string GetElf(art::InstructionSet instruction_set);
 
   llvm::LLVMContext* const context_;
   llvm::Module module_;
@@ -97,6 +101,8 @@
 
 class CodeGenPrepassVisitor: public CodeGenPassVisitor {
  public:
+  explicit CodeGenPrepassVisitor(const std::string& function_name):
+    function_name_(function_name) { }
   void Visit(SeaGraph* graph);
   void Visit(SignatureNode* region);
   void Visit(Region* region);
@@ -113,6 +119,9 @@
   void Visit(GotoInstructionNode* instruction) { }
   void Visit(IfEqzInstructionNode* instruction) { }
   void Visit(PhiInstructionNode* region);
+
+ private:
+  std::string function_name_;
 };
 
 class CodeGenPostpassVisitor: public CodeGenPassVisitor {
@@ -137,7 +146,8 @@
 
 class CodeGenVisitor: public CodeGenPassVisitor {
  public:
-  explicit CodeGenVisitor(CodeGenData* code_gen_data): CodeGenPassVisitor(code_gen_data) { }
+  explicit CodeGenVisitor(CodeGenData* code_gen_data,
+      const art::DexFile& dex_file): CodeGenPassVisitor(code_gen_data), dex_file_(dex_file) { }
   void Visit(SeaGraph* graph);
   void Visit(SignatureNode* region);
   void Visit(Region* region);
@@ -152,6 +162,10 @@
   void Visit(GotoInstructionNode* instruction);
   void Visit(IfEqzInstructionNode* instruction);
   void Visit(PhiInstructionNode* region) { }
+
+ private:
+  std::string function_name_;
+  const art::DexFile& dex_file_;
 };
 }  // namespace sea_ir
 #endif  // ART_COMPILER_SEA_IR_CODE_GEN_CODE_GEN_H_
diff --git a/compiler/sea_ir/code_gen/code_gen_data.cc b/compiler/sea_ir/code_gen/code_gen_data.cc
new file mode 100644
index 0000000..3baaa99
--- /dev/null
+++ b/compiler/sea_ir/code_gen/code_gen_data.cc
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <llvm/PassManager.h>
+#include <llvm/Support/TargetRegistry.h>
+#include <llvm/Support/FormattedStream.h>
+#include <llvm/Target/TargetMachine.h>
+#include <llvm/Transforms/IPO.h>
+#include <llvm/Transforms/IPO/PassManagerBuilder.h>
+
+#include "base/logging.h"
+#include "driver/compiler_driver.h"
+#include "sea_ir/ir/sea.h"
+#include "sea_ir/code_gen/code_gen.h"
+
+
+namespace sea_ir {
+std::string CodeGenData::GetElf(art::InstructionSet instruction_set) {
+  std::string elf;
+  ::llvm::raw_string_ostream out_stream(elf);
+  // Lookup the LLVM target
+  std::string target_triple;
+  std::string target_cpu;
+  std::string target_attr;
+  art::CompilerDriver::InstructionSetToLLVMTarget(instruction_set,
+      target_triple, target_cpu, target_attr);
+
+  std::string errmsg;
+  const ::llvm::Target* target =
+    ::llvm::TargetRegistry::lookupTarget(target_triple, errmsg);
+
+  CHECK(target != NULL) << errmsg;
+
+  // Target options
+  ::llvm::TargetOptions target_options;
+  target_options.FloatABIType = ::llvm::FloatABI::Soft;
+  target_options.NoFramePointerElim = true;
+  target_options.NoFramePointerElimNonLeaf = true;
+  target_options.UseSoftFloat = false;
+  target_options.EnableFastISel = false;
+
+  // Create the ::llvm::TargetMachine
+  ::llvm::OwningPtr< ::llvm::TargetMachine> target_machine(
+    target->createTargetMachine(target_triple, target_cpu, target_attr, target_options,
+                                ::llvm::Reloc::Static, ::llvm::CodeModel::Small,
+                                ::llvm::CodeGenOpt::Aggressive));
+
+  CHECK(target_machine.get() != NULL) << "Failed to create target machine";
+
+  // Add target data
+  const ::llvm::DataLayout* data_layout = target_machine->getDataLayout();
+
+  // PassManager for code generation passes
+  ::llvm::PassManager pm;
+  pm.add(new ::llvm::DataLayout(*data_layout));
+
+  // FunctionPassManager for optimization pass
+  ::llvm::FunctionPassManager fpm(&module_);
+  fpm.add(new ::llvm::DataLayout(*data_layout));
+
+  // Add optimization pass
+  ::llvm::PassManagerBuilder pm_builder;
+  // TODO: Use inliner after we can do IPO.
+  pm_builder.Inliner = NULL;
+  // pm_builder.Inliner = ::llvm::createFunctionInliningPass();
+  // pm_builder.Inliner = ::llvm::createAlwaysInlinerPass();
+  // pm_builder.Inliner = ::llvm::createPartialInliningPass();
+  pm_builder.OptLevel = 3;
+  pm_builder.DisableSimplifyLibCalls = 1;
+  pm_builder.DisableUnitAtATime = 1;
+  pm_builder.populateFunctionPassManager(fpm);
+  pm_builder.populateModulePassManager(pm);
+  pm.add(::llvm::createStripDeadPrototypesPass());
+  // Add passes to emit ELF image
+  {
+    ::llvm::formatted_raw_ostream formatted_os(out_stream, false);
+    // Ask the target to add backend passes as necessary.
+    if (target_machine->addPassesToEmitFile(pm,
+                                            formatted_os,
+                                            ::llvm::TargetMachine::CGFT_ObjectFile,
+                                            true)) {
+      LOG(FATAL) << "Unable to generate ELF for this target";
+    }
+
+    // Run the code generation passes
+    pm.run(module_);
+  }
+  return elf;
+}
+}
diff --git a/compiler/sea_ir/debug/dot_gen.h b/compiler/sea_ir/debug/dot_gen.h
index 05d97fa..f2ab8c4 100644
--- a/compiler/sea_ir/debug/dot_gen.h
+++ b/compiler/sea_ir/debug/dot_gen.h
@@ -101,10 +101,10 @@
   // Saves to @filename the .dot representation of @graph with the options @options.
   void DumpSea(SeaGraph* graph, std::string filename,
       art::SafeMap<int, const Type*>* types) const {
-    LOG(INFO) << "Starting to write SEA string to file.";
+    LOG(INFO) << "Starting to write SEA string to file " << filename << std::endl;
     DotGenerationVisitor dgv = DotGenerationVisitor(&options_, types);
     graph->Accept(&dgv);
-    art::File* file = art::OS::OpenFileReadWrite(filename.c_str());
+    art::File* file = art::OS::CreateEmptyFile(filename.c_str());
     art::FileOutputStream fos(file);
     std::string graph_as_string = dgv.GetResult();
     graph_as_string += "}";
diff --git a/compiler/sea_ir/frontend.cc b/compiler/sea_ir/frontend.cc
index 421c3a4..6efc103 100644
--- a/compiler/sea_ir/frontend.cc
+++ b/compiler/sea_ir/frontend.cc
@@ -35,7 +35,6 @@
 #include "sea_ir/types/types.h"
 #include "sea_ir/code_gen/code_gen.h"
 
-
 namespace art {
 
 static CompiledMethod* CompileMethodWithSeaIr(CompilerDriver& compiler,
@@ -48,34 +47,22 @@
                                      , llvm::LlvmCompilationUnit* llvm_compilation_unit
 #endif
 ) {
-  // NOTE: Instead of keeping the convention from the Dalvik frontend.cc
-  //       and silencing the cpplint.py warning, I just corrected the formatting.
-  VLOG(compiler) << "Compiling " << PrettyMethod(method_idx, dex_file) << "...";
+  LOG(INFO) << "Compiling " << PrettyMethod(method_idx, dex_file) << ".";
   sea_ir::SeaGraph* ir_graph = sea_ir::SeaGraph::GetGraph(dex_file);
-  sea_ir::CodeGenData* llvm_data =
-      ir_graph->CompileMethod(code_item, class_def_idx, method_idx, method_access_flags, dex_file);
+  std::string symbol = "dex_" + MangleForJni(PrettyMethod(method_idx, dex_file));
+  sea_ir::CodeGenData* llvm_data = ir_graph->CompileMethod(symbol,
+          code_item, class_def_idx, method_idx, method_access_flags, dex_file);
   sea_ir::DotConversion dc;
   SafeMap<int, const sea_ir::Type*>*  types = ir_graph->ti_->GetTypeMap();
   dc.DumpSea(ir_graph, "/tmp/temp.dot", types);
-  CHECK(0 && "No SEA compiled function exists yet.");
-
   MethodReference mref(&dex_file, method_idx);
-
-  // TODO: Passing the LLVM code as string is ugly and inefficient,
-  //       but it is the way portable did it. I kept it for compatibility,
-  //       but actually it should not happen.
-  std::string llvm_code;
-  ::llvm::raw_string_ostream str_os(llvm_code);
-  ::llvm::WriteBitcodeToFile(&llvm_data->module_, str_os);
-
-  std::string symbol = "dex_";
-  symbol += MangleForJni(PrettyMethod(method_idx, dex_file));
-
+  std::string llvm_code = llvm_data->GetElf(compiler.GetInstructionSet());
   CompiledMethod* compiled_method =  new CompiledMethod(
                               compiler.GetInstructionSet(),
                               llvm_code,
                               *verifier::MethodVerifier::GetDexGcMap(mref),
                               symbol);
+  LOG(INFO) << "Compiled SEA IR method " << PrettyMethod(method_idx, dex_file) << ".";
   return compiled_method;
 }
 
diff --git a/compiler/sea_ir/ir/instruction_nodes.h b/compiler/sea_ir/ir/instruction_nodes.h
index 906a10f..63e89e7 100644
--- a/compiler/sea_ir/ir/instruction_nodes.h
+++ b/compiler/sea_ir/ir/instruction_nodes.h
@@ -56,6 +56,8 @@
   // essentially creating SSA form.
   void RenameToSSA(int reg_no, InstructionNode* definition) {
     definition_edges_.insert(std::pair<int, InstructionNode*>(reg_no, definition));
+    DCHECK(NULL != definition) << "SSA definition for register " << reg_no
+        << " used in instruction " << Id() << " not found.";
     definition->AddSSAUse(this);
   }
   // Returns the ordered set of Instructions that define the input operands of this instruction.
@@ -179,14 +181,22 @@
 
 class InvokeStaticInstructionNode: public InstructionNode {
  public:
-  explicit InvokeStaticInstructionNode(const art::Instruction* inst): InstructionNode(inst) { }
+  explicit InvokeStaticInstructionNode(const art::Instruction* inst): InstructionNode(inst),
+    method_index_(inst->VRegB_35c()) { }
   int GetResultRegister() const {
     return RETURN_REGISTER;
   }
+
+  int GetCalledMethodIndex() const {
+    return method_index_;
+  }
   void Accept(IRVisitor* v) {
     v->Visit(this);
     v->Traverse(this);
   }
+
+ private:
+  const uint32_t method_index_;
 };
 
 class AddIntInstructionNode: public InstructionNode {
diff --git a/compiler/sea_ir/ir/sea.cc b/compiler/sea_ir/ir/sea.cc
index 902839d..5ccaba6 100644
--- a/compiler/sea_ir/ir/sea.cc
+++ b/compiler/sea_ir/ir/sea.cc
@@ -174,6 +174,21 @@
   DCHECK(!changed) << "Reaching definitions computation did not reach a fixed point.";
 }
 
+void SeaGraph::InsertSignatureNodes(const art::DexFile::CodeItem* code_item, Region* r) {
+  // Insert a fake SignatureNode for the first parameter.
+  // TODO: Provide a register enum value for the fake parameter.
+  SignatureNode* parameter_def_node = new sea_ir::SignatureNode(0, 0);
+  AddParameterNode(parameter_def_node);
+  r->AddChild(parameter_def_node);
+  // Insert SignatureNodes for each Dalvik register parameter.
+  for (unsigned int crt_offset = 0; crt_offset < code_item->ins_size_; crt_offset++) {
+    int register_no = code_item->registers_size_ - crt_offset - 1;
+    int position = crt_offset + 1;
+    SignatureNode* parameter_def_node = new sea_ir::SignatureNode(register_no, position);
+    AddParameterNode(parameter_def_node);
+    r->AddChild(parameter_def_node);
+  }
+}
 
 void SeaGraph::BuildMethodSeaGraph(const art::DexFile::CodeItem* code_item,
     const art::DexFile& dex_file, uint32_t class_def_idx,
@@ -209,15 +224,8 @@
 
 
   Region* r = GetNewRegion();
-  // Insert one SignatureNode per function argument,
-  // to serve as placeholder definitions in dataflow analysis.
-  for (unsigned int crt_offset = 0; crt_offset < code_item->ins_size_; crt_offset++) {
-    int position = crt_offset;  // TODO: Is this the correct offset in the signature?
-    SignatureNode* parameter_def_node =
-        new sea_ir::SignatureNode(code_item->registers_size_ - 1 - crt_offset, position);
-    AddParameterNode(parameter_def_node);
-    r->AddChild(parameter_def_node);
-  }
+
+  InsertSignatureNodes(code_item, r);
   // Pass: Assign instructions to region nodes and
   //         assign branches their control flow successors.
   i = 0;
@@ -386,23 +394,21 @@
   scoped_table->CloseScope();
 }
 
-CodeGenData* SeaGraph::GenerateLLVM() {
+CodeGenData* SeaGraph::GenerateLLVM(const std::string& function_name,
+    const art::DexFile& dex_file) {
   // Pass: Generate LLVM IR.
-  CodeGenPrepassVisitor code_gen_prepass_visitor;
+  CodeGenPrepassVisitor code_gen_prepass_visitor(function_name);
   std::cout << "Generating code..." << std::endl;
-  std::cout << "=== PRE VISITING ===" << std::endl;
   Accept(&code_gen_prepass_visitor);
-  CodeGenVisitor code_gen_visitor(code_gen_prepass_visitor.GetData());
-  std::cout << "=== VISITING ===" << std::endl;
+  CodeGenVisitor code_gen_visitor(code_gen_prepass_visitor.GetData(),  dex_file);
   Accept(&code_gen_visitor);
-  std::cout << "=== POST VISITING ===" << std::endl;
   CodeGenPostpassVisitor code_gen_postpass_visitor(code_gen_visitor.GetData());
   Accept(&code_gen_postpass_visitor);
-  code_gen_postpass_visitor.Write(std::string("my_file.llvm"));
   return code_gen_postpass_visitor.GetData();
 }
 
 CodeGenData* SeaGraph::CompileMethod(
+    const std::string& function_name,
     const art::DexFile::CodeItem* code_item, uint32_t class_def_idx,
     uint32_t method_idx, uint32_t method_access_flags, const art::DexFile& dex_file) {
   // Two passes: Builds the intermediate structure (non-SSA) of the sea-ir for the function.
@@ -422,7 +428,7 @@
   // Pass: type inference
   ti_->ComputeTypes(this);
   // Pass: Generate LLVM IR.
-  CodeGenData* cgd = GenerateLLVM();
+  CodeGenData* cgd = GenerateLLVM(function_name, dex_file);
   return cgd;
 }
 
@@ -607,7 +613,7 @@
       sea_instructions.push_back(new IfNeInstructionNode(in));
       break;
     case art::Instruction::ADD_INT_LIT8:
-      sea_instructions.push_back(new UnnamedConstInstructionNode(in, in->VRegB_22b()));
+      sea_instructions.push_back(new UnnamedConstInstructionNode(in, in->VRegC_22b()));
       sea_instructions.push_back(new AddIntLitInstructionNode(in));
       break;
     case art::Instruction::MOVE_RESULT:
diff --git a/compiler/sea_ir/ir/sea.h b/compiler/sea_ir/ir/sea.h
index df420ed..92c2043 100644
--- a/compiler/sea_ir/ir/sea.h
+++ b/compiler/sea_ir/ir/sea.h
@@ -50,12 +50,12 @@
 class SignatureNode: public InstructionNode {
  public:
   // Creates a new signature node representing the initial definition of the
-  // register @parameter_register which is the @position-th argument to the method.
-  explicit SignatureNode(unsigned int parameter_register, unsigned int position):
-    InstructionNode(NULL), parameter_register_(parameter_register), position_(position) { }
+  // register @register_no which is the @signature_position-th argument to the method.
+  explicit SignatureNode(unsigned int register_no, unsigned int signature_position):
+    InstructionNode(NULL), register_no_(register_no), position_(signature_position) { }
 
   int GetResultRegister() const {
-    return parameter_register_;
+    return register_no_;
   }
 
   unsigned int GetPositionInSignature() const {
@@ -72,7 +72,7 @@
   }
 
  private:
-  const unsigned int parameter_register_;
+  const unsigned int register_no_;
   const unsigned int position_;     // The position of this parameter node is
                                     // in the function parameter list.
 };
@@ -261,7 +261,8 @@
  public:
   static SeaGraph* GetGraph(const art::DexFile&);
 
-  CodeGenData* CompileMethod(const art::DexFile::CodeItem* code_item, uint32_t class_def_idx,
+  CodeGenData* CompileMethod(const std::string& function_name,
+      const art::DexFile::CodeItem* code_item, uint32_t class_def_idx,
       uint32_t method_idx, uint32_t method_access_flags, const art::DexFile& dex_file);
   // Returns all regions corresponding to this SeaGraph.
   std::vector<Region*>* GetRegions() {
@@ -338,7 +339,9 @@
   void RenameAsSSA(Region* node, utils::ScopedHashtable<int, InstructionNode*>* scoped_table);
   // Generate LLVM IR for the method.
   // Precondition: ConvertToSSA().
-  CodeGenData* GenerateLLVM();
+  CodeGenData* GenerateLLVM(const std::string& function_name, const art::DexFile& dex_file);
+  // Inserts one SignatureNode for each argument of the function in
+  void InsertSignatureNodes(const art::DexFile::CodeItem* code_item, Region* r);
 
   static SeaGraph graph_;
   std::vector<Region*> regions_;
diff --git a/compiler/sea_ir/types/type_inference.cc b/compiler/sea_ir/types/type_inference.cc
index 31d7f0f..1731987 100644
--- a/compiler/sea_ir/types/type_inference.cc
+++ b/compiler/sea_ir/types/type_inference.cc
@@ -68,6 +68,9 @@
 std::vector<const Type*> FunctionTypeInfo::GetDeclaredArgumentTypes() {
   art::ScopedObjectAccess soa(art::Thread::Current());
   std::vector<const Type*> argument_types;
+  // TODO: The additional (fake) Method parameter is added on the first position,
+  //       but is represented as integer because we don't support  pointers yet.
+  argument_types.push_back(&(type_cache_->Integer()));
   // Include the "this" pointer.
   size_t cur_arg = 0;
   if (!IsStatic()) {
@@ -82,7 +85,7 @@
     }
     cur_arg++;
   }
-
+  // Include the types of the parameters in the Java method signature.
   const art::DexFile::ProtoId& proto_id =
       dex_file_->GetMethodPrototype(dex_file_->GetMethodId(dex_method_idx_));
   art::DexFileParameterIterator iterator(*dex_file_, proto_id);
@@ -149,6 +152,13 @@
     std::copy(instructions->begin(), instructions->end(), std::back_inserter(worklist));
   }
   TypeInferenceVisitor tiv(graph, &type_data_, type_cache_);
+  // Record return type of the function.
+  graph->Accept(&tiv);
+  const Type* new_type = tiv.GetType();
+  type_data_.SetTypeOf(-1, new_type);   // TODO: Record this info in a way that
+                                        //      does not need magic constants.
+                                        //      Make SeaGraph a SeaNode?
+
   // Sparse (SSA) fixed-point algorithm that processes each instruction in the work-list,
   // adding consumers of instructions whose result changed type back into the work-list.
   // Note: According to [1] list iterators should not be invalidated on insertion,
@@ -159,14 +169,11 @@
   // TODO: Remove elements as I go.
   for (std::list<InstructionNode*>::const_iterator instruction_it = worklist.begin();
         instruction_it != worklist.end(); instruction_it++) {
-    std::cout << "[TI] Instruction: " << (*instruction_it)->Id() << std::endl;
     (*instruction_it)->Accept(&tiv);
     const Type* old_type = type_data_.FindTypeOf((*instruction_it)->Id());
     const Type* new_type = tiv.GetType();
     bool type_changed = (old_type != new_type);
     if (type_changed) {
-      std::cout << " New type:" << new_type->IsIntegralTypes() << std::endl;
-      std::cout << " Descrip:" << new_type->Dump()<< " on " << (*instruction_it)->Id() << std::endl;
       type_data_.SetTypeOf((*instruction_it)->Id(), new_type);
       // Add SSA consumers of the current instruction to the work-list.
       std::vector<InstructionNode*>* consumers = (*instruction_it)->GetSSAConsumers();
diff --git a/compiler/sea_ir/types/type_inference.h b/compiler/sea_ir/types/type_inference.h
index d951d82..7a178b2 100644
--- a/compiler/sea_ir/types/type_inference.h
+++ b/compiler/sea_ir/types/type_inference.h
@@ -31,8 +31,7 @@
 // precise verification (which is the job of the verifier).
 class TypeInference {
  public:
-  TypeInference() {
-    type_cache_ = new art::verifier::RegTypeCache(false);
+  TypeInference() : type_cache_(new art::verifier::RegTypeCache(false)) {
   }
 
   // Computes the types for the method with SEA IR representation provided by @graph.
@@ -43,10 +42,8 @@
   }
   // Returns true if @descriptor corresponds to a primitive type.
   static bool IsPrimitiveDescriptor(char descriptor);
-
- protected:
-  art::verifier::RegTypeCache* type_cache_;
-  TypeData type_data_;
+  TypeData type_data_;    // TODO: Make private, add accessor and not publish a SafeMap above.
+  art::verifier::RegTypeCache* const type_cache_;    // TODO: Make private.
 };
 
 // Stores information about the exact type of  a function.
diff --git a/compiler/sea_ir/types/type_inference_visitor.cc b/compiler/sea_ir/types/type_inference_visitor.cc
index 3da2fc1..139c89b 100644
--- a/compiler/sea_ir/types/type_inference_visitor.cc
+++ b/compiler/sea_ir/types/type_inference_visitor.cc
@@ -21,6 +21,12 @@
 
 namespace sea_ir {
 
+void TypeInferenceVisitor::Visit(SeaGraph* graph) {
+  FunctionTypeInfo fti(graph_, type_cache_);
+  const Type* return_type = fti.GetReturnValueType();
+  crt_type_.push_back(return_type);
+}
+
 void TypeInferenceVisitor::Visit(SignatureNode* parameter) {
   FunctionTypeInfo fti(graph_, type_cache_);
   std::vector<const Type*> arguments = fti.GetDeclaredArgumentTypes();
diff --git a/compiler/sea_ir/types/type_inference_visitor.h b/compiler/sea_ir/types/type_inference_visitor.h
index 200b9f0..469448f 100644
--- a/compiler/sea_ir/types/type_inference_visitor.h
+++ b/compiler/sea_ir/types/type_inference_visitor.h
@@ -40,7 +40,7 @@
   }
   // There are no type related actions to be performed on these classes.
   void Initialize(SeaGraph* graph) { }
-  void Visit(SeaGraph* graph) { }
+  void Visit(SeaGraph* graph);
   void Visit(Region* region) { }
 
   void Visit(PhiInstructionNode* instruction);