• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 #ifndef SkVMVisualizer_DEFINED
8 #define SkVMVisualizer_DEFINED
9 #include <unordered_map>
10 #include <vector>
11 #include "include/core/SkSpan.h"
12 #include "include/core/SkStream.h"
13 #include "include/core/SkString.h"
14 #include "include/private/SkBitmaskEnum.h"
15 #include "include/private/SkChecksum.h"
16 #include "include/private/SkTHash.h"
17 #include "src/core/SkOpts.h"
18 #include "src/sksl/SkSLOutputStream.h"
19 #include "src/sksl/tracing/SkVMDebugTrace.h"
20 
21 namespace skvm::viz {
22     enum InstructionFlags : uint8_t {
23         kNormal = 0x00,
24         kHoisted = 0x01,
25         kDead = 0x02,
26     };
27 
28     struct MachineCommand {
29         size_t address;
30         SkString label;
31         SkString command;
32         SkString extra;
33     };
34 
35     struct Instruction {
36         InstructionFlags kind = InstructionFlags::kNormal;
37         // Machine commands range (for disassembling):
38         size_t startCode = 0;
39         size_t endCode = 0;
40         int instructionIndex; // index in the actual instructions list
41         int duplicates = 0;   // number of duplicates;
42                               // -1 means it's a duplicate itself; 0 - it does not have dups
43         skvm::Instruction instruction;
44         bool operator == (const Instruction& o) const;
45         SkString classes() const;
46     };
47 
48     struct InstructionHash {
49         uint32_t operator()(const Instruction& i) const;
50     };
51 
52     class Visualizer {
53     public:
Visualizer(SkSL::SkVMDebugTrace * debugInfo)54         explicit Visualizer(SkSL::SkVMDebugTrace* debugInfo)
55                 : fDebugInfo(debugInfo), fOutput(nullptr) {}
56         ~Visualizer() = default;
57         void dump(SkWStream* output, const char* code);
58         void markAsDeadCode(std::vector<bool>& live, const std::vector<int>& newIds);
59         void finalize(const std::vector<skvm::Instruction>& all,
60                       const std::vector<skvm::OptimizedInstruction>& optimized);
61         void addInstructions(std::vector<skvm::Instruction>& program);
markAsDuplicate(int origin,int id)62         void markAsDuplicate(int origin, int id) {
63             ++fInstructions[origin].duplicates;
64         }
65         void addInstruction(Instruction skvm);
66         void addMachineCommands(int id, size_t start, size_t end);
67         SkString V(int reg) const;
68     private:
69         void parseDisassembler(SkWStream* output, const char* code);
70         void dumpInstruction(int id) const;
71         void dumpHead() const;
72         void dumpTail() const;
73         void formatVV(const char* op, int v1, int v2) const;
74         void formatPV(const char* op, int imm, int v1) const;
75         void formatPVV(const char* op, int imm, int v1, int v2) const;
76         void formatPVVVV(const char* op, int imm, int v1, int v2, int v3, int v4) const;
77         void formatA_(int id, const char* op) const;
78         void formatA_P(int id, const char* op, int imm) const;
79         void formatA_PH(int id, const char* op, int immA, int immB) const;
80         void formatA_PHH(int id, const char* op, int immA, int immB, int immC) const;
81         void formatA_PHV(int id, const char* op, int immA, int immB, int v) const;
82         void formatA_S(int id, const char* op, int imm) const;
83         void formatA_V(int id, const char* op, int v) const;
84         void formatA_VV(int id, const char* op, int v1, int v2) const;
85         void formatA_VVV(int id, const char* op,  int v1, int v2, int v3) const;
86         void formatA_VC(int id, const char* op,  int v, int imm) const;
87 
88         void writeText(const char* format, ...) const SK_PRINTF_LIKE(2, 3);
89 
90         SkSL::SkVMDebugTrace* fDebugInfo;
91         SkTHashMap<Instruction, size_t, InstructionHash> fIndex;
92         SkTArray<Instruction> fInstructions;
93         SkWStream* fOutput;
94         SkTHashMap<int, size_t> fToDisassembler;
95         SkTArray<MachineCommand> fAsm;
96         mutable size_t fAsmLine = 0;
97         size_t fAsmStart = 0;
98         size_t fAsmEnd = 0;
99     };
100 } // namespace skvm::viz
101 
102 namespace sknonstd {
103 template <> struct is_bitmask_enum<skvm::viz::InstructionFlags> : std::true_type {};
104 }  // namespace sknonstd
105 
106 #endif // SkVMVisualizer_DEFINED
107