Эх сурвалжийг харах

Merge pull request #2944 from lioncash/ast

video_core/shader: Minor changes
Fernando Sahmkow 6 жил өмнө
parent
commit
47ccfabe18

+ 47 - 75
src/video_core/shader/ast.cpp

@@ -17,6 +17,7 @@ void ASTZipper::Init(const ASTNode new_first, const ASTNode parent) {
     ASSERT(new_first->manager == nullptr);
     first = new_first;
     last = new_first;
+
     ASTNode current = first;
     while (current) {
         current->manager = this;
@@ -92,7 +93,7 @@ void ASTZipper::InsertBefore(const ASTNode new_node, const ASTNode at_node) {
     new_node->manager = this;
 }
 
-void ASTZipper::DetachTail(const ASTNode node) {
+void ASTZipper::DetachTail(ASTNode node) {
     ASSERT(node->manager == this);
     if (node == first) {
         first.reset();
@@ -103,7 +104,8 @@ void ASTZipper::DetachTail(const ASTNode node) {
     last = node->previous;
     last->next.reset();
     node->previous.reset();
-    ASTNode current = node;
+
+    ASTNode current = std::move(node);
     while (current) {
         current->manager = nullptr;
         current->parent.reset();
@@ -185,9 +187,7 @@ void ASTZipper::Remove(const ASTNode node) {
 
 class ExprPrinter final {
 public:
-    ExprPrinter() = default;
-
-    void operator()(ExprAnd const& expr) {
+    void operator()(const ExprAnd& expr) {
         inner += "( ";
         std::visit(*this, *expr.operand1);
         inner += " && ";
@@ -195,7 +195,7 @@ public:
         inner += ')';
     }
 
-    void operator()(ExprOr const& expr) {
+    void operator()(const ExprOr& expr) {
         inner += "( ";
         std::visit(*this, *expr.operand1);
         inner += " || ";
@@ -203,29 +203,29 @@ public:
         inner += ')';
     }
 
-    void operator()(ExprNot const& expr) {
+    void operator()(const ExprNot& expr) {
         inner += "!";
         std::visit(*this, *expr.operand1);
     }
 
-    void operator()(ExprPredicate const& expr) {
+    void operator()(const ExprPredicate& expr) {
         inner += "P" + std::to_string(expr.predicate);
     }
 
-    void operator()(ExprCondCode const& expr) {
+    void operator()(const ExprCondCode& expr) {
         u32 cc = static_cast<u32>(expr.cc);
         inner += "CC" + std::to_string(cc);
     }
 
-    void operator()(ExprVar const& expr) {
+    void operator()(const ExprVar& expr) {
         inner += "V" + std::to_string(expr.var_index);
     }
 
-    void operator()(ExprBoolean const& expr) {
+    void operator()(const ExprBoolean& expr) {
         inner += expr.value ? "true" : "false";
     }
 
-    std::string& GetResult() {
+    const std::string& GetResult() const {
         return inner;
     }
 
@@ -234,9 +234,7 @@ public:
 
 class ASTPrinter {
 public:
-    ASTPrinter() = default;
-
-    void operator()(ASTProgram& ast) {
+    void operator()(const ASTProgram& ast) {
         scope++;
         inner += "program {\n";
         ASTNode current = ast.nodes.GetFirst();
@@ -248,7 +246,7 @@ public:
         scope--;
     }
 
-    void operator()(ASTIfThen& ast) {
+    void operator()(const ASTIfThen& ast) {
         ExprPrinter expr_parser{};
         std::visit(expr_parser, *ast.condition);
         inner += Ident() + "if (" + expr_parser.GetResult() + ") {\n";
@@ -262,7 +260,7 @@ public:
         inner += Ident() + "}\n";
     }
 
-    void operator()(ASTIfElse& ast) {
+    void operator()(const ASTIfElse& ast) {
         inner += Ident() + "else {\n";
         scope++;
         ASTNode current = ast.nodes.GetFirst();
@@ -274,34 +272,34 @@ public:
         inner += Ident() + "}\n";
     }
 
-    void operator()(ASTBlockEncoded& ast) {
+    void operator()(const ASTBlockEncoded& ast) {
         inner += Ident() + "Block(" + std::to_string(ast.start) + ", " + std::to_string(ast.end) +
                  ");\n";
     }
 
-    void operator()(ASTBlockDecoded& ast) {
+    void operator()(const ASTBlockDecoded& ast) {
         inner += Ident() + "Block;\n";
     }
 
-    void operator()(ASTVarSet& ast) {
+    void operator()(const ASTVarSet& ast) {
         ExprPrinter expr_parser{};
         std::visit(expr_parser, *ast.condition);
         inner +=
             Ident() + "V" + std::to_string(ast.index) + " := " + expr_parser.GetResult() + ";\n";
     }
 
-    void operator()(ASTLabel& ast) {
+    void operator()(const ASTLabel& ast) {
         inner += "Label_" + std::to_string(ast.index) + ":\n";
     }
 
-    void operator()(ASTGoto& ast) {
+    void operator()(const ASTGoto& ast) {
         ExprPrinter expr_parser{};
         std::visit(expr_parser, *ast.condition);
         inner += Ident() + "(" + expr_parser.GetResult() + ") -> goto Label_" +
                  std::to_string(ast.label) + ";\n";
     }
 
-    void operator()(ASTDoWhile& ast) {
+    void operator()(const ASTDoWhile& ast) {
         ExprPrinter expr_parser{};
         std::visit(expr_parser, *ast.condition);
         inner += Ident() + "do {\n";
@@ -315,14 +313,14 @@ public:
         inner += Ident() + "} while (" + expr_parser.GetResult() + ");\n";
     }
 
-    void operator()(ASTReturn& ast) {
+    void operator()(const ASTReturn& ast) {
         ExprPrinter expr_parser{};
         std::visit(expr_parser, *ast.condition);
         inner += Ident() + "(" + expr_parser.GetResult() + ") -> " +
                  (ast.kills ? "discard" : "exit") + ";\n";
     }
 
-    void operator()(ASTBreak& ast) {
+    void operator()(const ASTBreak& ast) {
         ExprPrinter expr_parser{};
         std::visit(expr_parser, *ast.condition);
         inner += Ident() + "(" + expr_parser.GetResult() + ") -> break;\n";
@@ -341,7 +339,7 @@ public:
         std::visit(*this, *node->GetInnerData());
     }
 
-    std::string& GetResult() {
+    const std::string& GetResult() const {
         return inner;
     }
 
@@ -352,11 +350,9 @@ private:
     std::string tabs_memo{};
     u32 memo_scope{};
 
-    static std::string tabs;
+    static constexpr std::string_view tabs{"                                    "};
 };
 
-std::string ASTPrinter::tabs = "                                    ";
-
 std::string ASTManager::Print() {
     ASTPrinter printer{};
     printer.Visit(main_node);
@@ -376,30 +372,6 @@ void ASTManager::Init() {
     false_condition = MakeExpr<ExprBoolean>(false);
 }
 
-ASTManager::ASTManager(ASTManager&& other) noexcept
-    : labels_map(std::move(other.labels_map)), labels_count{other.labels_count},
-      gotos(std::move(other.gotos)), labels(std::move(other.labels)), variables{other.variables},
-      program{other.program}, main_node{other.main_node}, false_condition{other.false_condition},
-      disable_else_derivation{other.disable_else_derivation} {
-    other.main_node.reset();
-}
-
-ASTManager& ASTManager::operator=(ASTManager&& other) noexcept {
-    full_decompile = other.full_decompile;
-    labels_map = std::move(other.labels_map);
-    labels_count = other.labels_count;
-    gotos = std::move(other.gotos);
-    labels = std::move(other.labels);
-    variables = other.variables;
-    program = other.program;
-    main_node = other.main_node;
-    false_condition = other.false_condition;
-    disable_else_derivation = other.disable_else_derivation;
-
-    other.main_node.reset();
-    return *this;
-}
-
 void ASTManager::DeclareLabel(u32 address) {
     const auto pair = labels_map.emplace(address, labels_count);
     if (pair.second) {
@@ -417,19 +389,19 @@ void ASTManager::InsertLabel(u32 address) {
 
 void ASTManager::InsertGoto(Expr condition, u32 address) {
     const u32 index = labels_map[address];
-    const ASTNode goto_node = ASTBase::Make<ASTGoto>(main_node, condition, index);
+    const ASTNode goto_node = ASTBase::Make<ASTGoto>(main_node, std::move(condition), index);
     gotos.push_back(goto_node);
     program->nodes.PushBack(goto_node);
 }
 
 void ASTManager::InsertBlock(u32 start_address, u32 end_address) {
-    const ASTNode block = ASTBase::Make<ASTBlockEncoded>(main_node, start_address, end_address);
-    program->nodes.PushBack(block);
+    ASTNode block = ASTBase::Make<ASTBlockEncoded>(main_node, start_address, end_address);
+    program->nodes.PushBack(std::move(block));
 }
 
 void ASTManager::InsertReturn(Expr condition, bool kills) {
-    const ASTNode node = ASTBase::Make<ASTReturn>(main_node, condition, kills);
-    program->nodes.PushBack(node);
+    ASTNode node = ASTBase::Make<ASTReturn>(main_node, std::move(condition), kills);
+    program->nodes.PushBack(std::move(node));
 }
 
 // The decompile algorithm is based on
@@ -496,10 +468,10 @@ void ASTManager::Decompile() {
         }
         labels.clear();
     } else {
-        auto it = labels.begin();
-        while (it != labels.end()) {
+        auto label_it = labels.begin();
+        while (label_it != labels.end()) {
             bool can_remove = true;
-            ASTNode label = *it;
+            ASTNode label = *label_it;
             for (const ASTNode& goto_node : gotos) {
                 const auto label_index = goto_node->GetGotoLabel();
                 if (!label_index) {
@@ -543,11 +515,11 @@ bool ASTManager::IsBackwardsJump(ASTNode goto_node, ASTNode label_node) const {
     return false;
 }
 
-bool ASTManager::IndirectlyRelated(ASTNode first, ASTNode second) {
+bool ASTManager::IndirectlyRelated(const ASTNode& first, const ASTNode& second) const {
     return !(first->GetParent() == second->GetParent() || DirectlyRelated(first, second));
 }
 
-bool ASTManager::DirectlyRelated(ASTNode first, ASTNode second) {
+bool ASTManager::DirectlyRelated(const ASTNode& first, const ASTNode& second) const {
     if (first->GetParent() == second->GetParent()) {
         return false;
     }
@@ -577,7 +549,7 @@ bool ASTManager::DirectlyRelated(ASTNode first, ASTNode second) {
     return min->GetParent() == max->GetParent();
 }
 
-void ASTManager::ShowCurrentState(std::string state) {
+void ASTManager::ShowCurrentState(std::string_view state) {
     LOG_CRITICAL(HW_GPU, "\nState {}:\n\n{}\n", state, Print());
     SanityCheck();
 }
@@ -696,7 +668,7 @@ class ASTClearer {
 public:
     ASTClearer() = default;
 
-    void operator()(ASTProgram& ast) {
+    void operator()(const ASTProgram& ast) {
         ASTNode current = ast.nodes.GetFirst();
         while (current) {
             Visit(current);
@@ -704,7 +676,7 @@ public:
         }
     }
 
-    void operator()(ASTIfThen& ast) {
+    void operator()(const ASTIfThen& ast) {
         ASTNode current = ast.nodes.GetFirst();
         while (current) {
             Visit(current);
@@ -712,7 +684,7 @@ public:
         }
     }
 
-    void operator()(ASTIfElse& ast) {
+    void operator()(const ASTIfElse& ast) {
         ASTNode current = ast.nodes.GetFirst();
         while (current) {
             Visit(current);
@@ -720,19 +692,19 @@ public:
         }
     }
 
-    void operator()(ASTBlockEncoded& ast) {}
+    void operator()([[maybe_unused]] const ASTBlockEncoded& ast) {}
 
     void operator()(ASTBlockDecoded& ast) {
         ast.nodes.clear();
     }
 
-    void operator()(ASTVarSet& ast) {}
+    void operator()([[maybe_unused]] const ASTVarSet& ast) {}
 
-    void operator()(ASTLabel& ast) {}
+    void operator()([[maybe_unused]] const ASTLabel& ast) {}
 
-    void operator()(ASTGoto& ast) {}
+    void operator()([[maybe_unused]] const ASTGoto& ast) {}
 
-    void operator()(ASTDoWhile& ast) {
+    void operator()(const ASTDoWhile& ast) {
         ASTNode current = ast.nodes.GetFirst();
         while (current) {
             Visit(current);
@@ -740,11 +712,11 @@ public:
         }
     }
 
-    void operator()(ASTReturn& ast) {}
+    void operator()([[maybe_unused]] const ASTReturn& ast) {}
 
-    void operator()(ASTBreak& ast) {}
+    void operator()([[maybe_unused]] const ASTBreak& ast) {}
 
-    void Visit(ASTNode& node) {
+    void Visit(const ASTNode& node) {
         std::visit(*this, *node->GetInnerData());
         node->Clear();
     }

+ 47 - 38
src/video_core/shader/ast.h

@@ -18,17 +18,17 @@
 namespace VideoCommon::Shader {
 
 class ASTBase;
-class ASTProgram;
-class ASTIfThen;
-class ASTIfElse;
-class ASTBlockEncoded;
 class ASTBlockDecoded;
-class ASTVarSet;
+class ASTBlockEncoded;
+class ASTBreak;
+class ASTDoWhile;
 class ASTGoto;
+class ASTIfElse;
+class ASTIfThen;
 class ASTLabel;
-class ASTDoWhile;
+class ASTProgram;
 class ASTReturn;
-class ASTBreak;
+class ASTVarSet;
 
 using ASTData = std::variant<ASTProgram, ASTIfThen, ASTIfElse, ASTBlockEncoded, ASTBlockDecoded,
                              ASTVarSet, ASTGoto, ASTLabel, ASTDoWhile, ASTReturn, ASTBreak>;
@@ -48,11 +48,11 @@ public:
 
     void Init(ASTNode first, ASTNode parent);
 
-    ASTNode GetFirst() {
+    ASTNode GetFirst() const {
         return first;
     }
 
-    ASTNode GetLast() {
+    ASTNode GetLast() const {
         return last;
     }
 
@@ -71,20 +71,18 @@ public:
 
 class ASTProgram {
 public:
-    explicit ASTProgram() = default;
     ASTZipper nodes{};
 };
 
 class ASTIfThen {
 public:
-    explicit ASTIfThen(Expr condition) : condition(condition) {}
+    explicit ASTIfThen(Expr condition) : condition{std::move(condition)} {}
     Expr condition;
     ASTZipper nodes{};
 };
 
 class ASTIfElse {
 public:
-    explicit ASTIfElse() = default;
     ASTZipper nodes{};
 };
 
@@ -103,7 +101,7 @@ public:
 
 class ASTVarSet {
 public:
-    explicit ASTVarSet(u32 index, Expr condition) : index{index}, condition{condition} {}
+    explicit ASTVarSet(u32 index, Expr condition) : index{index}, condition{std::move(condition)} {}
     u32 index;
     Expr condition;
 };
@@ -117,42 +115,45 @@ public:
 
 class ASTGoto {
 public:
-    explicit ASTGoto(Expr condition, u32 label) : condition{condition}, label{label} {}
+    explicit ASTGoto(Expr condition, u32 label) : condition{std::move(condition)}, label{label} {}
     Expr condition;
     u32 label;
 };
 
 class ASTDoWhile {
 public:
-    explicit ASTDoWhile(Expr condition) : condition(condition) {}
+    explicit ASTDoWhile(Expr condition) : condition{std::move(condition)} {}
     Expr condition;
     ASTZipper nodes{};
 };
 
 class ASTReturn {
 public:
-    explicit ASTReturn(Expr condition, bool kills) : condition{condition}, kills{kills} {}
+    explicit ASTReturn(Expr condition, bool kills)
+        : condition{std::move(condition)}, kills{kills} {}
     Expr condition;
     bool kills;
 };
 
 class ASTBreak {
 public:
-    explicit ASTBreak(Expr condition) : condition{condition} {}
+    explicit ASTBreak(Expr condition) : condition{std::move(condition)} {}
     Expr condition;
 };
 
 class ASTBase {
 public:
-    explicit ASTBase(ASTNode parent, ASTData data) : parent{parent}, data{data} {}
+    explicit ASTBase(ASTNode parent, ASTData data)
+        : data{std::move(data)}, parent{std::move(parent)} {}
 
     template <class U, class... Args>
     static ASTNode Make(ASTNode parent, Args&&... args) {
-        return std::make_shared<ASTBase>(parent, ASTData(U(std::forward<Args>(args)...)));
+        return std::make_shared<ASTBase>(std::move(parent),
+                                         ASTData(U(std::forward<Args>(args)...)));
     }
 
     void SetParent(ASTNode new_parent) {
-        parent = new_parent;
+        parent = std::move(new_parent);
     }
 
     ASTNode& GetParent() {
@@ -177,6 +178,10 @@ public:
         return &data;
     }
 
+    const ASTData* GetInnerData() const {
+        return &data;
+    }
+
     ASTNode GetNext() const {
         return next;
     }
@@ -189,6 +194,10 @@ public:
         return *manager;
     }
 
+    const ASTZipper& GetManager() const {
+        return *manager;
+    }
+
     std::optional<u32> GetGotoLabel() const {
         auto inner = std::get_if<ASTGoto>(&data);
         if (inner) {
@@ -239,7 +248,7 @@ public:
     void SetGotoCondition(Expr new_condition) {
         auto inner = std::get_if<ASTGoto>(&data);
         if (inner) {
-            inner->condition = new_condition;
+            inner->condition = std::move(new_condition);
         }
     }
 
@@ -304,8 +313,8 @@ public:
     ASTManager(const ASTManager& o) = delete;
     ASTManager& operator=(const ASTManager& other) = delete;
 
-    ASTManager(ASTManager&& other) noexcept;
-    ASTManager& operator=(ASTManager&& other) noexcept;
+    ASTManager(ASTManager&& other) noexcept = default;
+    ASTManager& operator=(ASTManager&& other) noexcept = default;
 
     void Init();
 
@@ -323,7 +332,7 @@ public:
 
     void Decompile();
 
-    void ShowCurrentState(std::string state);
+    void ShowCurrentState(std::string_view state);
 
     void SanityCheck();
 
@@ -331,20 +340,20 @@ public:
 
     bool IsFullyDecompiled() const {
         if (full_decompile) {
-            return gotos.size() == 0;
-        } else {
-            for (ASTNode goto_node : gotos) {
-                auto label_index = goto_node->GetGotoLabel();
-                if (!label_index) {
-                    return false;
-                }
-                ASTNode glabel = labels[*label_index];
-                if (IsBackwardsJump(goto_node, glabel)) {
-                    return false;
-                }
+            return gotos.empty();
+        }
+
+        for (ASTNode goto_node : gotos) {
+            auto label_index = goto_node->GetGotoLabel();
+            if (!label_index) {
+                return false;
+            }
+            ASTNode glabel = labels[*label_index];
+            if (IsBackwardsJump(goto_node, glabel)) {
+                return false;
             }
-            return true;
         }
+        return true;
     }
 
     ASTNode GetProgram() const {
@@ -362,9 +371,9 @@ public:
 private:
     bool IsBackwardsJump(ASTNode goto_node, ASTNode label_node) const;
 
-    bool IndirectlyRelated(ASTNode first, ASTNode second);
+    bool IndirectlyRelated(const ASTNode& first, const ASTNode& second) const;
 
-    bool DirectlyRelated(ASTNode first, ASTNode second);
+    bool DirectlyRelated(const ASTNode& first, const ASTNode& second) const;
 
     void EncloseDoWhile(ASTNode goto_node, ASTNode label);
 

+ 13 - 10
src/video_core/shader/control_flow.cpp

@@ -479,7 +479,7 @@ std::unique_ptr<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code,
     auto result_out = std::make_unique<ShaderCharacteristics>();
     if (settings.depth == CompileDepth::BruteForce) {
         result_out->settings.depth = CompileDepth::BruteForce;
-        return std::move(result_out);
+        return result_out;
     }
 
     CFGRebuildState state{program_code, program_size, start_address};
@@ -490,7 +490,7 @@ std::unique_ptr<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code,
     while (!state.inspect_queries.empty()) {
         if (!TryInspectAddress(state)) {
             result_out->settings.depth = CompileDepth::BruteForce;
-            return std::move(result_out);
+            return result_out;
         }
     }
 
@@ -530,14 +530,15 @@ std::unique_ptr<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code,
             state.manager->ShowCurrentState("Of Shader");
             state.manager->Clear();
         } else {
-            auto result_out = std::make_unique<ShaderCharacteristics>();
-            result_out->start = start_address;
-            result_out->settings.depth = settings.depth;
-            result_out->manager = std::move(manager);
-            result_out->end = state.block_info.back().end + 1;
-            return std::move(result_out);
+            auto characteristics = std::make_unique<ShaderCharacteristics>();
+            characteristics->start = start_address;
+            characteristics->settings.depth = settings.depth;
+            characteristics->manager = std::move(manager);
+            characteristics->end = state.block_info.back().end + 1;
+            return characteristics;
         }
     }
+
     result_out->start = start_address;
     result_out->settings.depth =
         use_flow_stack ? CompileDepth::FlowStack : CompileDepth::NoFlowStack;
@@ -557,8 +558,9 @@ std::unique_ptr<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code,
     }
     if (!use_flow_stack) {
         result_out->labels = std::move(state.labels);
-        return std::move(result_out);
+        return result_out;
     }
+
     auto back = result_out->blocks.begin();
     auto next = std::next(back);
     while (next != result_out->blocks.end()) {
@@ -570,6 +572,7 @@ std::unique_ptr<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code,
         back = next;
         ++next;
     }
-    return std::move(result_out);
+
+    return result_out;
 }
 } // namespace VideoCommon::Shader

+ 25 - 14
src/video_core/shader/expr.cpp

@@ -2,40 +2,51 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
-#pragma once
-
 #include <memory>
 #include <variant>
 
 #include "video_core/shader/expr.h"
 
 namespace VideoCommon::Shader {
+namespace {
+bool ExprIsBoolean(const Expr& expr) {
+    return std::holds_alternative<ExprBoolean>(*expr);
+}
+
+bool ExprBooleanGet(const Expr& expr) {
+    return std::get_if<ExprBoolean>(expr.get())->value;
+}
+} // Anonymous namespace
 
 bool ExprAnd::operator==(const ExprAnd& b) const {
     return (*operand1 == *b.operand1) && (*operand2 == *b.operand2);
 }
 
+bool ExprAnd::operator!=(const ExprAnd& b) const {
+    return !operator==(b);
+}
+
 bool ExprOr::operator==(const ExprOr& b) const {
     return (*operand1 == *b.operand1) && (*operand2 == *b.operand2);
 }
 
-bool ExprNot::operator==(const ExprNot& b) const {
-    return (*operand1 == *b.operand1);
+bool ExprOr::operator!=(const ExprOr& b) const {
+    return !operator==(b);
 }
 
-bool ExprIsBoolean(Expr expr) {
-    return std::holds_alternative<ExprBoolean>(*expr);
+bool ExprNot::operator==(const ExprNot& b) const {
+    return *operand1 == *b.operand1;
 }
 
-bool ExprBooleanGet(Expr expr) {
-    return std::get_if<ExprBoolean>(expr.get())->value;
+bool ExprNot::operator!=(const ExprNot& b) const {
+    return !operator==(b);
 }
 
 Expr MakeExprNot(Expr first) {
     if (std::holds_alternative<ExprNot>(*first)) {
         return std::get_if<ExprNot>(first.get())->operand1;
     }
-    return MakeExpr<ExprNot>(first);
+    return MakeExpr<ExprNot>(std::move(first));
 }
 
 Expr MakeExprAnd(Expr first, Expr second) {
@@ -45,7 +56,7 @@ Expr MakeExprAnd(Expr first, Expr second) {
     if (ExprIsBoolean(second)) {
         return ExprBooleanGet(second) ? first : second;
     }
-    return MakeExpr<ExprAnd>(first, second);
+    return MakeExpr<ExprAnd>(std::move(first), std::move(second));
 }
 
 Expr MakeExprOr(Expr first, Expr second) {
@@ -55,14 +66,14 @@ Expr MakeExprOr(Expr first, Expr second) {
     if (ExprIsBoolean(second)) {
         return ExprBooleanGet(second) ? second : first;
     }
-    return MakeExpr<ExprOr>(first, second);
+    return MakeExpr<ExprOr>(std::move(first), std::move(second));
 }
 
-bool ExprAreEqual(Expr first, Expr second) {
+bool ExprAreEqual(const Expr& first, const Expr& second) {
     return (*first) == (*second);
 }
 
-bool ExprAreOpposite(Expr first, Expr second) {
+bool ExprAreOpposite(const Expr& first, const Expr& second) {
     if (std::holds_alternative<ExprNot>(*first)) {
         return ExprAreEqual(std::get_if<ExprNot>(first.get())->operand1, second);
     }
@@ -72,7 +83,7 @@ bool ExprAreOpposite(Expr first, Expr second) {
     return false;
 }
 
-bool ExprIsTrue(Expr first) {
+bool ExprIsTrue(const Expr& first) {
     if (ExprIsBoolean(first)) {
         return ExprBooleanGet(first);
     }

+ 28 - 9
src/video_core/shader/expr.h

@@ -15,12 +15,12 @@ using Tegra::Shader::ConditionCode;
 using Tegra::Shader::Pred;
 
 class ExprAnd;
-class ExprOr;
+class ExprBoolean;
+class ExprCondCode;
 class ExprNot;
+class ExprOr;
 class ExprPredicate;
-class ExprCondCode;
 class ExprVar;
-class ExprBoolean;
 
 using ExprData =
     std::variant<ExprVar, ExprCondCode, ExprPredicate, ExprNot, ExprOr, ExprAnd, ExprBoolean>;
@@ -28,9 +28,10 @@ using Expr = std::shared_ptr<ExprData>;
 
 class ExprAnd final {
 public:
-    explicit ExprAnd(Expr a, Expr b) : operand1{a}, operand2{b} {}
+    explicit ExprAnd(Expr a, Expr b) : operand1{std::move(a)}, operand2{std::move(b)} {}
 
     bool operator==(const ExprAnd& b) const;
+    bool operator!=(const ExprAnd& b) const;
 
     Expr operand1;
     Expr operand2;
@@ -38,9 +39,10 @@ public:
 
 class ExprOr final {
 public:
-    explicit ExprOr(Expr a, Expr b) : operand1{a}, operand2{b} {}
+    explicit ExprOr(Expr a, Expr b) : operand1{std::move(a)}, operand2{std::move(b)} {}
 
     bool operator==(const ExprOr& b) const;
+    bool operator!=(const ExprOr& b) const;
 
     Expr operand1;
     Expr operand2;
@@ -48,9 +50,10 @@ public:
 
 class ExprNot final {
 public:
-    explicit ExprNot(Expr a) : operand1{a} {}
+    explicit ExprNot(Expr a) : operand1{std::move(a)} {}
 
     bool operator==(const ExprNot& b) const;
+    bool operator!=(const ExprNot& b) const;
 
     Expr operand1;
 };
@@ -63,6 +66,10 @@ public:
         return var_index == b.var_index;
     }
 
+    bool operator!=(const ExprVar& b) const {
+        return !operator==(b);
+    }
+
     u32 var_index;
 };
 
@@ -74,6 +81,10 @@ public:
         return predicate == b.predicate;
     }
 
+    bool operator!=(const ExprPredicate& b) const {
+        return !operator==(b);
+    }
+
     u32 predicate;
 };
 
@@ -85,6 +96,10 @@ public:
         return cc == b.cc;
     }
 
+    bool operator!=(const ExprCondCode& b) const {
+        return !operator==(b);
+    }
+
     ConditionCode cc;
 };
 
@@ -96,6 +111,10 @@ public:
         return value == b.value;
     }
 
+    bool operator!=(const ExprBoolean& b) const {
+        return !operator==(b);
+    }
+
     bool value;
 };
 
@@ -105,9 +124,9 @@ Expr MakeExpr(Args&&... args) {
     return std::make_shared<ExprData>(T(std::forward<Args>(args)...));
 }
 
-bool ExprAreEqual(Expr first, Expr second);
+bool ExprAreEqual(const Expr& first, const Expr& second);
 
-bool ExprAreOpposite(Expr first, Expr second);
+bool ExprAreOpposite(const Expr& first, const Expr& second);
 
 Expr MakeExprNot(Expr first);
 
@@ -115,6 +134,6 @@ Expr MakeExprAnd(Expr first, Expr second);
 
 Expr MakeExprOr(Expr first, Expr second);
 
-bool ExprIsTrue(Expr first);
+bool ExprIsTrue(const Expr& first);
 
 } // namespace VideoCommon::Shader