mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 00:03:43 +00:00
Auto merge of #116555 - paulmenage:llvm-module-flag, r=wesleywiser
Add -Z llvm_module_flag Allow adding values to the `!llvm.module.flags` metadata for a generated module. The syntax is `-Z llvm_module_flag=<name>:<type>:<value>:<behavior>` Currently only u32 values are supported but the type is required to be specified for forward compatibility. The `behavior` element must match one of the named LLVM metadata behaviors.viors. This flag is expected to be perma-unstable.
This commit is contained in:
commit
0b24479638
@ -368,6 +368,24 @@ pub unsafe fn create_module<'ll>(
|
||||
llvm::LLVMMDNodeInContext(llcx, &name_metadata, 1),
|
||||
);
|
||||
|
||||
// Add module flags specified via -Z llvm_module_flag
|
||||
for (key, value, behavior) in &sess.opts.unstable_opts.llvm_module_flag {
|
||||
let key = format!("{key}\0");
|
||||
let behavior = match behavior.as_str() {
|
||||
"error" => llvm::LLVMModFlagBehavior::Error,
|
||||
"warning" => llvm::LLVMModFlagBehavior::Warning,
|
||||
"require" => llvm::LLVMModFlagBehavior::Require,
|
||||
"override" => llvm::LLVMModFlagBehavior::Override,
|
||||
"append" => llvm::LLVMModFlagBehavior::Append,
|
||||
"appendunique" => llvm::LLVMModFlagBehavior::AppendUnique,
|
||||
"max" => llvm::LLVMModFlagBehavior::Max,
|
||||
"min" => llvm::LLVMModFlagBehavior::Min,
|
||||
// We already checked this during option parsing
|
||||
_ => unreachable!(),
|
||||
};
|
||||
llvm::LLVMRustAddModuleFlag(llmod, behavior, key.as_ptr().cast(), *value)
|
||||
}
|
||||
|
||||
llmod
|
||||
}
|
||||
|
||||
|
@ -769,6 +769,7 @@ fn test_unstable_options_tracking_hash() {
|
||||
tracked!(instrument_xray, Some(InstrumentXRay::default()));
|
||||
tracked!(link_directives, false);
|
||||
tracked!(link_only, true);
|
||||
tracked!(llvm_module_flag, vec![("bar".to_string(), 123, "max".to_string())]);
|
||||
tracked!(llvm_plugins, vec![String::from("plugin_name")]);
|
||||
tracked!(location_detail, LocationDetail { file: true, line: false, column: false });
|
||||
tracked!(maximal_hir_to_mir_coverage, true);
|
||||
|
@ -429,6 +429,7 @@ mod desc {
|
||||
pub const parse_remap_path_scope: &str = "comma separated list of scopes: `macro`, `diagnostics`, `unsplit-debuginfo`, `split-debuginfo`, `split-debuginfo-path`, `object`, `all`";
|
||||
pub const parse_inlining_threshold: &str =
|
||||
"either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
|
||||
pub const parse_llvm_module_flag: &str = "<key>:<type>:<value>:<behavior>. Type must currently be `u32`. Behavior should be one of (`error`, `warning`, `require`, `override`, `append`, `appendunique`, `max`, `min`)";
|
||||
}
|
||||
|
||||
mod parse {
|
||||
@ -1331,6 +1332,33 @@ mod parse {
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
pub(crate) fn parse_llvm_module_flag(
|
||||
slot: &mut Vec<(String, u32, String)>,
|
||||
v: Option<&str>,
|
||||
) -> bool {
|
||||
let elements = v.unwrap_or_default().split(':').collect::<Vec<_>>();
|
||||
let [key, md_type, value, behavior] = elements.as_slice() else {
|
||||
return false;
|
||||
};
|
||||
if *md_type != "u32" {
|
||||
// Currently we only support u32 metadata flags, but require the
|
||||
// type for forward-compatibility.
|
||||
return false;
|
||||
}
|
||||
let Ok(value) = value.parse::<u32>() else {
|
||||
return false;
|
||||
};
|
||||
let behavior = behavior.to_lowercase();
|
||||
let all_behaviors =
|
||||
["error", "warning", "require", "override", "append", "appendunique", "max", "min"];
|
||||
if !all_behaviors.contains(&behavior.as_str()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
slot.push((key.to_string(), value, behavior));
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
options! {
|
||||
@ -1629,6 +1657,8 @@ options! {
|
||||
"link native libraries in the linker invocation (default: yes)"),
|
||||
link_only: bool = (false, parse_bool, [TRACKED],
|
||||
"link the `.rlink` file generated by `-Z no-link` (default: no)"),
|
||||
llvm_module_flag: Vec<(String, u32, String)> = (Vec::new(), parse_llvm_module_flag, [TRACKED],
|
||||
"a list of module flags to pass to LLVM (space separated)"),
|
||||
llvm_plugins: Vec<String> = (Vec::new(), parse_list, [TRACKED],
|
||||
"a list LLVM plugins to enable (space separated)"),
|
||||
llvm_time_trace: bool = (false, parse_bool, [UNTRACKED],
|
||||
|
12
src/doc/unstable-book/src/compiler-flags/llvm-module-flag.md
Normal file
12
src/doc/unstable-book/src/compiler-flags/llvm-module-flag.md
Normal file
@ -0,0 +1,12 @@
|
||||
# `llvm-module-flag`
|
||||
|
||||
---------------------
|
||||
|
||||
This flag allows adding a key/value to the `!llvm.module.flags` metadata in the
|
||||
LLVM-IR for a compiled Rust module. The syntax is
|
||||
|
||||
`-Z llvm_module_flag=<name>:<type>:<value>:<behavior>`
|
||||
|
||||
Currently only u32 values are supported but the type is required to be specified
|
||||
for forward compatibility. The `behavior` element must match one of the named
|
||||
LLVM [metadata behaviors](https://llvm.org/docs/LangRef.html#module-flags-metadata)
|
7
tests/codegen/llvm_module_flags.rs
Normal file
7
tests/codegen/llvm_module_flags.rs
Normal file
@ -0,0 +1,7 @@
|
||||
// Test for -Z llvm_module_flags
|
||||
// compile-flags: -Z llvm_module_flag=foo:u32:123:error -Z llvm_module_flag=bar:u32:42:max
|
||||
|
||||
fn main() {}
|
||||
|
||||
// CHECK: !{i32 1, !"foo", i32 123}
|
||||
// CHECK: !{i32 7, !"bar", i32 42}
|
Loading…
Reference in New Issue
Block a user