1 /* 2 * Copyright (C) 2014 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_OPTIMIZING_GRAPH_VISUALIZER_H_ 18 #define ART_COMPILER_OPTIMIZING_GRAPH_VISUALIZER_H_ 19 20 #include <ostream> 21 22 #include "arch/instruction_set.h" 23 #include "base/arena_containers.h" 24 #include "base/value_object.h" 25 26 namespace art { 27 28 class CodeGenerator; 29 class DexCompilationUnit; 30 class HGraph; 31 class HInstruction; 32 class SlowPathCode; 33 34 /** 35 * This class outputs the HGraph in the C1visualizer format. 36 * Note: Currently only works if the compiler is single threaded. 37 */ 38 struct GeneratedCodeInterval { 39 size_t start; 40 size_t end; 41 }; 42 43 struct SlowPathCodeInfo { 44 const SlowPathCode* slow_path; 45 GeneratedCodeInterval code_interval; 46 }; 47 48 // This information is filled by the code generator. It will be used by the 49 // graph visualizer to associate disassembly of the generated code with the 50 // instructions and slow paths. We assume that the generated code follows the 51 // following structure: 52 // - frame entry 53 // - instructions 54 // - slow paths 55 class DisassemblyInformation { 56 public: DisassemblyInformation(ArenaAllocator * allocator)57 explicit DisassemblyInformation(ArenaAllocator* allocator) 58 : frame_entry_interval_({0, 0}), 59 instruction_intervals_(std::less<const HInstruction*>(), allocator->Adapter()), 60 slow_path_intervals_(allocator->Adapter()) {} 61 SetFrameEntryInterval(size_t start,size_t end)62 void SetFrameEntryInterval(size_t start, size_t end) { 63 frame_entry_interval_ = {start, end}; 64 } 65 AddInstructionInterval(HInstruction * instr,size_t start,size_t end)66 void AddInstructionInterval(HInstruction* instr, size_t start, size_t end) { 67 instruction_intervals_.Put(instr, {start, end}); 68 } 69 AddSlowPathInterval(SlowPathCode * slow_path,size_t start,size_t end)70 void AddSlowPathInterval(SlowPathCode* slow_path, size_t start, size_t end) { 71 slow_path_intervals_.push_back({slow_path, {start, end}}); 72 } 73 GetFrameEntryInterval()74 GeneratedCodeInterval GetFrameEntryInterval() const { 75 return frame_entry_interval_; 76 } 77 GetFrameEntryInterval()78 GeneratedCodeInterval* GetFrameEntryInterval() { 79 return &frame_entry_interval_; 80 } 81 GetInstructionIntervals()82 const ArenaSafeMap<const HInstruction*, GeneratedCodeInterval>& GetInstructionIntervals() const { 83 return instruction_intervals_; 84 } 85 GetInstructionIntervals()86 ArenaSafeMap<const HInstruction*, GeneratedCodeInterval>* GetInstructionIntervals() { 87 return &instruction_intervals_; 88 } 89 GetSlowPathIntervals()90 const ArenaVector<SlowPathCodeInfo>& GetSlowPathIntervals() const { return slow_path_intervals_; } 91 GetSlowPathIntervals()92 ArenaVector<SlowPathCodeInfo>* GetSlowPathIntervals() { return &slow_path_intervals_; } 93 94 private: 95 GeneratedCodeInterval frame_entry_interval_; 96 ArenaSafeMap<const HInstruction*, GeneratedCodeInterval> instruction_intervals_; 97 ArenaVector<SlowPathCodeInfo> slow_path_intervals_; 98 }; 99 100 class HGraphVisualizer : public ValueObject { 101 public: 102 HGraphVisualizer(std::ostream* output, 103 HGraph* graph, 104 const CodeGenerator& codegen); 105 106 void PrintHeader(const char* method_name) const; 107 void DumpGraph(const char* pass_name, bool is_after_pass, bool graph_in_bad_state) const; 108 void DumpGraphWithDisassembly() const; 109 110 // C1visualizer file format does not support inserting arbitrary metadata into a cfg 111 // file. As a workaround a fake compilation block with the metadata in the name and the 112 // method attributes is used. Such empty blocks don't break the c1visualizer parser. 113 static std::string InsertMetaDataAsCompilationBlock(const std::string& meta_data); 114 115 private: 116 std::ostream* const output_; 117 HGraph* const graph_; 118 const CodeGenerator& codegen_; 119 120 DISALLOW_COPY_AND_ASSIGN(HGraphVisualizer); 121 }; 122 123 } // namespace art 124 125 #endif // ART_COMPILER_OPTIMIZING_GRAPH_VISUALIZER_H_ 126