summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-02-05 05:58:02 -0300
committerGravatar ameerj2021-07-22 21:51:21 -0400
commite81739493a0cacc1efe3295f9d287d5d31b1a989 (patch)
tree11a3d04ce9def535414a00226030798f337c053c /src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
parentshader: Initial instruction support (diff)
downloadyuzu-e81739493a0cacc1efe3295f9d287d5d31b1a989.tar.gz
yuzu-e81739493a0cacc1efe3295f9d287d5d31b1a989.tar.xz
yuzu-e81739493a0cacc1efe3295f9d287d5d31b1a989.zip
shader: Constant propagation and global memory to storage buffer
Diffstat (limited to 'src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp')
-rw-r--r--src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp56
1 files changed, 54 insertions, 2 deletions
diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
index a4b256a40..3c9b020e0 100644
--- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
+++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
@@ -14,8 +14,6 @@
14// https://link.springer.com/chapter/10.1007/978-3-642-37051-9_6 14// https://link.springer.com/chapter/10.1007/978-3-642-37051-9_6
15// 15//
16 16
17#include <map>
18
19#include <boost/container/flat_map.hpp> 17#include <boost/container/flat_map.hpp>
20 18
21#include "shader_recompiler/frontend/ir/basic_block.h" 19#include "shader_recompiler/frontend/ir/basic_block.h"
@@ -30,6 +28,12 @@ namespace Shader::Optimization {
30namespace { 28namespace {
31using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>; 29using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>;
32 30
31struct FlagTag {};
32struct ZeroFlagTag : FlagTag {};
33struct SignFlagTag : FlagTag {};
34struct CarryFlagTag : FlagTag {};
35struct OverflowFlagTag : FlagTag {};
36
33struct DefTable { 37struct DefTable {
34 [[nodiscard]] ValueMap& operator[](IR::Reg variable) noexcept { 38 [[nodiscard]] ValueMap& operator[](IR::Reg variable) noexcept {
35 return regs[IR::RegIndex(variable)]; 39 return regs[IR::RegIndex(variable)];
@@ -39,8 +43,28 @@ struct DefTable {
39 return preds[IR::PredIndex(variable)]; 43 return preds[IR::PredIndex(variable)];
40 } 44 }
41 45
46 [[nodiscard]] ValueMap& operator[](ZeroFlagTag) noexcept {
47 return zero_flag;
48 }
49
50 [[nodiscard]] ValueMap& operator[](SignFlagTag) noexcept {
51 return sign_flag;
52 }
53
54 [[nodiscard]] ValueMap& operator[](CarryFlagTag) noexcept {
55 return carry_flag;
56 }
57
58 [[nodiscard]] ValueMap& operator[](OverflowFlagTag) noexcept {
59 return overflow_flag;
60 }
61
42 std::array<ValueMap, IR::NUM_USER_REGS> regs; 62 std::array<ValueMap, IR::NUM_USER_REGS> regs;
43 std::array<ValueMap, IR::NUM_USER_PREDS> preds; 63 std::array<ValueMap, IR::NUM_USER_PREDS> preds;
64 ValueMap zero_flag;
65 ValueMap sign_flag;
66 ValueMap carry_flag;
67 ValueMap overflow_flag;
44}; 68};
45 69
46IR::Opcode UndefOpcode(IR::Reg) noexcept { 70IR::Opcode UndefOpcode(IR::Reg) noexcept {
@@ -51,6 +75,10 @@ IR::Opcode UndefOpcode(IR::Pred) noexcept {
51 return IR::Opcode::Undef1; 75 return IR::Opcode::Undef1;
52} 76}
53 77
78IR::Opcode UndefOpcode(const FlagTag&) noexcept {
79 return IR::Opcode::Undef1;
80}
81
54[[nodiscard]] bool IsPhi(const IR::Inst& inst) noexcept { 82[[nodiscard]] bool IsPhi(const IR::Inst& inst) noexcept {
55 return inst.Opcode() == IR::Opcode::Phi; 83 return inst.Opcode() == IR::Opcode::Phi;
56} 84}
@@ -135,6 +163,18 @@ void SsaRewritePass(IR::Function& function) {
135 pass.WriteVariable(pred, block.get(), inst.Arg(1)); 163 pass.WriteVariable(pred, block.get(), inst.Arg(1));
136 } 164 }
137 break; 165 break;
166 case IR::Opcode::SetZFlag:
167 pass.WriteVariable(ZeroFlagTag{}, block.get(), inst.Arg(0));
168 break;
169 case IR::Opcode::SetSFlag:
170 pass.WriteVariable(SignFlagTag{}, block.get(), inst.Arg(0));
171 break;
172 case IR::Opcode::SetCFlag:
173 pass.WriteVariable(CarryFlagTag{}, block.get(), inst.Arg(0));
174 break;
175 case IR::Opcode::SetOFlag:
176 pass.WriteVariable(OverflowFlagTag{}, block.get(), inst.Arg(0));
177 break;
138 case IR::Opcode::GetRegister: 178 case IR::Opcode::GetRegister:
139 if (const IR::Reg reg{inst.Arg(0).Reg()}; reg != IR::Reg::RZ) { 179 if (const IR::Reg reg{inst.Arg(0).Reg()}; reg != IR::Reg::RZ) {
140 inst.ReplaceUsesWith(pass.ReadVariable(reg, block.get())); 180 inst.ReplaceUsesWith(pass.ReadVariable(reg, block.get()));
@@ -145,6 +185,18 @@ void SsaRewritePass(IR::Function& function) {
145 inst.ReplaceUsesWith(pass.ReadVariable(pred, block.get())); 185 inst.ReplaceUsesWith(pass.ReadVariable(pred, block.get()));
146 } 186 }
147 break; 187 break;
188 case IR::Opcode::GetZFlag:
189 inst.ReplaceUsesWith(pass.ReadVariable(ZeroFlagTag{}, block.get()));
190 break;
191 case IR::Opcode::GetSFlag:
192 inst.ReplaceUsesWith(pass.ReadVariable(SignFlagTag{}, block.get()));
193 break;
194 case IR::Opcode::GetCFlag:
195 inst.ReplaceUsesWith(pass.ReadVariable(CarryFlagTag{}, block.get()));
196 break;
197 case IR::Opcode::GetOFlag:
198 inst.ReplaceUsesWith(pass.ReadVariable(OverflowFlagTag{}, block.get()));
199 break;
148 default: 200 default:
149 break; 201 break;
150 } 202 }