mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-27 12:34:37 +00:00
Add IR dumping from my read-const branch
This commit is contained in:
parent
87b3771285
commit
0d9337b1f9
@ -856,6 +856,7 @@ set(SHADER_RECOMPILER src/shader_recompiler/exception.h
|
|||||||
src/shader_recompiler/ir/passes/shared_memory_barrier_pass.cpp
|
src/shader_recompiler/ir/passes/shared_memory_barrier_pass.cpp
|
||||||
src/shader_recompiler/ir/passes/shared_memory_to_storage_pass.cpp
|
src/shader_recompiler/ir/passes/shared_memory_to_storage_pass.cpp
|
||||||
src/shader_recompiler/ir/passes/ssa_rewrite_pass.cpp
|
src/shader_recompiler/ir/passes/ssa_rewrite_pass.cpp
|
||||||
|
src/shader_recompiler/ir/abstract_syntax_list.cpp
|
||||||
src/shader_recompiler/ir/abstract_syntax_list.h
|
src/shader_recompiler/ir/abstract_syntax_list.h
|
||||||
src/shader_recompiler/ir/attribute.cpp
|
src/shader_recompiler/ir/attribute.cpp
|
||||||
src/shader_recompiler/ir/attribute.h
|
src/shader_recompiler/ir/attribute.h
|
||||||
|
44
src/shader_recompiler/ir/abstract_syntax_list.cpp
Normal file
44
src/shader_recompiler/ir/abstract_syntax_list.cpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "abstract_syntax_list.h"
|
||||||
|
|
||||||
|
namespace Shader::IR {
|
||||||
|
|
||||||
|
std::string DumpASLNode(const AbstractSyntaxNode& node,
|
||||||
|
const std::map<const Block*, size_t>& block_to_index,
|
||||||
|
const std::map<const Inst*, size_t>& inst_to_index) {
|
||||||
|
switch (node.type) {
|
||||||
|
case AbstractSyntaxNode::Type::Block:
|
||||||
|
return fmt::format("Block: ${}", block_to_index.at(node.data.block));
|
||||||
|
case AbstractSyntaxNode::Type::If:
|
||||||
|
return fmt::format("If: cond = %{}, body = ${}, merge = ${}",
|
||||||
|
inst_to_index.at(node.data.if_node.cond.Inst()),
|
||||||
|
block_to_index.at(node.data.if_node.body),
|
||||||
|
block_to_index.at(node.data.if_node.merge));
|
||||||
|
case AbstractSyntaxNode::Type::EndIf:
|
||||||
|
return fmt::format("EndIf: merge = ${}", block_to_index.at(node.data.end_if.merge));
|
||||||
|
case AbstractSyntaxNode::Type::Loop:
|
||||||
|
return fmt::format("Loop: body = ${}, continue = ${}, merge = ${}",
|
||||||
|
block_to_index.at(node.data.loop.body),
|
||||||
|
block_to_index.at(node.data.loop.continue_block),
|
||||||
|
block_to_index.at(node.data.loop.merge));
|
||||||
|
case AbstractSyntaxNode::Type::Repeat:
|
||||||
|
return fmt::format("Repeat: cond = %{}, header = ${}, merge = ${}",
|
||||||
|
inst_to_index.at(node.data.repeat.cond.Inst()),
|
||||||
|
block_to_index.at(node.data.repeat.loop_header),
|
||||||
|
block_to_index.at(node.data.repeat.merge));
|
||||||
|
case AbstractSyntaxNode::Type::Break:
|
||||||
|
return fmt::format("Break: cond = %{}, merge = ${}, skip = ${}",
|
||||||
|
inst_to_index.at(node.data.break_node.cond.Inst()),
|
||||||
|
block_to_index.at(node.data.break_node.merge),
|
||||||
|
block_to_index.at(node.data.break_node.skip));
|
||||||
|
case AbstractSyntaxNode::Type::Return:
|
||||||
|
return "Return";
|
||||||
|
case AbstractSyntaxNode::Type::Unreachable:
|
||||||
|
return "Unreachable";
|
||||||
|
};
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Shader::IR
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "shader_recompiler/ir/value.h"
|
#include "shader_recompiler/ir/value.h"
|
||||||
|
|
||||||
@ -53,4 +54,8 @@ struct AbstractSyntaxNode {
|
|||||||
};
|
};
|
||||||
using AbstractSyntaxList = std::vector<AbstractSyntaxNode>;
|
using AbstractSyntaxList = std::vector<AbstractSyntaxNode>;
|
||||||
|
|
||||||
|
std::string DumpASLNode(const AbstractSyntaxNode& node,
|
||||||
|
const std::map<const Block*, size_t>& block_to_index,
|
||||||
|
const std::map<const Inst*, size_t>& inst_to_index);
|
||||||
|
|
||||||
} // namespace Shader::IR
|
} // namespace Shader::IR
|
||||||
|
@ -6,13 +6,30 @@
|
|||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include "common/config.h"
|
||||||
|
#include "common/io_file.h"
|
||||||
|
#include "common/path_util.h"
|
||||||
#include "shader_recompiler/ir/basic_block.h"
|
#include "shader_recompiler/ir/basic_block.h"
|
||||||
#include "shader_recompiler/ir/program.h"
|
#include "shader_recompiler/ir/program.h"
|
||||||
#include "shader_recompiler/ir/value.h"
|
#include "shader_recompiler/ir/value.h"
|
||||||
|
|
||||||
namespace Shader::IR {
|
namespace Shader::IR {
|
||||||
|
|
||||||
std::string DumpProgram(const Program& program) {
|
void DumpProgram(const Program& program, const Info& info, const std::string& type) {
|
||||||
|
using namespace Common::FS;
|
||||||
|
|
||||||
|
if (!Config::dumpShaders()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto dump_dir = GetUserPath(PathType::ShaderDir) / "dumps";
|
||||||
|
if (!std::filesystem::exists(dump_dir)) {
|
||||||
|
std::filesystem::create_directories(dump_dir);
|
||||||
|
}
|
||||||
|
const auto ir_filename =
|
||||||
|
fmt::format("{}_{:#018x}.{}irprogram.txt", info.stage, info.pgm_hash, type);
|
||||||
|
const auto ir_file = IOFile{dump_dir / ir_filename, FileAccessMode::Write, FileType::TextFile};
|
||||||
|
|
||||||
size_t index{0};
|
size_t index{0};
|
||||||
std::map<const IR::Inst*, size_t> inst_to_index;
|
std::map<const IR::Inst*, size_t> inst_to_index;
|
||||||
std::map<const IR::Block*, size_t> block_to_index;
|
std::map<const IR::Block*, size_t> block_to_index;
|
||||||
@ -21,11 +38,20 @@ std::string DumpProgram(const Program& program) {
|
|||||||
block_to_index.emplace(block, index);
|
block_to_index.emplace(block, index);
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
std::string ret;
|
|
||||||
for (const auto& block : program.blocks) {
|
for (const auto& block : program.blocks) {
|
||||||
ret += IR::DumpBlock(*block, block_to_index, inst_to_index, index) + '\n';
|
std::string s = IR::DumpBlock(*block, block_to_index, inst_to_index, index) + '\n';
|
||||||
|
ir_file.WriteString(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto asl_filename = fmt::format("{}_{:#018x}.{}asl.txt", info.stage, info.pgm_hash, type);
|
||||||
|
const auto asl_file =
|
||||||
|
IOFile{dump_dir / asl_filename, FileAccessMode::Write, FileType::TextFile};
|
||||||
|
|
||||||
|
for (const auto& node : program.syntax_list) {
|
||||||
|
std::string s = IR::DumpASLNode(node, block_to_index, inst_to_index) + '\n';
|
||||||
|
asl_file.WriteString(s);
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Shader::IR
|
} // namespace Shader::IR
|
||||||
|
@ -21,6 +21,6 @@ struct Program {
|
|||||||
Info& info;
|
Info& info;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] std::string DumpProgram(const Program& program);
|
void DumpProgram(const Program& program, const Info& info, const std::string& type = "");
|
||||||
|
|
||||||
} // namespace Shader::IR
|
} // namespace Shader::IR
|
||||||
|
@ -85,6 +85,8 @@ IR::Program TranslateProgram(std::span<const u32> code, Pools& pools, Info& info
|
|||||||
Shader::Optimization::ConstantPropagationPass(program.post_order_blocks);
|
Shader::Optimization::ConstantPropagationPass(program.post_order_blocks);
|
||||||
Shader::Optimization::CollectShaderInfoPass(program);
|
Shader::Optimization::CollectShaderInfoPass(program);
|
||||||
|
|
||||||
|
Shader::IR::DumpProgram(program, info);
|
||||||
|
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user