[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 "src/tint/writer/spirv/ir/generator_impl_ir.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "spirv/unified1/spirv.h"
|
#include "spirv/unified1/spirv.h"
|
||||||
#include "src/tint/ir/binary.h"
|
#include "src/tint/ir/binary.h"
|
||||||
#include "src/tint/ir/block.h"
|
#include "src/tint/ir/block.h"
|
||||||
|
@ -191,17 +193,13 @@ uint32_t GeneratorImplIr::Value(const ir::Value* value) {
|
||||||
return Switch(
|
return Switch(
|
||||||
value, //
|
value, //
|
||||||
[&](const ir::Constant* constant) { return Constant(constant); },
|
[&](const ir::Constant* constant) { return Constant(constant); },
|
||||||
[&](const ir::Instruction* inst) {
|
[&](const ir::Value*) {
|
||||||
auto id = instructions_.Find(inst);
|
auto id = values_.Find(value);
|
||||||
if (TINT_UNLIKELY(!id)) {
|
if (TINT_UNLIKELY(!id)) {
|
||||||
TINT_ICE(Writer, diagnostics_) << "missing instruction result";
|
TINT_ICE(Writer, diagnostics_) << "missing result ID for value";
|
||||||
return 0u;
|
return 0u;
|
||||||
}
|
}
|
||||||
return *id;
|
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.
|
// Get the ID for the return type.
|
||||||
auto return_type_id = Type(func->ReturnType());
|
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, {}};
|
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 function_type_id = function_types_.GetOrCreate(function_type, [&]() {
|
||||||
auto func_ty_id = module_.NextId();
|
auto func_ty_id = module_.NextId();
|
||||||
OperandList operands = {func_ty_id, return_type_id};
|
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}};
|
{return_type_id, id, U32Operand(SpvFunctionControlMaskNone), function_type_id}};
|
||||||
|
|
||||||
// Create a function that we will add instructions to.
|
// 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();
|
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());
|
TINT_DEFER(current_function_ = Function());
|
||||||
|
|
||||||
// Emit the body of the function.
|
// Emit the body of the function.
|
||||||
|
@ -323,7 +333,7 @@ void GeneratorImplIr::EmitBlock(const ir::Block* block) {
|
||||||
<< "unimplemented instruction: " << inst->TypeInfo().name;
|
<< "unimplemented instruction: " << inst->TypeInfo().name;
|
||||||
return 0u;
|
return 0u;
|
||||||
});
|
});
|
||||||
instructions_.Add(inst, result);
|
values_.Add(inst, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -171,8 +171,8 @@ class GeneratorImplIr {
|
||||||
/// The map of constants to their result IDs.
|
/// The map of constants to their result IDs.
|
||||||
utils::Hashmap<const constant::Value*, uint32_t, 16> constants_;
|
utils::Hashmap<const constant::Value*, uint32_t, 16> constants_;
|
||||||
|
|
||||||
/// The map of instructions to their result IDs.
|
/// The map of non-constant values to their result IDs.
|
||||||
utils::Hashmap<const ir::Instruction*, uint32_t, 8> instructions_;
|
utils::Hashmap<const ir::Value*, uint32_t, 8> values_;
|
||||||
|
|
||||||
/// The map of blocks to the IDs of their label instructions.
|
/// The map of blocks to the IDs of their label instructions.
|
||||||
utils::Hashmap<const ir::Block*, uint32_t, 8> block_labels_;
|
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
|
||||||
} // namespace tint::writer::spirv
|
} // namespace tint::writer::spirv
|
||||||
|
|
Loading…
Reference in New Issue