blob: 9e071e16cdbb132d0d9817d103f52e1f911a13de [file] [log] [blame]
Dragos Sbirlea64479192013-08-01 15:38:43 -07001/*
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#include "sea_ir/debug/dot_gen.h"
18
19namespace sea_ir {
20
21void DotGenerationVisitor::Initialize(SeaGraph* graph) {
22 graph_ = graph;
23 Region* root_region;
24 ordered_regions_.clear();
25 for (std::vector<Region*>::const_iterator cit = graph->GetRegions()->begin();
26 cit != graph->GetRegions()->end(); cit++ ) {
27 if ((*cit)->GetIDominator() == (*cit)) {
28 root_region = *cit;
29 }
30 }
31 ordered_regions_.push_back(root_region);
32 for (unsigned int id = 0; id < ordered_regions_.size(); id++) {
33 Region* current_region = ordered_regions_.at(id);
34 const std::set<Region*>* dominated_regions = current_region->GetIDominatedSet();
35 for (std::set<Region*>::const_iterator cit = dominated_regions->begin();
36 cit != dominated_regions->end(); cit++ ) {
37 ordered_regions_.push_back(*cit);
38 }
39 }
40}
41
42void DotGenerationVisitor::ToDotSSAEdges(InstructionNode* instruction) {
43 std::map<int, InstructionNode*>* definition_edges = instruction->GetSSAProducersMap();
44 // SSA definitions:
45 for (std::map<int, InstructionNode*>::const_iterator
46 def_it = definition_edges->begin();
47 def_it != definition_edges->end(); def_it++) {
48 if (NULL != def_it->second) {
49 dot_text_ += def_it->second->StringId() + " -> ";
50 dot_text_ += instruction->StringId() + "[color=gray,label=\"";
51 dot_text_ += art::StringPrintf("vR = %d", def_it->first);
52 std::map<int, const Type*>::const_iterator type_it = types_->find(def_it->second->Id());
53 if (type_it != types_->end()) {
54 dot_text_ += "(" + type_it->second->Dump() + ")";
55 } else {
56 dot_text_ += "()";
57 }
58 dot_text_ += "\"] ; // SSA edge\n";
59 }
60 }
61
62 // SSA used-by:
63 if (options_->WillSaveUseEdges()) {
64 std::vector<InstructionNode*>* used_in = instruction->GetSSAConsumers();
65 for (std::vector<InstructionNode*>::const_iterator cit = used_in->begin();
66 cit != used_in->end(); cit++) {
67 dot_text_ += (*cit)->StringId() + " -> " + instruction->StringId() + "[color=gray,label=\"";
68 dot_text_ += "\"] ; // SSA used-by edge\n";
69 }
70 }
71}
72
73void DotGenerationVisitor::Visit(SignatureNode* parameter) {
74 dot_text_ += parameter->StringId() +" [label=\"signature:";
75 dot_text_ += art::StringPrintf("r%d", parameter->GetResultRegister());
76 dot_text_ += "\"] // signature node\n";
77 ToDotSSAEdges(parameter);
78}
79
80// Appends to @result a dot language formatted string representing the node and
81// (by convention) outgoing edges, so that the composition of theToDot() of all nodes
82// builds a complete dot graph (without prolog and epilog though).
83void DotGenerationVisitor::Visit(Region* region) {
84 dot_text_ += "\n// Region: \nsubgraph " + region->StringId();
85 dot_text_ += " { label=\"region " + region->StringId() + "(rpo=";
86 dot_text_ += art::StringPrintf("%d", region->GetRPO());
87 if (NULL != region->GetIDominator()) {
88 dot_text_ += " dom=" + region->GetIDominator()->StringId();
89 }
90 dot_text_ += ")\";\n";
91
92 std::vector<PhiInstructionNode*>* phi_instructions = region->GetPhiNodes();
93 for (std::vector<PhiInstructionNode*>::const_iterator cit = phi_instructions->begin();
94 cit != phi_instructions->end(); cit++) {
95 dot_text_ += (*cit)->StringId() +";\n";
96 }
97 std::vector<InstructionNode*>* instructions = region->GetInstructions();
98 for (std::vector<InstructionNode*>::const_iterator cit = instructions->begin();
99 cit != instructions->end(); cit++) {
100 dot_text_ += (*cit)->StringId() +";\n";
101 }
102
103 dot_text_ += "} // End Region.\n";
104 std::vector<Region*>* successors = region->GetSuccessors();
105 for (std::vector<Region*>::const_iterator cit = successors->begin(); cit != successors->end();
106 cit++) {
107 DCHECK(NULL != *cit) << "Null successor found for SeaNode" <<
108 region->GetLastChild()->StringId() << ".";
109 dot_text_ += region->GetLastChild()->StringId() + " -> " +
110 (*cit)->GetLastChild()->StringId() +
111 "[lhead=" + (*cit)->StringId() + ", " + "ltail=" + region->StringId() + "];\n\n";
112 }
113}
114void DotGenerationVisitor::Visit(InstructionNode* instruction) {
115 dot_text_ += "// Instruction ("+instruction->StringId()+"): \n" + instruction->StringId() +
116 " [label=\"" + instruction->GetInstruction()->DumpString(graph_->GetDexFile()) + "\"";
117 dot_text_ += "];\n";
118 ToDotSSAEdges(instruction);
119}
120
121void DotGenerationVisitor::Visit(UnnamedConstInstructionNode* instruction) {
122 dot_text_ += "// Instruction ("+instruction->StringId()+"): \n" + instruction->StringId() +
123 " [label=\"const/x v-3, #"+ art::StringPrintf("%d", instruction->GetConstValue()) + "\"";
124 dot_text_ += "];\n";
125 ToDotSSAEdges(instruction);
126}
127
128void DotGenerationVisitor::Visit(PhiInstructionNode* phi) {
129 dot_text_ += "// PhiInstruction: \n" + phi->StringId() +
130 " [label=\"" + "PHI(";
131 dot_text_ += art::StringPrintf("%d", phi->GetRegisterNumber());
132 dot_text_ += ")\"";
133 dot_text_ += "];\n";
134 ToDotSSAEdges(phi);
135}
136} // namespace sea_ir