summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend/maxwell/control_flow.h
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-02-02 21:07:00 -0300
committerGravatar ameerj2021-07-22 21:51:21 -0400
commit6c4cc0cd062fbbba5349da1108d3c23cb330ca8a (patch)
tree544291931da8a85fafcea71964c77d9278ec7f29 /src/shader_recompiler/frontend/maxwell/control_flow.h
parentshader: Initial recompiler work (diff)
downloadyuzu-6c4cc0cd062fbbba5349da1108d3c23cb330ca8a.tar.gz
yuzu-6c4cc0cd062fbbba5349da1108d3c23cb330ca8a.tar.xz
yuzu-6c4cc0cd062fbbba5349da1108d3c23cb330ca8a.zip
shader: SSA and dominance
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/control_flow.h')
-rw-r--r--src/shader_recompiler/frontend/maxwell/control_flow.h44
1 files changed, 38 insertions, 6 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/control_flow.h b/src/shader_recompiler/frontend/maxwell/control_flow.h
index b2ab0cdc3..20ada8afd 100644
--- a/src/shader_recompiler/frontend/maxwell/control_flow.h
+++ b/src/shader_recompiler/frontend/maxwell/control_flow.h
@@ -70,6 +70,12 @@ struct Block {
70 IR::Condition cond; 70 IR::Condition cond;
71 BlockId branch_true; 71 BlockId branch_true;
72 BlockId branch_false; 72 BlockId branch_false;
73 boost::container::small_vector<BlockId, 4> imm_predecessors;
74 boost::container::small_vector<BlockId, 8> dominance_frontiers;
75 union {
76 bool post_order_visited{false};
77 Block* imm_dominator;
78 };
73}; 79};
74 80
75struct Label { 81struct Label {
@@ -81,11 +87,30 @@ struct Label {
81struct Function { 87struct Function {
82 Function(Location start_address); 88 Function(Location start_address);
83 89
90 void BuildBlocksMap();
91
92 void BuildImmediatePredecessors();
93
94 void BuildPostOrder();
95
96 void BuildImmediateDominators();
97
98 void BuildDominanceFrontier();
99
100 [[nodiscard]] size_t NumBlocks() const noexcept {
101 return static_cast<size_t>(current_block_id) + 1;
102 }
103
84 Location entrypoint; 104 Location entrypoint;
85 BlockId current_block_id{0}; 105 BlockId current_block_id{0};
86 boost::container::small_vector<Label, 16> labels; 106 boost::container::small_vector<Label, 16> labels;
87 boost::container::small_vector<u32, 0x130> blocks; 107 boost::container::small_vector<u32, 0x130> blocks;
88 boost::container::small_vector<Block, 0x130> blocks_data; 108 boost::container::small_vector<Block, 0x130> blocks_data;
109 // Translates from BlockId to block index
110 boost::container::small_vector<Block*, 0x130> blocks_map;
111
112 boost::container::small_vector<u32, 0x130> post_order_blocks;
113 boost::container::small_vector<BlockId, 0x130> post_order_map;
89}; 114};
90 115
91class CFG { 116class CFG {
@@ -97,6 +122,12 @@ class CFG {
97public: 122public:
98 explicit CFG(Environment& env, Location start_address); 123 explicit CFG(Environment& env, Location start_address);
99 124
125 CFG& operator=(const CFG&) = delete;
126 CFG(const CFG&) = delete;
127
128 CFG& operator=(CFG&&) = delete;
129 CFG(CFG&&) = delete;
130
100 [[nodiscard]] std::string Dot() const; 131 [[nodiscard]] std::string Dot() const;
101 132
102 [[nodiscard]] std::span<const Function> Functions() const noexcept { 133 [[nodiscard]] std::span<const Function> Functions() const noexcept {
@@ -104,20 +135,22 @@ public:
104 } 135 }
105 136
106private: 137private:
138 void VisitFunctions(Location start_address);
139
107 void AnalyzeLabel(FunctionId function_id, Label& label); 140 void AnalyzeLabel(FunctionId function_id, Label& label);
108 141
109 /// Inspect already visited blocks. 142 /// Inspect already visited blocks.
110 /// Return true when the block has already been visited 143 /// Return true when the block has already been visited
111 [[nodiscard]] bool InspectVisitedBlocks(FunctionId function_id, const Label& label); 144 bool InspectVisitedBlocks(FunctionId function_id, const Label& label);
112 145
113 [[nodiscard]] AnalysisState AnalyzeInst(Block& block, FunctionId function_id, Location pc); 146 AnalysisState AnalyzeInst(Block& block, FunctionId function_id, Location pc);
114 147
115 void AnalyzeCondInst(Block& block, FunctionId function_id, Location pc, EndClass insn_end_class, 148 void AnalyzeCondInst(Block& block, FunctionId function_id, Location pc, EndClass insn_end_class,
116 IR::Condition cond); 149 IR::Condition cond);
117 150
118 /// Return true when the branch instruction is confirmed to be a branch 151 /// Return true when the branch instruction is confirmed to be a branch
119 [[nodiscard]] bool AnalyzeBranch(Block& block, FunctionId function_id, Location pc, 152 bool AnalyzeBranch(Block& block, FunctionId function_id, Location pc, Instruction inst,
120 Instruction inst, Opcode opcode); 153 Opcode opcode);
121 154
122 void AnalyzeBRA(Block& block, FunctionId function_id, Location pc, Instruction inst, 155 void AnalyzeBRA(Block& block, FunctionId function_id, Location pc, Instruction inst,
123 bool is_absolute); 156 bool is_absolute);
@@ -126,8 +159,7 @@ private:
126 AnalysisState AnalyzeEXIT(Block& block, FunctionId function_id, Location pc, Instruction inst); 159 AnalysisState AnalyzeEXIT(Block& block, FunctionId function_id, Location pc, Instruction inst);
127 160
128 /// Return the branch target block id 161 /// Return the branch target block id
129 [[nodiscard]] BlockId AddLabel(const Block& block, Stack stack, Location pc, 162 BlockId AddLabel(const Block& block, Stack stack, Location pc, FunctionId function_id);
130 FunctionId function_id);
131 163
132 Environment& env; 164 Environment& env;
133 boost::container::small_vector<Function, 1> functions; 165 boost::container::small_vector<Function, 1> functions;