mirror of
https://gitee.com/openharmony/third_party_spirv-tools
synced 2024-11-23 07:20:28 +00:00
linker: Recalculate interface variables (#4784)
* linker: Recalculate interface variables By resolving extern symbols Entry Points might access variables they hadn't declared before. * test/linker: add test to verify linked spir-vs importing functions validate Without the fix Validate will complain about: "ERROR: 9: Interface variable id <5> is used by entry point 'bar' id <1>, but is not listed as an interface\n %5 = OpVariable %_ptr_Input_v3uint Input\n"
This commit is contained in:
parent
46492aa45a
commit
edaf51038b
@ -34,6 +34,7 @@
|
||||
#include "source/opt/ir_loader.h"
|
||||
#include "source/opt/pass_manager.h"
|
||||
#include "source/opt/remove_duplicates_pass.h"
|
||||
#include "source/opt/remove_unused_interface_variables_pass.h"
|
||||
#include "source/opt/type_manager.h"
|
||||
#include "source/spirv_constant.h"
|
||||
#include "source/spirv_target_env.h"
|
||||
@ -807,11 +808,16 @@ spv_result_t Link(const Context& context, const uint32_t* const* binaries,
|
||||
pass_res = manager.Run(&linked_context);
|
||||
if (pass_res == opt::Pass::Status::Failure) return SPV_ERROR_INVALID_DATA;
|
||||
|
||||
// Phase 11: Warn if SPIR-V limits were exceeded
|
||||
// Phase 11: Recompute EntryPoint variables
|
||||
manager.AddPass<opt::RemoveUnusedInterfaceVariablesPass>();
|
||||
pass_res = manager.Run(&linked_context);
|
||||
if (pass_res == opt::Pass::Status::Failure) return SPV_ERROR_INVALID_DATA;
|
||||
|
||||
// Phase 12: Warn if SPIR-V limits were exceeded
|
||||
res = VerifyLimits(consumer, linked_context);
|
||||
if (res != SPV_SUCCESS) return res;
|
||||
|
||||
// Phase 12: Output the module
|
||||
// Phase 13: Output the module
|
||||
linked_context.module()->ToBinary(linked_binary, true);
|
||||
|
||||
return SPV_SUCCESS;
|
||||
|
@ -104,5 +104,48 @@ OpFunctionEnd
|
||||
"GLCompute, was already defined."));
|
||||
}
|
||||
|
||||
TEST_F(EntryPoints, LinkedVariables) {
|
||||
const std::string body1 = R"(
|
||||
OpCapability Addresses
|
||||
OpCapability Linkage
|
||||
OpCapability Kernel
|
||||
OpMemoryModel Physical64 OpenCL
|
||||
OpDecorate %7 LinkageAttributes "foo" Export
|
||||
%1 = OpTypeInt 32 0
|
||||
%2 = OpTypeVector %1 3
|
||||
%3 = OpTypePointer Input %2
|
||||
%4 = OpVariable %3 Input
|
||||
%5 = OpTypeVoid
|
||||
%6 = OpTypeFunction %5
|
||||
%7 = OpFunction %5 None %6
|
||||
%8 = OpLabel
|
||||
%9 = OpLoad %2 %4 Aligned 32
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
const std::string body2 = R"(
|
||||
OpCapability Linkage
|
||||
OpCapability Kernel
|
||||
OpMemoryModel Physical64 OpenCL
|
||||
OpEntryPoint Kernel %4 "bar"
|
||||
OpDecorate %3 LinkageAttributes "foo" Import
|
||||
%1 = OpTypeVoid
|
||||
%2 = OpTypeFunction %1
|
||||
%3 = OpFunction %1 None %2
|
||||
OpFunctionEnd
|
||||
%4 = OpFunction %1 None %2
|
||||
%5 = OpLabel
|
||||
%6 = OpFunctionCall %1 %3
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
spvtest::Binary linked_binary;
|
||||
EXPECT_EQ(SPV_SUCCESS, AssembleAndLink({body1, body2}, &linked_binary));
|
||||
EXPECT_THAT(GetErrorMessage(), std::string());
|
||||
EXPECT_TRUE(Validate(linked_binary));
|
||||
EXPECT_THAT(GetErrorMessage(), std::string());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace spvtools
|
||||
|
@ -208,6 +208,10 @@ class LinkerTest : public ::testing::Test {
|
||||
// Returns the accumulated error messages for the test.
|
||||
std::string GetErrorMessage() const { return error_message_; }
|
||||
|
||||
bool Validate(const spvtest::Binary& binary) {
|
||||
return tools_.Validate(binary);
|
||||
}
|
||||
|
||||
private:
|
||||
spvtools::Context context_;
|
||||
spvtools::SpirvTools
|
||||
|
Loading…
Reference in New Issue
Block a user