Skip to content

Commit

Permalink
Remove CodegenBackend::target_override.
Browse files Browse the repository at this point in the history
Backend and target selection is a mess: the target can override the
backend (via `Target::default_codegen_backend`), *and* the backend can
override the target (via `CodegenBackend::target_override`).

The code that handles this is ugly. It calls `build_target_config`
twice, once before getting the backend and once again afterward. It also
must check that both overrides aren't triggering at the same time.

This commit removes the latter override. It's used in rust-gpu but
@eddyb said via Zulip that removing it would be ok. This simplifies the
code greatly, and will allow some nice follow-up refactorings.
  • Loading branch information
nnethercote committed Mar 21, 2024
1 parent e3df96c commit 23ee523
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 80 deletions.
7 changes: 0 additions & 7 deletions compiler/rustc_codegen_ssa/src/traits/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ use rustc_session::{
};
use rustc_span::symbol::Symbol;
use rustc_target::abi::call::FnAbi;
use rustc_target::spec::Target;

use std::fmt;

Expand Down Expand Up @@ -70,12 +69,6 @@ pub trait CodegenBackend {
fn print_passes(&self) {}
fn print_version(&self) {}

/// If this plugin provides additional builtin targets, provide the one enabled by the options here.
/// Be careful: this is called *before* init() is called.
fn target_override(&self, _opts: &config::Options) -> Option<Target> {
None
}

/// The metadata loader used to load rlib and dylib metadata.
///
/// Alternative codegen backends may want to use different rlib or dylib formats than the
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -890,7 +890,7 @@ pub fn version_at_macro_invocation(
let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend="));
let opts = config::Options::default();
let sysroot = filesearch::materialize_sysroot(opts.maybe_sysroot.clone());
let target = config::build_target_config(early_dcx, &opts, None, &sysroot);
let target = config::build_target_config(early_dcx, &opts, &sysroot);

get_codegen_backend(early_dcx, &sysroot, backend_name, &target).print_version();
}
Expand Down Expand Up @@ -1100,7 +1100,7 @@ pub fn describe_flag_categories(early_dcx: &EarlyDiagCtxt, matches: &Matches) ->

let opts = config::Options::default();
let sysroot = filesearch::materialize_sysroot(opts.maybe_sysroot.clone());
let target = config::build_target_config(early_dcx, &opts, None, &sysroot);
let target = config::build_target_config(early_dcx, &opts, &sysroot);

get_codegen_backend(early_dcx, &sysroot, backend_name, &target).print_passes();
return true;
Expand Down
55 changes: 13 additions & 42 deletions compiler/rustc_interface/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,51 +341,22 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se

let sysroot = filesearch::materialize_sysroot(config.opts.maybe_sysroot.clone());

let (codegen_backend, target_override) = match config.make_codegen_backend {
None => {
// Build a target without override, so that it can override the backend if needed
let target =
config::build_target_config(&early_dcx, &config.opts, None, &sysroot);

let backend = util::get_codegen_backend(
&early_dcx,
&sysroot,
config.opts.unstable_opts.codegen_backend.as_deref(),
&target,
);

// target_override is documented to be called before init(), so this is okay
let target_override = backend.target_override(&config.opts);

// Assert that we don't use target's override of the backend and
// backend's override of the target at the same time
if config.opts.unstable_opts.codegen_backend.is_none()
&& target.default_codegen_backend.is_some()
&& target_override.is_some()
{
rustc_middle::bug!(
"Codegen backend requested target override even though the target requested the backend"
);
}

(backend, target_override)
}
let target = config::build_target_config(&early_dcx, &config.opts, &sysroot);

let codegen_backend = match config.make_codegen_backend {
None => util::get_codegen_backend(
&early_dcx,
&sysroot,
config.opts.unstable_opts.codegen_backend.as_deref(),
&target,
),
Some(make_codegen_backend) => {
// N.B. `make_codegen_backend` takes precedence over `target.default_codegen_backend`,
// which is ignored in this case.
let backend = make_codegen_backend(&config.opts);

// target_override is documented to be called before init(), so this is okay
let target_override = backend.target_override(&config.opts);

(backend, target_override)
// N.B. `make_codegen_backend` takes precedence over
// `target.default_codegen_backend`, which is ignored in this case.
make_codegen_backend(&config.opts)
}
};

// Re-build target with the (potential) override
let target_cfg =
config::build_target_config(&early_dcx, &config.opts, target_override, &sysroot);

let temps_dir = config.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);

let bundle = match rustc_errors::fluent_bundle(
Expand Down Expand Up @@ -418,7 +389,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
locale_resources,
config.lint_caps,
config.file_loader,
target_cfg,
target,
sysroot,
util::rustc_version_str().unwrap_or("unknown"),
config.ice_file,
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ fn mk_session(matches: getopts::Matches) -> (Session, Cfg) {

let sysroot = filesearch::materialize_sysroot(sessopts.maybe_sysroot.clone());

let target_cfg =
rustc_session::config::build_target_config(&early_dcx, &sessopts, None, &sysroot);
let target_cfg = rustc_session::config::build_target_config(&early_dcx, &sessopts, &sysroot);

let sess = build_session(
early_dcx,
Expand Down
45 changes: 18 additions & 27 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, SourceFileHa
use rustc_target::abi::Align;
use rustc_target::spec::LinkSelfContainedComponents;
use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, SplitDebuginfo};
use rustc_target::spec::{Target, TargetTriple, TargetWarnings, TARGETS};
use rustc_target::spec::{Target, TargetTriple, TARGETS};
use std::collections::btree_map::{
Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter,
};
Expand Down Expand Up @@ -1549,34 +1549,25 @@ pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg {
user_cfg
}

pub fn build_target_config(
early_dcx: &EarlyDiagCtxt,
opts: &Options,
target_override: Option<Target>,
sysroot: &Path,
) -> Target {
let target_result = target_override.map_or_else(
|| Target::search(&opts.target_triple, sysroot),
|t| Ok((t, TargetWarnings::empty())),
);
let (target, target_warnings) = target_result.unwrap_or_else(|e| {
early_dcx.early_fatal(format!(
pub fn build_target_config(early_dcx: &EarlyDiagCtxt, opts: &Options, sysroot: &Path) -> Target {
match Target::search(&opts.target_triple, sysroot) {
Ok((target, warnings)) => {
for warning in warnings.warning_messages() {
early_dcx.early_warn(warning)
}
if !matches!(target.pointer_width, 16 | 32 | 64) {
early_dcx.early_fatal(format!(
"target specification was invalid: unrecognized target-pointer-width {}",
target.pointer_width
))
}
target
}
Err(e) => early_dcx.early_fatal(format!(
"Error loading target specification: {e}. \
Run `rustc --print target-list` for a list of built-in targets"
))
});
for warning in target_warnings.warning_messages() {
early_dcx.early_warn(warning)
}

if !matches!(target.pointer_width, 16 | 32 | 64) {
early_dcx.early_fatal(format!(
"target specification was invalid: unrecognized target-pointer-width {}",
target.pointer_width
))
Run `rustc --print target-list` for a list of built-in targets"
)),
}

target
}

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2091,6 +2091,9 @@ pub struct TargetOptions {
/// compiling `rustc` will be used instead (or llvm if it is not set).
///
/// N.B. when *using* the compiler, backend can always be overridden with `-Zcodegen-backend`.
///
/// This was added by WaffleLapkin in #116793. The motivation is a rustc fork that requires a
/// custom codegen backend for a particular target.
pub default_codegen_backend: Option<StaticCow<str>>,

/// Whether to generate trap instructions in places where optimization would
Expand Down

0 comments on commit 23ee523

Please sign in to comment.