File: graph_visualizer.h

package info (click to toggle)
android-platform-art 14.0.0%2Br15-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 96,796 kB
  • sloc: cpp: 522,217; java: 194,312; asm: 28,950; python: 14,910; xml: 5,087; sh: 4,528; ansic: 4,035; makefile: 110; perl: 77
file content (144 lines) | stat: -rw-r--r-- 4,732 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_COMPILER_OPTIMIZING_GRAPH_VISUALIZER_H_
#define ART_COMPILER_OPTIMIZING_GRAPH_VISUALIZER_H_

#include <functional>
#include <ostream>

#include "arch/instruction_set.h"
#include "base/arena_containers.h"
#include "base/macros.h"
#include "base/value_object.h"
#include "block_namer.h"

namespace art HIDDEN {

class CodeGenerator;
class DexCompilationUnit;
class HGraph;
class HInstruction;
class SlowPathCode;

/**
 * This class outputs the HGraph in the C1visualizer format.
 * Note: Currently only works if the compiler is single threaded.
 */
struct GeneratedCodeInterval {
  size_t start;
  size_t end;
};

struct SlowPathCodeInfo {
  const SlowPathCode* slow_path;
  GeneratedCodeInterval code_interval;
};

// This information is filled by the code generator. It will be used by the
// graph visualizer to associate disassembly of the generated code with the
// instructions and slow paths. We assume that the generated code follows the
// following structure:
//   - frame entry
//   - instructions
//   - slow paths
class DisassemblyInformation {
 public:
  explicit DisassemblyInformation(ArenaAllocator* allocator)
      : frame_entry_interval_({0, 0}),
        instruction_intervals_(std::less<const HInstruction*>(), allocator->Adapter()),
        slow_path_intervals_(allocator->Adapter()) {}

  void SetFrameEntryInterval(size_t start, size_t end) {
    frame_entry_interval_ = {start, end};
  }

  void AddInstructionInterval(HInstruction* instr, size_t start, size_t end) {
    instruction_intervals_.Put(instr, {start, end});
  }

  void AddSlowPathInterval(SlowPathCode* slow_path, size_t start, size_t end) {
    slow_path_intervals_.push_back({slow_path, {start, end}});
  }

  GeneratedCodeInterval GetFrameEntryInterval() const {
    return frame_entry_interval_;
  }

  GeneratedCodeInterval* GetFrameEntryInterval() {
    return &frame_entry_interval_;
  }

  const ArenaSafeMap<const HInstruction*, GeneratedCodeInterval>& GetInstructionIntervals() const {
    return instruction_intervals_;
  }

  ArenaSafeMap<const HInstruction*, GeneratedCodeInterval>* GetInstructionIntervals() {
    return &instruction_intervals_;
  }

  const ArenaVector<SlowPathCodeInfo>& GetSlowPathIntervals() const { return slow_path_intervals_; }

  ArenaVector<SlowPathCodeInfo>* GetSlowPathIntervals() { return &slow_path_intervals_; }

 private:
  GeneratedCodeInterval frame_entry_interval_;
  ArenaSafeMap<const HInstruction*, GeneratedCodeInterval> instruction_intervals_;
  ArenaVector<SlowPathCodeInfo> slow_path_intervals_;
};

class HGraphVisualizer : public ValueObject {
 public:
  HGraphVisualizer(std::ostream* output,
                   HGraph* graph,
                   const CodeGenerator* codegen,
                   std::optional<std::reference_wrapper<const BlockNamer>> namer = std::nullopt);

  void PrintHeader(const char* method_name) const;
  void DumpGraph(const char* pass_name, bool is_after_pass, bool graph_in_bad_state) const;
  void DumpGraphDebug() const;
  void DumpGraphWithDisassembly() const;

  // C1visualizer file format does not support inserting arbitrary metadata into a cfg
  // file. As a workaround a fake compilation block with the metadata in the name and the
  // method attributes is used. Such empty blocks don't break the c1visualizer parser.
  static std::string InsertMetaDataAsCompilationBlock(const std::string& meta_data);

  static void DumpInstruction(std::ostream* output, HGraph* graph, HInstruction* instruction);

 private:
  class OptionalDefaultNamer final : public BlockNamer {
   public:
    explicit OptionalDefaultNamer(std::optional<std::reference_wrapper<const BlockNamer>> inner)
        : namer_(inner) {}

    std::ostream& PrintName(std::ostream& os, HBasicBlock* blk) const override;

   private:
    std::optional<std::reference_wrapper<const BlockNamer>> namer_;
  };

  std::ostream* const output_;
  HGraph* const graph_;
  const CodeGenerator* codegen_;
  OptionalDefaultNamer namer_;

  DISALLOW_COPY_AND_ASSIGN(HGraphVisualizer);
};

}  // namespace art

#endif  // ART_COMPILER_OPTIMIZING_GRAPH_VISUALIZER_H_