linker/test: keep Exports around, even after import->export resolution.

This commit is contained in:
Eduard-Mihai Burtescu 2022-12-02 13:23:38 +02:00 committed by Eduard-Mihai Burtescu
parent 00bb9be12d
commit 12172b3f17
4 changed files with 70 additions and 37 deletions

View File

@ -515,6 +515,7 @@ impl CodegenArgs {
// FIXME(eddyb) deduplicate between `CodegenArgs` and `linker::Options`.
emit_multiple_modules: module_output_type == ModuleOutputType::Multiple,
spirv_metadata,
keep_link_exports: false,
// NOTE(eddyb) these are debugging options that used to be env vars
// (for more information see `docs/src/codegen-args.md`).

View File

@ -5,10 +5,10 @@ use rspirv::spirv::{Capability, Decoration, LinkageType, Op, Word};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_session::Session;
pub fn run(sess: &Session, module: &mut Module) -> Result<()> {
pub fn run(opts: &super::Options, sess: &Session, module: &mut Module) -> Result<()> {
let (rewrite_rules, killed_parameters) =
find_import_export_pairs_and_killed_params(sess, module)?;
kill_linkage_instructions(module, &rewrite_rules);
kill_linkage_instructions(opts, module, &rewrite_rules);
import_kill_annotations_and_debug(module, &rewrite_rules, &killed_parameters);
replace_all_uses_with(module, &rewrite_rules);
Ok(())
@ -215,7 +215,11 @@ fn replace_all_uses_with(module: &mut Module, rules: &FxHashMap<u32, u32>) {
});
}
fn kill_linkage_instructions(module: &mut Module, rewrite_rules: &FxHashMap<u32, u32>) {
fn kill_linkage_instructions(
opts: &super::Options,
module: &mut Module,
rewrite_rules: &FxHashMap<u32, u32>,
) {
// drop imported functions
module
.functions
@ -227,16 +231,27 @@ fn kill_linkage_instructions(module: &mut Module, rewrite_rules: &FxHashMap<u32,
.map_or(true, |v| !rewrite_rules.contains_key(&v))
});
// NOTE(eddyb) `Options`'s `keep_link_export`s field requests that `Export`s
// are left in (primarily for unit testing - see also its doc comment).
let mut kept_any_linkage_decorations = false;
module.annotations.retain(|inst| {
inst.class.opcode != Op::Decorate
|| inst.operands[1].unwrap_decoration() != Decoration::LinkageAttributes
});
// drop OpCapability Linkage
module.capabilities.retain(|inst| {
inst.class.opcode != Op::Capability
|| inst.operands[0].unwrap_capability() != Capability::Linkage
!(inst.class.opcode == Op::Decorate
&& inst.operands[1].unwrap_decoration() == Decoration::LinkageAttributes
&& match inst.operands[3].unwrap_linkage_type() {
LinkageType::Export if opts.keep_link_exports => {
kept_any_linkage_decorations = true;
false
}
_ => true,
})
});
if !kept_any_linkage_decorations {
// drop OpCapability Linkage
module.capabilities.retain(|inst| {
inst.class.opcode != Op::Capability
|| inst.operands[0].unwrap_capability() != Capability::Linkage
});
}
}
fn import_kill_annotations_and_debug(

View File

@ -38,6 +38,12 @@ pub struct Options {
pub emit_multiple_modules: bool,
pub spirv_metadata: SpirvMetadata,
/// Whether to preserve `LinkageAttributes "..." Export` decorations,
/// even after resolving imports to exports.
///
/// **Note**: currently only used for unit testing, and not exposed elsewhere.
pub keep_link_exports: bool,
// NOTE(eddyb) these are debugging options that used to be env vars
// (for more information see `docs/src/codegen-args.md`).
pub dump_post_merge: Option<PathBuf>,
@ -176,7 +182,7 @@ pub fn link(sess: &Session, mut inputs: Vec<Module>, opts: &Options) -> Result<L
// find import / export pairs
{
let _timer = sess.timer("link_find_pairs");
import_export_link::run(sess, &mut output)?;
import_export_link::run(opts, sess, &mut output)?;
}
{

View File

@ -123,6 +123,7 @@ fn assemble_and_link(binaries: &[&[u8]]) -> Result<Module, PrettyString> {
modules,
&Options {
compact_ids: true,
keep_link_exports: true,
..Default::default()
},
);
@ -194,11 +195,13 @@ fn standard() {
);
let result = assemble_and_link(&[&a, &b]).unwrap();
let expect = r#"OpMemoryModel Logical OpenCL
%1 = OpTypeFloat 32
%2 = OpVariable %1 Input
%3 = OpConstant %1 42.0
%4 = OpVariable %1 Uniform %3"#;
let expect = r#"OpCapability Linkage
OpMemoryModel Logical OpenCL
OpDecorate %1 LinkageAttributes "foo" Export
%2 = OpTypeFloat 32
%3 = OpVariable %2 Input
%4 = OpConstant %2 42.0
%1 = OpVariable %2 Uniform %4"#;
without_header_eq(result, expect);
}
@ -214,9 +217,11 @@ fn not_a_lib_extra_exports() {
);
let result = assemble_and_link(&[&a]).unwrap();
let expect = r#"OpMemoryModel Logical OpenCL
%1 = OpTypeFloat 32
%2 = OpVariable %1 Uniform"#;
let expect = r#"OpCapability Linkage
OpMemoryModel Logical OpenCL
OpDecorate %1 LinkageAttributes "foo" Export
%2 = OpTypeFloat 32
%1 = OpVariable %2 Uniform"#;
without_header_eq(result, expect);
}
@ -403,12 +408,14 @@ fn func_ctrl() {
let result = assemble_and_link(&[&a, &b]).unwrap();
let expect = r#"OpMemoryModel Logical OpenCL
%1 = OpTypeVoid
%2 = OpTypeFunction %1
%3 = OpTypeFloat 32
%4 = OpVariable %3 Uniform
%5 = OpFunction %1 DontInline %2
let expect = r#"OpCapability Linkage
OpMemoryModel Logical OpenCL
OpDecorate %1 LinkageAttributes "foo" Export
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%4 = OpTypeFloat 32
%5 = OpVariable %4 Uniform
%1 = OpFunction %2 DontInline %3
%6 = OpLabel
OpReturn
OpFunctionEnd"#;
@ -461,22 +468,24 @@ fn use_exported_func_param_attr() {
let result = assemble_and_link(&[&a, &b]).unwrap();
let expect = r#"OpCapability Kernel
OpCapability Linkage
OpMemoryModel Logical OpenCL
OpDecorate %1 FuncParamAttr Zext
OpDecorate %2 FuncParamAttr Sext
%3 = OpTypeVoid
%4 = OpTypeInt 32 0
%5 = OpTypeFunction %3 %4
%6 = OpFunction %3 None %5
%1 = OpFunctionParameter %4
%7 = OpLabel
%8 = OpLoad %4 %1
OpDecorate %2 LinkageAttributes "foo" Export
OpDecorate %3 FuncParamAttr Sext
%4 = OpTypeVoid
%5 = OpTypeInt 32 0
%6 = OpTypeFunction %4 %5
%7 = OpFunction %4 None %6
%1 = OpFunctionParameter %5
%8 = OpLabel
%9 = OpLoad %5 %1
OpReturn
OpFunctionEnd
%9 = OpFunction %3 None %5
%2 = OpFunctionParameter %4
%2 = OpFunction %4 None %6
%3 = OpFunctionParameter %5
%10 = OpLabel
%11 = OpLoad %4 %2
%11 = OpLoad %5 %3
OpReturn
OpFunctionEnd"#;
@ -535,11 +544,13 @@ fn names_and_decorations() {
let result = assemble_and_link(&[&a, &b]).unwrap();
let expect = r#"OpCapability Kernel
OpCapability Linkage
OpMemoryModel Logical OpenCL
OpName %1 "foo"
OpName %2 "param"
OpDecorate %3 Restrict
OpDecorate %3 NonWritable
OpDecorate %1 LinkageAttributes "foo" Export
OpDecorate %2 Restrict
%4 = OpTypeVoid
%5 = OpTypeInt 32 0