diff options
| author | 2019-10-05 12:02:51 -0400 | |
|---|---|---|
| committer | 2019-10-05 12:02:51 -0400 | |
| commit | 47ccfabe18db3691a09f211fc4aec465ee186c2a (patch) | |
| tree | 8bd02e8d5e16dee8522e29d21c711ef98282bb52 /src | |
| parent | Merge pull request #2888 from FernandoS27/decompiler2 (diff) | |
| parent | video_core/control_flow: Eliminate variable shadowing warnings (diff) | |
| download | yuzu-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.cpp | 122 | ||||
| -rw-r--r-- | src/video_core/shader/ast.h | 85 | ||||
| -rw-r--r-- | src/video_core/shader/control_flow.cpp | 23 | ||||
| -rw-r--r-- | src/video_core/shader/expr.cpp | 39 | ||||
| -rw-r--r-- | src/video_core/shader/expr.h | 37 |
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 | ||
| 95 | void ASTZipper::DetachTail(const ASTNode node) { | 96 | void 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 | ||
| 186 | class ExprPrinter final { | 188 | class ExprPrinter final { |
| 187 | public: | 189 | public: |
| 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 | ||
| 235 | class ASTPrinter { | 235 | class ASTPrinter { |
| 236 | public: | 236 | public: |
| 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 | ||
| 358 | std::string ASTPrinter::tabs = " "; | ||
| 359 | |||
| 360 | std::string ASTManager::Print() { | 356 | std::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 | ||
| 379 | ASTManager::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 | |||
| 387 | ASTManager& 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 | |||
| 403 | void ASTManager::DeclareLabel(u32 address) { | 375 | void 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 | ||
| 418 | void ASTManager::InsertGoto(Expr condition, u32 address) { | 390 | void 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 | ||
| 425 | void ASTManager::InsertBlock(u32 start_address, u32 end_address) { | 397 | void 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 | ||
| 430 | void ASTManager::InsertReturn(Expr condition, bool kills) { | 402 | void 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 | ||
| 546 | bool ASTManager::IndirectlyRelated(ASTNode first, ASTNode second) { | 518 | bool 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 | ||
| 550 | bool ASTManager::DirectlyRelated(ASTNode first, ASTNode second) { | 522 | bool 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 | ||
| 580 | void ASTManager::ShowCurrentState(std::string state) { | 552 | void 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 { | |||
| 696 | public: | 668 | public: |
| 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 @@ | |||
| 18 | namespace VideoCommon::Shader { | 18 | namespace VideoCommon::Shader { |
| 19 | 19 | ||
| 20 | class ASTBase; | 20 | class ASTBase; |
| 21 | class ASTProgram; | ||
| 22 | class ASTIfThen; | ||
| 23 | class ASTIfElse; | ||
| 24 | class ASTBlockEncoded; | ||
| 25 | class ASTBlockDecoded; | 21 | class ASTBlockDecoded; |
| 26 | class ASTVarSet; | 22 | class ASTBlockEncoded; |
| 23 | class ASTBreak; | ||
| 24 | class ASTDoWhile; | ||
| 27 | class ASTGoto; | 25 | class ASTGoto; |
| 26 | class ASTIfElse; | ||
| 27 | class ASTIfThen; | ||
| 28 | class ASTLabel; | 28 | class ASTLabel; |
| 29 | class ASTDoWhile; | 29 | class ASTProgram; |
| 30 | class ASTReturn; | 30 | class ASTReturn; |
| 31 | class ASTBreak; | 31 | class ASTVarSet; |
| 32 | 32 | ||
| 33 | using ASTData = std::variant<ASTProgram, ASTIfThen, ASTIfElse, ASTBlockEncoded, ASTBlockDecoded, | 33 | using 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 | ||
| 72 | class ASTProgram { | 72 | class ASTProgram { |
| 73 | public: | 73 | public: |
| 74 | explicit ASTProgram() = default; | ||
| 75 | ASTZipper nodes{}; | 74 | ASTZipper nodes{}; |
| 76 | }; | 75 | }; |
| 77 | 76 | ||
| 78 | class ASTIfThen { | 77 | class ASTIfThen { |
| 79 | public: | 78 | public: |
| 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 | ||
| 85 | class ASTIfElse { | 84 | class ASTIfElse { |
| 86 | public: | 85 | public: |
| 87 | explicit ASTIfElse() = default; | ||
| 88 | ASTZipper nodes{}; | 86 | ASTZipper nodes{}; |
| 89 | }; | 87 | }; |
| 90 | 88 | ||
| @@ -103,7 +101,7 @@ public: | |||
| 103 | 101 | ||
| 104 | class ASTVarSet { | 102 | class ASTVarSet { |
| 105 | public: | 103 | public: |
| 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 | ||
| 118 | class ASTGoto { | 116 | class ASTGoto { |
| 119 | public: | 117 | public: |
| 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 | ||
| 125 | class ASTDoWhile { | 123 | class ASTDoWhile { |
| 126 | public: | 124 | public: |
| 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 | ||
| 132 | class ASTReturn { | 130 | class ASTReturn { |
| 133 | public: | 131 | public: |
| 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 | ||
| 139 | class ASTBreak { | 138 | class ASTBreak { |
| 140 | public: | 139 | public: |
| 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 | ||
| 145 | class ASTBase { | 144 | class ASTBase { |
| 146 | public: | 145 | public: |
| 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: | |||
| 362 | private: | 371 | private: |
| 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 | ||
| 12 | namespace VideoCommon::Shader { | 10 | namespace VideoCommon::Shader { |
| 11 | namespace { | ||
| 12 | bool ExprIsBoolean(const Expr& expr) { | ||
| 13 | return std::holds_alternative<ExprBoolean>(*expr); | ||
| 14 | } | ||
| 15 | |||
| 16 | bool ExprBooleanGet(const Expr& expr) { | ||
| 17 | return std::get_if<ExprBoolean>(expr.get())->value; | ||
| 18 | } | ||
| 19 | } // Anonymous namespace | ||
| 13 | 20 | ||
| 14 | bool ExprAnd::operator==(const ExprAnd& b) const { | 21 | bool 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 | ||
| 25 | bool ExprAnd::operator!=(const ExprAnd& b) const { | ||
| 26 | return !operator==(b); | ||
| 27 | } | ||
| 28 | |||
| 18 | bool ExprOr::operator==(const ExprOr& b) const { | 29 | bool 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 | ||
| 22 | bool ExprNot::operator==(const ExprNot& b) const { | 33 | bool ExprOr::operator!=(const ExprOr& b) const { |
| 23 | return (*operand1 == *b.operand1); | 34 | return !operator==(b); |
| 24 | } | 35 | } |
| 25 | 36 | ||
| 26 | bool ExprIsBoolean(Expr expr) { | 37 | bool ExprNot::operator==(const ExprNot& b) const { |
| 27 | return std::holds_alternative<ExprBoolean>(*expr); | 38 | return *operand1 == *b.operand1; |
| 28 | } | 39 | } |
| 29 | 40 | ||
| 30 | bool ExprBooleanGet(Expr expr) { | 41 | bool ExprNot::operator!=(const ExprNot& b) const { |
| 31 | return std::get_if<ExprBoolean>(expr.get())->value; | 42 | return !operator==(b); |
| 32 | } | 43 | } |
| 33 | 44 | ||
| 34 | Expr MakeExprNot(Expr first) { | 45 | Expr 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 | ||
| 41 | Expr MakeExprAnd(Expr first, Expr second) { | 52 | Expr 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 | ||
| 51 | Expr MakeExprOr(Expr first, Expr second) { | 62 | Expr 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 | ||
| 61 | bool ExprAreEqual(Expr first, Expr second) { | 72 | bool ExprAreEqual(const Expr& first, const Expr& second) { |
| 62 | return (*first) == (*second); | 73 | return (*first) == (*second); |
| 63 | } | 74 | } |
| 64 | 75 | ||
| 65 | bool ExprAreOpposite(Expr first, Expr second) { | 76 | bool 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 | ||
| 75 | bool ExprIsTrue(Expr first) { | 86 | bool 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; | |||
| 15 | using Tegra::Shader::Pred; | 15 | using Tegra::Shader::Pred; |
| 16 | 16 | ||
| 17 | class ExprAnd; | 17 | class ExprAnd; |
| 18 | class ExprOr; | 18 | class ExprBoolean; |
| 19 | class ExprCondCode; | ||
| 19 | class ExprNot; | 20 | class ExprNot; |
| 21 | class ExprOr; | ||
| 20 | class ExprPredicate; | 22 | class ExprPredicate; |
| 21 | class ExprCondCode; | ||
| 22 | class ExprVar; | 23 | class ExprVar; |
| 23 | class ExprBoolean; | ||
| 24 | 24 | ||
| 25 | using ExprData = | 25 | using 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 | ||
| 29 | class ExprAnd final { | 29 | class ExprAnd final { |
| 30 | public: | 30 | public: |
| 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 | ||
| 39 | class ExprOr final { | 40 | class ExprOr final { |
| 40 | public: | 41 | public: |
| 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 | ||
| 49 | class ExprNot final { | 51 | class ExprNot final { |
| 50 | public: | 52 | public: |
| 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 | ||
| 108 | bool ExprAreEqual(Expr first, Expr second); | 127 | bool ExprAreEqual(const Expr& first, const Expr& second); |
| 109 | 128 | ||
| 110 | bool ExprAreOpposite(Expr first, Expr second); | 129 | bool ExprAreOpposite(const Expr& first, const Expr& second); |
| 111 | 130 | ||
| 112 | Expr MakeExprNot(Expr first); | 131 | Expr MakeExprNot(Expr first); |
| 113 | 132 | ||
| @@ -115,6 +134,6 @@ Expr MakeExprAnd(Expr first, Expr second); | |||
| 115 | 134 | ||
| 116 | Expr MakeExprOr(Expr first, Expr second); | 135 | Expr MakeExprOr(Expr first, Expr second); |
| 117 | 136 | ||
| 118 | bool ExprIsTrue(Expr first); | 137 | bool ExprIsTrue(const Expr& first); |
| 119 | 138 | ||
| 120 | } // namespace VideoCommon::Shader | 139 | } // namespace VideoCommon::Shader |