Importing rustc-1.52.1
Change-Id: I3598a97301b4b2e71385e5a519f6d2ad946548b6
diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml
index f937364..4999cb3 100644
--- a/compiler/rustc_codegen_llvm/Cargo.toml
+++ b/compiler/rustc_codegen_llvm/Cargo.toml
@@ -10,8 +10,9 @@
[dependencies]
bitflags = "1.0"
+cstr = "0.2"
libc = "0.2"
-measureme = "9.0.0"
+measureme = "9.1.0"
snap = "1"
tracing = "0.1"
rustc_middle = { path = "../rustc_middle" }
@@ -29,6 +30,6 @@
rustc_session = { path = "../rustc_session" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_target = { path = "../rustc_target" }
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
+smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
rustc_ast = { path = "../rustc_ast" }
rustc_span = { path = "../rustc_span" }
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index a69241e..d9393ff 100644
--- a/compiler/rustc_codegen_llvm/src/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
@@ -430,7 +430,13 @@
PassMode::Indirect { ref attrs, extra_attrs: _, on_stack } => {
assert!(!on_stack);
let i = apply(attrs);
- llvm::Attribute::StructRet.apply_llfn(llvm::AttributePlace::Argument(i), llfn);
+ unsafe {
+ llvm::LLVMRustAddStructRetAttr(
+ llfn,
+ llvm::AttributePlace::Argument(i).as_uint(),
+ self.ret.layout.llvm_type(cx),
+ );
+ }
}
_ => {}
}
@@ -486,8 +492,13 @@
PassMode::Indirect { ref attrs, extra_attrs: _, on_stack } => {
assert!(!on_stack);
let i = apply(attrs);
- llvm::Attribute::StructRet
- .apply_callsite(llvm::AttributePlace::Argument(i), callsite);
+ unsafe {
+ llvm::LLVMRustAddStructRetCallSiteAttr(
+ callsite,
+ llvm::AttributePlace::Argument(i).as_uint(),
+ self.ret.layout.llvm_type(bx),
+ );
+ }
}
_ => {}
}
@@ -554,7 +565,7 @@
llvm::AddCallSiteAttrString(
callsite,
llvm::AttributePlace::Function,
- rustc_data_structures::const_cstr!("cmse_nonsecure_call"),
+ cstr::cstr!("cmse_nonsecure_call"),
);
}
}
diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs
index a5ea0b2..068e5e9 100644
--- a/compiler/rustc_codegen_llvm/src/allocator.rs
+++ b/compiler/rustc_codegen_llvm/src/allocator.rs
@@ -93,7 +93,7 @@
let args = [usize, usize]; // size, align
let ty = llvm::LLVMFunctionType(void, args.as_ptr(), args.len() as c_uint, False);
- let name = "__rust_alloc_error_handler".to_string();
+ let name = "__rust_alloc_error_handler";
let llfn = llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr().cast(), name.len(), ty);
// -> ! DIFlagNoReturn
llvm::Attribute::NoReturn.apply_llfn(llvm::AttributePlace::Function, llfn);
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index 8801211..e7d359c 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -61,9 +61,9 @@
// Default per-arch clobbers
// Basically what clang does
let arch_clobbers = match &self.sess().target.arch[..] {
- "x86" | "x86_64" => vec!["~{dirflag}", "~{fpsr}", "~{flags}"],
- "mips" | "mips64" => vec!["~{$1}"],
- _ => Vec::new(),
+ "x86" | "x86_64" => &["~{dirflag}", "~{fpsr}", "~{flags}"][..],
+ "mips" | "mips64" => &["~{$1}"],
+ _ => &[],
};
let all_constraints = ia
@@ -304,6 +304,7 @@
} else if options.contains(InlineAsmOptions::READONLY) {
llvm::Attribute::ReadOnly.apply_callsite(llvm::AttributePlace::Function, result);
}
+ llvm::Attribute::WillReturn.apply_callsite(llvm::AttributePlace::Function, result);
} else if options.contains(InlineAsmOptions::NOMEM) {
llvm::Attribute::InaccessibleMemOnly
.apply_callsite(llvm::AttributePlace::Function, result);
@@ -487,6 +488,9 @@
} else if reg == InlineAsmReg::AArch64(AArch64InlineAsmReg::x30) {
// LLVM doesn't recognize x30
"{lr}".to_string()
+ } else if reg == InlineAsmReg::Arm(ArmInlineAsmReg::r14) {
+ // LLVM doesn't recognize r14
+ "{lr}".to_string()
} else {
format!("{{{}}}", reg.name())
}
@@ -524,6 +528,7 @@
InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
bug!("LLVM backend does not support SPIR-V")
}
+ InlineAsmRegClass::Err => unreachable!(),
}
.to_string(),
}
@@ -590,6 +595,7 @@
InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
bug!("LLVM backend does not support SPIR-V")
}
+ InlineAsmRegClass::Err => unreachable!(),
}
}
@@ -633,6 +639,7 @@
InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
bug!("LLVM backend does not support SPIR-V")
}
+ InlineAsmRegClass::Err => unreachable!(),
}
}
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index a78d692..64ebe58 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -2,8 +2,8 @@
use std::ffi::CString;
+use cstr::cstr;
use rustc_codegen_ssa::traits::*;
-use rustc_data_structures::const_cstr;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_hir::def_id::DefId;
@@ -53,6 +53,9 @@
if enabled.contains(SanitizerSet::THREAD) {
llvm::Attribute::SanitizeThread.apply_llfn(Function, llfn);
}
+ if enabled.contains(SanitizerSet::HWADDRESS) {
+ llvm::Attribute::SanitizeHWAddress.apply_llfn(Function, llfn);
+ }
}
/// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function.
@@ -72,8 +75,8 @@
llvm::AddFunctionAttrStringValue(
llfn,
llvm::AttributePlace::Function,
- const_cstr!("frame-pointer"),
- const_cstr!("all"),
+ cstr!("frame-pointer"),
+ cstr!("all"),
);
}
}
@@ -92,7 +95,7 @@
llvm::AddFunctionAttrStringValue(
llfn,
llvm::AttributePlace::Function,
- const_cstr!("instrument-function-entry-inlined"),
+ cstr!("instrument-function-entry-inlined"),
&mcount_name,
);
}
@@ -126,16 +129,16 @@
StackProbeType::None => None,
// Request LLVM to generate the probes inline. If the given LLVM version does not support
// this, no probe is generated at all (even if the attribute is specified).
- StackProbeType::Inline => Some(const_cstr!("inline-asm")),
+ StackProbeType::Inline => Some(cstr!("inline-asm")),
// Flag our internal `__rust_probestack` function as the stack probe symbol.
// This is defined in the `compiler-builtins` crate for each architecture.
- StackProbeType::Call => Some(const_cstr!("__rust_probestack")),
+ StackProbeType::Call => Some(cstr!("__rust_probestack")),
// Pick from the two above based on the LLVM version.
StackProbeType::InlineOrCall { min_llvm_version_for_inline } => {
if llvm_util::get_version() < min_llvm_version_for_inline {
- Some(const_cstr!("__rust_probestack"))
+ Some(cstr!("__rust_probestack"))
} else {
- Some(const_cstr!("inline-asm"))
+ Some(cstr!("inline-asm"))
}
}
};
@@ -143,30 +146,18 @@
llvm::AddFunctionAttrStringValue(
llfn,
llvm::AttributePlace::Function,
- const_cstr!("probe-stack"),
+ cstr!("probe-stack"),
attr_value,
);
}
}
-pub fn llvm_target_features(sess: &Session) -> impl Iterator<Item = &str> {
- const RUSTC_SPECIFIC_FEATURES: &[&str] = &["crt-static"];
-
- let cmdline = sess
- .opts
- .cg
- .target_feature
- .split(',')
- .filter(|f| !RUSTC_SPECIFIC_FEATURES.iter().any(|s| f.contains(s)));
- sess.target.features.split(',').chain(cmdline).filter(|l| !l.is_empty())
-}
-
pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
let target_cpu = SmallCStr::new(llvm_util::target_cpu(cx.tcx.sess));
llvm::AddFunctionAttrStringValue(
llfn,
llvm::AttributePlace::Function,
- const_cstr!("target-cpu"),
+ cstr!("target-cpu"),
target_cpu.as_c_str(),
);
}
@@ -177,7 +168,7 @@
llvm::AddFunctionAttrStringValue(
llfn,
llvm::AttributePlace::Function,
- const_cstr!("tune-cpu"),
+ cstr!("tune-cpu"),
tune_cpu.as_c_str(),
);
}
@@ -286,7 +277,7 @@
Attribute::NoAlias.apply_llfn(llvm::AttributePlace::ReturnValue, llfn);
}
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::CMSE_NONSECURE_ENTRY) {
- llvm::AddFunctionAttrString(llfn, Function, const_cstr!("cmse_nonsecure_entry"));
+ llvm::AddFunctionAttrString(llfn, Function, cstr!("cmse_nonsecure_entry"));
}
sanitize(cx, codegen_fn_attrs.no_sanitize, llfn);
@@ -298,25 +289,27 @@
// The target doesn't care; the subtarget reads our attribute.
apply_tune_cpu_attr(cx, llfn);
- let features = llvm_target_features(cx.tcx.sess)
- .map(|s| s.to_string())
- .chain(codegen_fn_attrs.target_features.iter().map(|f| {
+ let function_features = codegen_fn_attrs
+ .target_features
+ .iter()
+ .map(|f| {
let feature = &f.as_str();
format!("+{}", llvm_util::to_llvm_feature(cx.tcx.sess, feature))
- }))
+ })
.chain(codegen_fn_attrs.instruction_set.iter().map(|x| match x {
InstructionSetAttr::ArmA32 => "-thumb-mode".to_string(),
InstructionSetAttr::ArmT32 => "+thumb-mode".to_string(),
}))
- .collect::<Vec<String>>()
- .join(",");
-
- if !features.is_empty() {
+ .collect::<Vec<String>>();
+ if !function_features.is_empty() {
+ let mut global_features = llvm_util::llvm_global_features(cx.tcx.sess);
+ global_features.extend(function_features.into_iter());
+ let features = global_features.join(",");
let val = CString::new(features).unwrap();
llvm::AddFunctionAttrStringValue(
llfn,
llvm::AttributePlace::Function,
- const_cstr!("target-features"),
+ cstr!("target-features"),
&val,
);
}
@@ -329,7 +322,7 @@
llvm::AddFunctionAttrStringValue(
llfn,
llvm::AttributePlace::Function,
- const_cstr!("wasm-import-module"),
+ cstr!("wasm-import-module"),
&module,
);
@@ -339,7 +332,7 @@
llvm::AddFunctionAttrStringValue(
llfn,
llvm::AttributePlace::Function,
- const_cstr!("wasm-import-name"),
+ cstr!("wasm-import-name"),
&name,
);
}
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 326ae35..388dd7c 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -1,4 +1,3 @@
-use crate::attributes;
use crate::back::lto::ThinBuffer;
use crate::back::profiling::{
selfprofile_after_pass_callback, selfprofile_before_pass_callback, LlvmSelfProfiler,
@@ -11,6 +10,7 @@
use crate::type_::Type;
use crate::LlvmCodegenBackend;
use crate::ModuleLlvm;
+use rustc_codegen_ssa::back::link::ensure_removed;
use rustc_codegen_ssa::back::write::{
BitcodeSection, CodegenContext, EmitObj, ModuleConfig, TargetMachineFactoryConfig,
TargetMachineFactoryFn,
@@ -93,7 +93,7 @@
pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> &'static mut llvm::TargetMachine {
let split_dwarf_file = if tcx.sess.target_can_use_split_dwarf() {
tcx.output_filenames(LOCAL_CRATE)
- .split_dwarf_filename(tcx.sess.split_debuginfo(), Some(mod_name))
+ .split_dwarf_path(tcx.sess.split_debuginfo(), Some(mod_name))
} else {
None
};
@@ -139,7 +139,7 @@
}
}
-fn to_llvm_code_model(code_model: Option<CodeModel>) -> llvm::CodeModel {
+pub(crate) fn to_llvm_code_model(code_model: Option<CodeModel>) -> llvm::CodeModel {
match code_model {
Some(CodeModel::Tiny) => llvm::CodeModel::Tiny,
Some(CodeModel::Small) => llvm::CodeModel::Small,
@@ -165,8 +165,6 @@
let code_model = to_llvm_code_model(sess.code_model());
- let mut features = llvm_util::handle_native_features(sess);
- features.extend(attributes::llvm_target_features(sess).map(|s| s.to_owned()));
let mut singlethread = sess.target.singlethread;
// On the wasm target once the `atomics` feature is enabled that means that
@@ -181,7 +179,7 @@
let triple = SmallCStr::new(&sess.target.llvm_target);
let cpu = SmallCStr::new(llvm_util::target_cpu(sess));
- let features = features.join(",");
+ let features = llvm_util::llvm_global_features(sess).join(",");
let features = CString::new(features).unwrap();
let abi = SmallCStr::new(&sess.target.llvm_abiname);
let trap_unreachable =
@@ -440,6 +438,8 @@
sanitize_memory_recover: config.sanitizer_recover.contains(SanitizerSet::MEMORY),
sanitize_memory_track_origins: config.sanitizer_memory_track_origins as c_int,
sanitize_thread: config.sanitizer.contains(SanitizerSet::THREAD),
+ sanitize_hwaddress: config.sanitizer.contains(SanitizerSet::HWADDRESS),
+ sanitize_hwaddress_recover: config.sanitizer_recover.contains(SanitizerSet::HWADDRESS),
})
} else {
None
@@ -652,6 +652,10 @@
if config.sanitizer.contains(SanitizerSet::THREAD) {
passes.push(llvm::LLVMRustCreateThreadSanitizerPass());
}
+ if config.sanitizer.contains(SanitizerSet::HWADDRESS) {
+ let recover = config.sanitizer_recover.contains(SanitizerSet::HWADDRESS);
+ passes.push(llvm::LLVMRustCreateHWAddressSanitizerPass(recover));
+ }
}
pub(crate) fn link(
@@ -873,9 +877,7 @@
if !config.emit_bc {
debug!("removing_bitcode {:?}", bc_out);
- if let Err(e) = fs::remove_file(&bc_out) {
- diag_handler.err(&format!("failed to remove bitcode: {}", e));
- }
+ ensure_removed(diag_handler, &bc_out);
}
}
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index d2f4d3e..f4852c9 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -5,13 +5,13 @@
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
+use cstr::cstr;
use libc::{c_char, c_uint};
use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, TypeKind};
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::MemFlags;
-use rustc_data_structures::const_cstr;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::layout::TyAndLayout;
@@ -979,7 +979,7 @@
}
fn cleanup_pad(&mut self, parent: Option<&'ll Value>, args: &[&'ll Value]) -> Funclet<'ll> {
- let name = const_cstr!("cleanuppad");
+ let name = cstr!("cleanuppad");
let ret = unsafe {
llvm::LLVMRustBuildCleanupPad(
self.llbuilder,
@@ -1003,7 +1003,7 @@
}
fn catch_pad(&mut self, parent: &'ll Value, args: &[&'ll Value]) -> Funclet<'ll> {
- let name = const_cstr!("catchpad");
+ let name = cstr!("catchpad");
let ret = unsafe {
llvm::LLVMRustBuildCatchPad(
self.llbuilder,
@@ -1022,7 +1022,7 @@
unwind: Option<&'ll BasicBlock>,
num_handlers: usize,
) -> &'ll Value {
- let name = const_cstr!("catchswitch");
+ let name = cstr!("catchswitch");
let ret = unsafe {
llvm::LLVMRustBuildCatchSwitch(
self.llbuilder,
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index 16e1a8a..9904683 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -5,9 +5,9 @@
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
+use cstr::cstr;
use libc::c_uint;
use rustc_codegen_ssa::traits::*;
-use rustc_data_structures::const_cstr;
use rustc_hir::def_id::DefId;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::interpret::{
@@ -419,9 +419,9 @@
.all(|&byte| byte == 0);
let sect_name = if all_bytes_are_zero {
- const_cstr!("__DATA,__thread_bss")
+ cstr!("__DATA,__thread_bss")
} else {
- const_cstr!("__DATA,__thread_data")
+ cstr!("__DATA,__thread_data")
};
llvm::LLVMSetSection(g, sect_name.as_ptr());
}
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 6acd26b..21473f3 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -1,4 +1,5 @@
use crate::attributes;
+use crate::back::write::to_llvm_code_model;
use crate::callee::get_fn;
use crate::coverageinfo;
use crate::debuginfo;
@@ -7,10 +8,10 @@
use crate::type_::Type;
use crate::value::Value;
+use cstr::cstr;
use rustc_codegen_ssa::base::wants_msvc_seh;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::base_n;
-use rustc_data_structures::const_cstr;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_middle::bug;
@@ -104,6 +105,10 @@
data_layout.replace("-p270:32:32-p271:32:32-p272:64:64-", "-")
}
+fn strip_powerpc64_vectors(data_layout: String) -> String {
+ data_layout.replace("-v256:256:256-v512:512:512", "")
+}
+
pub unsafe fn create_module(
tcx: TyCtxt<'_>,
llcx: &'ll llvm::Context,
@@ -119,6 +124,9 @@
{
target_data_layout = strip_x86_address_spaces(target_data_layout);
}
+ if llvm_util::get_version() < (12, 0, 0) && sess.target.arch == "powerpc64" {
+ target_data_layout = strip_powerpc64_vectors(target_data_layout);
+ }
// Ensure the data-layout values hardcoded remain the defaults.
if sess.target.is_builtin {
@@ -174,6 +182,13 @@
}
}
+ // Linking object files with different code models is undefined behavior
+ // because the compiler would have to generate additional code (to span
+ // longer jumps) if a larger code model is used with a smaller one.
+ //
+ // See https://reviews.llvm.org/D52322 and https://reviews.llvm.org/D52323.
+ llvm::LLVMRustSetModuleCodeModel(llmod, to_llvm_code_model(sess.code_model()));
+
// If skipping the PLT is enabled, we need to add some module metadata
// to ensure intrinsic calls don't use it.
if !sess.needs_plt() {
@@ -380,7 +395,7 @@
"rust_eh_personality"
};
let fty = self.type_variadic_func(&[], self.type_i32());
- self.declare_cfn(name, fty)
+ self.declare_cfn(name, llvm::UnnamedAddr::Global, fty)
}
};
attributes::apply_target_cpu_attr(self, llfn);
@@ -414,8 +429,8 @@
}
fn create_used_variable(&self) {
- let name = const_cstr!("llvm.used");
- let section = const_cstr!("llvm.metadata");
+ let name = cstr!("llvm.used");
+ let section = cstr!("llvm.metadata");
let array =
self.const_array(&self.type_ptr_to(self.type_i8()), &*self.used_statics.borrow());
@@ -429,7 +444,7 @@
fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {
if self.get_declared_value("main").is_none() {
- Some(self.declare_cfn("main", fn_type))
+ Some(self.declare_cfn("main", llvm::UnnamedAddr::Global, fn_type))
} else {
// If the symbol already exists, it is an error: for example, the user wrote
// #[no_mangle] extern "C" fn main(..) {..}
@@ -459,8 +474,7 @@
} else {
self.type_variadic_func(&[], ret)
};
- let f = self.declare_cfn(name, fn_ty);
- llvm::SetUnnamedAddress(f, llvm::UnnamedAddr::No);
+ let f = self.declare_cfn(name, llvm::UnnamedAddr::No, fn_ty);
self.intrinsics.borrow_mut().insert(name, f);
f
}
@@ -498,25 +512,6 @@
let t_f32 = self.type_f32();
let t_f64 = self.type_f64();
- macro_rules! vector_types {
- ($id_out:ident: $elem_ty:ident, $len:expr) => {
- let $id_out = self.type_vector($elem_ty, $len);
- };
- ($($id_out:ident: $elem_ty:ident, $len:expr;)*) => {
- $(vector_types!($id_out: $elem_ty, $len);)*
- }
- }
- vector_types! {
- t_v2f32: t_f32, 2;
- t_v4f32: t_f32, 4;
- t_v8f32: t_f32, 8;
- t_v16f32: t_f32, 16;
-
- t_v2f64: t_f64, 2;
- t_v4f64: t_f64, 4;
- t_v8f64: t_f64, 8;
- }
-
ifn!("llvm.wasm.trunc.saturate.unsigned.i32.f32", fn(t_f32) -> t_i32);
ifn!("llvm.wasm.trunc.saturate.unsigned.i32.f64", fn(t_f64) -> t_i32);
ifn!("llvm.wasm.trunc.saturate.unsigned.i64.f32", fn(t_f32) -> t_i64);
@@ -540,124 +535,40 @@
ifn!("llvm.sideeffect", fn() -> void);
ifn!("llvm.powi.f32", fn(t_f32, t_i32) -> t_f32);
- ifn!("llvm.powi.v2f32", fn(t_v2f32, t_i32) -> t_v2f32);
- ifn!("llvm.powi.v4f32", fn(t_v4f32, t_i32) -> t_v4f32);
- ifn!("llvm.powi.v8f32", fn(t_v8f32, t_i32) -> t_v8f32);
- ifn!("llvm.powi.v16f32", fn(t_v16f32, t_i32) -> t_v16f32);
ifn!("llvm.powi.f64", fn(t_f64, t_i32) -> t_f64);
- ifn!("llvm.powi.v2f64", fn(t_v2f64, t_i32) -> t_v2f64);
- ifn!("llvm.powi.v4f64", fn(t_v4f64, t_i32) -> t_v4f64);
- ifn!("llvm.powi.v8f64", fn(t_v8f64, t_i32) -> t_v8f64);
ifn!("llvm.pow.f32", fn(t_f32, t_f32) -> t_f32);
- ifn!("llvm.pow.v2f32", fn(t_v2f32, t_v2f32) -> t_v2f32);
- ifn!("llvm.pow.v4f32", fn(t_v4f32, t_v4f32) -> t_v4f32);
- ifn!("llvm.pow.v8f32", fn(t_v8f32, t_v8f32) -> t_v8f32);
- ifn!("llvm.pow.v16f32", fn(t_v16f32, t_v16f32) -> t_v16f32);
ifn!("llvm.pow.f64", fn(t_f64, t_f64) -> t_f64);
- ifn!("llvm.pow.v2f64", fn(t_v2f64, t_v2f64) -> t_v2f64);
- ifn!("llvm.pow.v4f64", fn(t_v4f64, t_v4f64) -> t_v4f64);
- ifn!("llvm.pow.v8f64", fn(t_v8f64, t_v8f64) -> t_v8f64);
ifn!("llvm.sqrt.f32", fn(t_f32) -> t_f32);
- ifn!("llvm.sqrt.v2f32", fn(t_v2f32) -> t_v2f32);
- ifn!("llvm.sqrt.v4f32", fn(t_v4f32) -> t_v4f32);
- ifn!("llvm.sqrt.v8f32", fn(t_v8f32) -> t_v8f32);
- ifn!("llvm.sqrt.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.sqrt.f64", fn(t_f64) -> t_f64);
- ifn!("llvm.sqrt.v2f64", fn(t_v2f64) -> t_v2f64);
- ifn!("llvm.sqrt.v4f64", fn(t_v4f64) -> t_v4f64);
- ifn!("llvm.sqrt.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.sin.f32", fn(t_f32) -> t_f32);
- ifn!("llvm.sin.v2f32", fn(t_v2f32) -> t_v2f32);
- ifn!("llvm.sin.v4f32", fn(t_v4f32) -> t_v4f32);
- ifn!("llvm.sin.v8f32", fn(t_v8f32) -> t_v8f32);
- ifn!("llvm.sin.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.sin.f64", fn(t_f64) -> t_f64);
- ifn!("llvm.sin.v2f64", fn(t_v2f64) -> t_v2f64);
- ifn!("llvm.sin.v4f64", fn(t_v4f64) -> t_v4f64);
- ifn!("llvm.sin.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.cos.f32", fn(t_f32) -> t_f32);
- ifn!("llvm.cos.v2f32", fn(t_v2f32) -> t_v2f32);
- ifn!("llvm.cos.v4f32", fn(t_v4f32) -> t_v4f32);
- ifn!("llvm.cos.v8f32", fn(t_v8f32) -> t_v8f32);
- ifn!("llvm.cos.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.cos.f64", fn(t_f64) -> t_f64);
- ifn!("llvm.cos.v2f64", fn(t_v2f64) -> t_v2f64);
- ifn!("llvm.cos.v4f64", fn(t_v4f64) -> t_v4f64);
- ifn!("llvm.cos.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.exp.f32", fn(t_f32) -> t_f32);
- ifn!("llvm.exp.v2f32", fn(t_v2f32) -> t_v2f32);
- ifn!("llvm.exp.v4f32", fn(t_v4f32) -> t_v4f32);
- ifn!("llvm.exp.v8f32", fn(t_v8f32) -> t_v8f32);
- ifn!("llvm.exp.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.exp.f64", fn(t_f64) -> t_f64);
- ifn!("llvm.exp.v2f64", fn(t_v2f64) -> t_v2f64);
- ifn!("llvm.exp.v4f64", fn(t_v4f64) -> t_v4f64);
- ifn!("llvm.exp.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.exp2.f32", fn(t_f32) -> t_f32);
- ifn!("llvm.exp2.v2f32", fn(t_v2f32) -> t_v2f32);
- ifn!("llvm.exp2.v4f32", fn(t_v4f32) -> t_v4f32);
- ifn!("llvm.exp2.v8f32", fn(t_v8f32) -> t_v8f32);
- ifn!("llvm.exp2.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.exp2.f64", fn(t_f64) -> t_f64);
- ifn!("llvm.exp2.v2f64", fn(t_v2f64) -> t_v2f64);
- ifn!("llvm.exp2.v4f64", fn(t_v4f64) -> t_v4f64);
- ifn!("llvm.exp2.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.log.f32", fn(t_f32) -> t_f32);
- ifn!("llvm.log.v2f32", fn(t_v2f32) -> t_v2f32);
- ifn!("llvm.log.v4f32", fn(t_v4f32) -> t_v4f32);
- ifn!("llvm.log.v8f32", fn(t_v8f32) -> t_v8f32);
- ifn!("llvm.log.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.log.f64", fn(t_f64) -> t_f64);
- ifn!("llvm.log.v2f64", fn(t_v2f64) -> t_v2f64);
- ifn!("llvm.log.v4f64", fn(t_v4f64) -> t_v4f64);
- ifn!("llvm.log.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.log10.f32", fn(t_f32) -> t_f32);
- ifn!("llvm.log10.v2f32", fn(t_v2f32) -> t_v2f32);
- ifn!("llvm.log10.v4f32", fn(t_v4f32) -> t_v4f32);
- ifn!("llvm.log10.v8f32", fn(t_v8f32) -> t_v8f32);
- ifn!("llvm.log10.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.log10.f64", fn(t_f64) -> t_f64);
- ifn!("llvm.log10.v2f64", fn(t_v2f64) -> t_v2f64);
- ifn!("llvm.log10.v4f64", fn(t_v4f64) -> t_v4f64);
- ifn!("llvm.log10.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.log2.f32", fn(t_f32) -> t_f32);
- ifn!("llvm.log2.v2f32", fn(t_v2f32) -> t_v2f32);
- ifn!("llvm.log2.v4f32", fn(t_v4f32) -> t_v4f32);
- ifn!("llvm.log2.v8f32", fn(t_v8f32) -> t_v8f32);
- ifn!("llvm.log2.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.log2.f64", fn(t_f64) -> t_f64);
- ifn!("llvm.log2.v2f64", fn(t_v2f64) -> t_v2f64);
- ifn!("llvm.log2.v4f64", fn(t_v4f64) -> t_v4f64);
- ifn!("llvm.log2.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.fma.f32", fn(t_f32, t_f32, t_f32) -> t_f32);
- ifn!("llvm.fma.v2f32", fn(t_v2f32, t_v2f32, t_v2f32) -> t_v2f32);
- ifn!("llvm.fma.v4f32", fn(t_v4f32, t_v4f32, t_v4f32) -> t_v4f32);
- ifn!("llvm.fma.v8f32", fn(t_v8f32, t_v8f32, t_v8f32) -> t_v8f32);
- ifn!("llvm.fma.v16f32", fn(t_v16f32, t_v16f32, t_v16f32) -> t_v16f32);
ifn!("llvm.fma.f64", fn(t_f64, t_f64, t_f64) -> t_f64);
- ifn!("llvm.fma.v2f64", fn(t_v2f64, t_v2f64, t_v2f64) -> t_v2f64);
- ifn!("llvm.fma.v4f64", fn(t_v4f64, t_v4f64, t_v4f64) -> t_v4f64);
- ifn!("llvm.fma.v8f64", fn(t_v8f64, t_v8f64, t_v8f64) -> t_v8f64);
ifn!("llvm.fabs.f32", fn(t_f32) -> t_f32);
- ifn!("llvm.fabs.v2f32", fn(t_v2f32) -> t_v2f32);
- ifn!("llvm.fabs.v4f32", fn(t_v4f32) -> t_v4f32);
- ifn!("llvm.fabs.v8f32", fn(t_v8f32) -> t_v8f32);
- ifn!("llvm.fabs.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.fabs.f64", fn(t_f64) -> t_f64);
- ifn!("llvm.fabs.v2f64", fn(t_v2f64) -> t_v2f64);
- ifn!("llvm.fabs.v4f64", fn(t_v4f64) -> t_v4f64);
- ifn!("llvm.fabs.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.minnum.f32", fn(t_f32, t_f32) -> t_f32);
ifn!("llvm.minnum.f64", fn(t_f64, t_f64) -> t_f64);
@@ -665,24 +576,10 @@
ifn!("llvm.maxnum.f64", fn(t_f64, t_f64) -> t_f64);
ifn!("llvm.floor.f32", fn(t_f32) -> t_f32);
- ifn!("llvm.floor.v2f32", fn(t_v2f32) -> t_v2f32);
- ifn!("llvm.floor.v4f32", fn(t_v4f32) -> t_v4f32);
- ifn!("llvm.floor.v8f32", fn(t_v8f32) -> t_v8f32);
- ifn!("llvm.floor.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.floor.f64", fn(t_f64) -> t_f64);
- ifn!("llvm.floor.v2f64", fn(t_v2f64) -> t_v2f64);
- ifn!("llvm.floor.v4f64", fn(t_v4f64) -> t_v4f64);
- ifn!("llvm.floor.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.ceil.f32", fn(t_f32) -> t_f32);
- ifn!("llvm.ceil.v2f32", fn(t_v2f32) -> t_v2f32);
- ifn!("llvm.ceil.v4f32", fn(t_v4f32) -> t_v4f32);
- ifn!("llvm.ceil.v8f32", fn(t_v8f32) -> t_v8f32);
- ifn!("llvm.ceil.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.ceil.f64", fn(t_f64) -> t_f64);
- ifn!("llvm.ceil.v2f64", fn(t_v2f64) -> t_v2f64);
- ifn!("llvm.ceil.v4f64", fn(t_v4f64) -> t_v4f64);
- ifn!("llvm.ceil.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.trunc.f32", fn(t_f32) -> t_f32);
ifn!("llvm.trunc.f64", fn(t_f64) -> t_f64);
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
index 444a9d4..352638a 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
@@ -254,7 +254,7 @@
///
/// 1. The file name of an "Unreachable" function must match the file name of the existing
/// codegenned (covered) function to which the unreachable code regions will be added.
-/// 2. The function to which the unreachable code regions will be added must not be a genaric
+/// 2. The function to which the unreachable code regions will be added must not be a generic
/// function (must not have type parameters) because the coverage tools will get confused
/// if the codegenned function has more than one instantiation and additional `CodeRegion`s
/// attached to only one of those instantiations.
@@ -284,7 +284,7 @@
let all_def_ids: DefIdSet =
tcx.mir_keys(LOCAL_CRATE).iter().map(|local_def_id| local_def_id.to_def_id()).collect();
- let (codegenned_def_ids, _) = tcx.collect_and_partition_mono_items(LOCAL_CRATE);
+ let codegenned_def_ids = tcx.codegened_and_inlined_items(LOCAL_CRATE);
let mut unreachable_def_ids_by_file: FxHashMap<Symbol, Vec<DefId>> = FxHashMap::default();
for &non_codegenned_def_id in all_def_ids.difference(codegenned_def_ids) {
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
index e777f36..e47b8fd 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
@@ -162,7 +162,7 @@
pub(crate) fn write_mapping_to_buffer(
virtual_file_mapping: Vec<u32>,
expressions: Vec<CounterExpression>,
- mut mapping_regions: Vec<CounterMappingRegion>,
+ mapping_regions: Vec<CounterMappingRegion>,
buffer: &RustString,
) {
unsafe {
@@ -171,7 +171,7 @@
virtual_file_mapping.len() as c_uint,
expressions.as_ptr(),
expressions.len() as c_uint,
- mapping_regions.as_mut_ptr(),
+ mapping_regions.as_ptr(),
mapping_regions.len() as c_uint,
buffer,
);
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
index 7673dfb..c2725b8 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
@@ -1,4 +1,4 @@
-use super::metadata::{file_metadata, UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER};
+use super::metadata::file_metadata;
use super::utils::DIB;
use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext};
use rustc_codegen_ssa::traits::*;
@@ -102,8 +102,8 @@
DIB(cx),
parent_scope.dbg_scope.unwrap(),
file_metadata,
- loc.line.unwrap_or(UNKNOWN_LINE_NUMBER),
- loc.col.unwrap_or(UNKNOWN_COLUMN_NUMBER),
+ loc.line,
+ loc.col,
)
},
};
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 6e7c0b3..d5b32e5 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -18,8 +18,8 @@
};
use crate::value::Value;
+use cstr::cstr;
use rustc_codegen_ssa::traits::*;
-use rustc_data_structures::const_cstr;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -979,7 +979,7 @@
// The OSX linker has an idiosyncrasy where it will ignore some debuginfo
// if multiple object files with the same `DW_AT_name` are linked together.
// As a workaround we generate unique names for each object file. Those do
- // not correspond to an actual source file but that should be harmless.
+ // not correspond to an actual source file but that is harmless.
if tcx.sess.target.is_like_osx {
name_in_debuginfo.push("@");
name_in_debuginfo.push(codegen_unit_name);
@@ -992,17 +992,17 @@
let producer = format!("clang LLVM ({})", rustc_producer);
let name_in_debuginfo = name_in_debuginfo.to_string_lossy();
+ let work_dir = tcx.sess.working_dir.0.to_string_lossy();
let flags = "\0";
-
let out_dir = &tcx.output_filenames(LOCAL_CRATE).out_directory;
let split_name = if tcx.sess.target_can_use_split_dwarf() {
tcx.output_filenames(LOCAL_CRATE)
- .split_dwarf_filename(tcx.sess.split_debuginfo(), Some(codegen_unit_name))
+ .split_dwarf_path(tcx.sess.split_debuginfo(), Some(codegen_unit_name))
+ .map(|f| out_dir.join(f))
} else {
None
}
.unwrap_or_default();
- let out_dir = out_dir.to_str().unwrap();
let split_name = split_name.to_str().unwrap();
// FIXME(#60020):
@@ -1024,12 +1024,12 @@
assert!(tcx.sess.opts.debuginfo != DebugInfo::None);
unsafe {
- let file_metadata = llvm::LLVMRustDIBuilderCreateFile(
+ let compile_unit_file = llvm::LLVMRustDIBuilderCreateFile(
debug_context.builder,
name_in_debuginfo.as_ptr().cast(),
name_in_debuginfo.len(),
- out_dir.as_ptr().cast(),
- out_dir.len(),
+ work_dir.as_ptr().cast(),
+ work_dir.len(),
llvm::ChecksumKind::None,
ptr::null(),
0,
@@ -1038,12 +1038,15 @@
let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
debug_context.builder,
DW_LANG_RUST,
- file_metadata,
+ compile_unit_file,
producer.as_ptr().cast(),
producer.len(),
tcx.sess.opts.optimize != config::OptLevel::No,
flags.as_ptr().cast(),
0,
+ // NB: this doesn't actually have any perceptible effect, it seems. LLVM will instead
+ // put the path supplied to `MCSplitDwarfFile` into the debug info of the final
+ // output(s).
split_name.as_ptr().cast(),
split_name.len(),
kind,
@@ -1072,7 +1075,7 @@
gcov_cu_info.len() as c_uint,
);
- let llvm_gcov_ident = const_cstr!("llvm.gcov");
+ let llvm_gcov_ident = cstr!("llvm.gcov");
llvm::LLVMAddNamedMetadataOperand(
debug_context.llmod,
llvm_gcov_ident.as_ptr(),
@@ -1090,7 +1093,7 @@
);
llvm::LLVMAddNamedMetadataOperand(
debug_context.llmod,
- const_cstr!("llvm.ident").as_ptr(),
+ cstr!("llvm.ident").as_ptr(),
llvm::LLVMMDNodeInContext(debug_context.llcontext, &name_metadata, 1),
);
}
@@ -1414,7 +1417,7 @@
def_id: DefId,
) -> (&'tcx GeneratorLayout<'tcx>, IndexVec<mir::GeneratorSavedLocal, Option<Symbol>>) {
let body = tcx.optimized_mir(def_id);
- let generator_layout = body.generator_layout.as_ref().unwrap();
+ let generator_layout = body.generator_layout().unwrap();
let mut generator_saved_local_names = IndexVec::from_elem(None, &generator_layout.field_tys);
let state_arg = mir::Local::new(1);
@@ -1839,10 +1842,7 @@
.span;
if !span.is_dummy() {
let loc = cx.lookup_debug_loc(span.lo());
- return Some(SourceInfo {
- file: file_metadata(cx, &loc.file),
- line: loc.line.unwrap_or(UNKNOWN_LINE_NUMBER),
- });
+ return Some(SourceInfo { file: file_metadata(cx, &loc.file), line: loc.line });
}
}
_ => {}
@@ -2369,7 +2369,7 @@
fn get_parameter_names(cx: &CodegenCx<'_, '_>, generics: &ty::Generics) -> Vec<Symbol> {
let mut names = generics
.parent
- .map_or(vec![], |def_id| get_parameter_names(cx, cx.tcx.generics_of(def_id)));
+ .map_or_else(Vec::new, |def_id| get_parameter_names(cx, cx.tcx.generics_of(def_id)));
names.extend(generics.params.iter().map(|param| param.name));
names
}
@@ -2481,7 +2481,7 @@
let loc = cx.lookup_debug_loc(span.lo());
(file_metadata(cx, &loc.file), loc.line)
} else {
- (unknown_file_metadata(cx), None)
+ (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)
};
let is_local_to_unit = is_node_local_to_unit(cx, def_id);
@@ -2504,7 +2504,7 @@
linkage_name.as_ptr().cast(),
linkage_name.len(),
file_metadata,
- line_number.unwrap_or(UNKNOWN_LINE_NUMBER),
+ line_number,
type_metadata,
is_local_to_unit,
global,
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index 955e739..440e4d5 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -224,9 +224,9 @@
/// Information about the original source file.
pub file: Lrc<SourceFile>,
/// The (1-based) line number.
- pub line: Option<u32>,
+ pub line: u32,
/// The (1-based) column number.
- pub col: Option<u32>,
+ pub col: u32,
}
impl CodegenCx<'ll, '_> {
@@ -243,16 +243,16 @@
let line = (line + 1) as u32;
let col = (pos - line_pos).to_u32() + 1;
- (file, Some(line), Some(col))
+ (file, line, col)
}
- Err(file) => (file, None, None),
+ Err(file) => (file, UNKNOWN_LINE_NUMBER, UNKNOWN_COLUMN_NUMBER),
};
// For MSVC, omit the column number.
// Otherwise, emit it. This mimics clang behaviour.
// See discussion in https://github.com/rust-lang/rust/issues/42921
if self.sess().target.is_like_msvc {
- DebugLoc { file, line, col: None }
+ DebugLoc { file, line, col: UNKNOWN_COLUMN_NUMBER }
} else {
DebugLoc { file, line, col }
}
@@ -358,9 +358,9 @@
linkage_name.as_ptr().cast(),
linkage_name.len(),
file_metadata,
- loc.line.unwrap_or(UNKNOWN_LINE_NUMBER),
+ loc.line,
function_type_metadata,
- scope_line.unwrap_or(UNKNOWN_LINE_NUMBER),
+ scope_line,
flags,
spflags,
maybe_definition_llfn,
@@ -481,9 +481,9 @@
}
fn get_parameter_names(cx: &CodegenCx<'_, '_>, generics: &ty::Generics) -> Vec<Symbol> {
- let mut names = generics
- .parent
- .map_or(vec![], |def_id| get_parameter_names(cx, cx.tcx.generics_of(def_id)));
+ let mut names = generics.parent.map_or_else(Vec::new, |def_id| {
+ get_parameter_names(cx, cx.tcx.generics_of(def_id))
+ });
names.extend(generics.params.iter().map(|param| param.name));
names
}
@@ -550,14 +550,7 @@
) -> &'ll DILocation {
let DebugLoc { line, col, .. } = self.lookup_debug_loc(span.lo());
- unsafe {
- llvm::LLVMRustDIBuilderCreateDebugLocation(
- line.unwrap_or(UNKNOWN_LINE_NUMBER),
- col.unwrap_or(UNKNOWN_COLUMN_NUMBER),
- scope,
- inlined_at,
- )
- }
+ unsafe { llvm::LLVMRustDIBuilderCreateDebugLocation(line, col, scope, inlined_at) }
}
fn create_vtable_metadata(&self, ty: Ty<'tcx>, vtable: Self::Value) {
@@ -606,7 +599,7 @@
name.as_ptr().cast(),
name.len(),
file_metadata,
- loc.line.unwrap_or(UNKNOWN_LINE_NUMBER),
+ loc.line,
type_metadata,
true,
DIFlags::FlagZero,
diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs
index 0591e0a..8977fa0 100644
--- a/compiler/rustc_codegen_llvm/src/declare.rs
+++ b/compiler/rustc_codegen_llvm/src/declare.rs
@@ -30,6 +30,7 @@
cx: &CodegenCx<'ll, '_>,
name: &str,
callconv: llvm::CallConv,
+ unnamed: llvm::UnnamedAddr,
ty: &'ll Type,
) -> &'ll Value {
debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty);
@@ -38,9 +39,7 @@
};
llvm::SetFunctionCallConv(llfn, callconv);
- // Function addresses in Rust are never significant, allowing functions to
- // be merged.
- llvm::SetUnnamedAddress(llfn, llvm::UnnamedAddr::Global);
+ llvm::SetUnnamedAddress(llfn, unnamed);
if cx.tcx.sess.opts.cg.no_redzone.unwrap_or(cx.tcx.sess.target.disable_redzone) {
llvm::Attribute::NoRedZone.apply_llfn(Function, llfn);
@@ -68,8 +67,13 @@
///
/// If there’s a value with the same name already declared, the function will
/// update the declaration and return existing Value instead.
- pub fn declare_cfn(&self, name: &str, fn_type: &'ll Type) -> &'ll Value {
- declare_raw_fn(self, name, llvm::CCallConv, fn_type)
+ pub fn declare_cfn(
+ &self,
+ name: &str,
+ unnamed: llvm::UnnamedAddr,
+ fn_type: &'ll Type,
+ ) -> &'ll Value {
+ declare_raw_fn(self, name, llvm::CCallConv, unnamed, fn_type)
}
/// Declare a Rust function.
@@ -79,7 +83,15 @@
pub fn declare_fn(&self, name: &str, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> &'ll Value {
debug!("declare_rust_fn(name={:?}, fn_abi={:?})", name, fn_abi);
- let llfn = declare_raw_fn(self, name, fn_abi.llvm_cconv(), fn_abi.llvm_type(self));
+ // Function addresses in Rust are never significant, allowing functions to
+ // be merged.
+ let llfn = declare_raw_fn(
+ self,
+ name,
+ fn_abi.llvm_cconv(),
+ llvm::UnnamedAddr::Global,
+ fn_abi.llvm_type(self),
+ );
fn_abi.apply_attrs_llfn(self, llfn);
llfn
}
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index bf0d499..af366f9 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -334,8 +334,11 @@
self.call(expect, &[cond, self.const_bool(expected)], None)
}
- fn sideeffect(&mut self, unconditional: bool) {
- if unconditional || self.tcx.sess.opts.debugging_opts.insert_sideeffect {
+ fn sideeffect(&mut self) {
+ // This kind of check would make a ton of sense in the caller, but currently the only
+ // caller of this function is in `rustc_codegen_ssa`, which is agnostic to whether LLVM
+ // codegen backend being used, and so is unable to check the LLVM version.
+ if unsafe { llvm::LLVMRustVersionMajor() } < 12 {
let fnname = self.get_intrinsic(&("llvm.sideeffect"));
self.call(fnname, &[], None);
}
@@ -390,7 +393,6 @@
) {
let llfn = get_rust_try_fn(bx, &mut |mut bx| {
bx.set_personality_fn(bx.eh_personality());
- bx.sideeffect(false);
let mut normal = bx.build_sibling_block("normal");
let mut catchswitch = bx.build_sibling_block("catchswitch");
@@ -552,9 +554,6 @@
// (%ptr, _) = landingpad
// call %catch_func(%data, %ptr)
// ret 1
-
- bx.sideeffect(false);
-
let mut then = bx.build_sibling_block("then");
let mut catch = bx.build_sibling_block("catch");
@@ -614,9 +613,6 @@
// %catch_data[1] = %is_rust_panic
// call %catch_func(%data, %catch_data)
// ret 1
-
- bx.sideeffect(false);
-
let mut then = bx.build_sibling_block("then");
let mut catch = bx.build_sibling_block("catch");
@@ -1009,7 +1005,7 @@
}
fn simd_simple_float_intrinsic(
- name: &str,
+ name: Symbol,
in_elem: &::rustc_middle::ty::TyS<'_>,
in_ty: &::rustc_middle::ty::TyS<'_>,
in_len: u64,
@@ -1036,93 +1032,69 @@
}
}
}
- let ety = match in_elem.kind() {
- ty::Float(f) if f.bit_width() == 32 => {
- if in_len < 2 || in_len > 16 {
+
+ let (elem_ty_str, elem_ty) = if let ty::Float(f) = in_elem.kind() {
+ let elem_ty = bx.cx.type_float_from_ty(*f);
+ match f.bit_width() {
+ 32 => ("f32", elem_ty),
+ 64 => ("f64", elem_ty),
+ _ => {
return_error!(
- "unsupported floating-point vector `{}` with length `{}` \
- out-of-range [2, 16]",
- in_ty,
- in_len
+ "unsupported element type `{}` of floating-point vector `{}`",
+ f.name_str(),
+ in_ty
);
}
- "f32"
}
- ty::Float(f) if f.bit_width() == 64 => {
- if in_len < 2 || in_len > 8 {
- return_error!(
- "unsupported floating-point vector `{}` with length `{}` \
- out-of-range [2, 8]",
- in_ty,
- in_len
- );
- }
- "f64"
- }
- ty::Float(f) => {
- return_error!(
- "unsupported element type `{}` of floating-point vector `{}`",
- f.name_str(),
- in_ty
- );
- }
- _ => {
- return_error!("`{}` is not a floating-point type", in_ty);
- }
+ } else {
+ return_error!("`{}` is not a floating-point type", in_ty);
};
- let llvm_name = &format!("llvm.{0}.v{1}{2}", name, in_len, ety);
- let intrinsic = bx.get_intrinsic(&llvm_name);
- let c =
- bx.call(intrinsic, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None);
+ let vec_ty = bx.type_vector(elem_ty, in_len);
+
+ let (intr_name, fn_ty) = match name {
+ sym::simd_fsqrt => ("sqrt", bx.type_func(&[vec_ty], vec_ty)),
+ sym::simd_fsin => ("sin", bx.type_func(&[vec_ty], vec_ty)),
+ sym::simd_fcos => ("cos", bx.type_func(&[vec_ty], vec_ty)),
+ sym::simd_fabs => ("fabs", bx.type_func(&[vec_ty], vec_ty)),
+ sym::simd_floor => ("floor", bx.type_func(&[vec_ty], vec_ty)),
+ sym::simd_ceil => ("ceil", bx.type_func(&[vec_ty], vec_ty)),
+ sym::simd_fexp => ("exp", bx.type_func(&[vec_ty], vec_ty)),
+ sym::simd_fexp2 => ("exp2", bx.type_func(&[vec_ty], vec_ty)),
+ sym::simd_flog10 => ("log10", bx.type_func(&[vec_ty], vec_ty)),
+ sym::simd_flog2 => ("log2", bx.type_func(&[vec_ty], vec_ty)),
+ sym::simd_flog => ("log", bx.type_func(&[vec_ty], vec_ty)),
+ sym::simd_fpowi => ("powi", bx.type_func(&[vec_ty, bx.type_i32()], vec_ty)),
+ sym::simd_fpow => ("pow", bx.type_func(&[vec_ty, vec_ty], vec_ty)),
+ sym::simd_fma => ("fma", bx.type_func(&[vec_ty, vec_ty, vec_ty], vec_ty)),
+ _ => return_error!("unrecognized intrinsic `{}`", name),
+ };
+
+ let llvm_name = &format!("llvm.{0}.v{1}{2}", intr_name, in_len, elem_ty_str);
+ let f = bx.declare_cfn(&llvm_name, llvm::UnnamedAddr::No, fn_ty);
+ let c = bx.call(f, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None);
unsafe { llvm::LLVMRustSetHasUnsafeAlgebra(c) };
Ok(c)
}
- match name {
- sym::simd_fsqrt => {
- return simd_simple_float_intrinsic("sqrt", in_elem, in_ty, in_len, bx, span, args);
- }
- sym::simd_fsin => {
- return simd_simple_float_intrinsic("sin", in_elem, in_ty, in_len, bx, span, args);
- }
- sym::simd_fcos => {
- return simd_simple_float_intrinsic("cos", in_elem, in_ty, in_len, bx, span, args);
- }
- sym::simd_fabs => {
- return simd_simple_float_intrinsic("fabs", in_elem, in_ty, in_len, bx, span, args);
- }
- sym::simd_floor => {
- return simd_simple_float_intrinsic("floor", in_elem, in_ty, in_len, bx, span, args);
- }
- sym::simd_ceil => {
- return simd_simple_float_intrinsic("ceil", in_elem, in_ty, in_len, bx, span, args);
- }
- sym::simd_fexp => {
- return simd_simple_float_intrinsic("exp", in_elem, in_ty, in_len, bx, span, args);
- }
- sym::simd_fexp2 => {
- return simd_simple_float_intrinsic("exp2", in_elem, in_ty, in_len, bx, span, args);
- }
- sym::simd_flog10 => {
- return simd_simple_float_intrinsic("log10", in_elem, in_ty, in_len, bx, span, args);
- }
- sym::simd_flog2 => {
- return simd_simple_float_intrinsic("log2", in_elem, in_ty, in_len, bx, span, args);
- }
- sym::simd_flog => {
- return simd_simple_float_intrinsic("log", in_elem, in_ty, in_len, bx, span, args);
- }
- sym::simd_fpowi => {
- return simd_simple_float_intrinsic("powi", in_elem, in_ty, in_len, bx, span, args);
- }
- sym::simd_fpow => {
- return simd_simple_float_intrinsic("pow", in_elem, in_ty, in_len, bx, span, args);
- }
- sym::simd_fma => {
- return simd_simple_float_intrinsic("fma", in_elem, in_ty, in_len, bx, span, args);
- }
- _ => { /* fallthrough */ }
+ if std::matches!(
+ name,
+ sym::simd_fsqrt
+ | sym::simd_fsin
+ | sym::simd_fcos
+ | sym::simd_fabs
+ | sym::simd_floor
+ | sym::simd_ceil
+ | sym::simd_fexp
+ | sym::simd_fexp2
+ | sym::simd_flog10
+ | sym::simd_flog2
+ | sym::simd_flog
+ | sym::simd_fpowi
+ | sym::simd_fpow
+ | sym::simd_fma
+ ) {
+ return simd_simple_float_intrinsic(name, in_elem, in_ty, in_len, bx, span, args);
}
// FIXME: use:
@@ -1278,12 +1250,12 @@
format!("llvm.masked.gather.{}.{}", llvm_elem_vec_str, llvm_pointer_vec_str);
let f = bx.declare_cfn(
&llvm_intrinsic,
+ llvm::UnnamedAddr::No,
bx.type_func(
&[llvm_pointer_vec_ty, alignment_ty, mask_ty, llvm_elem_vec_ty],
llvm_elem_vec_ty,
),
);
- llvm::SetUnnamedAddress(f, llvm::UnnamedAddr::No);
let v = bx.call(f, &[args[1].immediate(), alignment, mask, args[0].immediate()], None);
return Ok(v);
}
@@ -1408,9 +1380,9 @@
format!("llvm.masked.scatter.{}.{}", llvm_elem_vec_str, llvm_pointer_vec_str);
let f = bx.declare_cfn(
&llvm_intrinsic,
+ llvm::UnnamedAddr::No,
bx.type_func(&[llvm_elem_vec_ty, llvm_pointer_vec_ty, alignment_ty, mask_ty], ret_t),
);
- llvm::SetUnnamedAddress(f, llvm::UnnamedAddr::No);
let v = bx.call(f, &[args[0].immediate(), args[1].immediate(), alignment, mask], None);
return Ok(v);
}
@@ -1656,7 +1628,7 @@
out_elem
);
}
- macro_rules! arith {
+ macro_rules! arith_binary {
($($name: ident: $($($p: ident),* => $call: ident),*;)*) => {
$(if name == sym::$name {
match in_elem.kind() {
@@ -1672,7 +1644,7 @@
})*
}
}
- arith! {
+ arith_binary! {
simd_add: Uint, Int => add, Float => fadd;
simd_sub: Uint, Int => sub, Float => fsub;
simd_mul: Uint, Int => mul, Float => fmul;
@@ -1687,6 +1659,25 @@
simd_fmin: Float => minnum;
}
+ macro_rules! arith_unary {
+ ($($name: ident: $($($p: ident),* => $call: ident),*;)*) => {
+ $(if name == sym::$name {
+ match in_elem.kind() {
+ $($(ty::$p(_))|* => {
+ return Ok(bx.$call(args[0].immediate()))
+ })*
+ _ => {},
+ }
+ require!(false,
+ "unsupported operation on `{}` with element `{}`",
+ in_ty,
+ in_elem)
+ })*
+ }
+ }
+ arith_unary! {
+ simd_neg: Int => neg, Float => fneg;
+ }
if name == sym::simd_saturating_add || name == sym::simd_saturating_sub {
let lhs = args[0].immediate();
@@ -1714,8 +1705,11 @@
);
let vec_ty = bx.cx.type_vector(elem_ty, in_len as u64);
- let f = bx.declare_cfn(&llvm_intrinsic, bx.type_func(&[vec_ty, vec_ty], vec_ty));
- llvm::SetUnnamedAddress(f, llvm::UnnamedAddr::No);
+ let f = bx.declare_cfn(
+ &llvm_intrinsic,
+ llvm::UnnamedAddr::No,
+ bx.type_func(&[vec_ty, vec_ty], vec_ty),
+ );
let v = bx.call(f, &[lhs, rhs], None);
return Ok(v);
}
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index e82198f..82cd1be 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -131,6 +131,8 @@
ReturnsTwice = 25,
ReadNone = 26,
InaccessibleMemOnly = 27,
+ SanitizeHWAddress = 28,
+ WillReturn = 29,
}
/// LLVMIntPredicate
@@ -238,6 +240,7 @@
Token = 16,
ScalableVector = 17,
BFloat = 18,
+ X86_AMX = 19,
}
impl TypeKind {
@@ -262,6 +265,7 @@
TypeKind::Token => rustc_codegen_ssa::common::TypeKind::Token,
TypeKind::ScalableVector => rustc_codegen_ssa::common::TypeKind::ScalableVector,
TypeKind::BFloat => rustc_codegen_ssa::common::TypeKind::BFloat,
+ TypeKind::X86_AMX => rustc_codegen_ssa::common::TypeKind::X86_AMX,
}
}
}
@@ -439,6 +443,8 @@
pub sanitize_memory_recover: bool,
pub sanitize_memory_track_origins: c_int,
pub sanitize_thread: bool,
+ pub sanitize_hwaddress: bool,
+ pub sanitize_hwaddress_recover: bool,
}
/// LLVMRelocMode
@@ -671,9 +677,7 @@
/// array", encoded separately), and source location (start and end positions of the represented
/// code region).
///
- /// Aligns with [llvm::coverage::CounterMappingRegion](https://github.com/rust-lang/llvm-project/blob/rustc/11.0-2020-10-12/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L224-L227)
- /// Important: The Rust struct layout (order and types of fields) must match its C++
- /// counterpart.
+ /// Matches LLVMRustCounterMappingRegion.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct CounterMappingRegion {
@@ -1070,6 +1074,7 @@
pub fn LLVMRustAddDereferenceableAttr(Fn: &Value, index: c_uint, bytes: u64);
pub fn LLVMRustAddDereferenceableOrNullAttr(Fn: &Value, index: c_uint, bytes: u64);
pub fn LLVMRustAddByValAttr(Fn: &Value, index: c_uint, ty: &Type);
+ pub fn LLVMRustAddStructRetAttr(Fn: &Value, index: c_uint, ty: &Type);
pub fn LLVMRustAddFunctionAttribute(Fn: &Value, index: c_uint, attr: Attribute);
pub fn LLVMRustAddFunctionAttrStringValue(
Fn: &Value,
@@ -1105,6 +1110,7 @@
pub fn LLVMRustAddDereferenceableCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64);
pub fn LLVMRustAddDereferenceableOrNullCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64);
pub fn LLVMRustAddByValCallSiteAttr(Instr: &Value, index: c_uint, ty: &Type);
+ pub fn LLVMRustAddStructRetCallSiteAttr(Instr: &Value, index: c_uint, ty: &Type);
// Operations on load/store instructions (only)
pub fn LLVMSetVolatile(MemoryAccessInst: &Value, volatile: Bool);
@@ -1789,7 +1795,7 @@
NumVirtualFileMappingIDs: c_uint,
Expressions: *const coverage_map::CounterExpression,
NumExpressions: c_uint,
- MappingRegions: *mut coverageinfo::CounterMappingRegion,
+ MappingRegions: *const coverageinfo::CounterMappingRegion,
NumMappingRegions: c_uint,
BufferOut: &RustString,
);
@@ -2128,6 +2134,7 @@
Recover: bool,
) -> &'static mut Pass;
pub fn LLVMRustCreateThreadSanitizerPass() -> &'static mut Pass;
+ pub fn LLVMRustCreateHWAddressSanitizerPass(Recover: bool) -> &'static mut Pass;
pub fn LLVMRustAddPass(PM: &PassManager<'_>, Pass: &'static mut Pass);
pub fn LLVMRustAddLastExtensionPasses(
PMB: &PassManagerBuilder,
@@ -2319,6 +2326,7 @@
pub fn LLVMRustUnsetComdat(V: &Value);
pub fn LLVMRustSetModulePICLevel(M: &Module);
pub fn LLVMRustSetModulePIELevel(M: &Module);
+ pub fn LLVMRustSetModuleCodeModel(M: &Module, Model: CodeModel);
pub fn LLVMRustModuleBufferCreate(M: &Module) -> &'static mut ModuleBuffer;
pub fn LLVMRustModuleBufferPtr(p: &ModuleBuffer) -> *const u8;
pub fn LLVMRustModuleBufferLen(p: &ModuleBuffer) -> usize;
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 544ef38..c7dff41 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -218,13 +218,39 @@
handle_native(name)
}
-pub fn handle_native_features(sess: &Session) -> Vec<String> {
- match sess.opts.cg.target_cpu {
- Some(ref s) => {
- if s != "native" {
- return vec![];
- }
+/// The list of LLVM features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
+/// `--target` and similar).
+// FIXME(nagisa): Cache the output of this somehow? Maybe make this a query? We're calling this
+// for every function that has `#[target_feature]` on it. The global features won't change between
+// the functions; only crates, maybe…
+pub fn llvm_global_features(sess: &Session) -> Vec<String> {
+ // FIXME(nagisa): this should definitely be available more centrally and to other codegen backends.
+ /// These features control behaviour of rustc rather than llvm.
+ const RUSTC_SPECIFIC_FEATURES: &[&str] = &["crt-static"];
+ // Features that come earlier are overriden by conflicting features later in the string.
+ // Typically we'll want more explicit settings to override the implicit ones, so:
+ //
+ // * Features from -Ctarget-cpu=*; are overriden by [^1]
+ // * Features implied by --target; are overriden by
+ // * Features from -Ctarget-feature; are overriden by
+ // * function specific features.
+ //
+ // [^1]: target-cpu=native is handled here, other target-cpu values are handled implicitly
+ // through LLVM TargetMachine implementation.
+ //
+ // FIXME(nagisa): it isn't clear what's the best interaction between features implied by
+ // `-Ctarget-cpu` and `--target` are. On one hand, you'd expect CLI arguments to always
+ // override anything that's implicit, so e.g. when there's no `--target` flag, features implied
+ // the host target are overriden by `-Ctarget-cpu=*`. On the other hand, what about when both
+ // `--target` and `-Ctarget-cpu=*` are specified? Both then imply some target features and both
+ // flags are specified by the user on the CLI. It isn't as clear-cut which order of precedence
+ // should be taken in cases like these.
+ let mut features = vec![];
+
+ // -Ctarget-cpu=native
+ match sess.opts.cg.target_cpu {
+ Some(ref s) if s == "native" => {
let features_string = unsafe {
let ptr = llvm::LLVMGetHostCPUFeatures();
let features_string = if !ptr.is_null() {
@@ -242,11 +268,31 @@
features_string
};
-
- features_string.split(",").map(|s| s.to_owned()).collect()
+ features.extend(features_string.split(",").map(String::from));
}
- None => vec![],
- }
+ Some(_) | None => {}
+ };
+
+ // Features implied by an implicit or explicit `--target`.
+ features.extend(
+ sess.target
+ .features
+ .split(',')
+ .filter(|f| !f.is_empty() && !RUSTC_SPECIFIC_FEATURES.iter().any(|s| f.contains(s)))
+ .map(String::from),
+ );
+
+ // -Ctarget-features
+ features.extend(
+ sess.opts
+ .cg
+ .target_feature
+ .split(',')
+ .filter(|f| !f.is_empty() && !RUSTC_SPECIFIC_FEATURES.iter().any(|s| f.contains(s)))
+ .map(String::from),
+ );
+
+ features
}
pub fn tune_cpu(sess: &Session) -> Option<&str> {
diff --git a/compiler/rustc_codegen_llvm/src/metadata.rs b/compiler/rustc_codegen_llvm/src/metadata.rs
index 3912d6a..b007df5 100644
--- a/compiler/rustc_codegen_llvm/src/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/metadata.rs
@@ -65,8 +65,8 @@
while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
let mut name_buf = None;
let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf);
- let name = name_buf.map_or(
- String::new(), // We got a NULL ptr, ignore `name_len`.
+ let name = name_buf.map_or_else(
+ String::new, // We got a NULL ptr, ignore `name_len`.
|buf| {
String::from_utf8(
slice::from_raw_parts(buf.as_ptr() as *const u8, name_len as usize)