[ir][spirv-writer] Add support for parameters
Change the instruction->id map to a generic non-constant value->id map so that it can be used for other types of values. Bug: tint:1906 Change-Id: I79a0a7f671214167fa17ca903f9e94a54507d17c Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/134201 Reviewed-by: Dan Sinclair <dsinclair@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: James Price <jrprice@google.com>
This commit is contained in:
parent
f5a62539f4
commit
1ea7f0f351
|
@ -14,6 +14,8 @@
|
|||
|
||||
#include "src/tint/writer/spirv/ir/generator_impl_ir.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "spirv/unified1/spirv.h"
|
||||
#include "src/tint/ir/binary.h"
|
||||
#include "src/tint/ir/block.h"
|
||||
|
@ -191,17 +193,13 @@ uint32_t GeneratorImplIr::Value(const ir::Value* value) {
|
|||
return Switch(
|
||||
value, //
|
||||
[&](const ir::Constant* constant) { return Constant(constant); },
|
||||
[&](const ir::Instruction* inst) {
|
||||
auto id = instructions_.Find(inst);
|
||||
[&](const ir::Value*) {
|
||||
auto id = values_.Find(value);
|
||||
if (TINT_UNLIKELY(!id)) {
|
||||
TINT_ICE(Writer, diagnostics_) << "missing instruction result";
|
||||
TINT_ICE(Writer, diagnostics_) << "missing result ID for value";
|
||||
return 0u;
|
||||
}
|
||||
return *id;
|
||||
},
|
||||
[&](Default) {
|
||||
TINT_ICE(Writer, diagnostics_) << "unhandled value node: " << value->TypeInfo().name;
|
||||
return 0u;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -224,9 +222,22 @@ void GeneratorImplIr::EmitFunction(const ir::Function* func) {
|
|||
// Get the ID for the return type.
|
||||
auto return_type_id = Type(func->ReturnType());
|
||||
|
||||
// Get the ID for the function type (creating it if needed).
|
||||
// TODO(jrprice): Add the parameter types when they are supported in the IR.
|
||||
FunctionType function_type{return_type_id, {}};
|
||||
InstructionList params;
|
||||
|
||||
// Generate function parameter declarations and add their type IDs to the function signature.
|
||||
for (auto* param : func->Params()) {
|
||||
auto param_type_id = Type(param->Type());
|
||||
auto param_id = module_.NextId();
|
||||
params.push_back(Instruction(spv::Op::OpFunctionParameter, {param_type_id, param_id}));
|
||||
values_.Add(param, param_id);
|
||||
function_type.param_type_ids.Push(param_type_id);
|
||||
if (auto name = ir_->NameOf(param)) {
|
||||
module_.PushDebug(spv::Op::OpName, {param_id, Operand(name.Name())});
|
||||
}
|
||||
}
|
||||
|
||||
// Get the ID for the function type (creating it if needed).
|
||||
auto function_type_id = function_types_.GetOrCreate(function_type, [&]() {
|
||||
auto func_ty_id = module_.NextId();
|
||||
OperandList operands = {func_ty_id, return_type_id};
|
||||
|
@ -242,9 +253,8 @@ void GeneratorImplIr::EmitFunction(const ir::Function* func) {
|
|||
{return_type_id, id, U32Operand(SpvFunctionControlMaskNone), function_type_id}};
|
||||
|
||||
// Create a function that we will add instructions to.
|
||||
// TODO(jrprice): Add the parameter declarations when they are supported in the IR.
|
||||
auto entry_block = module_.NextId();
|
||||
current_function_ = Function(decl, entry_block, {});
|
||||
current_function_ = Function(decl, entry_block, std::move(params));
|
||||
TINT_DEFER(current_function_ = Function());
|
||||
|
||||
// Emit the body of the function.
|
||||
|
@ -323,7 +333,7 @@ void GeneratorImplIr::EmitBlock(const ir::Block* block) {
|
|||
<< "unimplemented instruction: " << inst->TypeInfo().name;
|
||||
return 0u;
|
||||
});
|
||||
instructions_.Add(inst, result);
|
||||
values_.Add(inst, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -171,8 +171,8 @@ class GeneratorImplIr {
|
|||
/// The map of constants to their result IDs.
|
||||
utils::Hashmap<const constant::Value*, uint32_t, 16> constants_;
|
||||
|
||||
/// The map of instructions to their result IDs.
|
||||
utils::Hashmap<const ir::Instruction*, uint32_t, 8> instructions_;
|
||||
/// The map of non-constant values to their result IDs.
|
||||
utils::Hashmap<const ir::Value*, uint32_t, 8> values_;
|
||||
|
||||
/// The map of blocks to the IDs of their label instructions.
|
||||
utils::Hashmap<const ir::Block*, uint32_t, 8> block_labels_;
|
||||
|
|
|
@ -155,5 +155,33 @@ OpFunctionEnd
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(SpvGeneratorImplTest, Function_Parameters) {
|
||||
auto* i32 = mod.types.i32();
|
||||
auto* x = b.FunctionParam(i32);
|
||||
auto* y = b.FunctionParam(i32);
|
||||
auto* result = b.Add(i32, x, y);
|
||||
auto* func = b.CreateFunction("foo", i32);
|
||||
func->SetParams(utils::Vector{x, y});
|
||||
func->StartTarget()->SetInstructions(
|
||||
utils::Vector{result, b.Branch(func->EndTarget(), utils::Vector{result})});
|
||||
mod.SetName(x, "x");
|
||||
mod.SetName(y, "y");
|
||||
|
||||
generator_.EmitFunction(func);
|
||||
EXPECT_EQ(DumpModule(generator_.Module()), R"(OpName %1 "foo"
|
||||
OpName %3 "x"
|
||||
OpName %4 "y"
|
||||
%2 = OpTypeInt 32 1
|
||||
%5 = OpTypeFunction %2 %2 %2
|
||||
%1 = OpFunction %2 None %5
|
||||
%3 = OpFunctionParameter %2
|
||||
%4 = OpFunctionParameter %2
|
||||
%6 = OpLabel
|
||||
%7 = OpIAdd %2 %3 %4
|
||||
OpReturnValue %7
|
||||
OpFunctionEnd
|
||||
)");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::writer::spirv
|
||||
|
|
Loading…
Reference in New Issue