Skip to content

Commit

Permalink
Auto merge of rust-lang#134944 - Zalathar:rollup-e43guzp, r=Zalathar
Browse files Browse the repository at this point in the history
Rollup of 7 pull requests

Successful merges:

 - rust-lang#133461 (Add COPYRIGHT-*.html files to distribution and update `COPYRIGHT`)
 - rust-lang#134919 (bootstrap: Make `./x test compiler` actually run the compiler unit tests)
 - rust-lang#134927 (Make slice::as_flattened_mut unstably const)
 - rust-lang#134930 (ptr docs: make it clear that we are talking only about memory accesses)
 - rust-lang#134932 (explicitly set float ABI for all ARM targets)
 - rust-lang#134934 (Fix typos)
 - rust-lang#134941 (compiler: Add a statement-of-intent to `rustc_abi`)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Dec 31, 2024
2 parents 4e5fec2 + b494acf commit e3e6bb7
Show file tree
Hide file tree
Showing 78 changed files with 401 additions and 509 deletions.
392 changes: 21 additions & 371 deletions COPYRIGHT

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions LICENSE-MIT
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Copyright (c) The Rust Project Contributors

Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Expand Down
32 changes: 32 additions & 0 deletions compiler/rustc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,38 @@
#![warn(unreachable_pub)]
// tidy-alphabetical-end

/*! ABI handling for rustc
## What is an "ABI"?
Literally, "application binary interface", which means it is everything about how code interacts,
at the machine level, with other code. This means it technically covers all of the following:
- object binary format for e.g. relocations or offset tables
- in-memory layout of types
- procedure calling conventions
When we discuss "ABI" in the context of rustc, we are probably discussing calling conventions.
To describe those `rustc_abi` also covers type layout, as it must for values passed on the stack.
Despite `rustc_abi` being about calling conventions, it is good to remember these usages exist.
You will encounter all of them and more if you study target-specific codegen enough!
Even in general conversation, when someone says "the Rust ABI is unstable", it may allude to
either or both of
- `repr(Rust)` types have a mostly-unspecified layout
- `extern "Rust" fn(A) -> R` has an unspecified calling convention
## Crate Goal
ABI is a foundational concept, so the `rustc_abi` crate serves as an equally foundational crate.
It cannot carry all details relevant to an ABI: those permeate code generation and linkage.
Instead, `rustc_abi` is intended to provide the interface for reasoning about the binary interface.
It should contain traits and types that other crates then use in their implementation.
For example, a platform's `extern "C" fn` calling convention will be implemented in `rustc_target`
but `rustc_abi` contains the types for calculating layout and describing register-passing.
This makes it easier to describe things in the same way across targets, codegen backends, and
even other Rust compilers, such as rust-analyzer!
*/

use std::fmt;
#[cfg(feature = "nightly")]
use std::iter::Step;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl OwnedTargetMachine {
model: llvm::CodeModel,
reloc: llvm::RelocModel,
level: llvm::CodeGenOptLevel,
use_soft_fp: bool,
float_abi: llvm::FloatAbi,
function_sections: bool,
data_sections: bool,
unique_section_names: bool,
Expand Down Expand Up @@ -57,7 +57,7 @@ impl OwnedTargetMachine {
model,
reloc,
level,
use_soft_fp,
float_abi,
function_sections,
data_sections,
unique_section_names,
Expand Down
18 changes: 13 additions & 5 deletions compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use rustc_session::config::{
self, Lto, OutputType, Passes, RemapPathScopeComponents, SplitDwarfKind, SwitchWithOptPath,
};
use rustc_span::{BytePos, InnerSpan, Pos, SpanData, SyntaxContext, sym};
use rustc_target::spec::{CodeModel, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel};
use rustc_target::spec::{CodeModel, FloatAbi, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel};
use tracing::debug;

use crate::back::lto::ThinBuffer;
Expand Down Expand Up @@ -181,6 +181,14 @@ pub(crate) fn to_llvm_code_model(code_model: Option<CodeModel>) -> llvm::CodeMod
}
}

fn to_llvm_float_abi(float_abi: Option<FloatAbi>) -> llvm::FloatAbi {
match float_abi {
None => llvm::FloatAbi::Default,
Some(FloatAbi::Soft) => llvm::FloatAbi::Soft,
Some(FloatAbi::Hard) => llvm::FloatAbi::Hard,
}
}

pub(crate) fn target_machine_factory(
sess: &Session,
optlvl: config::OptLevel,
Expand All @@ -189,12 +197,12 @@ pub(crate) fn target_machine_factory(
let reloc_model = to_llvm_relocation_model(sess.relocation_model());

let (opt_level, _) = to_llvm_opt_settings(optlvl);
let use_softfp = if sess.target.arch == "arm" {
sess.opts.cg.soft_float
let float_abi = if sess.target.arch == "arm" && sess.opts.cg.soft_float {
llvm::FloatAbi::Soft
} else {
// `validate_commandline_args_with_session_available` has already warned about this being
// ignored. Let's make sure LLVM doesn't suddenly start using this flag on more targets.
false
to_llvm_float_abi(sess.target.llvm_floatabi)
};

let ffunction_sections =
Expand Down Expand Up @@ -290,7 +298,7 @@ pub(crate) fn target_machine_factory(
code_model,
reloc_model,
opt_level,
use_softfp,
float_abi,
ffunction_sections,
fdata_sections,
funique_section_names,
Expand Down
13 changes: 11 additions & 2 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ pub struct SanitizerOptions {
pub sanitize_kernel_address_recover: bool,
}

/// LLVMRelocMode
/// LLVMRustRelocModel
#[derive(Copy, Clone, PartialEq)]
#[repr(C)]
pub enum RelocModel {
Expand All @@ -538,6 +538,15 @@ pub enum RelocModel {
ROPI_RWPI,
}

/// LLVMRustFloatABI
#[derive(Copy, Clone, PartialEq)]
#[repr(C)]
pub enum FloatAbi {
Default,
Soft,
Hard,
}

/// LLVMRustCodeModel
#[derive(Copy, Clone)]
#[repr(C)]
Expand Down Expand Up @@ -2192,7 +2201,7 @@ unsafe extern "C" {
Model: CodeModel,
Reloc: RelocModel,
Level: CodeGenOptLevel,
UseSoftFP: bool,
FloatABIType: FloatAbi,
FunctionSections: bool,
DataSections: bool,
UniqueSectionNames: bool,
Expand Down
26 changes: 21 additions & 5 deletions compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,24 @@ static Reloc::Model fromRust(LLVMRustRelocModel RustReloc) {
report_fatal_error("Bad RelocModel.");
}

enum class LLVMRustFloatABI {
Default,
Soft,
Hard,
};

static FloatABI::ABIType fromRust(LLVMRustFloatABI RustFloatAbi) {
switch (RustFloatAbi) {
case LLVMRustFloatABI::Default:
return FloatABI::Default;
case LLVMRustFloatABI::Soft:
return FloatABI::Soft;
case LLVMRustFloatABI::Hard:
return FloatABI::Hard;
}
report_fatal_error("Bad FloatABI.");
}

/// getLongestEntryLength - Return the length of the longest entry in the table.
template <typename KV> static size_t getLongestEntryLength(ArrayRef<KV> Table) {
size_t MaxLen = 0;
Expand Down Expand Up @@ -358,7 +376,7 @@ extern "C" const char *LLVMRustGetHostCPUName(size_t *OutLen) {
extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
const char *TripleStr, const char *CPU, const char *Feature,
const char *ABIStr, LLVMRustCodeModel RustCM, LLVMRustRelocModel RustReloc,
LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
LLVMRustCodeGenOptLevel RustOptLevel, LLVMRustFloatABI RustFloatABIType,
bool FunctionSections, bool DataSections, bool UniqueSectionNames,
bool TrapUnreachable, bool Singlethread, bool VerboseAsm,
bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray,
Expand All @@ -369,6 +387,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
auto OptLevel = fromRust(RustOptLevel);
auto RM = fromRust(RustReloc);
auto CM = fromRust(RustCM);
auto FloatABIType = fromRust(RustFloatABIType);

std::string Error;
auto Trip = Triple(Triple::normalize(TripleStr));
Expand All @@ -381,10 +400,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(

TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(Trip);

Options.FloatABIType = FloatABI::Default;
if (UseSoftFloat) {
Options.FloatABIType = FloatABI::Soft;
}
Options.FloatABIType = FloatABIType;
Options.DataSections = DataSections;
Options.FunctionSections = FunctionSections;
Options.UniqueSectionNames = UniqueSectionNames;
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_middle/src/mir/interpret/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ use crate::ty::{self, GenericArgs, TyCtxt};
impl<'tcx> TyCtxt<'tcx> {
/// Evaluates a constant without providing any generic parameters. This is useful to evaluate consts
/// that can't take any generic arguments like const items or enum discriminants. If a
/// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned.
/// generic parameter is used within the constant `ErrorHandled::TooGeneric` will be returned.
#[instrument(skip(self), level = "debug")]
pub fn const_eval_poly(self, def_id: DefId) -> EvalToConstValueResult<'tcx> {
// In some situations def_id will have generic parameters within scope, but they aren't allowed
// to be used. So we can't use `Instance::mono`, instead we feed unresolved generic parameters
// into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are
// into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are
// encountered.
let args = GenericArgs::identity_for_item(self, def_id);
let instance = ty::Instance::new(def_id, args);
Expand All @@ -32,12 +32,12 @@ impl<'tcx> TyCtxt<'tcx> {

/// Evaluates a constant without providing any generic parameters. This is useful to evaluate consts
/// that can't take any generic arguments like const items or enum discriminants. If a
/// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned.
/// generic parameter is used within the constant `ErrorHandled::TooGeneric` will be returned.
#[instrument(skip(self), level = "debug")]
pub fn const_eval_poly_to_alloc(self, def_id: DefId) -> EvalToAllocationRawResult<'tcx> {
// In some situations def_id will have generic parameters within scope, but they aren't allowed
// to be used. So we can't use `Instance::mono`, instead we feed unresolved generic parameters
// into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are
// into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are
// encountered.
let args = GenericArgs::identity_for_item(self, def_id);
let instance = ty::Instance::new(def_id, args);
Expand Down Expand Up @@ -201,12 +201,12 @@ impl<'tcx> TyCtxt<'tcx> {
impl<'tcx> TyCtxtEnsure<'tcx> {
/// Evaluates a constant without providing any generic parameters. This is useful to evaluate consts
/// that can't take any generic arguments like const items or enum discriminants. If a
/// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned.
/// generic parameter is used within the constant `ErrorHandled::TooGeneric` will be returned.
#[instrument(skip(self), level = "debug")]
pub fn const_eval_poly(self, def_id: DefId) {
// In some situations def_id will have generic parameters within scope, but they aren't allowed
// to be used. So we can't use `Instance::mono`, instead we feed unresolved generic parameters
// into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are
// into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are
// encountered.
let args = GenericArgs::identity_for_item(self.tcx, def_id);
let instance = ty::Instance::new(def_id, self.tcx.erase_regions(args));
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_target/src/spec/base/apple/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use std::borrow::Cow;
use std::env;

use crate::spec::{
Cc, DebuginfoKind, FramePointer, LinkerFlavor, Lld, SplitDebuginfo, StackProbeType, StaticCow,
TargetOptions, cvs,
Cc, DebuginfoKind, FloatAbi, FramePointer, LinkerFlavor, Lld, SplitDebuginfo, StackProbeType,
StaticCow, TargetOptions, cvs,
};

#[cfg(test)]
Expand Down Expand Up @@ -105,6 +105,7 @@ pub(crate) fn base(
) -> (TargetOptions, StaticCow<str>, StaticCow<str>) {
let opts = TargetOptions {
abi: abi.target_abi().into(),
llvm_floatabi: Some(FloatAbi::Hard),
os: os.into(),
cpu: arch.target_cpu(abi).into(),
link_env_remove: link_env_remove(os),
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_target/src/spec/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,18 @@ impl Target {
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, FloatAbi) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
match s.parse::<super::FloatAbi>() {
Ok(float_abi) => base.$key_name = Some(float_abi),
_ => return Some(Err(format!("'{}' is not a valid value for \
llvm-floatabi. Use 'soft' or 'hard'.",
s))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, RelocModel) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
Expand Down Expand Up @@ -598,6 +610,7 @@ impl Target {
key!(mcount = "target-mcount");
key!(llvm_mcount_intrinsic, optional);
key!(llvm_abiname);
key!(llvm_floatabi, FloatAbi)?;
key!(relax_elf_relocations, bool);
key!(llvm_args, list);
key!(use_ctors_section, bool);
Expand Down Expand Up @@ -772,6 +785,7 @@ impl ToJson for Target {
target_option_val!(mcount, "target-mcount");
target_option_val!(llvm_mcount_intrinsic);
target_option_val!(llvm_abiname);
target_option_val!(llvm_floatabi);
target_option_val!(relax_elf_relocations);
target_option_val!(llvm_args);
target_option_val!(use_ctors_section);
Expand Down
47 changes: 46 additions & 1 deletion compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,35 @@ impl ToJson for CodeModel {
}
}

/// The float ABI setting to be configured in the LLVM target machine.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum FloatAbi {
Soft,
Hard,
}

impl FromStr for FloatAbi {
type Err = ();

fn from_str(s: &str) -> Result<FloatAbi, ()> {
Ok(match s {
"soft" => FloatAbi::Soft,
"hard" => FloatAbi::Hard,
_ => return Err(()),
})
}
}

impl ToJson for FloatAbi {
fn to_json(&self) -> Json {
match *self {
FloatAbi::Soft => "soft",
FloatAbi::Hard => "hard",
}
.to_json()
}
}

#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum TlsModel {
GeneralDynamic,
Expand Down Expand Up @@ -2150,6 +2179,8 @@ pub struct TargetOptions {
pub env: StaticCow<str>,
/// ABI name to distinguish multiple ABIs on the same OS and architecture. For instance, `"eabi"`
/// or `"eabihf"`. Defaults to "".
/// This field is *not* forwarded directly to LLVM; its primary purpose is `cfg(target_abi)`.
/// However, parts of the backend do check this field for specific values to enable special behavior.
pub abi: StaticCow<str>,
/// Vendor name to use for conditional compilation (`target_vendor`). Defaults to "unknown".
pub vendor: StaticCow<str>,
Expand Down Expand Up @@ -2446,8 +2477,17 @@ pub struct TargetOptions {
pub llvm_mcount_intrinsic: Option<StaticCow<str>>,

/// LLVM ABI name, corresponds to the '-mabi' parameter available in multilib C compilers
/// and the `-target-abi` flag in llc. In the LLVM API this is `MCOptions.ABIName`.
pub llvm_abiname: StaticCow<str>,

/// Control the float ABI to use, for architectures that support it. The only architecture we
/// currently use this for is ARM. Corresponds to the `-float-abi` flag in llc. In the LLVM API
/// this is `FloatABIType`. (clang's `-mfloat-abi` is similar but more complicated since it
/// can also affect the `soft-float` target feature.)
///
/// If not provided, LLVM will infer the float ABI from the target triple (`llvm_target`).
pub llvm_floatabi: Option<FloatAbi>,

/// Whether or not RelaxElfRelocation flag will be passed to the linker
pub relax_elf_relocations: bool,

Expand Down Expand Up @@ -2719,6 +2759,7 @@ impl Default for TargetOptions {
mcount: "mcount".into(),
llvm_mcount_intrinsic: None,
llvm_abiname: "".into(),
llvm_floatabi: None,
relax_elf_relocations: false,
llvm_args: cvs![],
use_ctors_section: false,
Expand Down Expand Up @@ -3153,7 +3194,8 @@ impl Target {
);
}

// Check that RISC-V targets always specify which ABI they use.
// Check that RISC-V targets always specify which ABI they use,
// and that ARM targets specify their float ABI.
match &*self.arch {
"riscv32" => {
check_matches!(
Expand All @@ -3170,6 +3212,9 @@ impl Target {
"invalid RISC-V ABI name"
);
}
"arm" => {
check!(self.llvm_floatabi.is_some(), "ARM targets must specify their float ABI",)
}
_ => {}
}

Expand Down
Loading

0 comments on commit e3e6bb7

Please sign in to comment.