mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-02 15:32:52 +00:00
Add conditional tree
This commit is contained in:
parent
60be1e4376
commit
4bf9bbf86f
@ -849,6 +849,8 @@ set(SHADER_RECOMPILER src/shader_recompiler/exception.h
|
|||||||
src/shader_recompiler/ir/basic_block.cpp
|
src/shader_recompiler/ir/basic_block.cpp
|
||||||
src/shader_recompiler/ir/basic_block.h
|
src/shader_recompiler/ir/basic_block.h
|
||||||
src/shader_recompiler/ir/condition.h
|
src/shader_recompiler/ir/condition.h
|
||||||
|
src/shader_recompiler/ir/conditional_tree.cpp
|
||||||
|
src/shader_recompiler/ir/conditional_tree.h
|
||||||
src/shader_recompiler/ir/ir_emitter.cpp
|
src/shader_recompiler/ir/ir_emitter.cpp
|
||||||
src/shader_recompiler/ir/ir_emitter.h
|
src/shader_recompiler/ir/ir_emitter.h
|
||||||
src/shader_recompiler/ir/microinstruction.cpp
|
src/shader_recompiler/ir/microinstruction.cpp
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "common/object_pool.h"
|
#include "common/object_pool.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
#include "shader_recompiler/ir/abstract_syntax_list.h"
|
||||||
#include "shader_recompiler/ir/reg.h"
|
#include "shader_recompiler/ir/reg.h"
|
||||||
#include "shader_recompiler/ir/value.h"
|
#include "shader_recompiler/ir/value.h"
|
||||||
|
|
||||||
@ -18,6 +19,12 @@ namespace Shader::IR {
|
|||||||
|
|
||||||
class Block {
|
class Block {
|
||||||
public:
|
public:
|
||||||
|
struct ConditionalData {
|
||||||
|
std::uint32_t depth;
|
||||||
|
const ConditionalData* parent;
|
||||||
|
const AbstractSyntaxNode* asl_node;
|
||||||
|
};
|
||||||
|
|
||||||
using InstructionList = boost::intrusive::list<Inst>;
|
using InstructionList = boost::intrusive::list<Inst>;
|
||||||
using size_type = InstructionList::size_type;
|
using size_type = InstructionList::size_type;
|
||||||
using iterator = InstructionList::iterator;
|
using iterator = InstructionList::iterator;
|
||||||
@ -65,6 +72,16 @@ public:
|
|||||||
return imm_successors;
|
return imm_successors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the conditional data for this block.
|
||||||
|
void SetConditionalData(const ConditionalData& data) {
|
||||||
|
cond_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the conditional data for this block.
|
||||||
|
[[nodiscard]] const ConditionalData& CondData() const {
|
||||||
|
return cond_data;
|
||||||
|
}
|
||||||
|
|
||||||
/// Intrusively store the host definition of this instruction.
|
/// Intrusively store the host definition of this instruction.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void SetDefinition(T def) {
|
void SetDefinition(T def) {
|
||||||
@ -164,6 +181,9 @@ private:
|
|||||||
/// Block immediate successors
|
/// Block immediate successors
|
||||||
std::vector<Block*> imm_successors;
|
std::vector<Block*> imm_successors;
|
||||||
|
|
||||||
|
// Conditional data
|
||||||
|
Block::ConditionalData cond_data;
|
||||||
|
|
||||||
/// Intrusively store if the block is sealed in the SSA pass.
|
/// Intrusively store if the block is sealed in the SSA pass.
|
||||||
bool is_ssa_sealed{false};
|
bool is_ssa_sealed{false};
|
||||||
|
|
||||||
|
59
src/shader_recompiler/ir/conditional_tree.cpp
Normal file
59
src/shader_recompiler/ir/conditional_tree.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "shader_recompiler/ir/conditional_tree.h"
|
||||||
|
#include "shader_recompiler/ir/basic_block.h"
|
||||||
|
|
||||||
|
#include <span>
|
||||||
|
|
||||||
|
namespace Shader::IR {
|
||||||
|
|
||||||
|
static void AddConditionalTree(std::span<AbstractSyntaxNode> asl_span, Block::ConditionalData* parent) {
|
||||||
|
const auto get_span = [&asl_span](AbstractSyntaxNode& node, Block* merge_block) -> std::span<AbstractSyntaxNode> {
|
||||||
|
auto it = std::find_if(asl_span.begin(), asl_span.end(),
|
||||||
|
[&node, &merge_block](const AbstractSyntaxNode& n) {
|
||||||
|
return n.data.block == merge_block;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
ASSERT(it != asl_span.end());
|
||||||
|
std::ptrdiff_t merge_index = std::distance(asl_span.begin(), it);
|
||||||
|
return std::span<AbstractSyntaxNode>(&node + 1, asl_span.data() + merge_index);
|
||||||
|
};
|
||||||
|
const Block::ConditionalData* copied_parent = nullptr;
|
||||||
|
for (auto it = asl_span.begin(); it < asl_span.end(); ++it) {
|
||||||
|
AbstractSyntaxNode& node = *it;
|
||||||
|
if (node.type == AbstractSyntaxNode::Type::If || node.type == AbstractSyntaxNode::Type::Loop) {
|
||||||
|
ASSERT(copied_parent);
|
||||||
|
Block* merge_block;
|
||||||
|
switch (node.type) {
|
||||||
|
case AbstractSyntaxNode::Type::If:
|
||||||
|
merge_block = node.data.if_node.merge;
|
||||||
|
break;
|
||||||
|
case AbstractSyntaxNode::Type::Loop:
|
||||||
|
merge_block = node.data.loop.merge;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
auto subspan = get_span(node, merge_block);
|
||||||
|
Block::ConditionalData cond{copied_parent->depth + 1, copied_parent, &node};
|
||||||
|
AddConditionalTree(subspan, &cond);
|
||||||
|
it += subspan.size();
|
||||||
|
} else if (node.type == AbstractSyntaxNode::Type::Block) {
|
||||||
|
Block* block = node.data.block;
|
||||||
|
if (!copied_parent) {
|
||||||
|
block->SetConditionalData(*parent);
|
||||||
|
copied_parent = &block->CondData();
|
||||||
|
} else {
|
||||||
|
block->SetConditionalData(*copied_parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddConditionalTreeFromASL(AbstractSyntaxList& syntax_list) {
|
||||||
|
Block::ConditionalData cond{0, nullptr, nullptr};
|
||||||
|
AddConditionalTree(syntax_list, &cond);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Shader::IR
|
12
src/shader_recompiler/ir/conditional_tree.h
Normal file
12
src/shader_recompiler/ir/conditional_tree.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "shader_recompiler/ir/abstract_syntax_list.h"
|
||||||
|
|
||||||
|
namespace Shader::IR {
|
||||||
|
|
||||||
|
void AddConditionalTreeFromASL(AbstractSyntaxList& syntax_list);
|
||||||
|
|
||||||
|
} // namespace Shader::IR
|
@ -2,6 +2,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "shader_recompiler/frontend/control_flow_graph.h"
|
#include "shader_recompiler/frontend/control_flow_graph.h"
|
||||||
|
#include "shader_recompiler/ir/conditional_tree.h"
|
||||||
#include "shader_recompiler/frontend/decode.h"
|
#include "shader_recompiler/frontend/decode.h"
|
||||||
#include "shader_recompiler/frontend/structured_control_flow.h"
|
#include "shader_recompiler/frontend/structured_control_flow.h"
|
||||||
#include "shader_recompiler/ir/passes/ir_passes.h"
|
#include "shader_recompiler/ir/passes/ir_passes.h"
|
||||||
@ -58,6 +59,8 @@ IR::Program TranslateProgram(std::span<const u32> code, Pools& pools, Info& info
|
|||||||
program.info, runtime_info, profile);
|
program.info, runtime_info, profile);
|
||||||
program.blocks = GenerateBlocks(program.syntax_list);
|
program.blocks = GenerateBlocks(program.syntax_list);
|
||||||
program.post_order_blocks = Shader::IR::PostOrder(program.syntax_list.front());
|
program.post_order_blocks = Shader::IR::PostOrder(program.syntax_list.front());
|
||||||
|
|
||||||
|
Shader::IR::AddConditionalTreeFromASL(program.syntax_list);
|
||||||
|
|
||||||
// Run optimization passes
|
// Run optimization passes
|
||||||
Shader::Optimization::SsaRewritePass(program.post_order_blocks);
|
Shader::Optimization::SsaRewritePass(program.post_order_blocks);
|
||||||
|
Loading…
Reference in New Issue
Block a user