diff options
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp | 235 |
1 files changed, 136 insertions, 99 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp index cc5410c6d..e7e2e9c82 100644 --- a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp +++ b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp | |||
| @@ -36,7 +36,6 @@ using Tree = boost::intrusive::list<Statement, | |||
| 36 | // Avoid linear complexity on splice, size is never called | 36 | // Avoid linear complexity on splice, size is never called |
| 37 | boost::intrusive::constant_time_size<false>>; | 37 | boost::intrusive::constant_time_size<false>>; |
| 38 | using Node = Tree::iterator; | 38 | using Node = Tree::iterator; |
| 39 | using ConstNode = Tree::const_iterator; | ||
| 40 | 39 | ||
| 41 | enum class StatementType { | 40 | enum class StatementType { |
| 42 | Code, | 41 | Code, |
| @@ -91,7 +90,8 @@ struct IndirectBranchCond {}; | |||
| 91 | #pragma warning(disable : 26495) // Always initialize a member variable, expected in Statement | 90 | #pragma warning(disable : 26495) // Always initialize a member variable, expected in Statement |
| 92 | #endif | 91 | #endif |
| 93 | struct Statement : ListBaseHook { | 92 | struct Statement : ListBaseHook { |
| 94 | Statement(IR::Block* code_, Statement* up_) : code{code_}, up{up_}, type{StatementType::Code} {} | 93 | Statement(const Flow::Block* block_, Statement* up_) |
| 94 | : block{block_}, up{up_}, type{StatementType::Code} {} | ||
| 95 | Statement(Goto, Statement* cond_, Node label_, Statement* up_) | 95 | Statement(Goto, Statement* cond_, Node label_, Statement* up_) |
| 96 | : label{label_}, cond{cond_}, up{up_}, type{StatementType::Goto} {} | 96 | : label{label_}, cond{cond_}, up{up_}, type{StatementType::Goto} {} |
| 97 | Statement(Label, u32 id_, Statement* up_) : id{id_}, up{up_}, type{StatementType::Label} {} | 97 | Statement(Label, u32 id_, Statement* up_) : id{id_}, up{up_}, type{StatementType::Label} {} |
| @@ -125,7 +125,7 @@ struct Statement : ListBaseHook { | |||
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | union { | 127 | union { |
| 128 | IR::Block* code; | 128 | const Flow::Block* block; |
| 129 | Node label; | 129 | Node label; |
| 130 | Tree children; | 130 | Tree children; |
| 131 | IR::Condition guest_cond; | 131 | IR::Condition guest_cond; |
| @@ -171,8 +171,8 @@ std::string DumpTree(const Tree& tree, u32 indentation = 0) { | |||
| 171 | switch (stmt->type) { | 171 | switch (stmt->type) { |
| 172 | case StatementType::Code: | 172 | case StatementType::Code: |
| 173 | ret += fmt::format("{} Block {:04x} -> {:04x} (0x{:016x});\n", indent, | 173 | ret += fmt::format("{} Block {:04x} -> {:04x} (0x{:016x});\n", indent, |
| 174 | stmt->code->LocationBegin(), stmt->code->LocationEnd(), | 174 | stmt->block->begin, stmt->block->end, |
| 175 | reinterpret_cast<uintptr_t>(stmt->code)); | 175 | reinterpret_cast<uintptr_t>(stmt->block)); |
| 176 | break; | 176 | break; |
| 177 | case StatementType::Goto: | 177 | case StatementType::Goto: |
| 178 | ret += fmt::format("{} if ({}) goto L{};\n", indent, DumpExpr(stmt->cond), | 178 | ret += fmt::format("{} if ({}) goto L{};\n", indent, DumpExpr(stmt->cond), |
| @@ -407,11 +407,7 @@ private: | |||
| 407 | }}; | 407 | }}; |
| 408 | root.push_front(make_reset_variable()); | 408 | root.push_front(make_reset_variable()); |
| 409 | root.insert(ip, make_reset_variable()); | 409 | root.insert(ip, make_reset_variable()); |
| 410 | 410 | root.insert(ip, *pool.Create(&block, &root_stmt)); | |
| 411 | const u32 begin_offset{block.begin.Offset()}; | ||
| 412 | const u32 end_offset{block.end.Offset()}; | ||
| 413 | IR::Block* const ir_block{block_pool.Create(inst_pool, begin_offset, end_offset)}; | ||
| 414 | root.insert(ip, *pool.Create(ir_block, &root_stmt)); | ||
| 415 | 411 | ||
| 416 | switch (block.end_class) { | 412 | switch (block.end_class) { |
| 417 | case Flow::EndClass::Branch: { | 413 | case Flow::EndClass::Branch: { |
| @@ -620,13 +616,13 @@ private: | |||
| 620 | Statement root_stmt{FunctionTag{}}; | 616 | Statement root_stmt{FunctionTag{}}; |
| 621 | }; | 617 | }; |
| 622 | 618 | ||
| 623 | IR::Block* TryFindForwardBlock(const Statement& stmt) { | 619 | [[nodiscard]] Statement* TryFindForwardBlock(Statement& stmt) { |
| 624 | const Tree& tree{stmt.up->children}; | 620 | Tree& tree{stmt.up->children}; |
| 625 | const ConstNode end{tree.cend()}; | 621 | const Node end{tree.end()}; |
| 626 | ConstNode forward_node{std::next(Tree::s_iterator_to(stmt))}; | 622 | Node forward_node{std::next(Tree::s_iterator_to(stmt))}; |
| 627 | while (forward_node != end && !HasChildren(forward_node->type)) { | 623 | while (forward_node != end && !HasChildren(forward_node->type)) { |
| 628 | if (forward_node->type == StatementType::Code) { | 624 | if (forward_node->type == StatementType::Code) { |
| 629 | return forward_node->code; | 625 | return &*forward_node; |
| 630 | } | 626 | } |
| 631 | ++forward_node; | 627 | ++forward_node; |
| 632 | } | 628 | } |
| @@ -654,21 +650,29 @@ class TranslatePass { | |||
| 654 | public: | 650 | public: |
| 655 | TranslatePass(ObjectPool<IR::Inst>& inst_pool_, ObjectPool<IR::Block>& block_pool_, | 651 | TranslatePass(ObjectPool<IR::Inst>& inst_pool_, ObjectPool<IR::Block>& block_pool_, |
| 656 | ObjectPool<Statement>& stmt_pool_, Environment& env_, Statement& root_stmt, | 652 | ObjectPool<Statement>& stmt_pool_, Environment& env_, Statement& root_stmt, |
| 657 | IR::BlockList& block_list_) | 653 | IR::AbstractSyntaxList& syntax_list_) |
| 658 | : stmt_pool{stmt_pool_}, inst_pool{inst_pool_}, block_pool{block_pool_}, env{env_}, | 654 | : stmt_pool{stmt_pool_}, inst_pool{inst_pool_}, block_pool{block_pool_}, env{env_}, |
| 659 | block_list{block_list_} { | 655 | syntax_list{syntax_list_} { |
| 660 | Visit(root_stmt, nullptr, nullptr); | 656 | Visit(root_stmt, nullptr, nullptr); |
| 661 | 657 | ||
| 662 | IR::Block& first_block{*block_list.front()}; | 658 | IR::Block& first_block{*syntax_list.front().block}; |
| 663 | IR::IREmitter ir{first_block, first_block.begin()}; | 659 | IR::IREmitter ir{first_block, first_block.begin()}; |
| 664 | ir.Prologue(); | 660 | ir.Prologue(); |
| 665 | } | 661 | } |
| 666 | 662 | ||
| 667 | private: | 663 | private: |
| 668 | void Visit(Statement& parent, IR::Block* continue_block, IR::Block* break_block) { | 664 | void Visit(Statement& parent, IR::Block* break_block, IR::Block* fallthrough_block) { |
| 665 | IR::Block* current_block{}; | ||
| 666 | const auto ensure_block{[&] { | ||
| 667 | if (current_block) { | ||
| 668 | return; | ||
| 669 | } | ||
| 670 | current_block = block_pool.Create(inst_pool); | ||
| 671 | auto& node{syntax_list.emplace_back()}; | ||
| 672 | node.type = IR::AbstractSyntaxNode::Type::Block; | ||
| 673 | node.block = current_block; | ||
| 674 | }}; | ||
| 669 | Tree& tree{parent.children}; | 675 | Tree& tree{parent.children}; |
| 670 | IR::Block* current_block{nullptr}; | ||
| 671 | |||
| 672 | for (auto it = tree.begin(); it != tree.end(); ++it) { | 676 | for (auto it = tree.begin(); it != tree.end(); ++it) { |
| 673 | Statement& stmt{*it}; | 677 | Statement& stmt{*it}; |
| 674 | switch (stmt.type) { | 678 | switch (stmt.type) { |
| @@ -676,124 +680,157 @@ private: | |||
| 676 | // Labels can be ignored | 680 | // Labels can be ignored |
| 677 | break; | 681 | break; |
| 678 | case StatementType::Code: { | 682 | case StatementType::Code: { |
| 679 | if (current_block && current_block != stmt.code) { | 683 | ensure_block(); |
| 680 | IR::IREmitter{*current_block}.Branch(stmt.code); | 684 | Translate(env, current_block, stmt.block->begin.Offset(), stmt.block->end.Offset()); |
| 681 | } | ||
| 682 | current_block = stmt.code; | ||
| 683 | Translate(env, stmt.code); | ||
| 684 | block_list.push_back(stmt.code); | ||
| 685 | break; | 685 | break; |
| 686 | } | 686 | } |
| 687 | case StatementType::SetVariable: { | 687 | case StatementType::SetVariable: { |
| 688 | if (!current_block) { | 688 | ensure_block(); |
| 689 | current_block = MergeBlock(parent, stmt); | ||
| 690 | } | ||
| 691 | IR::IREmitter ir{*current_block}; | 689 | IR::IREmitter ir{*current_block}; |
| 692 | ir.SetGotoVariable(stmt.id, VisitExpr(ir, *stmt.op)); | 690 | ir.SetGotoVariable(stmt.id, VisitExpr(ir, *stmt.op)); |
| 693 | break; | 691 | break; |
| 694 | } | 692 | } |
| 695 | case StatementType::SetIndirectBranchVariable: { | 693 | case StatementType::SetIndirectBranchVariable: { |
| 696 | if (!current_block) { | 694 | ensure_block(); |
| 697 | current_block = MergeBlock(parent, stmt); | ||
| 698 | } | ||
| 699 | IR::IREmitter ir{*current_block}; | 695 | IR::IREmitter ir{*current_block}; |
| 700 | IR::U32 address{ir.IAdd(ir.GetReg(stmt.branch_reg), ir.Imm32(stmt.branch_offset))}; | 696 | IR::U32 address{ir.IAdd(ir.GetReg(stmt.branch_reg), ir.Imm32(stmt.branch_offset))}; |
| 701 | ir.SetIndirectBranchVariable(address); | 697 | ir.SetIndirectBranchVariable(address); |
| 702 | break; | 698 | break; |
| 703 | } | 699 | } |
| 704 | case StatementType::If: { | 700 | case StatementType::If: { |
| 705 | if (!current_block) { | 701 | ensure_block(); |
| 706 | current_block = block_pool.Create(inst_pool); | ||
| 707 | block_list.push_back(current_block); | ||
| 708 | } | ||
| 709 | IR::Block* const merge_block{MergeBlock(parent, stmt)}; | 702 | IR::Block* const merge_block{MergeBlock(parent, stmt)}; |
| 710 | 703 | ||
| 711 | // Visit children | ||
| 712 | const size_t first_block_index{block_list.size()}; | ||
| 713 | Visit(stmt, merge_block, break_block); | ||
| 714 | |||
| 715 | // Implement if header block | 704 | // Implement if header block |
| 716 | IR::Block* const first_if_block{block_list.at(first_block_index)}; | ||
| 717 | IR::IREmitter ir{*current_block}; | 705 | IR::IREmitter ir{*current_block}; |
| 718 | const IR::U1 cond{VisitExpr(ir, *stmt.cond)}; | 706 | const IR::U1 cond{VisitExpr(ir, *stmt.cond)}; |
| 719 | ir.SelectionMerge(merge_block); | 707 | ir.BranchConditionRef(cond); |
| 720 | ir.BranchConditional(cond, first_if_block, merge_block); | ||
| 721 | 708 | ||
| 709 | const size_t if_node_index{syntax_list.size()}; | ||
| 710 | syntax_list.emplace_back(); | ||
| 711 | |||
| 712 | // Visit children | ||
| 713 | const size_t then_block_index{syntax_list.size()}; | ||
| 714 | Visit(stmt, break_block, merge_block); | ||
| 715 | |||
| 716 | IR::Block* const then_block{syntax_list.at(then_block_index).block}; | ||
| 717 | current_block->AddBranch(then_block); | ||
| 718 | current_block->AddBranch(merge_block); | ||
| 722 | current_block = merge_block; | 719 | current_block = merge_block; |
| 720 | |||
| 721 | auto& if_node{syntax_list[if_node_index]}; | ||
| 722 | if_node.type = IR::AbstractSyntaxNode::Type::If; | ||
| 723 | if_node.if_node.cond = cond; | ||
| 724 | if_node.if_node.body = then_block; | ||
| 725 | if_node.if_node.merge = merge_block; | ||
| 726 | |||
| 727 | auto& endif_node{syntax_list.emplace_back()}; | ||
| 728 | endif_node.type = IR::AbstractSyntaxNode::Type::EndIf; | ||
| 729 | endif_node.end_if.merge = merge_block; | ||
| 730 | |||
| 731 | auto& merge{syntax_list.emplace_back()}; | ||
| 732 | merge.type = IR::AbstractSyntaxNode::Type::Block; | ||
| 733 | merge.block = merge_block; | ||
| 723 | break; | 734 | break; |
| 724 | } | 735 | } |
| 725 | case StatementType::Loop: { | 736 | case StatementType::Loop: { |
| 726 | IR::Block* const loop_header_block{block_pool.Create(inst_pool)}; | 737 | IR::Block* const loop_header_block{block_pool.Create(inst_pool)}; |
| 727 | if (current_block) { | 738 | if (current_block) { |
| 728 | IR::IREmitter{*current_block}.Branch(loop_header_block); | 739 | current_block->AddBranch(loop_header_block); |
| 729 | } | 740 | } |
| 730 | block_list.push_back(loop_header_block); | 741 | auto& header_node{syntax_list.emplace_back()}; |
| 742 | header_node.type = IR::AbstractSyntaxNode::Type::Block; | ||
| 743 | header_node.block = loop_header_block; | ||
| 731 | 744 | ||
| 732 | IR::Block* const new_continue_block{block_pool.Create(inst_pool)}; | 745 | IR::Block* const continue_block{block_pool.Create(inst_pool)}; |
| 733 | IR::Block* const merge_block{MergeBlock(parent, stmt)}; | 746 | IR::Block* const merge_block{MergeBlock(parent, stmt)}; |
| 734 | 747 | ||
| 748 | const size_t loop_node_index{syntax_list.size()}; | ||
| 749 | syntax_list.emplace_back(); | ||
| 750 | |||
| 735 | // Visit children | 751 | // Visit children |
| 736 | const size_t first_block_index{block_list.size()}; | 752 | const size_t body_block_index{syntax_list.size()}; |
| 737 | Visit(stmt, new_continue_block, merge_block); | 753 | Visit(stmt, merge_block, continue_block); |
| 738 | 754 | ||
| 739 | // The continue block is located at the end of the loop | 755 | // The continue block is located at the end of the loop |
| 740 | block_list.push_back(new_continue_block); | 756 | IR::IREmitter ir{*continue_block}; |
| 757 | const IR::U1 cond{VisitExpr(ir, *stmt.cond)}; | ||
| 758 | ir.BranchConditionRef(cond); | ||
| 741 | 759 | ||
| 742 | // Implement loop header block | 760 | IR::Block* const body_block{syntax_list.at(body_block_index).block}; |
| 743 | IR::Block* const first_loop_block{block_list.at(first_block_index)}; | 761 | loop_header_block->AddBranch(body_block); |
| 744 | IR::IREmitter ir{*loop_header_block}; | ||
| 745 | ir.LoopMerge(merge_block, new_continue_block); | ||
| 746 | ir.Branch(first_loop_block); | ||
| 747 | 762 | ||
| 748 | // Implement continue block | 763 | continue_block->AddBranch(loop_header_block); |
| 749 | IR::IREmitter continue_ir{*new_continue_block}; | 764 | continue_block->AddBranch(merge_block); |
| 750 | const IR::U1 continue_cond{VisitExpr(continue_ir, *stmt.cond)}; | ||
| 751 | continue_ir.BranchConditional(continue_cond, ir.block, merge_block); | ||
| 752 | 765 | ||
| 753 | current_block = merge_block; | 766 | current_block = merge_block; |
| 767 | |||
| 768 | auto& loop{syntax_list[loop_node_index]}; | ||
| 769 | loop.type = IR::AbstractSyntaxNode::Type::Loop; | ||
| 770 | loop.loop.body = body_block; | ||
| 771 | loop.loop.continue_block = continue_block; | ||
| 772 | loop.loop.merge = merge_block; | ||
| 773 | |||
| 774 | auto& continue_block_node{syntax_list.emplace_back()}; | ||
| 775 | continue_block_node.type = IR::AbstractSyntaxNode::Type::Block; | ||
| 776 | continue_block_node.block = continue_block; | ||
| 777 | |||
| 778 | auto& repeat{syntax_list.emplace_back()}; | ||
| 779 | repeat.type = IR::AbstractSyntaxNode::Type::Repeat; | ||
| 780 | repeat.repeat.cond = cond; | ||
| 781 | repeat.repeat.loop_header = loop_header_block; | ||
| 782 | repeat.repeat.merge = merge_block; | ||
| 783 | |||
| 784 | auto& merge{syntax_list.emplace_back()}; | ||
| 785 | merge.type = IR::AbstractSyntaxNode::Type::Block; | ||
| 786 | merge.block = merge_block; | ||
| 754 | break; | 787 | break; |
| 755 | } | 788 | } |
| 756 | case StatementType::Break: { | 789 | case StatementType::Break: { |
| 757 | if (!current_block) { | 790 | ensure_block(); |
| 758 | current_block = block_pool.Create(inst_pool); | ||
| 759 | block_list.push_back(current_block); | ||
| 760 | } | ||
| 761 | IR::Block* const skip_block{MergeBlock(parent, stmt)}; | 791 | IR::Block* const skip_block{MergeBlock(parent, stmt)}; |
| 762 | 792 | ||
| 763 | IR::IREmitter ir{*current_block}; | 793 | IR::IREmitter ir{*current_block}; |
| 764 | ir.BranchConditional(VisitExpr(ir, *stmt.cond), break_block, skip_block); | 794 | const IR::U1 cond{VisitExpr(ir, *stmt.cond)}; |
| 765 | 795 | ir.BranchConditionRef(cond); | |
| 796 | current_block->AddBranch(break_block); | ||
| 797 | current_block->AddBranch(skip_block); | ||
| 766 | current_block = skip_block; | 798 | current_block = skip_block; |
| 799 | |||
| 800 | auto& break_node{syntax_list.emplace_back()}; | ||
| 801 | break_node.type = IR::AbstractSyntaxNode::Type::Break; | ||
| 802 | break_node.break_node.cond = cond; | ||
| 803 | break_node.break_node.merge = break_block; | ||
| 804 | break_node.break_node.skip = skip_block; | ||
| 805 | |||
| 806 | auto& merge{syntax_list.emplace_back()}; | ||
| 807 | merge.type = IR::AbstractSyntaxNode::Type::Block; | ||
| 808 | merge.block = skip_block; | ||
| 767 | break; | 809 | break; |
| 768 | } | 810 | } |
| 769 | case StatementType::Return: { | 811 | case StatementType::Return: { |
| 770 | if (!current_block) { | 812 | ensure_block(); |
| 771 | current_block = block_pool.Create(inst_pool); | 813 | IR::IREmitter{*current_block}.Epilogue(); |
| 772 | block_list.push_back(current_block); | ||
| 773 | } | ||
| 774 | IR::IREmitter ir{*current_block}; | ||
| 775 | ir.Epilogue(); | ||
| 776 | ir.Return(); | ||
| 777 | current_block = nullptr; | 814 | current_block = nullptr; |
| 815 | syntax_list.emplace_back().type = IR::AbstractSyntaxNode::Type::Return; | ||
| 778 | break; | 816 | break; |
| 779 | } | 817 | } |
| 780 | case StatementType::Kill: { | 818 | case StatementType::Kill: { |
| 781 | if (!current_block) { | 819 | ensure_block(); |
| 782 | current_block = block_pool.Create(inst_pool); | ||
| 783 | block_list.push_back(current_block); | ||
| 784 | } | ||
| 785 | IR::Block* demote_block{MergeBlock(parent, stmt)}; | 820 | IR::Block* demote_block{MergeBlock(parent, stmt)}; |
| 786 | IR::IREmitter{*current_block}.DemoteToHelperInvocation(demote_block); | 821 | IR::IREmitter{*current_block}.DemoteToHelperInvocation(); |
| 822 | current_block->AddBranch(demote_block); | ||
| 787 | current_block = demote_block; | 823 | current_block = demote_block; |
| 824 | |||
| 825 | auto& merge{syntax_list.emplace_back()}; | ||
| 826 | merge.type = IR::AbstractSyntaxNode::Type::Block; | ||
| 827 | merge.block = demote_block; | ||
| 788 | break; | 828 | break; |
| 789 | } | 829 | } |
| 790 | case StatementType::Unreachable: { | 830 | case StatementType::Unreachable: { |
| 791 | if (!current_block) { | 831 | ensure_block(); |
| 792 | current_block = block_pool.Create(inst_pool); | ||
| 793 | block_list.push_back(current_block); | ||
| 794 | } | ||
| 795 | IR::IREmitter{*current_block}.Unreachable(); | ||
| 796 | current_block = nullptr; | 832 | current_block = nullptr; |
| 833 | syntax_list.emplace_back().type = IR::AbstractSyntaxNode::Type::Unreachable; | ||
| 797 | break; | 834 | break; |
| 798 | } | 835 | } |
| 799 | default: | 836 | default: |
| @@ -801,42 +838,42 @@ private: | |||
| 801 | } | 838 | } |
| 802 | } | 839 | } |
| 803 | if (current_block) { | 840 | if (current_block) { |
| 804 | IR::IREmitter ir{*current_block}; | 841 | if (fallthrough_block) { |
| 805 | if (continue_block) { | 842 | current_block->AddBranch(fallthrough_block); |
| 806 | ir.Branch(continue_block); | ||
| 807 | } else { | 843 | } else { |
| 808 | ir.Unreachable(); | 844 | syntax_list.emplace_back().type = IR::AbstractSyntaxNode::Type::Unreachable; |
| 809 | } | 845 | } |
| 810 | } | 846 | } |
| 811 | } | 847 | } |
| 812 | 848 | ||
| 813 | IR::Block* MergeBlock(Statement& parent, Statement& stmt) { | 849 | IR::Block* MergeBlock(Statement& parent, Statement& stmt) { |
| 814 | if (IR::Block* const block{TryFindForwardBlock(stmt)}) { | 850 | Statement* merge_stmt{TryFindForwardBlock(stmt)}; |
| 815 | return block; | 851 | if (!merge_stmt) { |
| 852 | // Create a merge block we can visit later | ||
| 853 | merge_stmt = stmt_pool.Create(&dummy_flow_block, &parent); | ||
| 854 | parent.children.insert(std::next(Tree::s_iterator_to(stmt)), *merge_stmt); | ||
| 816 | } | 855 | } |
| 817 | // Create a merge block we can visit later | 856 | return block_pool.Create(inst_pool); |
| 818 | IR::Block* const block{block_pool.Create(inst_pool)}; | ||
| 819 | Statement* const merge_stmt{stmt_pool.Create(block, &parent)}; | ||
| 820 | parent.children.insert(std::next(Tree::s_iterator_to(stmt)), *merge_stmt); | ||
| 821 | return block; | ||
| 822 | } | 857 | } |
| 823 | 858 | ||
| 824 | ObjectPool<Statement>& stmt_pool; | 859 | ObjectPool<Statement>& stmt_pool; |
| 825 | ObjectPool<IR::Inst>& inst_pool; | 860 | ObjectPool<IR::Inst>& inst_pool; |
| 826 | ObjectPool<IR::Block>& block_pool; | 861 | ObjectPool<IR::Block>& block_pool; |
| 827 | Environment& env; | 862 | Environment& env; |
| 828 | IR::BlockList& block_list; | 863 | IR::AbstractSyntaxList& syntax_list; |
| 864 | // TODO: Make this constexpr when std::vector is constexpr | ||
| 865 | const Flow::Block dummy_flow_block; | ||
| 829 | }; | 866 | }; |
| 830 | } // Anonymous namespace | 867 | } // Anonymous namespace |
| 831 | 868 | ||
| 832 | IR::BlockList VisitAST(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Block>& block_pool, | 869 | IR::AbstractSyntaxList BuildASL(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Block>& block_pool, |
| 833 | Environment& env, Flow::CFG& cfg) { | 870 | Environment& env, Flow::CFG& cfg) { |
| 834 | ObjectPool<Statement> stmt_pool{64}; | 871 | ObjectPool<Statement> stmt_pool{64}; |
| 835 | GotoPass goto_pass{cfg, inst_pool, block_pool, stmt_pool}; | 872 | GotoPass goto_pass{cfg, inst_pool, block_pool, stmt_pool}; |
| 836 | Statement& root{goto_pass.RootStatement()}; | 873 | Statement& root{goto_pass.RootStatement()}; |
| 837 | IR::BlockList block_list; | 874 | IR::AbstractSyntaxList syntax_list; |
| 838 | TranslatePass{inst_pool, block_pool, stmt_pool, env, root, block_list}; | 875 | TranslatePass{inst_pool, block_pool, stmt_pool, env, root, syntax_list}; |
| 839 | return block_list; | 876 | return syntax_list; |
| 840 | } | 877 | } |
| 841 | 878 | ||
| 842 | } // namespace Shader::Maxwell | 879 | } // namespace Shader::Maxwell |