Fixed SEA IR bugs.

Bug 1: The type inference visitor did not clear type between visits,
so all instructions had types attached because of this.

Bug 2: The .dot file genration was missing phi ssa edges because
the GetSSAProducers map hasn't got the same semantics.
(Phi Nodes use a single register which has multiple definitions,
not multiple registers with a single definition each)

Bug 3: Added the SE IR id in the textual representation of nodes
in the .dot representation to ease debugging.

Change-Id: Iccbce6f7a3ffba044677c2d548d26af62223be15
diff --git a/compiler/sea_ir/debug/dot_gen.cc b/compiler/sea_ir/debug/dot_gen.cc
index 340a20e..ecb641e 100644
--- a/compiler/sea_ir/debug/dot_gen.cc
+++ b/compiler/sea_ir/debug/dot_gen.cc
@@ -72,8 +72,40 @@
   }
 }
 
+void DotGenerationVisitor::ToDotSSAEdges(PhiInstructionNode* instruction) {
+  std::vector<InstructionNode*> definition_edges = instruction->GetSSAProducers();
+  // SSA definitions:
+  for (std::vector<InstructionNode*>::const_iterator
+      def_it = definition_edges.begin();
+      def_it != definition_edges.end(); def_it++) {
+    if (NULL != *def_it) {
+      dot_text_ += (*def_it)->StringId() + " -> ";
+      dot_text_ += instruction->StringId() + "[color=gray,label=\"";
+      dot_text_ += art::StringPrintf("vR = %d", instruction->GetRegisterNumber());
+      std::map<int, const Type*>::const_iterator type_it = types_->find((*def_it)->Id());
+      if (type_it != types_->end()) {
+        art::ScopedObjectAccess soa(art::Thread::Current());
+        dot_text_ += "(" + type_it->second->Dump() + ")";
+      } else {
+        dot_text_ += "()";
+      }
+      dot_text_ += "\"] ; // SSA edge\n";
+    }
+  }
+
+  // SSA used-by:
+  if (options_->WillSaveUseEdges()) {
+    std::vector<InstructionNode*>* used_in = instruction->GetSSAConsumers();
+    for (std::vector<InstructionNode*>::const_iterator cit = used_in->begin();
+        cit != used_in->end(); cit++) {
+      dot_text_ += (*cit)->StringId() + " -> " + instruction->StringId() + "[color=gray,label=\"";
+      dot_text_ += "\"] ; // SSA used-by edge\n";
+    }
+  }
+}
+
 void DotGenerationVisitor::Visit(SignatureNode* parameter) {
-  dot_text_ += parameter->StringId() +" [label=\"signature:";
+  dot_text_ += parameter->StringId() +" [label=\"[" + parameter->StringId() + "] signature:";
   dot_text_ += art::StringPrintf("r%d", parameter->GetResultRegister());
   dot_text_ += "\"] // signature node\n";
   ToDotSSAEdges(parameter);
@@ -115,21 +147,23 @@
 }
 void DotGenerationVisitor::Visit(InstructionNode* instruction) {
   dot_text_ += "// Instruction ("+instruction->StringId()+"): \n" + instruction->StringId() +
-      " [label=\"" + instruction->GetInstruction()->DumpString(graph_->GetDexFile()) + "\"";
+      " [label=\"[" + instruction->StringId() + "] " +
+      instruction->GetInstruction()->DumpString(graph_->GetDexFile()) + "\"";
   dot_text_ += "];\n";
   ToDotSSAEdges(instruction);
 }
 
 void DotGenerationVisitor::Visit(UnnamedConstInstructionNode* instruction) {
   dot_text_ += "// Instruction ("+instruction->StringId()+"): \n" + instruction->StringId() +
-        " [label=\"const/x v-3, #"+ art::StringPrintf("%d", instruction->GetConstValue()) + "\"";
+        " [label=\"[" + instruction->StringId() + "] const/x v-3, #" +
+        art::StringPrintf("%d", instruction->GetConstValue()) + "\"";
   dot_text_ += "];\n";
   ToDotSSAEdges(instruction);
 }
 
 void DotGenerationVisitor::Visit(PhiInstructionNode* phi) {
   dot_text_ += "// PhiInstruction: \n" + phi->StringId() +
-      " [label=\"" + "PHI(";
+      " [label=\"[" + phi->StringId() + "] PHI(";
   dot_text_ += art::StringPrintf("%d", phi->GetRegisterNumber());
   dot_text_ += ")\"";
   dot_text_ += "];\n";
diff --git a/compiler/sea_ir/debug/dot_gen.h b/compiler/sea_ir/debug/dot_gen.h
index 259cdfc..df74901 100644
--- a/compiler/sea_ir/debug/dot_gen.h
+++ b/compiler/sea_ir/debug/dot_gen.h
@@ -42,6 +42,7 @@
   virtual void Initialize(SeaGraph* graph);
   // Saves the ssa def->use edges corresponding to @instruction.
   void ToDotSSAEdges(InstructionNode* instruction);
+  void ToDotSSAEdges(PhiInstructionNode* instruction);
   void Visit(SeaGraph* graph) {
     dot_text_ += "digraph seaOfNodes {\ncompound=true\n";
   }
diff --git a/compiler/sea_ir/instruction_nodes.h b/compiler/sea_ir/instruction_nodes.h
index fb1f83f..504fe46 100644
--- a/compiler/sea_ir/instruction_nodes.h
+++ b/compiler/sea_ir/instruction_nodes.h
@@ -60,7 +60,7 @@
   }
   // Returns the ordered set of Instructions that define the input operands of this instruction.
   // Precondition: SeaGraph.ConvertToSSA().
-  std::vector<InstructionNode*> GetSSAProducers() {
+  virtual std::vector<InstructionNode*> GetSSAProducers() {
     std::vector<int> uses = GetUses();
     std::vector<InstructionNode*> ssa_uses;
     for (std::vector<int>::const_iterator cit = uses.begin(); cit != uses.end(); cit++) {
diff --git a/compiler/sea_ir/sea.cc b/compiler/sea_ir/sea.cc
index cb159e1..eca32a4 100644
--- a/compiler/sea_ir/sea.cc
+++ b/compiler/sea_ir/sea.cc
@@ -418,7 +418,6 @@
   // Two Passes: Phi node insertion.
   ConvertToSSA();
   // Pass: type inference
-  std::cout << "TYPES." << std::endl;
   ti_->ComputeTypes(this);
   // Pass: Generate LLVM IR.
   GenerateLLVM();
diff --git a/compiler/sea_ir/sea.h b/compiler/sea_ir/sea.h
index 3a8efcd..93f35f2 100644
--- a/compiler/sea_ir/sea.h
+++ b/compiler/sea_ir/sea.h
@@ -102,6 +102,17 @@
     definition->AddSSAUse(this);
   }
 
+  // Returns the ordered set of Instructions that define the input operands of this instruction.
+  // Precondition: SeaGraph.ConvertToSSA().
+  std::vector<InstructionNode*> GetSSAProducers() {
+    std::vector<InstructionNode*> producers;
+    for (std::vector<std::vector<InstructionNode*>*>::const_iterator
+        cit = definition_edges_.begin(); cit != definition_edges_.end(); cit++) {
+      producers.insert(producers.end(), (*cit)->begin(), (*cit)->end());
+    }
+    return producers;
+  }
+
   // Returns the instruction that defines the phi register from predecessor
   // on position @predecessor_pos. Note that the return value is vector<> just
   // for consistency with the return value of GetSSAUses() on regular instructions,
@@ -117,6 +128,9 @@
 
  private:
   int register_no_;
+  // This vector has one entry for each predecessors, each with a single
+  // element, storing the id of the instruction that defines the register
+  // corresponding to this phi function.
   std::vector<std::vector<InstructionNode*>*> definition_edges_;
 };
 
diff --git a/compiler/sea_ir/types/type_inference_visitor.h b/compiler/sea_ir/types/type_inference_visitor.h
index 9518c97..bf7f4c0 100644
--- a/compiler/sea_ir/types/type_inference_visitor.h
+++ b/compiler/sea_ir/types/type_inference_visitor.h
@@ -43,7 +43,7 @@
   void Visit(Region* region) { }
 
   void Visit(PhiInstructionNode* instruction) { }
-  void Visit(SignatureNode* parameter) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void Visit(SignatureNode* parameter);
   void Visit(InstructionNode* instruction) { }
   void Visit(ConstInstructionNode* instruction) { }
   void Visit(ReturnInstructionNode* instruction) { }
@@ -54,9 +54,13 @@
   void Visit(GotoInstructionNode* instruction) { }
   void Visit(IfEqzInstructionNode* instruction) { }
 
-  const Type* GetType() const {
+  const Type* GetType() {
     // TODO: Currently multiple defined types are not supported.
-    if (crt_type_.size()>0) return crt_type_.at(0);
+    if (crt_type_.size()>0) {
+      const Type* single_type = crt_type_.at(0);
+      crt_type_.clear();
+      return single_type;
+    }
     return NULL;
   }