Merge pull request #2944 from lioncash/ast
video_core/shader: Minor changes
This commit is contained in:
		| @@ -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(); | ||||
|     } | ||||
|   | ||||
| @@ -18,17 +18,17 @@ | ||||
| namespace VideoCommon::Shader { | ||||
|  | ||||
| class ASTBase; | ||||
| class ASTProgram; | ||||
| class ASTIfThen; | ||||
| class ASTIfElse; | ||||
| class ASTBlockEncoded; | ||||
| class ASTBlockDecoded; | ||||
| class ASTVarSet; | ||||
| class ASTGoto; | ||||
| class ASTLabel; | ||||
| class ASTDoWhile; | ||||
| class ASTReturn; | ||||
| class ASTBlockEncoded; | ||||
| class ASTBreak; | ||||
| class ASTDoWhile; | ||||
| class ASTGoto; | ||||
| class ASTIfElse; | ||||
| class ASTIfThen; | ||||
| class ASTLabel; | ||||
| class ASTProgram; | ||||
| class ASTReturn; | ||||
| 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,8 +340,9 @@ public: | ||||
|  | ||||
|     bool IsFullyDecompiled() const { | ||||
|         if (full_decompile) { | ||||
|             return gotos.size() == 0; | ||||
|         } else { | ||||
|             return gotos.empty(); | ||||
|         } | ||||
|  | ||||
|         for (ASTNode goto_node : gotos) { | ||||
|             auto label_index = goto_node->GetGotoLabel(); | ||||
|             if (!label_index) { | ||||
| @@ -345,7 +355,6 @@ public: | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|     } | ||||
|  | ||||
|     ASTNode GetProgram() const { | ||||
|         return main_node; | ||||
| @@ -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); | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 ExprOr::operator!=(const ExprOr& b) const { | ||||
|     return !operator==(b); | ||||
| } | ||||
|  | ||||
| bool ExprNot::operator==(const ExprNot& b) const { | ||||
|     return (*operand1 == *b.operand1); | ||||
|     return *operand1 == *b.operand1; | ||||
| } | ||||
|  | ||||
| bool ExprIsBoolean(Expr expr) { | ||||
|     return std::holds_alternative<ExprBoolean>(*expr); | ||||
| } | ||||
|  | ||||
| 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); | ||||
|     } | ||||
|   | ||||
| @@ -15,12 +15,12 @@ using Tegra::Shader::ConditionCode; | ||||
| using Tegra::Shader::Pred; | ||||
|  | ||||
| class ExprAnd; | ||||
| class ExprOr; | ||||
| class ExprNot; | ||||
| class ExprPredicate; | ||||
| class ExprCondCode; | ||||
| class ExprVar; | ||||
| class ExprBoolean; | ||||
| class ExprCondCode; | ||||
| class ExprNot; | ||||
| class ExprOr; | ||||
| class ExprPredicate; | ||||
| class ExprVar; | ||||
|  | ||||
| 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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Fernando Sahmkow
					Fernando Sahmkow