dot_gen.cc revision 6547fa9749d0e32cc367d64f8cc6b3d65bf43a5d
16447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea/* 26447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * Copyright (C) 2013 The Android Open Source Project 36447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * 46447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * Licensed under the Apache License, Version 2.0 (the "License"); 56447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * you may not use this file except in compliance with the License. 66447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * You may obtain a copy of the License at 76447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * 86447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * http://www.apache.org/licenses/LICENSE-2.0 96447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * 106447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * Unless required by applicable law or agreed to in writing, software 116447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * distributed under the License is distributed on an "AS IS" BASIS, 126447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * See the License for the specific language governing permissions and 146447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * limitations under the License. 156447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea */ 166447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea 176547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea 18147c00cd39840e6ec3fd940c14ac75a59f205297Dragos Sbirlea#include "scoped_thread_state_change.h" 196447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea#include "sea_ir/debug/dot_gen.h" 206447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea 216447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirleanamespace sea_ir { 226447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea 236447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirleavoid DotGenerationVisitor::Initialize(SeaGraph* graph) { 246447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea graph_ = graph; 256447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea Region* root_region; 266447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea ordered_regions_.clear(); 276447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea for (std::vector<Region*>::const_iterator cit = graph->GetRegions()->begin(); 286447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea cit != graph->GetRegions()->end(); cit++ ) { 296447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea if ((*cit)->GetIDominator() == (*cit)) { 306447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea root_region = *cit; 316447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea } 326447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea } 336447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea ordered_regions_.push_back(root_region); 346447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea for (unsigned int id = 0; id < ordered_regions_.size(); id++) { 356447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea Region* current_region = ordered_regions_.at(id); 366447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea const std::set<Region*>* dominated_regions = current_region->GetIDominatedSet(); 376447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea for (std::set<Region*>::const_iterator cit = dominated_regions->begin(); 386447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea cit != dominated_regions->end(); cit++ ) { 396447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea ordered_regions_.push_back(*cit); 406447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea } 416447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea } 426447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea} 436447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea 446447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirleavoid DotGenerationVisitor::ToDotSSAEdges(InstructionNode* instruction) { 456447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea std::map<int, InstructionNode*>* definition_edges = instruction->GetSSAProducersMap(); 466447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea // SSA definitions: 476447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea for (std::map<int, InstructionNode*>::const_iterator 486447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea def_it = definition_edges->begin(); 496447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea def_it != definition_edges->end(); def_it++) { 506447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea if (NULL != def_it->second) { 516447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += def_it->second->StringId() + " -> "; 526447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += instruction->StringId() + "[color=gray,label=\""; 536447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += art::StringPrintf("vR = %d", def_it->first); 546547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea art::SafeMap<int, const Type*>::const_iterator type_it = types_->find(def_it->second->Id()); 556447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea if (type_it != types_->end()) { 56147c00cd39840e6ec3fd940c14ac75a59f205297Dragos Sbirlea art::ScopedObjectAccess soa(art::Thread::Current()); 576447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += "(" + type_it->second->Dump() + ")"; 586447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea } else { 596447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += "()"; 606447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea } 616447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += "\"] ; // SSA edge\n"; 626447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea } 636447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea } 646447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea 656447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea // SSA used-by: 666447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea if (options_->WillSaveUseEdges()) { 676447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea std::vector<InstructionNode*>* used_in = instruction->GetSSAConsumers(); 686447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea for (std::vector<InstructionNode*>::const_iterator cit = used_in->begin(); 696447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea cit != used_in->end(); cit++) { 706447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += (*cit)->StringId() + " -> " + instruction->StringId() + "[color=gray,label=\""; 716447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += "\"] ; // SSA used-by edge\n"; 726447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea } 736447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea } 746447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea} 756447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea 767b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirleavoid DotGenerationVisitor::ToDotSSAEdges(PhiInstructionNode* instruction) { 777b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea std::vector<InstructionNode*> definition_edges = instruction->GetSSAProducers(); 787b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea // SSA definitions: 797b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea for (std::vector<InstructionNode*>::const_iterator 807b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea def_it = definition_edges.begin(); 817b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea def_it != definition_edges.end(); def_it++) { 827b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea if (NULL != *def_it) { 837b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea dot_text_ += (*def_it)->StringId() + " -> "; 847b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea dot_text_ += instruction->StringId() + "[color=gray,label=\""; 857b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea dot_text_ += art::StringPrintf("vR = %d", instruction->GetRegisterNumber()); 866547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea art::SafeMap<int, const Type*>::const_iterator type_it = types_->find((*def_it)->Id()); 877b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea if (type_it != types_->end()) { 887b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea art::ScopedObjectAccess soa(art::Thread::Current()); 897b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea dot_text_ += "(" + type_it->second->Dump() + ")"; 907b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea } else { 917b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea dot_text_ += "()"; 927b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea } 937b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea dot_text_ += "\"] ; // SSA edge\n"; 947b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea } 957b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea } 967b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea 977b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea // SSA used-by: 987b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea if (options_->WillSaveUseEdges()) { 997b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea std::vector<InstructionNode*>* used_in = instruction->GetSSAConsumers(); 1007b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea for (std::vector<InstructionNode*>::const_iterator cit = used_in->begin(); 1017b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea cit != used_in->end(); cit++) { 1027b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea dot_text_ += (*cit)->StringId() + " -> " + instruction->StringId() + "[color=gray,label=\""; 1037b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea dot_text_ += "\"] ; // SSA used-by edge\n"; 1047b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea } 1057b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea } 1067b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea} 1077b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea 1086447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirleavoid DotGenerationVisitor::Visit(SignatureNode* parameter) { 1097b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea dot_text_ += parameter->StringId() +" [label=\"[" + parameter->StringId() + "] signature:"; 1106447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += art::StringPrintf("r%d", parameter->GetResultRegister()); 1116447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += "\"] // signature node\n"; 1126447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea ToDotSSAEdges(parameter); 1136447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea} 1146447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea 1156447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea// Appends to @result a dot language formatted string representing the node and 1166447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea// (by convention) outgoing edges, so that the composition of theToDot() of all nodes 1176447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea// builds a complete dot graph (without prolog and epilog though). 1186447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirleavoid DotGenerationVisitor::Visit(Region* region) { 1196447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += "\n// Region: \nsubgraph " + region->StringId(); 1206447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += " { label=\"region " + region->StringId() + "(rpo="; 1216447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += art::StringPrintf("%d", region->GetRPO()); 1226447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea if (NULL != region->GetIDominator()) { 1236447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += " dom=" + region->GetIDominator()->StringId(); 1246447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea } 1256447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += ")\";\n"; 1266447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea 1276447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea std::vector<PhiInstructionNode*>* phi_instructions = region->GetPhiNodes(); 1286447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea for (std::vector<PhiInstructionNode*>::const_iterator cit = phi_instructions->begin(); 1296447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea cit != phi_instructions->end(); cit++) { 1306447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += (*cit)->StringId() +";\n"; 1316447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea } 1326447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea std::vector<InstructionNode*>* instructions = region->GetInstructions(); 1336447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea for (std::vector<InstructionNode*>::const_iterator cit = instructions->begin(); 1346447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea cit != instructions->end(); cit++) { 1356447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += (*cit)->StringId() +";\n"; 1366447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea } 1376447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea 1386447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += "} // End Region.\n"; 1396447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea std::vector<Region*>* successors = region->GetSuccessors(); 1406447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea for (std::vector<Region*>::const_iterator cit = successors->begin(); cit != successors->end(); 1416447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea cit++) { 1426447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea DCHECK(NULL != *cit) << "Null successor found for SeaNode" << 1436447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea region->GetLastChild()->StringId() << "."; 1446447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += region->GetLastChild()->StringId() + " -> " + 1456447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea (*cit)->GetLastChild()->StringId() + 1466447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea "[lhead=" + (*cit)->StringId() + ", " + "ltail=" + region->StringId() + "];\n\n"; 1476447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea } 1486447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea} 1496447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirleavoid DotGenerationVisitor::Visit(InstructionNode* instruction) { 1506447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += "// Instruction ("+instruction->StringId()+"): \n" + instruction->StringId() + 1517b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea " [label=\"[" + instruction->StringId() + "] " + 1527b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea instruction->GetInstruction()->DumpString(graph_->GetDexFile()) + "\""; 1536447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += "];\n"; 1546447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea ToDotSSAEdges(instruction); 1556447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea} 1566447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea 1576447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirleavoid DotGenerationVisitor::Visit(UnnamedConstInstructionNode* instruction) { 1586447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += "// Instruction ("+instruction->StringId()+"): \n" + instruction->StringId() + 1597b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea " [label=\"[" + instruction->StringId() + "] const/x v-3, #" + 1607b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea art::StringPrintf("%d", instruction->GetConstValue()) + "\""; 1616447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += "];\n"; 1626447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea ToDotSSAEdges(instruction); 1636447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea} 1646447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea 1656447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirleavoid DotGenerationVisitor::Visit(PhiInstructionNode* phi) { 1666447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += "// PhiInstruction: \n" + phi->StringId() + 1677b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea " [label=\"[" + phi->StringId() + "] PHI("; 1686447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += art::StringPrintf("%d", phi->GetRegisterNumber()); 1696447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += ")\""; 1706447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea dot_text_ += "];\n"; 1716447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea ToDotSSAEdges(phi); 1726447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea} 1736447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea} // namespace sea_ir 174