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 #ifndef ART_COMPILER_SEA_IR_DEBUG_DOT_GEN_H_
     18 #define ART_COMPILER_SEA_IR_DEBUG_DOT_GEN_H_
     19 
     20 #include "safe_map.h"
     21 #include "base/stringprintf.h"
     22 #include "file_output_stream.h"
     23 #include "os.h"
     24 #include "sea_ir/ir/sea.h"
     25 #include "sea_ir/types/type_inference.h"
     26 
     27 namespace sea_ir {
     28 
     29 class DotConversionOptions {
     30  public:
     31   DotConversionOptions(): save_use_edges_(false) { }
     32   bool WillSaveUseEdges() const {
     33     return save_use_edges_;
     34   }
     35  private:
     36   bool save_use_edges_;
     37 };
     38 
     39 class DotGenerationVisitor: public IRVisitor {
     40  public:
     41   explicit DotGenerationVisitor(const DotConversionOptions* const options,
     42       art::SafeMap<int, const Type*>* types): graph_(), types_(types), options_(options) { }
     43 
     44   virtual void Initialize(SeaGraph* graph);
     45   // Saves the ssa def->use edges corresponding to @instruction.
     46   void ToDotSSAEdges(InstructionNode* instruction);
     47   void ToDotSSAEdges(PhiInstructionNode* instruction);
     48   void Visit(SeaGraph* graph) {
     49     dot_text_ += "digraph seaOfNodes {\ncompound=true\n";
     50   }
     51   void Visit(SignatureNode* parameter);
     52 
     53   // Appends to @result a dot language formatted string representing the node and
     54   //    (by convention) outgoing edges, so that the composition of theToDot() of all nodes
     55   //    builds a complete dot graph (without prolog and epilog though).
     56   void Visit(Region* region);
     57   void Visit(InstructionNode* instruction);
     58   void Visit(PhiInstructionNode* phi);
     59   void Visit(UnnamedConstInstructionNode* instruction);
     60 
     61   void Visit(ConstInstructionNode* instruction) {
     62     Visit(reinterpret_cast<InstructionNode*>(instruction));
     63   }
     64   void Visit(ReturnInstructionNode* instruction) {
     65     Visit(reinterpret_cast<InstructionNode*>(instruction));
     66   }
     67   void Visit(IfNeInstructionNode* instruction) {
     68     Visit(reinterpret_cast<InstructionNode*>(instruction));
     69   }
     70   void Visit(MoveResultInstructionNode* instruction) {
     71     Visit(reinterpret_cast<InstructionNode*>(instruction));
     72   }
     73   void Visit(InvokeStaticInstructionNode* instruction) {
     74     Visit(reinterpret_cast<InstructionNode*>(instruction));
     75   }
     76   void Visit(AddIntInstructionNode* instruction) {
     77     Visit(reinterpret_cast<InstructionNode*>(instruction));
     78   }
     79   void Visit(GotoInstructionNode* instruction) {
     80     Visit(reinterpret_cast<InstructionNode*>(instruction));
     81   }
     82   void Visit(IfEqzInstructionNode* instruction) {
     83     Visit(reinterpret_cast<InstructionNode*>(instruction));
     84   }
     85 
     86   std::string GetResult() const {
     87     return dot_text_;
     88   }
     89 
     90  private:
     91   std::string dot_text_;
     92   SeaGraph* graph_;
     93   art::SafeMap<int, const Type*>* types_;
     94   const DotConversionOptions* const options_;
     95 };
     96 
     97 // Stores options for turning a SEA IR graph to a .dot file.
     98 class DotConversion {
     99  public:
    100   DotConversion(): options_() { }
    101   // Saves to @filename the .dot representation of @graph with the options @options.
    102   void DumpSea(SeaGraph* graph, std::string filename,
    103       art::SafeMap<int, const Type*>* types) const {
    104     LOG(INFO) << "Starting to write SEA string to file " << filename << std::endl;
    105     DotGenerationVisitor dgv = DotGenerationVisitor(&options_, types);
    106     graph->Accept(&dgv);
    107     // TODO: UniquePtr to close file properly. Switch to BufferedOutputStream.
    108     art::File* file = art::OS::CreateEmptyFile(filename.c_str());
    109     art::FileOutputStream fos(file);
    110     std::string graph_as_string = dgv.GetResult();
    111     graph_as_string += "}";
    112     fos.WriteFully(graph_as_string.c_str(), graph_as_string.size());
    113     LOG(INFO) << "Written SEA string to file.";
    114   }
    115 
    116  private:
    117   DotConversionOptions options_;
    118 };
    119 
    120 }  // namespace sea_ir
    121 #endif  // ART_COMPILER_SEA_IR_DEBUG_DOT_GEN_H_
    122