Home | History | Annotate | Download | only in debug
      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