mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-03 22:58:39 +00:00
cleanup. delete vaarg stuff. Smuggle format string in Info and flags
This commit is contained in:
parent
6b830f641c
commit
e69b2d410c
12 changed files with 52 additions and 160 deletions
|
@ -49,9 +49,7 @@ void EmitPrologue(EmitContext& ctx);
|
||||||
void EmitEpilogue(EmitContext& ctx);
|
void EmitEpilogue(EmitContext& ctx);
|
||||||
void EmitDiscard(EmitContext& ctx);
|
void EmitDiscard(EmitContext& ctx);
|
||||||
void EmitDiscardCond(EmitContext& ctx, Id condition);
|
void EmitDiscardCond(EmitContext& ctx, Id condition);
|
||||||
void EmitVaArg(EmitContext& ctx, IR::Inst* inst, Id arg, Id next);
|
void EmitDebugPrint(EmitContext& ctx, IR::Inst* inst, Id arg0, Id arg1, Id arg2, Id arg3, Id arg4);
|
||||||
Id EmitStringLiteral(EmitContext& ctx, IR::Inst* inst);
|
|
||||||
void EmitDebugPrint(EmitContext& ctx, IR::Inst* inst, Id fmt);
|
|
||||||
void EmitBarrier(EmitContext& ctx);
|
void EmitBarrier(EmitContext& ctx);
|
||||||
void EmitWorkgroupMemoryBarrier(EmitContext& ctx);
|
void EmitWorkgroupMemoryBarrier(EmitContext& ctx);
|
||||||
void EmitDeviceMemoryBarrier(EmitContext& ctx);
|
void EmitDeviceMemoryBarrier(EmitContext& ctx);
|
||||||
|
|
|
@ -55,45 +55,15 @@ void EmitEndPrimitive(EmitContext& ctx, const IR::Value& stream) {
|
||||||
throw NotImplementedException("Geometry streams");
|
throw NotImplementedException("Geometry streams");
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isEmptyInst(IR::Value val) {
|
void EmitDebugPrint(EmitContext& ctx, IR::Inst* inst, Id arg0, Id arg1, Id arg2, Id arg3, Id arg4) {
|
||||||
if (auto* inst = val.TryInstRecursive()) {
|
DebugPrintFlags flags = inst->Flags<DebugPrintFlags>();
|
||||||
return inst->GetOpcode() == IR::Opcode::Void;
|
const std::string& format_string = ctx.info.string_pool[flags.string_idx];
|
||||||
}
|
Id fmt = ctx.String(format_string);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmitVaArg(EmitContext& ctx, IR::Inst* inst, Id arg, Id next) {
|
std::array<Id, 5> fmt_args = {arg0, arg1, arg2, arg3, arg4};
|
||||||
IR::Value next_val = inst->Arg(1);
|
const std::span<Id> fmt_args_span =
|
||||||
u32 va_arglist_idx;
|
std::span<Id>(fmt_args.begin(), fmt_args.begin() + flags.num_args);
|
||||||
if (isEmptyInst(next_val)) {
|
ctx.OpDebugPrintf(fmt, fmt_args_span);
|
||||||
va_arglist_idx = ctx.va_arg_lists.size();
|
|
||||||
ctx.va_arg_lists.emplace_back();
|
|
||||||
} else {
|
|
||||||
va_arglist_idx = next_val.Inst()->Flags<VariadicArgInfo>().va_arg_idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.va_arg_lists[va_arglist_idx].push_back(arg);
|
|
||||||
auto va_info = inst->Flags<VariadicArgInfo>();
|
|
||||||
va_info.va_arg_idx.Assign(va_arglist_idx);
|
|
||||||
inst->SetFlags(va_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
Id EmitStringLiteral(EmitContext& ctx, IR::Inst* inst) {
|
|
||||||
// ctx.
|
|
||||||
return ctx.String(inst->StringLiteral());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmitDebugPrint(EmitContext& ctx, IR::Inst* inst, Id fmt) {
|
|
||||||
IR::Value arglist = inst->Arg(1);
|
|
||||||
boost::container::small_vector<Id, 4> fmt_arg_operands;
|
|
||||||
if (!isEmptyInst(arglist)) {
|
|
||||||
u32 va_arglist_idx = arglist.Inst()->Flags<VariadicArgInfo>().va_arg_idx;
|
|
||||||
const auto& va_arglist = ctx.va_arg_lists[va_arglist_idx];
|
|
||||||
// reverse the order
|
|
||||||
std::copy(va_arglist.rbegin(), va_arglist.rend(), std::back_inserter(fmt_arg_operands));
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.OpDebugPrintf(fmt, fmt_arg_operands);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Shader::Backend::SPIRV
|
} // namespace Shader::Backend::SPIRV
|
||||||
|
|
|
@ -644,7 +644,7 @@ private:
|
||||||
}
|
}
|
||||||
case StatementType::SetVariable: {
|
case StatementType::SetVariable: {
|
||||||
ensure_block();
|
ensure_block();
|
||||||
IR::IREmitter ir{*current_block};
|
IR::IREmitter ir{*current_block, info};
|
||||||
ir.SetGotoVariable(stmt.id, VisitExpr(ir, *stmt.op));
|
ir.SetGotoVariable(stmt.id, VisitExpr(ir, *stmt.op));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -653,7 +653,7 @@ private:
|
||||||
IR::Block* const merge_block{MergeBlock(parent, stmt)};
|
IR::Block* const merge_block{MergeBlock(parent, stmt)};
|
||||||
|
|
||||||
// Implement if header block
|
// Implement if header block
|
||||||
IR::IREmitter ir{*current_block};
|
IR::IREmitter ir{*current_block, info};
|
||||||
const IR::U1 cond{ir.ConditionRef(VisitExpr(ir, *stmt.cond))};
|
const IR::U1 cond{ir.ConditionRef(VisitExpr(ir, *stmt.cond))};
|
||||||
|
|
||||||
const size_t if_node_index{syntax_list.size()};
|
const size_t if_node_index{syntax_list.size()};
|
||||||
|
@ -703,7 +703,7 @@ private:
|
||||||
Visit(stmt, merge_block, continue_block);
|
Visit(stmt, merge_block, continue_block);
|
||||||
|
|
||||||
// The continue block is located at the end of the loop
|
// The continue block is located at the end of the loop
|
||||||
IR::IREmitter ir{*continue_block};
|
IR::IREmitter ir{*continue_block, info};
|
||||||
const IR::U1 cond{ir.ConditionRef(VisitExpr(ir, *stmt.cond))};
|
const IR::U1 cond{ir.ConditionRef(VisitExpr(ir, *stmt.cond))};
|
||||||
|
|
||||||
IR::Block* const body_block{syntax_list.at(body_block_index).data.block};
|
IR::Block* const body_block{syntax_list.at(body_block_index).data.block};
|
||||||
|
@ -739,7 +739,7 @@ private:
|
||||||
ensure_block();
|
ensure_block();
|
||||||
IR::Block* const skip_block{MergeBlock(parent, stmt)};
|
IR::Block* const skip_block{MergeBlock(parent, stmt)};
|
||||||
|
|
||||||
IR::IREmitter ir{*current_block};
|
IR::IREmitter ir{*current_block, info};
|
||||||
const IR::U1 cond{ir.ConditionRef(VisitExpr(ir, *stmt.cond))};
|
const IR::U1 cond{ir.ConditionRef(VisitExpr(ir, *stmt.cond))};
|
||||||
current_block->AddBranch(break_block);
|
current_block->AddBranch(break_block);
|
||||||
current_block->AddBranch(skip_block);
|
current_block->AddBranch(skip_block);
|
||||||
|
@ -759,7 +759,7 @@ private:
|
||||||
case StatementType::Return: {
|
case StatementType::Return: {
|
||||||
ensure_block();
|
ensure_block();
|
||||||
IR::Block* return_block{block_pool.Create(inst_pool)};
|
IR::Block* return_block{block_pool.Create(inst_pool)};
|
||||||
IR::IREmitter{*return_block}.Epilogue();
|
IR::IREmitter{*return_block, info}.Epilogue();
|
||||||
current_block->AddBranch(return_block);
|
current_block->AddBranch(return_block);
|
||||||
|
|
||||||
auto& merge{syntax_list.emplace_back()};
|
auto& merge{syntax_list.emplace_back()};
|
||||||
|
@ -773,7 +773,7 @@ private:
|
||||||
case StatementType::Kill: {
|
case StatementType::Kill: {
|
||||||
ensure_block();
|
ensure_block();
|
||||||
IR::Block* demote_block{MergeBlock(parent, stmt)};
|
IR::Block* demote_block{MergeBlock(parent, stmt)};
|
||||||
IR::IREmitter{*current_block}.Discard();
|
IR::IREmitter{*current_block, info}.Discard();
|
||||||
current_block->AddBranch(demote_block);
|
current_block->AddBranch(demote_block);
|
||||||
current_block = demote_block;
|
current_block = demote_block;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,8 @@ namespace Shader::Gcn {
|
||||||
|
|
||||||
Translator::Translator(IR::Block* block_, Info& info_, const RuntimeInfo& runtime_info_,
|
Translator::Translator(IR::Block* block_, Info& info_, const RuntimeInfo& runtime_info_,
|
||||||
const Profile& profile_)
|
const Profile& profile_)
|
||||||
: ir{*block_, block_->begin()}, info{info_}, runtime_info{runtime_info_}, profile{profile_} {}
|
: ir{*block_, block_->begin(), info_}, info{info_}, runtime_info{runtime_info_},
|
||||||
|
profile{profile_} {}
|
||||||
|
|
||||||
void Translator::EmitPrologue() {
|
void Translator::EmitPrologue() {
|
||||||
ir.Prologue();
|
ir.Prologue();
|
||||||
|
|
|
@ -179,6 +179,9 @@ struct Info {
|
||||||
std::span<const u32> user_data;
|
std::span<const u32> user_data;
|
||||||
Stage stage;
|
Stage stage;
|
||||||
|
|
||||||
|
using StringPool = boost::container::small_vector<std::string, 4>;
|
||||||
|
StringPool string_pool;
|
||||||
|
|
||||||
u64 pgm_hash{};
|
u64 pgm_hash{};
|
||||||
VAddr pgm_base;
|
VAddr pgm_base;
|
||||||
bool has_storage_images{};
|
bool has_storage_images{};
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#include "common/bit_field.h"
|
#include "common/bit_field.h"
|
||||||
#include "src/common/enum.h"
|
#include "src/common/types.h"
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
union VariadicArgInfo {
|
union DebugPrintFlags {
|
||||||
u32 raw;
|
u32 raw;
|
||||||
|
BitField<0, 16, u32> string_idx;
|
||||||
BitField<0, 12, u32> va_arg_idx;
|
BitField<16, 16, u32> num_args;
|
||||||
};
|
};
|
|
@ -1,15 +1,13 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <bit>
|
#include <bit>
|
||||||
#include <iterator>
|
|
||||||
#include <source_location>
|
#include <source_location>
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
#include "common/assert.h"
|
|
||||||
#include "shader_recompiler/exception.h"
|
#include "shader_recompiler/exception.h"
|
||||||
#include "shader_recompiler/ir/debug_print.h"
|
#include "shader_recompiler/ir/debug_print.h"
|
||||||
#include "shader_recompiler/ir/ir_emitter.h"
|
#include "shader_recompiler/ir/ir_emitter.h"
|
||||||
#include "shader_recompiler/ir/opcodes.h"
|
|
||||||
#include "shader_recompiler/ir/value.h"
|
#include "shader_recompiler/ir/value.h"
|
||||||
|
|
||||||
namespace Shader::IR {
|
namespace Shader::IR {
|
||||||
|
@ -1558,72 +1556,27 @@ void IREmitter::ImageWrite(const Value& handle, const Value& coords, const Value
|
||||||
Inst(Opcode::ImageWrite, Flags{info}, handle, coords, color);
|
Inst(Opcode::ImageWrite, Flags{info}, handle, coords, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value IREmitter::VaArg(Value arg, Value next) {
|
void IREmitter::DebugPrint(std::string_view format,
|
||||||
return Inst(Opcode::VaArg, arg, next);
|
boost::container::small_vector<Value, 5> format_args,
|
||||||
}
|
|
||||||
|
|
||||||
Value IREmitter::StringLiteral(std::string_view s) {
|
|
||||||
Value val = Inst(Opcode::StringLiteral);
|
|
||||||
val.Inst()->SetStringLiteral(s);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IREmitter::DebugPrint(std::string_view format, boost::container::small_vector<Value, 4> args,
|
|
||||||
bool infer_specifiers) {
|
bool infer_specifiers) {
|
||||||
auto infer_specifier = [&](IR::Value arg) -> const char* {
|
std::array<Value, 5> args;
|
||||||
switch (arg.Type()) {
|
|
||||||
case Shader::IR::Type::U1:
|
|
||||||
case Shader::IR::Type::U8:
|
|
||||||
case Shader::IR::Type::U16:
|
|
||||||
case Shader::IR::Type::U32:
|
|
||||||
return "%u";
|
|
||||||
case Shader::IR::Type::U64:
|
|
||||||
return "%lu";
|
|
||||||
case Shader::IR::Type::F16:
|
|
||||||
case Shader::IR::Type::F32:
|
|
||||||
case Shader::IR::Type::F64:
|
|
||||||
return "%lf";
|
|
||||||
case Shader::IR::Type::U32x2:
|
|
||||||
return "%v2u";
|
|
||||||
case Shader::IR::Type::U32x3:
|
|
||||||
return "%v3u";
|
|
||||||
case Shader::IR::Type::U32x4:
|
|
||||||
return "%v4u";
|
|
||||||
case Shader::IR::Type::F16x2:
|
|
||||||
case Shader::IR::Type::F32x2:
|
|
||||||
case Shader::IR::Type::F64x2:
|
|
||||||
return "%v2f";
|
|
||||||
case Shader::IR::Type::F16x3:
|
|
||||||
case Shader::IR::Type::F32x3:
|
|
||||||
case Shader::IR::Type::F64x3:
|
|
||||||
return "%v3f";
|
|
||||||
case Shader::IR::Type::F16x4:
|
|
||||||
case Shader::IR::Type::F32x4:
|
|
||||||
case Shader::IR::Type::F64x4:
|
|
||||||
return "%v4f";
|
|
||||||
case Shader::IR::Type::Void:
|
|
||||||
case Shader::IR::Type::Opaque:
|
|
||||||
case Shader::IR::Type::ScalarReg:
|
|
||||||
case Shader::IR::Type::VectorReg:
|
|
||||||
case Shader::IR::Type::Attribute:
|
|
||||||
case Shader::IR::Type::SystemValue:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (infer_specifiers) {
|
for (int i = 0; i < format_args.size(); i++) {
|
||||||
UNREACHABLE();
|
args[i] = format_args[i];
|
||||||
// need to fmt the format string with dynamic sized array of format spec strings
|
|
||||||
// could use param pack for this function, but less flexible
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Value arg_list = Inst(Opcode::Void);
|
for (int i = format_args.size(); i < 4; i++) {
|
||||||
for (Value arg : args) {
|
args[i] = Inst(Opcode::Void);
|
||||||
arg_list = VaArg(arg, arg_list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Value string_val = StringLiteral(format);
|
Value val = Inst(Opcode::DebugPrint, args[0], args[1], args[2], args[3], args[4]);
|
||||||
Inst(Opcode::DebugPrint, string_val, arg_list);
|
DebugPrintFlags flags;
|
||||||
|
|
||||||
|
flags.string_idx.Assign(info.string_pool.size());
|
||||||
|
info.string_pool.emplace_back(format);
|
||||||
|
flags.num_args.Assign(format_args.size());
|
||||||
|
|
||||||
|
val.Inst()->SetFlags<DebugPrintFlags>(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Shader::IR
|
} // namespace Shader::IR
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
|
|
||||||
|
#include "shader_recompiler/info.h"
|
||||||
#include "shader_recompiler/ir/attribute.h"
|
#include "shader_recompiler/ir/attribute.h"
|
||||||
#include "shader_recompiler/ir/basic_block.h"
|
#include "shader_recompiler/ir/basic_block.h"
|
||||||
#include "shader_recompiler/ir/condition.h"
|
#include "shader_recompiler/ir/condition.h"
|
||||||
|
@ -17,9 +18,10 @@ namespace Shader::IR {
|
||||||
|
|
||||||
class IREmitter {
|
class IREmitter {
|
||||||
public:
|
public:
|
||||||
explicit IREmitter(Block& block_) : block{&block_}, insertion_point{block->end()} {}
|
explicit IREmitter(Block& block_, Shader::Info& info_)
|
||||||
explicit IREmitter(Block& block_, Block::iterator insertion_point_)
|
: block{&block_}, insertion_point{block->end()}, info(info_) {}
|
||||||
: block{&block_}, insertion_point{insertion_point_} {}
|
explicit IREmitter(Block& block_, Block::iterator insertion_point_, Shader::Info& info_)
|
||||||
|
: block{&block_}, insertion_point{insertion_point_}, info(info_) {}
|
||||||
|
|
||||||
Block* block;
|
Block* block;
|
||||||
|
|
||||||
|
@ -45,11 +47,7 @@ public:
|
||||||
void Epilogue();
|
void Epilogue();
|
||||||
void Discard();
|
void Discard();
|
||||||
void Discard(const U1& cond);
|
void Discard(const U1& cond);
|
||||||
|
void DebugPrint(std::string_view format, boost::container::small_vector<Value, 5> args,
|
||||||
Value VaArg(Value arg, Value next);
|
|
||||||
Value StringLiteral(std::string_view s);
|
|
||||||
|
|
||||||
void DebugPrint(std::string_view format, boost::container::small_vector<Value, 4> args,
|
|
||||||
bool infer_specifiers = false);
|
bool infer_specifiers = false);
|
||||||
|
|
||||||
void Barrier();
|
void Barrier();
|
||||||
|
@ -320,6 +318,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IR::Block::iterator insertion_point;
|
IR::Block::iterator insertion_point;
|
||||||
|
Shader::Info& info;
|
||||||
|
|
||||||
template <typename T = Value, typename... Args>
|
template <typename T = Value, typename... Args>
|
||||||
T Inst(Opcode op, Args... args) {
|
T Inst(Opcode op, Args... args) {
|
||||||
|
|
|
@ -14,8 +14,6 @@ namespace Shader::IR {
|
||||||
Inst::Inst(IR::Opcode op_, u32 flags_) noexcept : op{op_}, flags{flags_} {
|
Inst::Inst(IR::Opcode op_, u32 flags_) noexcept : op{op_}, flags{flags_} {
|
||||||
if (op == Opcode::Phi) {
|
if (op == Opcode::Phi) {
|
||||||
std::construct_at(&phi_args);
|
std::construct_at(&phi_args);
|
||||||
} else if (op == Opcode::StringLiteral) {
|
|
||||||
std::construct_at(&string_literal);
|
|
||||||
} else {
|
} else {
|
||||||
std::construct_at(&args);
|
std::construct_at(&args);
|
||||||
}
|
}
|
||||||
|
@ -24,8 +22,6 @@ Inst::Inst(IR::Opcode op_, u32 flags_) noexcept : op{op_}, flags{flags_} {
|
||||||
Inst::Inst(const Inst& base) : op{base.op}, flags{base.flags} {
|
Inst::Inst(const Inst& base) : op{base.op}, flags{base.flags} {
|
||||||
if (base.op == Opcode::Phi) {
|
if (base.op == Opcode::Phi) {
|
||||||
throw NotImplementedException("Copying phi node");
|
throw NotImplementedException("Copying phi node");
|
||||||
} else if (base.op == Opcode::StringLiteral) {
|
|
||||||
std::construct_at(&string_literal, base.string_literal);
|
|
||||||
} else {
|
} else {
|
||||||
std::construct_at(&args);
|
std::construct_at(&args);
|
||||||
const size_t num_args{base.NumArgs()};
|
const size_t num_args{base.NumArgs()};
|
||||||
|
@ -38,8 +34,6 @@ Inst::Inst(const Inst& base) : op{base.op}, flags{base.flags} {
|
||||||
Inst::~Inst() {
|
Inst::~Inst() {
|
||||||
if (op == Opcode::Phi) {
|
if (op == Opcode::Phi) {
|
||||||
std::destroy_at(&phi_args);
|
std::destroy_at(&phi_args);
|
||||||
} else if (op == Opcode::StringLiteral) {
|
|
||||||
std::destroy_at(&string_literal);
|
|
||||||
} else {
|
} else {
|
||||||
std::destroy_at(&args);
|
std::destroy_at(&args);
|
||||||
}
|
}
|
||||||
|
@ -107,9 +101,6 @@ bool Inst::AreAllArgsImmediates() const {
|
||||||
if (op == Opcode::Phi) {
|
if (op == Opcode::Phi) {
|
||||||
UNREACHABLE_MSG("Testing for all arguments are immediates on phi instruction");
|
UNREACHABLE_MSG("Testing for all arguments are immediates on phi instruction");
|
||||||
}
|
}
|
||||||
if (op == Opcode::StringLiteral) {
|
|
||||||
UNREACHABLE_MSG("Testing for all arguments are immediates on StringLiteral instruction");
|
|
||||||
}
|
|
||||||
return std::all_of(args.begin(), args.begin() + NumArgs(),
|
return std::all_of(args.begin(), args.begin() + NumArgs(),
|
||||||
[](const IR::Value& value) { return value.IsImmediate(); });
|
[](const IR::Value& value) { return value.IsImmediate(); });
|
||||||
}
|
}
|
||||||
|
@ -131,8 +122,6 @@ void Inst::SetArg(size_t index, Value value) {
|
||||||
}
|
}
|
||||||
if (op == Opcode::Phi) {
|
if (op == Opcode::Phi) {
|
||||||
phi_args[index].second = value;
|
phi_args[index].second = value;
|
||||||
} else if (op == Opcode::StringLiteral) {
|
|
||||||
UNREACHABLE_MSG("SetArg on StringLiteral instruction");
|
|
||||||
} else {
|
} else {
|
||||||
args[index] = value;
|
args[index] = value;
|
||||||
}
|
}
|
||||||
|
@ -169,8 +158,6 @@ void Inst::ClearArgs() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
phi_args.clear();
|
phi_args.clear();
|
||||||
} else if (op == Opcode::StringLiteral) {
|
|
||||||
string_literal.clear();
|
|
||||||
} else {
|
} else {
|
||||||
for (auto& value : args) {
|
for (auto& value : args) {
|
||||||
if (!value.IsImmediate()) {
|
if (!value.IsImmediate()) {
|
||||||
|
@ -196,9 +183,6 @@ void Inst::ReplaceOpcode(IR::Opcode opcode) {
|
||||||
if (opcode == IR::Opcode::Phi) {
|
if (opcode == IR::Opcode::Phi) {
|
||||||
UNREACHABLE_MSG("Cannot transition into Phi");
|
UNREACHABLE_MSG("Cannot transition into Phi");
|
||||||
}
|
}
|
||||||
if (op == IR::Opcode::StringLiteral || opcode == IR::Opcode::StringLiteral) {
|
|
||||||
UNREACHABLE_MSG("Cannot transition to or from StringLiteral");
|
|
||||||
}
|
|
||||||
if (op == Opcode::Phi) {
|
if (op == Opcode::Phi) {
|
||||||
// Transition out of phi arguments into non-phi
|
// Transition out of phi arguments into non-phi
|
||||||
std::destroy_at(&phi_args);
|
std::destroy_at(&phi_args);
|
||||||
|
|
|
@ -14,9 +14,7 @@ OPCODE(Prologue, Void,
|
||||||
OPCODE(Epilogue, Void, )
|
OPCODE(Epilogue, Void, )
|
||||||
OPCODE(Discard, Void, )
|
OPCODE(Discard, Void, )
|
||||||
OPCODE(DiscardCond, Void, U1, )
|
OPCODE(DiscardCond, Void, U1, )
|
||||||
OPCODE(DebugPrint, Void, Opaque, Opaque, )
|
OPCODE(DebugPrint, Void, Opaque, Opaque, Opaque, Opaque, Opaque, )
|
||||||
OPCODE(VaArg, Opaque, Opaque, Opaque )
|
|
||||||
OPCODE(StringLiteral, Opaque, )
|
|
||||||
|
|
||||||
// Constant memory operations
|
// Constant memory operations
|
||||||
OPCODE(ReadConst, U32, U32x2, U32, )
|
OPCODE(ReadConst, U32, U32x2, U32, )
|
||||||
|
|
|
@ -377,7 +377,7 @@ void PatchBufferInstruction(IR::Block& block, IR::Inst& inst, Info& info,
|
||||||
const auto inst_info = inst.Flags<IR::BufferInstInfo>();
|
const auto inst_info = inst.Flags<IR::BufferInstInfo>();
|
||||||
|
|
||||||
// Replace handle with binding index in buffer resource list.
|
// Replace handle with binding index in buffer resource list.
|
||||||
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
|
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst), info};
|
||||||
inst.SetArg(0, ir.Imm32(binding));
|
inst.SetArg(0, ir.Imm32(binding));
|
||||||
ASSERT(!buffer.add_tid_enable);
|
ASSERT(!buffer.add_tid_enable);
|
||||||
|
|
||||||
|
@ -436,7 +436,7 @@ void PatchTextureBufferInstruction(IR::Block& block, IR::Inst& inst, Info& info,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Replace handle with binding index in texture buffer resource list.
|
// Replace handle with binding index in texture buffer resource list.
|
||||||
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
|
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst), info};
|
||||||
inst.SetArg(0, ir.Imm32(binding));
|
inst.SetArg(0, ir.Imm32(binding));
|
||||||
ASSERT(!buffer.swizzle_enable && !buffer.add_tid_enable);
|
ASSERT(!buffer.swizzle_enable && !buffer.add_tid_enable);
|
||||||
}
|
}
|
||||||
|
@ -534,7 +534,7 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
|
||||||
image_binding |= (sampler_binding << 16);
|
image_binding |= (sampler_binding << 16);
|
||||||
|
|
||||||
// Patch image handle
|
// Patch image handle
|
||||||
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
|
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst), info};
|
||||||
inst.SetArg(0, ir.Imm32(image_binding));
|
inst.SetArg(0, ir.Imm32(image_binding));
|
||||||
|
|
||||||
// No need to patch coordinates if we are just querying.
|
// No need to patch coordinates if we are just querying.
|
||||||
|
@ -667,7 +667,7 @@ void PatchDataRingInstruction(IR::Block& block, IR::Inst& inst, Info& info,
|
||||||
}();
|
}();
|
||||||
|
|
||||||
// Patch instruction.
|
// Patch instruction.
|
||||||
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
|
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst), info};
|
||||||
inst.SetArg(0, ir.Imm32(gds_addr >> 2));
|
inst.SetArg(0, ir.Imm32(gds_addr >> 2));
|
||||||
inst.SetArg(1, ir.Imm32(binding));
|
inst.SetArg(1, ir.Imm32(binding));
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,9 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <bit>
|
#include <bit>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string_view>
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
#include <boost/container/string.hpp>
|
|
||||||
#include <boost/intrusive/list.hpp>
|
#include <boost/intrusive/list.hpp>
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
@ -148,7 +146,6 @@ public:
|
||||||
if (op == IR::Opcode::Phi) {
|
if (op == IR::Opcode::Phi) {
|
||||||
return phi_args[index].second;
|
return phi_args[index].second;
|
||||||
} else {
|
} else {
|
||||||
ASSERT(op != IR::Opcode::StringLiteral);
|
|
||||||
return args[index];
|
return args[index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,16 +158,6 @@ public:
|
||||||
/// Add phi operand to a phi instruction.
|
/// Add phi operand to a phi instruction.
|
||||||
void AddPhiOperand(Block* predecessor, const Value& value);
|
void AddPhiOperand(Block* predecessor, const Value& value);
|
||||||
|
|
||||||
[[nodiscard]] std::string_view StringLiteral() const {
|
|
||||||
ASSERT(op == IR::Opcode::StringLiteral);
|
|
||||||
return string_literal;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetStringLiteral(std::string_view s) noexcept {
|
|
||||||
ASSERT(op == IR::Opcode::StringLiteral);
|
|
||||||
string_literal = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Invalidate();
|
void Invalidate();
|
||||||
void ClearArgs();
|
void ClearArgs();
|
||||||
|
|
||||||
|
@ -220,7 +207,6 @@ private:
|
||||||
NonTriviallyDummy dummy{};
|
NonTriviallyDummy dummy{};
|
||||||
boost::container::small_vector<std::pair<Block*, Value>, 2> phi_args;
|
boost::container::small_vector<std::pair<Block*, Value>, 2> phi_args;
|
||||||
std::array<Value, 5> args;
|
std::array<Value, 5> args;
|
||||||
boost::container::string string_literal;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
static_assert(sizeof(Inst) <= 128, "Inst size unintentionally increased");
|
static_assert(sizeof(Inst) <= 128, "Inst size unintentionally increased");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue