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 10 #include "include/core/SkString.h" 11 #include "include/core/SkTypes.h" 12 #include "include/private/base/SkTArray.h" 13 #include "src/core/SkTHash.h" 14 #include "src/core/SkVM.h" 15 16 #include <cstddef> 17 #include <cstdint> 18 #include <type_traits> 19 #include <vector> 20 21 class SkWStream; 22 namespace SkSL { class SkVMDebugTrace; } 23 24 namespace skvm::viz { 25 enum InstructionFlags : uint8_t { 26 kNormal = 0x00, 27 kHoisted = 0x01, 28 kDead = 0x02, 29 }; 30 31 struct Instruction { 32 InstructionFlags kind = InstructionFlags::kNormal; 33 int instructionIndex; // index in the actual instructions list 34 int duplicates = 0; // number of duplicates; 35 // -1 means it's a duplicate itself; 0 - it does not have dups 36 skvm::Instruction instruction; 37 bool operator == (const Instruction& o) const; 38 SkString classes() const; 39 }; 40 41 struct InstructionHash { 42 uint32_t operator()(const Instruction& i) const; 43 }; 44 45 class Visualizer { 46 public: 47 explicit Visualizer(SkSL::SkVMDebugTrace* debugInfo); 48 ~Visualizer() = default; 49 void dump(SkWStream* output); 50 void markAsDeadCode(std::vector<bool>& live, const std::vector<int>& newIds); 51 void finalize(const std::vector<skvm::Instruction>& all, 52 const std::vector<skvm::OptimizedInstruction>& optimized); 53 void addInstructions(std::vector<skvm::Instruction>& program); markAsDuplicate(int origin,int id)54 void markAsDuplicate(int origin, int id) { 55 ++fInstructions[origin].duplicates; 56 } 57 void addInstruction(Instruction skvm); 58 SkString V(int reg) const; 59 private: 60 void dumpInstruction(int id) const; 61 void dumpHead() const; 62 void dumpTail() const; 63 void formatVV(const char* op, int v1, int v2) const; 64 void formatPV(const char* op, int imm, int v1) const; 65 void formatPVV(const char* op, int imm, int v1, int v2) const; 66 void formatPVVVV(const char* op, int imm, int v1, int v2, int v3, int v4) const; 67 void formatA_(int id, const char* op) const; 68 void formatA_P(int id, const char* op, int imm) const; 69 void formatA_PH(int id, const char* op, int immA, int immB) const; 70 void formatA_PHH(int id, const char* op, int immA, int immB, int immC) const; 71 void formatA_PHV(int id, const char* op, int immA, int immB, int v) const; 72 void formatA_S(int id, const char* op, int imm) const; 73 void formatA_V(int id, const char* op, int v) const; 74 void formatA_VV(int id, const char* op, int v1, int v2) const; 75 void formatA_VVV(int id, const char* op, int v1, int v2, int v3) const; 76 void formatA_VC(int id, const char* op, int v, int imm) const; 77 78 void writeText(const char* format, ...) const SK_PRINTF_LIKE(2, 3); 79 #if defined(SK_ENABLE_SKSL) 80 SkSL::SkVMDebugTrace* fDebugInfo; 81 #endif 82 SkTHashMap<Instruction, size_t, InstructionHash> fIndex; 83 SkTArray<Instruction> fInstructions; 84 SkWStream* fOutput; 85 SkTHashMap<int, size_t> fToDisassembler; 86 }; 87 } // namespace skvm::viz 88 89 namespace sknonstd { 90 template <typename T> struct is_bitmask_enum; 91 template <> struct is_bitmask_enum<skvm::viz::InstructionFlags> : std::true_type {}; 92 } // namespace sknonstd 93 94 #endif // SkVMVisualizer_DEFINED 95