1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 18 #include "scoped_thread_state_change.h" 19 #include "sea_ir/debug/dot_gen.h" 20 21 namespace sea_ir { 22 23 void DotGenerationVisitor::Initialize(SeaGraph* graph) { 24 graph_ = graph; 25 Region* root_region; 26 ordered_regions_.clear(); 27 for (std::vector<Region*>::const_iterator cit = graph->GetRegions()->begin(); 28 cit != graph->GetRegions()->end(); cit++ ) { 29 if ((*cit)->GetIDominator() == (*cit)) { 30 root_region = *cit; 31 } 32 } 33 ordered_regions_.push_back(root_region); 34 for (unsigned int id = 0; id < ordered_regions_.size(); id++) { 35 Region* current_region = ordered_regions_.at(id); 36 const std::set<Region*>* dominated_regions = current_region->GetIDominatedSet(); 37 for (std::set<Region*>::const_iterator cit = dominated_regions->begin(); 38 cit != dominated_regions->end(); cit++ ) { 39 ordered_regions_.push_back(*cit); 40 } 41 } 42 } 43 44 void DotGenerationVisitor::ToDotSSAEdges(InstructionNode* instruction) { 45 std::map<int, InstructionNode*>* definition_edges = instruction->GetSSAProducersMap(); 46 // SSA definitions: 47 for (std::map<int, InstructionNode*>::const_iterator 48 def_it = definition_edges->begin(); 49 def_it != definition_edges->end(); def_it++) { 50 if (NULL != def_it->second) { 51 dot_text_ += def_it->second->StringId() + " -> "; 52 dot_text_ += instruction->StringId() + "[color=gray,label=\""; 53 dot_text_ += art::StringPrintf("vR = %d", def_it->first); 54 art::SafeMap<int, const Type*>::const_iterator type_it = types_->find(def_it->second->Id()); 55 if (type_it != types_->end()) { 56 art::ScopedObjectAccess soa(art::Thread::Current()); 57 dot_text_ += "(" + type_it->second->Dump() + ")"; 58 } else { 59 dot_text_ += "()"; 60 } 61 dot_text_ += "\"] ; // SSA edge\n"; 62 } 63 } 64 65 // SSA used-by: 66 if (options_->WillSaveUseEdges()) { 67 std::vector<InstructionNode*>* used_in = instruction->GetSSAConsumers(); 68 for (std::vector<InstructionNode*>::const_iterator cit = used_in->begin(); 69 cit != used_in->end(); cit++) { 70 dot_text_ += (*cit)->StringId() + " -> " + instruction->StringId() + "[color=gray,label=\""; 71 dot_text_ += "\"] ; // SSA used-by edge\n"; 72 } 73 } 74 } 75 76 void DotGenerationVisitor::ToDotSSAEdges(PhiInstructionNode* instruction) { 77 std::vector<InstructionNode*> definition_edges = instruction->GetSSAProducers(); 78 // SSA definitions: 79 for (std::vector<InstructionNode*>::const_iterator 80 def_it = definition_edges.begin(); 81 def_it != definition_edges.end(); def_it++) { 82 if (NULL != *def_it) { 83 dot_text_ += (*def_it)->StringId() + " -> "; 84 dot_text_ += instruction->StringId() + "[color=gray,label=\""; 85 dot_text_ += art::StringPrintf("vR = %d", instruction->GetRegisterNumber()); 86 art::SafeMap<int, const Type*>::const_iterator type_it = types_->find((*def_it)->Id()); 87 if (type_it != types_->end()) { 88 art::ScopedObjectAccess soa(art::Thread::Current()); 89 dot_text_ += "(" + type_it->second->Dump() + ")"; 90 } else { 91 dot_text_ += "()"; 92 } 93 dot_text_ += "\"] ; // SSA edge\n"; 94 } 95 } 96 97 // SSA used-by: 98 if (options_->WillSaveUseEdges()) { 99 std::vector<InstructionNode*>* used_in = instruction->GetSSAConsumers(); 100 for (std::vector<InstructionNode*>::const_iterator cit = used_in->begin(); 101 cit != used_in->end(); cit++) { 102 dot_text_ += (*cit)->StringId() + " -> " + instruction->StringId() + "[color=gray,label=\""; 103 dot_text_ += "\"] ; // SSA used-by edge\n"; 104 } 105 } 106 } 107 108 void DotGenerationVisitor::Visit(SignatureNode* parameter) { 109 dot_text_ += parameter->StringId() +" [label=\"[" + parameter->StringId() + "] signature:"; 110 dot_text_ += art::StringPrintf("r%d", parameter->GetResultRegister()); 111 dot_text_ += "\"] // signature node\n"; 112 ToDotSSAEdges(parameter); 113 } 114 115 // Appends to @result a dot language formatted string representing the node and 116 // (by convention) outgoing edges, so that the composition of theToDot() of all nodes 117 // builds a complete dot graph (without prolog and epilog though). 118 void DotGenerationVisitor::Visit(Region* region) { 119 dot_text_ += "\n// Region: \nsubgraph " + region->StringId(); 120 dot_text_ += " { label=\"region " + region->StringId() + "(rpo="; 121 dot_text_ += art::StringPrintf("%d", region->GetRPO()); 122 if (NULL != region->GetIDominator()) { 123 dot_text_ += " dom=" + region->GetIDominator()->StringId(); 124 } 125 dot_text_ += ")\";\n"; 126 127 std::vector<PhiInstructionNode*>* phi_instructions = region->GetPhiNodes(); 128 for (std::vector<PhiInstructionNode*>::const_iterator cit = phi_instructions->begin(); 129 cit != phi_instructions->end(); cit++) { 130 dot_text_ += (*cit)->StringId() +";\n"; 131 } 132 std::vector<InstructionNode*>* instructions = region->GetInstructions(); 133 for (std::vector<InstructionNode*>::const_iterator cit = instructions->begin(); 134 cit != instructions->end(); cit++) { 135 dot_text_ += (*cit)->StringId() +";\n"; 136 } 137 138 dot_text_ += "} // End Region.\n"; 139 std::vector<Region*>* successors = region->GetSuccessors(); 140 for (std::vector<Region*>::const_iterator cit = successors->begin(); cit != successors->end(); 141 cit++) { 142 DCHECK(NULL != *cit) << "Null successor found for SeaNode" << 143 region->GetLastChild()->StringId() << "."; 144 dot_text_ += region->GetLastChild()->StringId() + " -> " + 145 (*cit)->GetLastChild()->StringId() + 146 "[lhead=" + (*cit)->StringId() + ", " + "ltail=" + region->StringId() + "];\n\n"; 147 } 148 } 149 void DotGenerationVisitor::Visit(InstructionNode* instruction) { 150 dot_text_ += "// Instruction ("+instruction->StringId()+"): \n" + instruction->StringId() + 151 " [label=\"[" + instruction->StringId() + "] " + 152 instruction->GetInstruction()->DumpString(graph_->GetDexFile()) + "\""; 153 dot_text_ += "];\n"; 154 ToDotSSAEdges(instruction); 155 } 156 157 void DotGenerationVisitor::Visit(UnnamedConstInstructionNode* instruction) { 158 dot_text_ += "// Instruction ("+instruction->StringId()+"): \n" + instruction->StringId() + 159 " [label=\"[" + instruction->StringId() + "] const/x v-3, #" + 160 art::StringPrintf("%d", instruction->GetConstValue()) + "\""; 161 dot_text_ += "];\n"; 162 ToDotSSAEdges(instruction); 163 } 164 165 void DotGenerationVisitor::Visit(PhiInstructionNode* phi) { 166 dot_text_ += "// PhiInstruction: \n" + phi->StringId() + 167 " [label=\"[" + phi->StringId() + "] PHI("; 168 dot_text_ += art::StringPrintf("%d", phi->GetRegisterNumber()); 169 dot_text_ += ")\""; 170 dot_text_ += "];\n"; 171 ToDotSSAEdges(phi); 172 } 173 } // namespace sea_ir 174