summaryrefslogtreecommitdiffstats
path: root/compiler/sea_ir
diff options
context:
space:
mode:
authorDragos Sbirlea <dragoss@google.com>2013-08-05 16:24:57 -0700
committerDragos Sbirlea <dragoss@google.com>2013-08-05 16:47:02 -0700
commit7b89bc0d1e73ae5a4265f93bb5497019b1a9bf17 (patch)
tree018a7cb81e6f3e8c16ae80cab7bf3503357bf0a7 /compiler/sea_ir
parent52a5099ae81573f5eaa66a84135edbf904c1f49e (diff)
downloadart-7b89bc0d1e73ae5a4265f93bb5497019b1a9bf17.tar.gz
art-7b89bc0d1e73ae5a4265f93bb5497019b1a9bf17.tar.bz2
art-7b89bc0d1e73ae5a4265f93bb5497019b1a9bf17.zip
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
Diffstat (limited to 'compiler/sea_ir')
-rw-r--r--compiler/sea_ir/debug/dot_gen.cc42
-rw-r--r--compiler/sea_ir/debug/dot_gen.h1
-rw-r--r--compiler/sea_ir/instruction_nodes.h2
-rw-r--r--compiler/sea_ir/sea.cc1
-rw-r--r--compiler/sea_ir/sea.h14
-rw-r--r--compiler/sea_ir/types/type_inference_visitor.h10
6 files changed, 61 insertions, 9 deletions
diff --git a/compiler/sea_ir/debug/dot_gen.cc b/compiler/sea_ir/debug/dot_gen.cc
index 340a20ead..ecb641e66 100644
--- a/compiler/sea_ir/debug/dot_gen.cc
+++ b/compiler/sea_ir/debug/dot_gen.cc
@@ -72,8 +72,40 @@ void DotGenerationVisitor::ToDotSSAEdges(InstructionNode* instruction) {
}
}
+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(Region* region) {
}
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 259cdfca8..df74901c7 100644
--- a/compiler/sea_ir/debug/dot_gen.h
+++ b/compiler/sea_ir/debug/dot_gen.h
@@ -42,6 +42,7 @@ class DotGenerationVisitor: public IRVisitor {
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 fb1f83f07..504fe468f 100644
--- a/compiler/sea_ir/instruction_nodes.h
+++ b/compiler/sea_ir/instruction_nodes.h
@@ -60,7 +60,7 @@ class InstructionNode: public SeaNode {
}
// 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 cb159e110..eca32a415 100644
--- a/compiler/sea_ir/sea.cc
+++ b/compiler/sea_ir/sea.cc
@@ -418,7 +418,6 @@ void SeaGraph::CompileMethod(const art::DexFile::CodeItem* code_item, uint32_t c
// 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 3a8efcde3..93f35f245 100644
--- a/compiler/sea_ir/sea.h
+++ b/compiler/sea_ir/sea.h
@@ -102,6 +102,17 @@ class PhiInstructionNode: public InstructionNode {
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 @@ class PhiInstructionNode: public InstructionNode {
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 9518c975e..bf7f4c0d1 100644
--- a/compiler/sea_ir/types/type_inference_visitor.h
+++ b/compiler/sea_ir/types/type_inference_visitor.h
@@ -43,7 +43,7 @@ class TypeInferenceVisitor: public IRVisitor {
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 @@ class TypeInferenceVisitor: public IRVisitor {
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;
}