Importing rustc-1.51.0
Change-Id: Ie4f520eabee71971211e4637a45cbc9bf4a91e95
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index 915dd3d..a69241e 100644
--- a/compiler/rustc_codegen_llvm/src/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
@@ -389,7 +389,7 @@
fn llvm_cconv(&self) -> llvm::CallConv {
match self.conv {
- Conv::C | Conv::Rust => llvm::CCallConv,
+ Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
Conv::AmdGpuKernel => llvm::AmdGpuKernel,
Conv::AvrInterrupt => llvm::AvrInterrupt,
Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
@@ -546,6 +546,18 @@
if cconv != llvm::CCallConv {
llvm::SetInstructionCallConv(callsite, cconv);
}
+
+ if self.conv == Conv::CCmseNonSecureCall {
+ // This will probably get ignored on all targets but those supporting the TrustZone-M
+ // extension (thumbv8m targets).
+ unsafe {
+ llvm::AddCallSiteAttrString(
+ callsite,
+ llvm::AttributePlace::Function,
+ rustc_data_structures::const_cstr!("cmse_nonsecure_call"),
+ );
+ }
+ }
}
}
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index 97c38e0..a78d692 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -13,6 +13,7 @@
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::config::{OptLevel, SanitizerSet};
use rustc_session::Session;
+use rustc_target::spec::StackProbeType;
use crate::attributes;
use crate::llvm::AttributePlace::Function;
@@ -98,12 +99,6 @@
}
fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
- // Only use stack probes if the target specification indicates that we
- // should be using stack probes
- if !cx.sess().target.stack_probes {
- return;
- }
-
// Currently stack probes seem somewhat incompatible with the address
// sanitizer and thread sanitizer. With asan we're already protected from
// stack overflow anyway so we don't really need stack probes regardless.
@@ -127,14 +122,31 @@
return;
}
- // Flag our internal `__rust_probestack` function as the stack probe symbol.
- // This is defined in the `compiler-builtins` crate for each architecture.
- llvm::AddFunctionAttrStringValue(
- llfn,
- llvm::AttributePlace::Function,
- const_cstr!("probe-stack"),
- const_cstr!("__rust_probestack"),
- );
+ let attr_value = match cx.sess().target.stack_probes {
+ 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")),
+ // 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")),
+ // 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"))
+ } else {
+ Some(const_cstr!("inline-asm"))
+ }
+ }
+ };
+ if let Some(attr_value) = attr_value {
+ llvm::AddFunctionAttrStringValue(
+ llfn,
+ llvm::AttributePlace::Function,
+ const_cstr!("probe-stack"),
+ attr_value,
+ );
+ }
}
pub fn llvm_target_features(sess: &Session) -> impl Iterator<Item = &str> {
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index 2941597..5effe68 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -732,10 +732,7 @@
let diag_handler = cgcx.create_diag_handler();
let module_name = &thin_module.shared.module_names[thin_module.idx];
- let split_dwarf_file = cgcx
- .output_filenames
- .split_dwarf_filename(cgcx.split_dwarf_kind, Some(module_name.to_str().unwrap()));
- let tm_factory_config = TargetMachineFactoryConfig { split_dwarf_file };
+ let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, module_name.to_str().unwrap());
let tm =
(cgcx.tm_factory)(tm_factory_config).map_err(|e| write::llvm_err(&diag_handler, &e))?;
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 3fda1e2..326ae35 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -23,13 +23,11 @@
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::bug;
use rustc_middle::ty::TyCtxt;
-use rustc_session::config::{
- self, Lto, OutputType, Passes, SanitizerSet, SplitDwarfKind, SwitchWithOptPath,
-};
+use rustc_session::config::{self, Lto, OutputType, Passes, SanitizerSet, SwitchWithOptPath};
use rustc_session::Session;
use rustc_span::symbol::sym;
use rustc_span::InnerSpan;
-use rustc_target::spec::{CodeModel, RelocModel};
+use rustc_target::spec::{CodeModel, RelocModel, SplitDebuginfo};
use tracing::debug;
use libc::{c_char, c_int, c_uint, c_void, size_t};
@@ -93,9 +91,12 @@
}
pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> &'static mut llvm::TargetMachine {
- let split_dwarf_file = tcx
- .output_filenames(LOCAL_CRATE)
- .split_dwarf_filename(tcx.sess.opts.debugging_opts.split_dwarf, Some(mod_name));
+ 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))
+ } else {
+ None
+ };
let config = TargetMachineFactoryConfig { split_dwarf_file };
target_machine_factory(&tcx.sess, tcx.backend_optimization_level(LOCAL_CRATE))(config)
.unwrap_or_else(|err| llvm_err(tcx.sess.diagnostic(), &err).raise())
@@ -164,7 +165,8 @@
let code_model = to_llvm_code_model(sess.code_model());
- let features = attributes::llvm_target_features(sess).collect::<Vec<_>>();
+ 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
@@ -485,7 +487,7 @@
diag_handler: &Handler,
module: &ModuleCodegen<ModuleLlvm>,
config: &ModuleConfig,
-) -> Result<(), FatalError> {
+) {
let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_optimize", &module.name[..]);
let llmod = module.module_llvm.llmod();
@@ -511,7 +513,7 @@
_ => llvm::OptStage::PreLinkNoLTO,
};
optimize_with_new_llvm_pass_manager(cgcx, module, config, opt_level, opt_stage);
- return Ok(());
+ return;
}
if cgcx.prof.llvm_recording_enabled() {
@@ -634,7 +636,6 @@
llvm::LLVMDisposePassManager(fpm);
llvm::LLVMDisposePassManager(mpm);
}
- Ok(())
}
unsafe fn add_sanitizer_passes(config: &ModuleConfig, passes: &mut Vec<&'static mut llvm::Pass>) {
@@ -838,11 +839,17 @@
.generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]);
let dwo_out = cgcx.output_filenames.temp_path_dwo(module_name);
- let dwo_out = match cgcx.split_dwarf_kind {
+ let dwo_out = match cgcx.split_debuginfo {
// Don't change how DWARF is emitted in single mode (or when disabled).
- SplitDwarfKind::None | SplitDwarfKind::Single => None,
+ SplitDebuginfo::Off | SplitDebuginfo::Packed => None,
// Emit (a subset of the) DWARF into a separate file in split mode.
- SplitDwarfKind::Split => Some(dwo_out.as_path()),
+ SplitDebuginfo::Unpacked => {
+ if cgcx.target_can_use_split_dwarf {
+ Some(dwo_out.as_path())
+ } else {
+ None
+ }
+ }
};
with_codegen(tm, llmod, config.no_builtins, |cpm| {
@@ -880,7 +887,7 @@
Ok(module.into_compiled_module(
config.emit_obj != EmitObj::None,
- cgcx.split_dwarf_kind == SplitDwarfKind::Split,
+ cgcx.target_can_use_split_dwarf && cgcx.split_debuginfo == SplitDebuginfo::Unpacked,
config.emit_bc,
&cgcx.output_filenames,
))
@@ -1002,8 +1009,7 @@
// reasonable defaults and prepare it to actually populate the pass
// manager.
let builder = llvm::LLVMPassManagerBuilderCreate();
- let opt_size =
- config.opt_size.map(|x| to_llvm_opt_settings(x).1).unwrap_or(llvm::CodeGenOptSizeNone);
+ let opt_size = config.opt_size.map_or(llvm::CodeGenOptSizeNone, |x| to_llvm_opt_settings(x).1);
let inline_threshold = config.inline_threshold;
let pgo_gen_path = get_pgo_gen_path(config);
let pgo_use_path = get_pgo_use_path(config);
diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs
index 7d01f6a..d5be313 100644
--- a/compiler/rustc_codegen_llvm/src/base.rs
+++ b/compiler/rustc_codegen_llvm/src/base.rs
@@ -1,17 +1,15 @@
-//! Codegen the completed AST to the LLVM IR.
-//!
-//! Some functions here, such as codegen_block and codegen_expr, return a value --
-//! the result of the codegen to LLVM -- while others, such as codegen_fn
-//! and mono_item, are called only for the side effect of adding a
-//! particular definition to the LLVM IR output we're producing.
+//! Codegen the MIR to the LLVM IR.
//!
//! Hopefully useful general knowledge about codegen:
//!
-//! * There's no way to find out the `Ty` type of a Value. Doing so
+//! * There's no way to find out the [`Ty`] type of a [`Value`]. Doing so
//! would be "trying to get the eggs out of an omelette" (credit:
-//! pcwalton). You can, instead, find out its `llvm::Type` by calling `val_ty`,
-//! but one `llvm::Type` corresponds to many `Ty`s; for instance, `tup(int, int,
-//! int)` and `rec(x=int, y=int, z=int)` will have the same `llvm::Type`.
+//! pcwalton). You can, instead, find out its [`llvm::Type`] by calling [`val_ty`],
+//! but one [`llvm::Type`] corresponds to many [`Ty`]s; for instance, `tup(int, int,
+//! int)` and `rec(x=int, y=int, z=int)` will have the same [`llvm::Type`].
+//!
+//! [`Ty`]: rustc_middle::ty::Ty
+//! [`val_ty`]: common::val_ty
use super::ModuleLlvm;
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index f122fa1..d2f4d3e 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -304,9 +304,8 @@
lhs: Self::Value,
rhs: Self::Value,
) -> (Self::Value, Self::Value) {
- use rustc_ast::IntTy::*;
- use rustc_ast::UintTy::*;
use rustc_middle::ty::{Int, Uint};
+ use rustc_middle::ty::{IntTy::*, UintTy::*};
let new_kind = match ty.kind() {
Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.pointer_width)),
diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs
index 34e1b7a..58af9d4 100644
--- a/compiler/rustc_codegen_llvm/src/common.rs
+++ b/compiler/rustc_codegen_llvm/src/common.rs
@@ -314,6 +314,7 @@
}
}
+/// Get the [LLVM type][Type] of a [`Value`].
pub fn val_ty(v: &Value) -> &Type {
unsafe { llvm::LLVMTypeOf(v) }
}
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index 14dd245..16e1a8a 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -8,9 +8,7 @@
use libc::c_uint;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::const_cstr;
-use rustc_hir as hir;
use rustc_hir::def_id::DefId;
-use rustc_hir::Node;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::interpret::{
read_target_uint, Allocation, ErrorHandled, GlobalAlloc, Pointer,
@@ -18,7 +16,6 @@
use rustc_middle::mir::mono::MonoItem;
use rustc_middle::ty::{self, Instance, Ty};
use rustc_middle::{bug, span_bug};
-use rustc_span::symbol::sym;
use rustc_target::abi::{AddressSpace, Align, HasDataLayout, LayoutOf, Primitive, Scalar, Size};
use tracing::debug;
@@ -209,70 +206,42 @@
let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all());
let sym = self.tcx.symbol_name(instance).name;
+ let fn_attrs = self.tcx.codegen_fn_attrs(def_id);
- debug!("get_static: sym={} instance={:?}", sym, instance);
+ debug!("get_static: sym={} instance={:?} fn_attrs={:?}", sym, instance, fn_attrs);
- let g = if let Some(local_def_id) = def_id.as_local() {
- let id = self.tcx.hir().local_def_id_to_hir_id(local_def_id);
+ let g = if def_id.is_local() && !self.tcx.is_foreign_item(def_id) {
let llty = self.layout_of(ty).llvm_type(self);
- // FIXME: refactor this to work without accessing the HIR
- let (g, attrs) = match self.tcx.hir().get(id) {
- Node::Item(&hir::Item { attrs, kind: hir::ItemKind::Static(..), .. }) => {
- if let Some(g) = self.get_declared_value(sym) {
- if self.val_ty(g) != self.type_ptr_to(llty) {
- span_bug!(self.tcx.def_span(def_id), "Conflicting types for static");
- }
- }
-
- let g = self.declare_global(sym, llty);
-
- if !self.tcx.is_reachable_non_generic(local_def_id) {
- unsafe {
- llvm::LLVMRustSetVisibility(g, llvm::Visibility::Hidden);
- }
- }
-
- (g, attrs)
+ if let Some(g) = self.get_declared_value(sym) {
+ if self.val_ty(g) != self.type_ptr_to(llty) {
+ span_bug!(self.tcx.def_span(def_id), "Conflicting types for static");
}
+ }
- Node::ForeignItem(&hir::ForeignItem {
- ref attrs,
- kind: hir::ForeignItemKind::Static(..),
- ..
- }) => {
- let fn_attrs = self.tcx.codegen_fn_attrs(local_def_id);
- (check_and_apply_linkage(&self, &fn_attrs, ty, sym, def_id), &**attrs)
- }
+ let g = self.declare_global(sym, llty);
- item => bug!("get_static: expected static, found {:?}", item),
- };
-
- debug!("get_static: sym={} attrs={:?}", sym, attrs);
-
- for attr in attrs {
- if self.tcx.sess.check_name(attr, sym::thread_local) {
- llvm::set_thread_local_mode(g, self.tls_model);
+ if !self.tcx.is_reachable_non_generic(def_id) {
+ unsafe {
+ llvm::LLVMRustSetVisibility(g, llvm::Visibility::Hidden);
}
}
g
} else {
- // FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
- debug!("get_static: sym={} item_attr={:?}", sym, self.tcx.item_attrs(def_id));
+ check_and_apply_linkage(&self, &fn_attrs, ty, sym, def_id)
+ };
- let attrs = self.tcx.codegen_fn_attrs(def_id);
- let g = check_and_apply_linkage(&self, &attrs, ty, sym, def_id);
+ // Thread-local statics in some other crate need to *always* be linked
+ // against in a thread-local fashion, so we need to be sure to apply the
+ // thread-local attribute locally if it was present remotely. If we
+ // don't do this then linker errors can be generated where the linker
+ // complains that one object files has a thread local version of the
+ // symbol and another one doesn't.
+ if fn_attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) {
+ llvm::set_thread_local_mode(g, self.tls_model);
+ }
- // Thread-local statics in some other crate need to *always* be linked
- // against in a thread-local fashion, so we need to be sure to apply the
- // thread-local attribute locally if it was present remotely. If we
- // don't do this then linker errors can be generated where the linker
- // complains that one object files has a thread local version of the
- // symbol and another one doesn't.
- if attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) {
- llvm::set_thread_local_mode(g, self.tls_model);
- }
-
+ if !def_id.is_local() {
let needs_dll_storage_attr = self.use_dll_storage_attrs && !self.tcx.is_foreign_item(def_id) &&
// ThinLTO can't handle this workaround in all cases, so we don't
// emit the attrs. Instead we make them unnecessary by disallowing
@@ -304,8 +273,7 @@
}
}
}
- g
- };
+ }
if self.use_dll_storage_attrs && self.tcx.is_dllimport_foreign_item(def_id) {
// For foreign (native) libs we know the exact storage type to use.
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 8dd4030..6acd26b 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -114,7 +114,7 @@
let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
let mut target_data_layout = sess.target.data_layout.clone();
- if llvm_util::get_major_version() < 10
+ if llvm_util::get_version() < (10, 0, 0)
&& (sess.target.arch == "x86" || sess.target.arch == "x86_64")
{
target_data_layout = strip_x86_address_spaces(target_data_layout);
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
index 72ba5bb..444a9d4 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
@@ -292,7 +292,7 @@
if let Some(non_codegenned_file_name) = tcx.covered_file_name(non_codegenned_def_id) {
let def_ids = unreachable_def_ids_by_file
.entry(*non_codegenned_file_name)
- .or_insert_with(|| Vec::new());
+ .or_insert_with(Vec::new);
def_ids.push(non_codegenned_def_id);
}
}
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index fa285f3..6e7c0b3 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -18,7 +18,6 @@
};
use crate::value::Value;
-use rustc_ast as ast;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::const_cstr;
use rustc_data_structures::fingerprint::Fingerprint;
@@ -830,37 +829,37 @@
fn msvc_basic_name(self) -> &'static str;
}
-impl MsvcBasicName for ast::IntTy {
+impl MsvcBasicName for ty::IntTy {
fn msvc_basic_name(self) -> &'static str {
match self {
- ast::IntTy::Isize => "ptrdiff_t",
- ast::IntTy::I8 => "__int8",
- ast::IntTy::I16 => "__int16",
- ast::IntTy::I32 => "__int32",
- ast::IntTy::I64 => "__int64",
- ast::IntTy::I128 => "__int128",
+ ty::IntTy::Isize => "ptrdiff_t",
+ ty::IntTy::I8 => "__int8",
+ ty::IntTy::I16 => "__int16",
+ ty::IntTy::I32 => "__int32",
+ ty::IntTy::I64 => "__int64",
+ ty::IntTy::I128 => "__int128",
}
}
}
-impl MsvcBasicName for ast::UintTy {
+impl MsvcBasicName for ty::UintTy {
fn msvc_basic_name(self) -> &'static str {
match self {
- ast::UintTy::Usize => "size_t",
- ast::UintTy::U8 => "unsigned __int8",
- ast::UintTy::U16 => "unsigned __int16",
- ast::UintTy::U32 => "unsigned __int32",
- ast::UintTy::U64 => "unsigned __int64",
- ast::UintTy::U128 => "unsigned __int128",
+ ty::UintTy::Usize => "size_t",
+ ty::UintTy::U8 => "unsigned __int8",
+ ty::UintTy::U16 => "unsigned __int16",
+ ty::UintTy::U32 => "unsigned __int32",
+ ty::UintTy::U64 => "unsigned __int64",
+ ty::UintTy::U128 => "unsigned __int128",
}
}
}
-impl MsvcBasicName for ast::FloatTy {
+impl MsvcBasicName for ty::FloatTy {
fn msvc_basic_name(self) -> &'static str {
match self {
- ast::FloatTy::F32 => "float",
- ast::FloatTy::F64 => "double",
+ ty::FloatTy::F32 => "float",
+ ty::FloatTy::F64 => "double",
}
}
}
@@ -996,10 +995,13 @@
let flags = "\0";
let out_dir = &tcx.output_filenames(LOCAL_CRATE).out_directory;
- let split_name = tcx
- .output_filenames(LOCAL_CRATE)
- .split_dwarf_filename(tcx.sess.opts.debugging_opts.split_dwarf, Some(codegen_unit_name))
- .unwrap_or_default();
+ 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))
+ } else {
+ None
+ }
+ .unwrap_or_default();
let out_dir = out_dir.to_str().unwrap();
let split_name = split_name.to_str().unwrap();
@@ -1832,8 +1834,9 @@
fn source_info(&self, cx: &CodegenCx<'ll, 'tcx>) -> Option<SourceInfo<'ll>> {
match self {
VariantInfo::Generator { def_id, variant_index, .. } => {
- let span =
- cx.tcx.generator_layout(*def_id).variant_source_info[*variant_index].span;
+ let span = cx.tcx.generator_layout(*def_id).unwrap().variant_source_info
+ [*variant_index]
+ .span;
if !span.is_dummy() {
let loc = cx.lookup_debug_loc(span.lo());
return Some(SourceInfo {
@@ -2322,13 +2325,13 @@
DIB(cx),
composite_type_metadata,
Some(type_array),
- type_params,
+ Some(type_params),
);
}
}
/// Computes the type parameters for a type, if any, for the given metadata.
-fn compute_type_parameters(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> Option<&'ll DIArray> {
+fn compute_type_parameters(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> &'ll DIArray {
if let ty::Adt(def, substs) = *ty.kind() {
if substs.types().next().is_some() {
let generics = cx.tcx.generics_of(def.did);
@@ -2358,10 +2361,10 @@
})
.collect();
- return Some(create_DIArray(DIB(cx), &template_params[..]));
+ return create_DIArray(DIB(cx), &template_params[..]);
}
}
- return Some(create_DIArray(DIB(cx), &[]));
+ return create_DIArray(DIB(cx), &[]);
fn get_parameter_names(cx: &CodegenCx<'_, '_>, generics: &ty::Generics) -> Vec<Symbol> {
let mut names = generics
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index ccbe732..955e739 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -552,7 +552,6 @@
unsafe {
llvm::LLVMRustDIBuilderCreateDebugLocation(
- utils::debug_context(self).llcontext,
line.unwrap_or(UNKNOWN_LINE_NUMBER),
col.unwrap_or(UNKNOWN_COLUMN_NUMBER),
scope,
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index a58c2fb..d11c159 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -160,7 +160,7 @@
module: &ModuleCodegen<Self::Module>,
config: &ModuleConfig,
) -> Result<(), FatalError> {
- back::write::optimize(cgcx, diag_handler, module, config)
+ Ok(back::write::optimize(cgcx, diag_handler, module, config))
}
unsafe fn optimize_thin(
cgcx: &CodegenContext<Self>,
@@ -298,21 +298,19 @@
codegen_results: CodegenResults,
outputs: &OutputFilenames,
) -> Result<(), ErrorReported> {
+ use crate::back::archive::LlvmArchiveBuilder;
+ use rustc_codegen_ssa::back::link::link_binary;
+
// Run the linker on any artifacts that resulted from the LLVM run.
// This should produce either a finished executable or library.
- sess.time("link_crate", || {
- use crate::back::archive::LlvmArchiveBuilder;
- use rustc_codegen_ssa::back::link::link_binary;
-
- let target_cpu = crate::llvm_util::target_cpu(sess);
- link_binary::<LlvmArchiveBuilder<'_>>(
- sess,
- &codegen_results,
- outputs,
- &codegen_results.crate_name.as_str(),
- target_cpu,
- );
- });
+ let target_cpu = crate::llvm_util::target_cpu(sess);
+ link_binary::<LlvmArchiveBuilder<'_>>(
+ sess,
+ &codegen_results,
+ outputs,
+ &codegen_results.crate_name.as_str(),
+ target_cpu,
+ );
Ok(())
}
@@ -353,12 +351,7 @@
unsafe {
let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names);
let llmod_raw = back::lto::parse_module(llcx, name, buffer, handler)?;
-
- let split_dwarf_file = cgcx
- .output_filenames
- .split_dwarf_filename(cgcx.split_dwarf_kind, Some(name.to_str().unwrap()));
- let tm_factory_config = TargetMachineFactoryConfig { split_dwarf_file };
-
+ let tm_factory_config = TargetMachineFactoryConfig::new(&cgcx, name.to_str().unwrap());
let tm = match (cgcx.tm_factory)(tm_factory_config) {
Ok(m) => m,
Err(e) => {
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 707aaa2..e82198f 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -1100,6 +1100,7 @@
// Operations on call sites
pub fn LLVMSetInstructionCallConv(Instr: &Value, CC: c_uint);
pub fn LLVMRustAddCallSiteAttribute(Instr: &Value, index: c_uint, attr: Attribute);
+ pub fn LLVMRustAddCallSiteAttrString(Instr: &Value, index: c_uint, Name: *const c_char);
pub fn LLVMRustAddAlignmentCallSiteAttr(Instr: &Value, index: c_uint, bytes: u32);
pub fn LLVMRustAddDereferenceableCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64);
pub fn LLVMRustAddDereferenceableOrNullCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64);
@@ -1708,6 +1709,10 @@
PM: &PassManager<'_>,
);
+ pub fn LLVMGetHostCPUFeatures() -> *mut c_char;
+
+ pub fn LLVMDisposeMessage(message: *mut c_char);
+
// Stuff that's in llvm-wrapper/ because it's not upstream yet.
/// Opens an object file.
@@ -1807,6 +1812,7 @@
pub fn LLVMRustDebugMetadataVersion() -> u32;
pub fn LLVMRustVersionMajor() -> u32;
pub fn LLVMRustVersionMinor() -> u32;
+ pub fn LLVMRustVersionPatch() -> u32;
pub fn LLVMRustAddModuleFlag(M: &Module, name: *const c_char, value: u32);
@@ -2098,7 +2104,6 @@
);
pub fn LLVMRustDIBuilderCreateDebugLocation(
- Context: &'a Context,
Line: c_uint,
Column: c_uint,
Scope: &'a DIScope,
diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
index fc40065..bb9c6d4 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
@@ -43,6 +43,10 @@
}
}
+pub fn AddCallSiteAttrString(callsite: &Value, idx: AttributePlace, attr: &CStr) {
+ unsafe { LLVMRustAddCallSiteAttrString(callsite, idx.as_uint(), attr.as_ptr()) }
+}
+
#[derive(Copy, Clone)]
pub enum AttributePlace {
ReturnValue,
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index a3139ce..544ef38 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -8,7 +8,7 @@
use rustc_session::Session;
use rustc_span::symbol::Symbol;
use rustc_target::spec::{MergeFunctions, PanicStrategy};
-use std::ffi::CString;
+use std::ffi::{CStr, CString};
use std::slice;
use std::str;
@@ -171,14 +171,15 @@
}
pub fn print_version() {
- // Can be called without initializing LLVM
- unsafe {
- println!("LLVM version: {}.{}", llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor());
- }
+ let (major, minor, patch) = get_version();
+ println!("LLVM version: {}.{}.{}", major, minor, patch);
}
-pub fn get_major_version() -> u32 {
- unsafe { llvm::LLVMRustVersionMajor() }
+pub fn get_version() -> (u32, u32, u32) {
+ // Can be called without initializing LLVM
+ unsafe {
+ (llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor(), llvm::LLVMRustVersionPatch())
+ }
}
pub fn print_passes() {
@@ -213,17 +214,42 @@
}
pub fn target_cpu(sess: &Session) -> &str {
- let name = match sess.opts.cg.target_cpu {
- Some(ref s) => &**s,
- None => &*sess.target.cpu,
- };
-
+ let name = sess.opts.cg.target_cpu.as_ref().unwrap_or(&sess.target.cpu);
handle_native(name)
}
-pub fn tune_cpu(sess: &Session) -> Option<&str> {
- match sess.opts.debugging_opts.tune_cpu {
- Some(ref s) => Some(handle_native(&**s)),
- None => None,
+pub fn handle_native_features(sess: &Session) -> Vec<String> {
+ match sess.opts.cg.target_cpu {
+ Some(ref s) => {
+ if s != "native" {
+ return vec![];
+ }
+
+ let features_string = unsafe {
+ let ptr = llvm::LLVMGetHostCPUFeatures();
+ let features_string = if !ptr.is_null() {
+ CStr::from_ptr(ptr)
+ .to_str()
+ .unwrap_or_else(|e| {
+ bug!("LLVM returned a non-utf8 features string: {}", e);
+ })
+ .to_owned()
+ } else {
+ bug!("could not allocate host CPU features, LLVM returned a `null` string");
+ };
+
+ llvm::LLVMDisposeMessage(ptr);
+
+ features_string
+ };
+
+ features_string.split(",").map(|s| s.to_owned()).collect()
+ }
+ None => vec![],
}
}
+
+pub fn tune_cpu(sess: &Session) -> Option<&str> {
+ let name = sess.opts.debugging_opts.tune_cpu.as_ref()?;
+ Some(handle_native(name))
+}
diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs
index a43724f..8fd0caae 100644
--- a/compiler/rustc_codegen_llvm/src/type_.rs
+++ b/compiler/rustc_codegen_llvm/src/type_.rs
@@ -7,13 +7,12 @@
use crate::llvm::{Bool, False, True};
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
-use rustc_ast as ast;
use rustc_codegen_ssa::common::TypeKind;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_middle::bug;
use rustc_middle::ty::layout::TyAndLayout;
-use rustc_middle::ty::Ty;
+use rustc_middle::ty::{self, Ty};
use rustc_target::abi::call::{CastTarget, FnAbi, Reg};
use rustc_target::abi::{AddressSpace, Align, Integer, Size};
@@ -80,32 +79,32 @@
self.type_i8()
}
- crate fn type_int_from_ty(&self, t: ast::IntTy) -> &'ll Type {
+ crate fn type_int_from_ty(&self, t: ty::IntTy) -> &'ll Type {
match t {
- ast::IntTy::Isize => self.type_isize(),
- ast::IntTy::I8 => self.type_i8(),
- ast::IntTy::I16 => self.type_i16(),
- ast::IntTy::I32 => self.type_i32(),
- ast::IntTy::I64 => self.type_i64(),
- ast::IntTy::I128 => self.type_i128(),
+ ty::IntTy::Isize => self.type_isize(),
+ ty::IntTy::I8 => self.type_i8(),
+ ty::IntTy::I16 => self.type_i16(),
+ ty::IntTy::I32 => self.type_i32(),
+ ty::IntTy::I64 => self.type_i64(),
+ ty::IntTy::I128 => self.type_i128(),
}
}
- crate fn type_uint_from_ty(&self, t: ast::UintTy) -> &'ll Type {
+ crate fn type_uint_from_ty(&self, t: ty::UintTy) -> &'ll Type {
match t {
- ast::UintTy::Usize => self.type_isize(),
- ast::UintTy::U8 => self.type_i8(),
- ast::UintTy::U16 => self.type_i16(),
- ast::UintTy::U32 => self.type_i32(),
- ast::UintTy::U64 => self.type_i64(),
- ast::UintTy::U128 => self.type_i128(),
+ ty::UintTy::Usize => self.type_isize(),
+ ty::UintTy::U8 => self.type_i8(),
+ ty::UintTy::U16 => self.type_i16(),
+ ty::UintTy::U32 => self.type_i32(),
+ ty::UintTy::U64 => self.type_i64(),
+ ty::UintTy::U128 => self.type_i128(),
}
}
- crate fn type_float_from_ty(&self, t: ast::FloatTy) -> &'ll Type {
+ crate fn type_float_from_ty(&self, t: ty::FloatTy) -> &'ll Type {
match t {
- ast::FloatTy::F32 => self.type_f32(),
- ast::FloatTy::F64 => self.type_f64(),
+ ty::FloatTy::F32 => self.type_f32(),
+ ty::FloatTy::F64 => self.type_f64(),
}
}
diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs
index 3fc56ee..39d08fb 100644
--- a/compiler/rustc_codegen_llvm/src/va_arg.rs
+++ b/compiler/rustc_codegen_llvm/src/va_arg.rs
@@ -9,7 +9,7 @@
};
use rustc_middle::ty::layout::HasTyCtxt;
use rustc_middle::ty::Ty;
-use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size};
+use rustc_target::abi::{Align, Endian, HasDataLayout, LayoutOf, Size};
fn round_pointer_up_to_alignment(
bx: &mut Builder<'a, 'll, 'tcx>,
@@ -52,7 +52,7 @@
let next = bx.inbounds_gep(addr, &[full_direct_size]);
bx.store(next, va_list_addr, bx.tcx().data_layout.pointer_align.abi);
- if size.bytes() < slot_size.bytes() && &*bx.tcx().sess.target.endian == "big" {
+ if size.bytes() < slot_size.bytes() && bx.tcx().sess.target.endian == Endian::Big {
let adjusted_size = bx.cx().const_i32((slot_size.bytes() - size.bytes()) as i32);
let adjusted = bx.inbounds_gep(addr, &[adjusted_size]);
(bx.bitcast(adjusted, bx.cx().type_ptr_to(llty)), addr_align)
@@ -105,7 +105,6 @@
let mut end = bx.build_sibling_block("va_arg.end");
let zero = bx.const_i32(0);
let offset_align = Align::from_bytes(4).unwrap();
- assert!(&*bx.tcx().sess.target.endian == "little");
let gr_type = target_ty.is_any_ptr() || target_ty.is_integral();
let (reg_off, reg_top_index, slot_size) = if gr_type {
@@ -144,9 +143,14 @@
let top = in_reg.load(top, bx.tcx().data_layout.pointer_align.abi);
// reg_value = *(@top + reg_off_v);
- let top = in_reg.gep(top, &[reg_off_v]);
- let top = in_reg.bitcast(top, bx.cx.type_ptr_to(layout.llvm_type(bx)));
- let reg_value = in_reg.load(top, layout.align.abi);
+ let mut reg_addr = in_reg.gep(top, &[reg_off_v]);
+ if bx.tcx().sess.target.endian == Endian::Big && layout.size.bytes() != slot_size {
+ // On big-endian systems the value is right-aligned in its slot.
+ let offset = bx.const_i32((slot_size - layout.size.bytes()) as i32);
+ reg_addr = in_reg.gep(reg_addr, &[offset]);
+ }
+ let reg_addr = in_reg.bitcast(reg_addr, bx.cx.type_ptr_to(layout.llvm_type(bx)));
+ let reg_value = in_reg.load(reg_addr, layout.align.abi);
in_reg.br(&end.llbb());
// On Stack block