diff options
author | Dragos Sbirlea <dragoss@google.com> | 2013-08-05 16:24:57 -0700 |
---|---|---|
committer | Dragos Sbirlea <dragoss@google.com> | 2013-08-05 16:47:02 -0700 |
commit | 7b89bc0d1e73ae5a4265f93bb5497019b1a9bf17 (patch) | |
tree | 018a7cb81e6f3e8c16ae80cab7bf3503357bf0a7 /compiler/sea_ir | |
parent | 52a5099ae81573f5eaa66a84135edbf904c1f49e (diff) | |
download | art-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.cc | 42 | ||||
-rw-r--r-- | compiler/sea_ir/debug/dot_gen.h | 1 | ||||
-rw-r--r-- | compiler/sea_ir/instruction_nodes.h | 2 | ||||
-rw-r--r-- | compiler/sea_ir/sea.cc | 1 | ||||
-rw-r--r-- | compiler/sea_ir/sea.h | 14 | ||||
-rw-r--r-- | compiler/sea_ir/types/type_inference_visitor.h | 10 |
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; } |