1f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray/*
2f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * Copyright (C) 2014 The Android Open Source Project
3f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray *
4f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License");
5f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * you may not use this file except in compliance with the License.
6f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * You may obtain a copy of the License at
7f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray *
8f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray *      http://www.apache.org/licenses/LICENSE-2.0
9f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray *
10f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * Unless required by applicable law or agreed to in writing, software
11f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS,
12f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * See the License for the specific language governing permissions and
14f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * limitations under the License.
15f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray */
16f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
17f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray#ifndef ART_COMPILER_OPTIMIZING_GRAPH_VISUALIZER_H_
18f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray#define ART_COMPILER_OPTIMIZING_GRAPH_VISUALIZER_H_
19f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
20cf7f19135f0e273f7b0136315633c2abfc715343Ian Rogers#include <ostream>
21cf7f19135f0e273f7b0136315633c2abfc715343Ian Rogers
22eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames#include "arch/instruction_set.h"
23eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames#include "base/arena_containers.h"
240279ebb3efd653e6bb255470c99d26949c7bcd95Ian Rogers#include "base/value_object.h"
25f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
26f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffraynamespace art {
27f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
28a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffrayclass CodeGenerator;
29f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffrayclass DexCompilationUnit;
30f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffrayclass HGraph;
31eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Ramesclass HInstruction;
32eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Ramesclass SlowPathCode;
33f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
34f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray/**
35ee690a3dd364c025ebc1767d9f84097bb7473eecDavid Brazdil * This class outputs the HGraph in the C1visualizer format.
36ee690a3dd364c025ebc1767d9f84097bb7473eecDavid Brazdil * Note: Currently only works if the compiler is single threaded.
37f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray */
38eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Ramesstruct GeneratedCodeInterval {
39eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  size_t start;
40eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  size_t end;
41eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames};
42eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames
43eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Ramesstruct SlowPathCodeInfo {
44eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  const SlowPathCode* slow_path;
45eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  GeneratedCodeInterval code_interval;
46eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames};
47eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames
48eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames// This information is filled by the code generator. It will be used by the
49eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames// graph visualizer to associate disassembly of the generated code with the
50eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames// instructions and slow paths. We assume that the generated code follows the
51eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames// following structure:
52eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames//   - frame entry
53eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames//   - instructions
54eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames//   - slow paths
55eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Ramesclass DisassemblyInformation {
56eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames public:
57eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  explicit DisassemblyInformation(ArenaAllocator* allocator)
58eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames      : frame_entry_interval_({0, 0}),
59eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames        instruction_intervals_(std::less<const HInstruction*>(), allocator->Adapter()),
60eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames        slow_path_intervals_(allocator->Adapter()) {}
61eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames
62eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  void SetFrameEntryInterval(size_t start, size_t end) {
63eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames    frame_entry_interval_ = {start, end};
64eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  }
65eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames
66eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  void AddInstructionInterval(HInstruction* instr, size_t start, size_t end) {
67eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames    instruction_intervals_.Put(instr, {start, end});
68eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  }
69eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames
70eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  void AddSlowPathInterval(SlowPathCode* slow_path, size_t start, size_t end) {
71eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames    slow_path_intervals_.push_back({slow_path, {start, end}});
72eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  }
73eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames
74eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  GeneratedCodeInterval GetFrameEntryInterval() const {
75eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames    return frame_entry_interval_;
76eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  }
77eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames
78eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  GeneratedCodeInterval* GetFrameEntryInterval() {
79eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames    return &frame_entry_interval_;
80eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  }
81eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames
82eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  const ArenaSafeMap<const HInstruction*, GeneratedCodeInterval>& GetInstructionIntervals() const {
83eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames    return instruction_intervals_;
84eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  }
85eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames
86eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  ArenaSafeMap<const HInstruction*, GeneratedCodeInterval>* GetInstructionIntervals() {
87eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames    return &instruction_intervals_;
88eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  }
89eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames
90eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  const ArenaVector<SlowPathCodeInfo>& GetSlowPathIntervals() const { return slow_path_intervals_; }
91eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames
92eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  ArenaVector<SlowPathCodeInfo>* GetSlowPathIntervals() { return &slow_path_intervals_; }
93eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames
94eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames private:
95eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  GeneratedCodeInterval frame_entry_interval_;
96eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  ArenaSafeMap<const HInstruction*, GeneratedCodeInterval> instruction_intervals_;
97eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  ArenaVector<SlowPathCodeInfo> slow_path_intervals_;
98eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames};
99eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames
100f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffrayclass HGraphVisualizer : public ValueObject {
101f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray public:
102f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  HGraphVisualizer(std::ostream* output,
103f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray                   HGraph* graph,
10462e074f0d1a18f0f5aa6716f000825704f55e81bDavid Brazdil                   const CodeGenerator& codegen);
1050d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray
10662e074f0d1a18f0f5aa6716f000825704f55e81bDavid Brazdil  void PrintHeader(const char* method_name) const;
107ffee3d33f3ea39aa6031c3d2ff29c4806c8dcc51David Brazdil  void DumpGraph(const char* pass_name, bool is_after_pass, bool graph_in_bad_state) const;
108eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  void DumpGraphWithDisassembly() const;
109f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
110f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray private:
111f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  std::ostream* const output_;
112f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  HGraph* const graph_;
113a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  const CodeGenerator& codegen_;
114f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
115f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  DISALLOW_COPY_AND_ASSIGN(HGraphVisualizer);
116f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray};
117f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
118f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray}  // namespace art
119f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
120f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray#endif  // ART_COMPILER_OPTIMIZING_GRAPH_VISUALIZER_H_
121