summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-10-05 12:02:51 -0400
committerGravatar GitHub2019-10-05 12:02:51 -0400
commit47ccfabe18db3691a09f211fc4aec465ee186c2a (patch)
tree8bd02e8d5e16dee8522e29d21c711ef98282bb52 /src
parentMerge pull request #2888 from FernandoS27/decompiler2 (diff)
parentvideo_core/control_flow: Eliminate variable shadowing warnings (diff)
downloadyuzu-47ccfabe18db3691a09f211fc4aec465ee186c2a.tar.gz
yuzu-47ccfabe18db3691a09f211fc4aec465ee186c2a.tar.xz
yuzu-47ccfabe18db3691a09f211fc4aec465ee186c2a.zip
Merge pull request #2944 from lioncash/ast
video_core/shader: Minor changes
Diffstat (limited to 'src')
-rw-r--r--src/video_core/shader/ast.cpp122
-rw-r--r--src/video_core/shader/ast.h85
-rw-r--r--src/video_core/shader/control_flow.cpp23
-rw-r--r--src/video_core/shader/expr.cpp39
-rw-r--r--src/video_core/shader/expr.h37
5 files changed, 160 insertions, 146 deletions
diff --git a/src/video_core/shader/ast.cpp b/src/video_core/shader/ast.cpp
index 2eb065c3d..436d45f4b 100644
--- a/src/video_core/shader/ast.cpp
+++ b/src/video_core/shader/ast.cpp
@@ -17,6 +17,7 @@ void ASTZipper::Init(const ASTNode new_first, const ASTNode parent) {
17 ASSERT(new_first->manager == nullptr); 17 ASSERT(new_first->manager == nullptr);
18 first = new_first; 18 first = new_first;
19 last = new_first; 19 last = new_first;
20
20 ASTNode current = first; 21 ASTNode current = first;
21 while (current) { 22 while (current) {
22 current->manager = this; 23 current->manager = this;
@@ -92,7 +93,7 @@ void ASTZipper::InsertBefore(const ASTNode new_node, const ASTNode at_node) {
92 new_node->manager = this; 93 new_node->manager = this;
93} 94}
94 95
95void ASTZipper::DetachTail(const ASTNode node) { 96void ASTZipper::DetachTail(ASTNode node) {
96 ASSERT(node->manager == this); 97 ASSERT(node->manager == this);
97 if (node == first) { 98 if (node == first) {
98 first.reset(); 99 first.reset();
@@ -103,7 +104,8 @@ void ASTZipper::DetachTail(const ASTNode node) {
103 last = node->previous; 104 last = node->previous;
104 last->next.reset(); 105 last->next.reset();
105 node->previous.reset(); 106 node->previous.reset();
106 ASTNode current = node; 107
108 ASTNode current = std::move(node);
107 while (current) { 109 while (current) {
108 current->manager = nullptr; 110 current->manager = nullptr;
109 current->parent.reset(); 111 current->parent.reset();
@@ -185,9 +187,7 @@ void ASTZipper::Remove(const ASTNode node) {
185 187
186class ExprPrinter final { 188class ExprPrinter final {
187public: 189public:
188 ExprPrinter() = default; 190 void operator()(const ExprAnd& expr) {
189
190 void operator()(ExprAnd const& expr) {
191 inner += "( "; 191 inner += "( ";
192 std::visit(*this, *expr.operand1); 192 std::visit(*this, *expr.operand1);
193 inner += " && "; 193 inner += " && ";
@@ -195,7 +195,7 @@ public:
195 inner += ')'; 195 inner += ')';
196 } 196 }
197 197
198 void operator()(ExprOr const& expr) { 198 void operator()(const ExprOr& expr) {
199 inner += "( "; 199 inner += "( ";
200 std::visit(*this, *expr.operand1); 200 std::visit(*this, *expr.operand1);
201 inner += " || "; 201 inner += " || ";
@@ -203,29 +203,29 @@ public:
203 inner += ')'; 203 inner += ')';
204 } 204 }
205 205
206 void operator()(ExprNot const& expr) { 206 void operator()(const ExprNot& expr) {
207 inner += "!"; 207 inner += "!";
208 std::visit(*this, *expr.operand1); 208 std::visit(*this, *expr.operand1);
209 } 209 }
210 210
211 void operator()(ExprPredicate const& expr) { 211 void operator()(const ExprPredicate& expr) {
212 inner += "P" + std::to_string(expr.predicate); 212 inner += "P" + std::to_string(expr.predicate);
213 } 213 }
214 214
215 void operator()(ExprCondCode const& expr) { 215 void operator()(const ExprCondCode& expr) {
216 u32 cc = static_cast<u32>(expr.cc); 216 u32 cc = static_cast<u32>(expr.cc);
217 inner += "CC" + std::to_string(cc); 217 inner += "CC" + std::to_string(cc);
218 } 218 }
219 219
220 void operator()(ExprVar const& expr) { 220 void operator()(const ExprVar& expr) {
221 inner += "V" + std::to_string(expr.var_index); 221 inner += "V" + std::to_string(expr.var_index);
222 } 222 }
223 223
224 void operator()(ExprBoolean const& expr) { 224 void operator()(const ExprBoolean& expr) {
225 inner += expr.value ? "true" : "false"; 225 inner += expr.value ? "true" : "false";
226 } 226 }
227 227
228 std::string& GetResult() { 228 const std::string& GetResult() const {
229 return inner; 229 return inner;
230 } 230 }
231 231
@@ -234,9 +234,7 @@ public:
234 234
235class ASTPrinter { 235class ASTPrinter {
236public: 236public:
237 ASTPrinter() = default; 237 void operator()(const ASTProgram& ast) {
238
239 void operator()(ASTProgram& ast) {
240 scope++; 238 scope++;
241 inner += "program {\n"; 239 inner += "program {\n";
242 ASTNode current = ast.nodes.GetFirst(); 240 ASTNode current = ast.nodes.GetFirst();
@@ -248,7 +246,7 @@ public:
248 scope--; 246 scope--;
249 } 247 }
250 248
251 void operator()(ASTIfThen& ast) { 249 void operator()(const ASTIfThen& ast) {
252 ExprPrinter expr_parser{}; 250 ExprPrinter expr_parser{};
253 std::visit(expr_parser, *ast.condition); 251 std::visit(expr_parser, *ast.condition);
254 inner += Ident() + "if (" + expr_parser.GetResult() + ") {\n"; 252 inner += Ident() + "if (" + expr_parser.GetResult() + ") {\n";
@@ -262,7 +260,7 @@ public:
262 inner += Ident() + "}\n"; 260 inner += Ident() + "}\n";
263 } 261 }
264 262
265 void operator()(ASTIfElse& ast) { 263 void operator()(const ASTIfElse& ast) {
266 inner += Ident() + "else {\n"; 264 inner += Ident() + "else {\n";
267 scope++; 265 scope++;
268 ASTNode current = ast.nodes.GetFirst(); 266 ASTNode current = ast.nodes.GetFirst();
@@ -274,34 +272,34 @@ public:
274 inner += Ident() + "}\n"; 272 inner += Ident() + "}\n";
275 } 273 }
276 274
277 void operator()(ASTBlockEncoded& ast) { 275 void operator()(const ASTBlockEncoded& ast) {
278 inner += Ident() + "Block(" + std::to_string(ast.start) + ", " + std::to_string(ast.end) + 276 inner += Ident() + "Block(" + std::to_string(ast.start) + ", " + std::to_string(ast.end) +
279 ");\n"; 277 ");\n";
280 } 278 }
281 279
282 void operator()(ASTBlockDecoded& ast) { 280 void operator()(const ASTBlockDecoded& ast) {
283 inner += Ident() + "Block;\n"; 281 inner += Ident() + "Block;\n";
284 } 282 }
285 283
286 void operator()(ASTVarSet& ast) { 284 void operator()(const ASTVarSet& ast) {
287 ExprPrinter expr_parser{}; 285 ExprPrinter expr_parser{};
288 std::visit(expr_parser, *ast.condition); 286 std::visit(expr_parser, *ast.condition);
289 inner += 287 inner +=
290 Ident() + "V" + std::to_string(ast.index) + " := " + expr_parser.GetResult() + ";\n"; 288 Ident() + "V" + std::to_string(ast.index) + " := " + expr_parser.GetResult() + ";\n";
291 } 289 }
292 290
293 void operator()(ASTLabel& ast) { 291 void operator()(const ASTLabel& ast) {
294 inner += "Label_" + std::to_string(ast.index) + ":\n"; 292 inner += "Label_" + std::to_string(ast.index) + ":\n";
295 } 293 }
296 294
297 void operator()(ASTGoto& ast) { 295 void operator()(const ASTGoto& ast) {
298 ExprPrinter expr_parser{}; 296 ExprPrinter expr_parser{};
299 std::visit(expr_parser, *ast.condition); 297 std::visit(expr_parser, *ast.condition);
300 inner += Ident() + "(" + expr_parser.GetResult() + ") -> goto Label_" + 298 inner += Ident() + "(" + expr_parser.GetResult() + ") -> goto Label_" +
301 std::to_string(ast.label) + ";\n"; 299 std::to_string(ast.label) + ";\n";
302 } 300 }
303 301
304 void operator()(ASTDoWhile& ast) { 302 void operator()(const ASTDoWhile& ast) {
305 ExprPrinter expr_parser{}; 303 ExprPrinter expr_parser{};
306 std::visit(expr_parser, *ast.condition); 304 std::visit(expr_parser, *ast.condition);
307 inner += Ident() + "do {\n"; 305 inner += Ident() + "do {\n";
@@ -315,14 +313,14 @@ public:
315 inner += Ident() + "} while (" + expr_parser.GetResult() + ");\n"; 313 inner += Ident() + "} while (" + expr_parser.GetResult() + ");\n";
316 } 314 }
317 315
318 void operator()(ASTReturn& ast) { 316 void operator()(const ASTReturn& ast) {
319 ExprPrinter expr_parser{}; 317 ExprPrinter expr_parser{};
320 std::visit(expr_parser, *ast.condition); 318 std::visit(expr_parser, *ast.condition);
321 inner += Ident() + "(" + expr_parser.GetResult() + ") -> " + 319 inner += Ident() + "(" + expr_parser.GetResult() + ") -> " +
322 (ast.kills ? "discard" : "exit") + ";\n"; 320 (ast.kills ? "discard" : "exit") + ";\n";
323 } 321 }
324 322
325 void operator()(ASTBreak& ast) { 323 void operator()(const ASTBreak& ast) {
326 ExprPrinter expr_parser{}; 324 ExprPrinter expr_parser{};
327 std::visit(expr_parser, *ast.condition); 325 std::visit(expr_parser, *ast.condition);
328 inner += Ident() + "(" + expr_parser.GetResult() + ") -> break;\n"; 326 inner += Ident() + "(" + expr_parser.GetResult() + ") -> break;\n";
@@ -341,7 +339,7 @@ public:
341 std::visit(*this, *node->GetInnerData()); 339 std::visit(*this, *node->GetInnerData());
342 } 340 }
343 341
344 std::string& GetResult() { 342 const std::string& GetResult() const {
345 return inner; 343 return inner;
346 } 344 }
347 345
@@ -352,11 +350,9 @@ private:
352 std::string tabs_memo{}; 350 std::string tabs_memo{};
353 u32 memo_scope{}; 351 u32 memo_scope{};
354 352
355 static std::string tabs; 353 static constexpr std::string_view tabs{" "};
356}; 354};
357 355
358std::string ASTPrinter::tabs = " ";
359
360std::string ASTManager::Print() { 356std::string ASTManager::Print() {
361 ASTPrinter printer{}; 357 ASTPrinter printer{};
362 printer.Visit(main_node); 358 printer.Visit(main_node);
@@ -376,30 +372,6 @@ void ASTManager::Init() {
376 false_condition = MakeExpr<ExprBoolean>(false); 372 false_condition = MakeExpr<ExprBoolean>(false);
377} 373}
378 374
379ASTManager::ASTManager(ASTManager&& other) noexcept
380 : labels_map(std::move(other.labels_map)), labels_count{other.labels_count},
381 gotos(std::move(other.gotos)), labels(std::move(other.labels)), variables{other.variables},
382 program{other.program}, main_node{other.main_node}, false_condition{other.false_condition},
383 disable_else_derivation{other.disable_else_derivation} {
384 other.main_node.reset();
385}
386
387ASTManager& ASTManager::operator=(ASTManager&& other) noexcept {
388 full_decompile = other.full_decompile;
389 labels_map = std::move(other.labels_map);
390 labels_count = other.labels_count;
391 gotos = std::move(other.gotos);
392 labels = std::move(other.labels);
393 variables = other.variables;
394 program = other.program;
395 main_node = other.main_node;
396 false_condition = other.false_condition;
397 disable_else_derivation = other.disable_else_derivation;
398
399 other.main_node.reset();
400 return *this;
401}
402
403void ASTManager::DeclareLabel(u32 address) { 375void ASTManager::DeclareLabel(u32 address) {
404 const auto pair = labels_map.emplace(address, labels_count); 376 const auto pair = labels_map.emplace(address, labels_count);
405 if (pair.second) { 377 if (pair.second) {
@@ -417,19 +389,19 @@ void ASTManager::InsertLabel(u32 address) {
417 389
418void ASTManager::InsertGoto(Expr condition, u32 address) { 390void ASTManager::InsertGoto(Expr condition, u32 address) {
419 const u32 index = labels_map[address]; 391 const u32 index = labels_map[address];
420 const ASTNode goto_node = ASTBase::Make<ASTGoto>(main_node, condition, index); 392 const ASTNode goto_node = ASTBase::Make<ASTGoto>(main_node, std::move(condition), index);
421 gotos.push_back(goto_node); 393 gotos.push_back(goto_node);
422 program->nodes.PushBack(goto_node); 394 program->nodes.PushBack(goto_node);
423} 395}
424 396
425void ASTManager::InsertBlock(u32 start_address, u32 end_address) { 397void ASTManager::InsertBlock(u32 start_address, u32 end_address) {
426 const ASTNode block = ASTBase::Make<ASTBlockEncoded>(main_node, start_address, end_address); 398 ASTNode block = ASTBase::Make<ASTBlockEncoded>(main_node, start_address, end_address);
427 program->nodes.PushBack(block); 399 program->nodes.PushBack(std::move(block));
428} 400}
429 401
430void ASTManager::InsertReturn(Expr condition, bool kills) { 402void ASTManager::InsertReturn(Expr condition, bool kills) {
431 const ASTNode node = ASTBase::Make<ASTReturn>(main_node, condition, kills); 403 ASTNode node = ASTBase::Make<ASTReturn>(main_node, std::move(condition), kills);
432 program->nodes.PushBack(node); 404 program->nodes.PushBack(std::move(node));
433} 405}
434 406
435// The decompile algorithm is based on 407// The decompile algorithm is based on
@@ -496,10 +468,10 @@ void ASTManager::Decompile() {
496 } 468 }
497 labels.clear(); 469 labels.clear();
498 } else { 470 } else {
499 auto it = labels.begin(); 471 auto label_it = labels.begin();
500 while (it != labels.end()) { 472 while (label_it != labels.end()) {
501 bool can_remove = true; 473 bool can_remove = true;
502 ASTNode label = *it; 474 ASTNode label = *label_it;
503 for (const ASTNode& goto_node : gotos) { 475 for (const ASTNode& goto_node : gotos) {
504 const auto label_index = goto_node->GetGotoLabel(); 476 const auto label_index = goto_node->GetGotoLabel();
505 if (!label_index) { 477 if (!label_index) {
@@ -543,11 +515,11 @@ bool ASTManager::IsBackwardsJump(ASTNode goto_node, ASTNode label_node) const {
543 return false; 515 return false;
544} 516}
545 517
546bool ASTManager::IndirectlyRelated(ASTNode first, ASTNode second) { 518bool ASTManager::IndirectlyRelated(const ASTNode& first, const ASTNode& second) const {
547 return !(first->GetParent() == second->GetParent() || DirectlyRelated(first, second)); 519 return !(first->GetParent() == second->GetParent() || DirectlyRelated(first, second));
548} 520}
549 521
550bool ASTManager::DirectlyRelated(ASTNode first, ASTNode second) { 522bool ASTManager::DirectlyRelated(const ASTNode& first, const ASTNode& second) const {
551 if (first->GetParent() == second->GetParent()) { 523 if (first->GetParent() == second->GetParent()) {
552 return false; 524 return false;
553 } 525 }
@@ -577,7 +549,7 @@ bool ASTManager::DirectlyRelated(ASTNode first, ASTNode second) {
577 return min->GetParent() == max->GetParent(); 549 return min->GetParent() == max->GetParent();
578} 550}
579 551
580void ASTManager::ShowCurrentState(std::string state) { 552void ASTManager::ShowCurrentState(std::string_view state) {
581 LOG_CRITICAL(HW_GPU, "\nState {}:\n\n{}\n", state, Print()); 553 LOG_CRITICAL(HW_GPU, "\nState {}:\n\n{}\n", state, Print());
582 SanityCheck(); 554 SanityCheck();
583} 555}
@@ -696,7 +668,7 @@ class ASTClearer {
696public: 668public:
697 ASTClearer() = default; 669 ASTClearer() = default;
698 670
699 void operator()(ASTProgram& ast) { 671 void operator()(const ASTProgram& ast) {
700 ASTNode current = ast.nodes.GetFirst(); 672 ASTNode current = ast.nodes.GetFirst();
701 while (current) { 673 while (current) {
702 Visit(current); 674 Visit(current);
@@ -704,7 +676,7 @@ public:
704 } 676 }
705 } 677 }
706 678
707 void operator()(ASTIfThen& ast) { 679 void operator()(const ASTIfThen& ast) {
708 ASTNode current = ast.nodes.GetFirst(); 680 ASTNode current = ast.nodes.GetFirst();
709 while (current) { 681 while (current) {
710 Visit(current); 682 Visit(current);
@@ -712,7 +684,7 @@ public:
712 } 684 }
713 } 685 }
714 686
715 void operator()(ASTIfElse& ast) { 687 void operator()(const ASTIfElse& ast) {
716 ASTNode current = ast.nodes.GetFirst(); 688 ASTNode current = ast.nodes.GetFirst();
717 while (current) { 689 while (current) {
718 Visit(current); 690 Visit(current);
@@ -720,19 +692,19 @@ public:
720 } 692 }
721 } 693 }
722 694
723 void operator()(ASTBlockEncoded& ast) {} 695 void operator()([[maybe_unused]] const ASTBlockEncoded& ast) {}
724 696
725 void operator()(ASTBlockDecoded& ast) { 697 void operator()(ASTBlockDecoded& ast) {
726 ast.nodes.clear(); 698 ast.nodes.clear();
727 } 699 }
728 700
729 void operator()(ASTVarSet& ast) {} 701 void operator()([[maybe_unused]] const ASTVarSet& ast) {}
730 702
731 void operator()(ASTLabel& ast) {} 703 void operator()([[maybe_unused]] const ASTLabel& ast) {}
732 704
733 void operator()(ASTGoto& ast) {} 705 void operator()([[maybe_unused]] const ASTGoto& ast) {}
734 706
735 void operator()(ASTDoWhile& ast) { 707 void operator()(const ASTDoWhile& ast) {
736 ASTNode current = ast.nodes.GetFirst(); 708 ASTNode current = ast.nodes.GetFirst();
737 while (current) { 709 while (current) {
738 Visit(current); 710 Visit(current);
@@ -740,11 +712,11 @@ public:
740 } 712 }
741 } 713 }
742 714
743 void operator()(ASTReturn& ast) {} 715 void operator()([[maybe_unused]] const ASTReturn& ast) {}
744 716
745 void operator()(ASTBreak& ast) {} 717 void operator()([[maybe_unused]] const ASTBreak& ast) {}
746 718
747 void Visit(ASTNode& node) { 719 void Visit(const ASTNode& node) {
748 std::visit(*this, *node->GetInnerData()); 720 std::visit(*this, *node->GetInnerData());
749 node->Clear(); 721 node->Clear();
750 } 722 }
diff --git a/src/video_core/shader/ast.h b/src/video_core/shader/ast.h
index ba234138e..d7bf11821 100644
--- a/src/video_core/shader/ast.h
+++ b/src/video_core/shader/ast.h
@@ -18,17 +18,17 @@
18namespace VideoCommon::Shader { 18namespace VideoCommon::Shader {
19 19
20class ASTBase; 20class ASTBase;
21class ASTProgram;
22class ASTIfThen;
23class ASTIfElse;
24class ASTBlockEncoded;
25class ASTBlockDecoded; 21class ASTBlockDecoded;
26class ASTVarSet; 22class ASTBlockEncoded;
23class ASTBreak;
24class ASTDoWhile;
27class ASTGoto; 25class ASTGoto;
26class ASTIfElse;
27class ASTIfThen;
28class ASTLabel; 28class ASTLabel;
29class ASTDoWhile; 29class ASTProgram;
30class ASTReturn; 30class ASTReturn;
31class ASTBreak; 31class ASTVarSet;
32 32
33using ASTData = std::variant<ASTProgram, ASTIfThen, ASTIfElse, ASTBlockEncoded, ASTBlockDecoded, 33using ASTData = std::variant<ASTProgram, ASTIfThen, ASTIfElse, ASTBlockEncoded, ASTBlockDecoded,
34 ASTVarSet, ASTGoto, ASTLabel, ASTDoWhile, ASTReturn, ASTBreak>; 34 ASTVarSet, ASTGoto, ASTLabel, ASTDoWhile, ASTReturn, ASTBreak>;
@@ -48,11 +48,11 @@ public:
48 48
49 void Init(ASTNode first, ASTNode parent); 49 void Init(ASTNode first, ASTNode parent);
50 50
51 ASTNode GetFirst() { 51 ASTNode GetFirst() const {
52 return first; 52 return first;
53 } 53 }
54 54
55 ASTNode GetLast() { 55 ASTNode GetLast() const {
56 return last; 56 return last;
57 } 57 }
58 58
@@ -71,20 +71,18 @@ public:
71 71
72class ASTProgram { 72class ASTProgram {
73public: 73public:
74 explicit ASTProgram() = default;
75 ASTZipper nodes{}; 74 ASTZipper nodes{};
76}; 75};
77 76
78class ASTIfThen { 77class ASTIfThen {
79public: 78public:
80 explicit ASTIfThen(Expr condition) : condition(condition) {} 79 explicit ASTIfThen(Expr condition) : condition{std::move(condition)} {}
81 Expr condition; 80 Expr condition;
82 ASTZipper nodes{}; 81 ASTZipper nodes{};
83}; 82};
84 83
85class ASTIfElse { 84class ASTIfElse {
86public: 85public:
87 explicit ASTIfElse() = default;
88 ASTZipper nodes{}; 86 ASTZipper nodes{};
89}; 87};
90 88
@@ -103,7 +101,7 @@ public:
103 101
104class ASTVarSet { 102class ASTVarSet {
105public: 103public:
106 explicit ASTVarSet(u32 index, Expr condition) : index{index}, condition{condition} {} 104 explicit ASTVarSet(u32 index, Expr condition) : index{index}, condition{std::move(condition)} {}
107 u32 index; 105 u32 index;
108 Expr condition; 106 Expr condition;
109}; 107};
@@ -117,42 +115,45 @@ public:
117 115
118class ASTGoto { 116class ASTGoto {
119public: 117public:
120 explicit ASTGoto(Expr condition, u32 label) : condition{condition}, label{label} {} 118 explicit ASTGoto(Expr condition, u32 label) : condition{std::move(condition)}, label{label} {}
121 Expr condition; 119 Expr condition;
122 u32 label; 120 u32 label;
123}; 121};
124 122
125class ASTDoWhile { 123class ASTDoWhile {
126public: 124public:
127 explicit ASTDoWhile(Expr condition) : condition(condition) {} 125 explicit ASTDoWhile(Expr condition) : condition{std::move(condition)} {}
128 Expr condition; 126 Expr condition;
129 ASTZipper nodes{}; 127 ASTZipper nodes{};
130}; 128};
131 129
132class ASTReturn { 130class ASTReturn {
133public: 131public:
134 explicit ASTReturn(Expr condition, bool kills) : condition{condition}, kills{kills} {} 132 explicit ASTReturn(Expr condition, bool kills)
133 : condition{std::move(condition)}, kills{kills} {}
135 Expr condition; 134 Expr condition;
136 bool kills; 135 bool kills;
137}; 136};
138 137
139class ASTBreak { 138class ASTBreak {
140public: 139public:
141 explicit ASTBreak(Expr condition) : condition{condition} {} 140 explicit ASTBreak(Expr condition) : condition{std::move(condition)} {}
142 Expr condition; 141 Expr condition;
143}; 142};
144 143
145class ASTBase { 144class ASTBase {
146public: 145public:
147 explicit ASTBase(ASTNode parent, ASTData data) : parent{parent}, data{data} {} 146 explicit ASTBase(ASTNode parent, ASTData data)
147 : data{std::move(data)}, parent{std::move(parent)} {}
148 148
149 template <class U, class... Args> 149 template <class U, class... Args>
150 static ASTNode Make(ASTNode parent, Args&&... args) { 150 static ASTNode Make(ASTNode parent, Args&&... args) {
151 return std::make_shared<ASTBase>(parent, ASTData(U(std::forward<Args>(args)...))); 151 return std::make_shared<ASTBase>(std::move(parent),
152 ASTData(U(std::forward<Args>(args)...)));
152 } 153 }
153 154
154 void SetParent(ASTNode new_parent) { 155 void SetParent(ASTNode new_parent) {
155 parent = new_parent; 156 parent = std::move(new_parent);
156 } 157 }
157 158
158 ASTNode& GetParent() { 159 ASTNode& GetParent() {
@@ -177,6 +178,10 @@ public:
177 return &data; 178 return &data;
178 } 179 }
179 180
181 const ASTData* GetInnerData() const {
182 return &data;
183 }
184
180 ASTNode GetNext() const { 185 ASTNode GetNext() const {
181 return next; 186 return next;
182 } 187 }
@@ -189,6 +194,10 @@ public:
189 return *manager; 194 return *manager;
190 } 195 }
191 196
197 const ASTZipper& GetManager() const {
198 return *manager;
199 }
200
192 std::optional<u32> GetGotoLabel() const { 201 std::optional<u32> GetGotoLabel() const {
193 auto inner = std::get_if<ASTGoto>(&data); 202 auto inner = std::get_if<ASTGoto>(&data);
194 if (inner) { 203 if (inner) {
@@ -239,7 +248,7 @@ public:
239 void SetGotoCondition(Expr new_condition) { 248 void SetGotoCondition(Expr new_condition) {
240 auto inner = std::get_if<ASTGoto>(&data); 249 auto inner = std::get_if<ASTGoto>(&data);
241 if (inner) { 250 if (inner) {
242 inner->condition = new_condition; 251 inner->condition = std::move(new_condition);
243 } 252 }
244 } 253 }
245 254
@@ -304,8 +313,8 @@ public:
304 ASTManager(const ASTManager& o) = delete; 313 ASTManager(const ASTManager& o) = delete;
305 ASTManager& operator=(const ASTManager& other) = delete; 314 ASTManager& operator=(const ASTManager& other) = delete;
306 315
307 ASTManager(ASTManager&& other) noexcept; 316 ASTManager(ASTManager&& other) noexcept = default;
308 ASTManager& operator=(ASTManager&& other) noexcept; 317 ASTManager& operator=(ASTManager&& other) noexcept = default;
309 318
310 void Init(); 319 void Init();
311 320
@@ -323,7 +332,7 @@ public:
323 332
324 void Decompile(); 333 void Decompile();
325 334
326 void ShowCurrentState(std::string state); 335 void ShowCurrentState(std::string_view state);
327 336
328 void SanityCheck(); 337 void SanityCheck();
329 338
@@ -331,20 +340,20 @@ public:
331 340
332 bool IsFullyDecompiled() const { 341 bool IsFullyDecompiled() const {
333 if (full_decompile) { 342 if (full_decompile) {
334 return gotos.size() == 0; 343 return gotos.empty();
335 } else { 344 }
336 for (ASTNode goto_node : gotos) { 345
337 auto label_index = goto_node->GetGotoLabel(); 346 for (ASTNode goto_node : gotos) {
338 if (!label_index) { 347 auto label_index = goto_node->GetGotoLabel();
339 return false; 348 if (!label_index) {
340 } 349 return false;
341 ASTNode glabel = labels[*label_index]; 350 }
342 if (IsBackwardsJump(goto_node, glabel)) { 351 ASTNode glabel = labels[*label_index];
343 return false; 352 if (IsBackwardsJump(goto_node, glabel)) {
344 } 353 return false;
345 } 354 }
346 return true;
347 } 355 }
356 return true;
348 } 357 }
349 358
350 ASTNode GetProgram() const { 359 ASTNode GetProgram() const {
@@ -362,9 +371,9 @@ public:
362private: 371private:
363 bool IsBackwardsJump(ASTNode goto_node, ASTNode label_node) const; 372 bool IsBackwardsJump(ASTNode goto_node, ASTNode label_node) const;
364 373
365 bool IndirectlyRelated(ASTNode first, ASTNode second); 374 bool IndirectlyRelated(const ASTNode& first, const ASTNode& second) const;
366 375
367 bool DirectlyRelated(ASTNode first, ASTNode second); 376 bool DirectlyRelated(const ASTNode& first, const ASTNode& second) const;
368 377
369 void EncloseDoWhile(ASTNode goto_node, ASTNode label); 378 void EncloseDoWhile(ASTNode goto_node, ASTNode label);
370 379
diff --git a/src/video_core/shader/control_flow.cpp b/src/video_core/shader/control_flow.cpp
index 3c3a41ba6..268d1aed0 100644
--- a/src/video_core/shader/control_flow.cpp
+++ b/src/video_core/shader/control_flow.cpp
@@ -479,7 +479,7 @@ std::unique_ptr<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code,
479 auto result_out = std::make_unique<ShaderCharacteristics>(); 479 auto result_out = std::make_unique<ShaderCharacteristics>();
480 if (settings.depth == CompileDepth::BruteForce) { 480 if (settings.depth == CompileDepth::BruteForce) {
481 result_out->settings.depth = CompileDepth::BruteForce; 481 result_out->settings.depth = CompileDepth::BruteForce;
482 return std::move(result_out); 482 return result_out;
483 } 483 }
484 484
485 CFGRebuildState state{program_code, program_size, start_address}; 485 CFGRebuildState state{program_code, program_size, start_address};
@@ -490,7 +490,7 @@ std::unique_ptr<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code,
490 while (!state.inspect_queries.empty()) { 490 while (!state.inspect_queries.empty()) {
491 if (!TryInspectAddress(state)) { 491 if (!TryInspectAddress(state)) {
492 result_out->settings.depth = CompileDepth::BruteForce; 492 result_out->settings.depth = CompileDepth::BruteForce;
493 return std::move(result_out); 493 return result_out;
494 } 494 }
495 } 495 }
496 496
@@ -530,14 +530,15 @@ std::unique_ptr<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code,
530 state.manager->ShowCurrentState("Of Shader"); 530 state.manager->ShowCurrentState("Of Shader");
531 state.manager->Clear(); 531 state.manager->Clear();
532 } else { 532 } else {
533 auto result_out = std::make_unique<ShaderCharacteristics>(); 533 auto characteristics = std::make_unique<ShaderCharacteristics>();
534 result_out->start = start_address; 534 characteristics->start = start_address;
535 result_out->settings.depth = settings.depth; 535 characteristics->settings.depth = settings.depth;
536 result_out->manager = std::move(manager); 536 characteristics->manager = std::move(manager);
537 result_out->end = state.block_info.back().end + 1; 537 characteristics->end = state.block_info.back().end + 1;
538 return std::move(result_out); 538 return characteristics;
539 } 539 }
540 } 540 }
541
541 result_out->start = start_address; 542 result_out->start = start_address;
542 result_out->settings.depth = 543 result_out->settings.depth =
543 use_flow_stack ? CompileDepth::FlowStack : CompileDepth::NoFlowStack; 544 use_flow_stack ? CompileDepth::FlowStack : CompileDepth::NoFlowStack;
@@ -557,8 +558,9 @@ std::unique_ptr<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code,
557 } 558 }
558 if (!use_flow_stack) { 559 if (!use_flow_stack) {
559 result_out->labels = std::move(state.labels); 560 result_out->labels = std::move(state.labels);
560 return std::move(result_out); 561 return result_out;
561 } 562 }
563
562 auto back = result_out->blocks.begin(); 564 auto back = result_out->blocks.begin();
563 auto next = std::next(back); 565 auto next = std::next(back);
564 while (next != result_out->blocks.end()) { 566 while (next != result_out->blocks.end()) {
@@ -570,6 +572,7 @@ std::unique_ptr<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code,
570 back = next; 572 back = next;
571 ++next; 573 ++next;
572 } 574 }
573 return std::move(result_out); 575
576 return result_out;
574} 577}
575} // namespace VideoCommon::Shader 578} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/expr.cpp b/src/video_core/shader/expr.cpp
index ca633ffb1..2647865d4 100644
--- a/src/video_core/shader/expr.cpp
+++ b/src/video_core/shader/expr.cpp
@@ -2,40 +2,51 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma once
6
7#include <memory> 5#include <memory>
8#include <variant> 6#include <variant>
9 7
10#include "video_core/shader/expr.h" 8#include "video_core/shader/expr.h"
11 9
12namespace VideoCommon::Shader { 10namespace VideoCommon::Shader {
11namespace {
12bool ExprIsBoolean(const Expr& expr) {
13 return std::holds_alternative<ExprBoolean>(*expr);
14}
15
16bool ExprBooleanGet(const Expr& expr) {
17 return std::get_if<ExprBoolean>(expr.get())->value;
18}
19} // Anonymous namespace
13 20
14bool ExprAnd::operator==(const ExprAnd& b) const { 21bool ExprAnd::operator==(const ExprAnd& b) const {
15 return (*operand1 == *b.operand1) && (*operand2 == *b.operand2); 22 return (*operand1 == *b.operand1) && (*operand2 == *b.operand2);
16} 23}
17 24
25bool ExprAnd::operator!=(const ExprAnd& b) const {
26 return !operator==(b);
27}
28
18bool ExprOr::operator==(const ExprOr& b) const { 29bool ExprOr::operator==(const ExprOr& b) const {
19 return (*operand1 == *b.operand1) && (*operand2 == *b.operand2); 30 return (*operand1 == *b.operand1) && (*operand2 == *b.operand2);
20} 31}
21 32
22bool ExprNot::operator==(const ExprNot& b) const { 33bool ExprOr::operator!=(const ExprOr& b) const {
23 return (*operand1 == *b.operand1); 34 return !operator==(b);
24} 35}
25 36
26bool ExprIsBoolean(Expr expr) { 37bool ExprNot::operator==(const ExprNot& b) const {
27 return std::holds_alternative<ExprBoolean>(*expr); 38 return *operand1 == *b.operand1;
28} 39}
29 40
30bool ExprBooleanGet(Expr expr) { 41bool ExprNot::operator!=(const ExprNot& b) const {
31 return std::get_if<ExprBoolean>(expr.get())->value; 42 return !operator==(b);
32} 43}
33 44
34Expr MakeExprNot(Expr first) { 45Expr MakeExprNot(Expr first) {
35 if (std::holds_alternative<ExprNot>(*first)) { 46 if (std::holds_alternative<ExprNot>(*first)) {
36 return std::get_if<ExprNot>(first.get())->operand1; 47 return std::get_if<ExprNot>(first.get())->operand1;
37 } 48 }
38 return MakeExpr<ExprNot>(first); 49 return MakeExpr<ExprNot>(std::move(first));
39} 50}
40 51
41Expr MakeExprAnd(Expr first, Expr second) { 52Expr MakeExprAnd(Expr first, Expr second) {
@@ -45,7 +56,7 @@ Expr MakeExprAnd(Expr first, Expr second) {
45 if (ExprIsBoolean(second)) { 56 if (ExprIsBoolean(second)) {
46 return ExprBooleanGet(second) ? first : second; 57 return ExprBooleanGet(second) ? first : second;
47 } 58 }
48 return MakeExpr<ExprAnd>(first, second); 59 return MakeExpr<ExprAnd>(std::move(first), std::move(second));
49} 60}
50 61
51Expr MakeExprOr(Expr first, Expr second) { 62Expr MakeExprOr(Expr first, Expr second) {
@@ -55,14 +66,14 @@ Expr MakeExprOr(Expr first, Expr second) {
55 if (ExprIsBoolean(second)) { 66 if (ExprIsBoolean(second)) {
56 return ExprBooleanGet(second) ? second : first; 67 return ExprBooleanGet(second) ? second : first;
57 } 68 }
58 return MakeExpr<ExprOr>(first, second); 69 return MakeExpr<ExprOr>(std::move(first), std::move(second));
59} 70}
60 71
61bool ExprAreEqual(Expr first, Expr second) { 72bool ExprAreEqual(const Expr& first, const Expr& second) {
62 return (*first) == (*second); 73 return (*first) == (*second);
63} 74}
64 75
65bool ExprAreOpposite(Expr first, Expr second) { 76bool ExprAreOpposite(const Expr& first, const Expr& second) {
66 if (std::holds_alternative<ExprNot>(*first)) { 77 if (std::holds_alternative<ExprNot>(*first)) {
67 return ExprAreEqual(std::get_if<ExprNot>(first.get())->operand1, second); 78 return ExprAreEqual(std::get_if<ExprNot>(first.get())->operand1, second);
68 } 79 }
@@ -72,7 +83,7 @@ bool ExprAreOpposite(Expr first, Expr second) {
72 return false; 83 return false;
73} 84}
74 85
75bool ExprIsTrue(Expr first) { 86bool ExprIsTrue(const Expr& first) {
76 if (ExprIsBoolean(first)) { 87 if (ExprIsBoolean(first)) {
77 return ExprBooleanGet(first); 88 return ExprBooleanGet(first);
78 } 89 }
diff --git a/src/video_core/shader/expr.h b/src/video_core/shader/expr.h
index 4c399cef9..d3dcd00ec 100644
--- a/src/video_core/shader/expr.h
+++ b/src/video_core/shader/expr.h
@@ -15,12 +15,12 @@ using Tegra::Shader::ConditionCode;
15using Tegra::Shader::Pred; 15using Tegra::Shader::Pred;
16 16
17class ExprAnd; 17class ExprAnd;
18class ExprOr; 18class ExprBoolean;
19class ExprCondCode;
19class ExprNot; 20class ExprNot;
21class ExprOr;
20class ExprPredicate; 22class ExprPredicate;
21class ExprCondCode;
22class ExprVar; 23class ExprVar;
23class ExprBoolean;
24 24
25using ExprData = 25using ExprData =
26 std::variant<ExprVar, ExprCondCode, ExprPredicate, ExprNot, ExprOr, ExprAnd, ExprBoolean>; 26 std::variant<ExprVar, ExprCondCode, ExprPredicate, ExprNot, ExprOr, ExprAnd, ExprBoolean>;
@@ -28,9 +28,10 @@ using Expr = std::shared_ptr<ExprData>;
28 28
29class ExprAnd final { 29class ExprAnd final {
30public: 30public:
31 explicit ExprAnd(Expr a, Expr b) : operand1{a}, operand2{b} {} 31 explicit ExprAnd(Expr a, Expr b) : operand1{std::move(a)}, operand2{std::move(b)} {}
32 32
33 bool operator==(const ExprAnd& b) const; 33 bool operator==(const ExprAnd& b) const;
34 bool operator!=(const ExprAnd& b) const;
34 35
35 Expr operand1; 36 Expr operand1;
36 Expr operand2; 37 Expr operand2;
@@ -38,9 +39,10 @@ public:
38 39
39class ExprOr final { 40class ExprOr final {
40public: 41public:
41 explicit ExprOr(Expr a, Expr b) : operand1{a}, operand2{b} {} 42 explicit ExprOr(Expr a, Expr b) : operand1{std::move(a)}, operand2{std::move(b)} {}
42 43
43 bool operator==(const ExprOr& b) const; 44 bool operator==(const ExprOr& b) const;
45 bool operator!=(const ExprOr& b) const;
44 46
45 Expr operand1; 47 Expr operand1;
46 Expr operand2; 48 Expr operand2;
@@ -48,9 +50,10 @@ public:
48 50
49class ExprNot final { 51class ExprNot final {
50public: 52public:
51 explicit ExprNot(Expr a) : operand1{a} {} 53 explicit ExprNot(Expr a) : operand1{std::move(a)} {}
52 54
53 bool operator==(const ExprNot& b) const; 55 bool operator==(const ExprNot& b) const;
56 bool operator!=(const ExprNot& b) const;
54 57
55 Expr operand1; 58 Expr operand1;
56}; 59};
@@ -63,6 +66,10 @@ public:
63 return var_index == b.var_index; 66 return var_index == b.var_index;
64 } 67 }
65 68
69 bool operator!=(const ExprVar& b) const {
70 return !operator==(b);
71 }
72
66 u32 var_index; 73 u32 var_index;
67}; 74};
68 75
@@ -74,6 +81,10 @@ public:
74 return predicate == b.predicate; 81 return predicate == b.predicate;
75 } 82 }
76 83
84 bool operator!=(const ExprPredicate& b) const {
85 return !operator==(b);
86 }
87
77 u32 predicate; 88 u32 predicate;
78}; 89};
79 90
@@ -85,6 +96,10 @@ public:
85 return cc == b.cc; 96 return cc == b.cc;
86 } 97 }
87 98
99 bool operator!=(const ExprCondCode& b) const {
100 return !operator==(b);
101 }
102
88 ConditionCode cc; 103 ConditionCode cc;
89}; 104};
90 105
@@ -96,6 +111,10 @@ public:
96 return value == b.value; 111 return value == b.value;
97 } 112 }
98 113
114 bool operator!=(const ExprBoolean& b) const {
115 return !operator==(b);
116 }
117
99 bool value; 118 bool value;
100}; 119};
101 120
@@ -105,9 +124,9 @@ Expr MakeExpr(Args&&... args) {
105 return std::make_shared<ExprData>(T(std::forward<Args>(args)...)); 124 return std::make_shared<ExprData>(T(std::forward<Args>(args)...));
106} 125}
107 126
108bool ExprAreEqual(Expr first, Expr second); 127bool ExprAreEqual(const Expr& first, const Expr& second);
109 128
110bool ExprAreOpposite(Expr first, Expr second); 129bool ExprAreOpposite(const Expr& first, const Expr& second);
111 130
112Expr MakeExprNot(Expr first); 131Expr MakeExprNot(Expr first);
113 132
@@ -115,6 +134,6 @@ Expr MakeExprAnd(Expr first, Expr second);
115 134
116Expr MakeExprOr(Expr first, Expr second); 135Expr MakeExprOr(Expr first, Expr second);
117 136
118bool ExprIsTrue(Expr first); 137bool ExprIsTrue(const Expr& first);
119 138
120} // namespace VideoCommon::Shader 139} // namespace VideoCommon::Shader