Skip to content

Commit

Permalink
Implement optimize(none)
Browse files Browse the repository at this point in the history
  • Loading branch information
clubby789 committed Aug 5, 2024
1 parent ab1527f commit 976f3e0
Show file tree
Hide file tree
Showing 15 changed files with 78 additions and 16 deletions.
9 changes: 9 additions & 0 deletions compiler/rustc_attr/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,20 @@ pub enum InstructionSetAttr {

#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum OptimizeAttr {
/// `#[optimize(none)]`
None,
/// `#[optimize(speed)]`
Speed,
/// `#[optimize(size)]`
Size,
}

impl OptimizeAttr {
pub fn is_none(&self) -> bool {
matches!(*self, OptimizeAttr::None)
}
}

/// Represents the following attributes:
///
/// - `#[stable]`
Expand Down
9 changes: 6 additions & 3 deletions compiler/rustc_codegen_llvm/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,14 +336,17 @@ pub fn from_fn_attrs<'ll, 'tcx>(
let mut to_add = SmallVec::<[_; 16]>::new();

match codegen_fn_attrs.optimize {
OptimizeAttr::None => {
None => {
to_add.extend(default_optimisation_attrs(cx));
}
OptimizeAttr::Size => {
Some(OptimizeAttr::None) => {
to_add.push(llvm::AttributeKind::OptimizeNone.create_attr(cx.llcx));
}
Some(OptimizeAttr::Size) => {
to_add.push(llvm::AttributeKind::MinSize.create_attr(cx.llcx));
to_add.push(llvm::AttributeKind::OptimizeForSize.create_attr(cx.llcx));
}
OptimizeAttr::Speed => {}
Some(OptimizeAttr::Speed) => {}
}

let inline =
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1024,8 +1024,8 @@ pub fn provide(providers: &mut Providers) {
let any_for_speed = defids.items().any(|id| {
let CodegenFnAttrs { optimize, .. } = tcx.codegen_fn_attrs(*id);
match optimize {
attr::OptimizeAttr::None | attr::OptimizeAttr::Size => false,
attr::OptimizeAttr::Speed => true,
None | Some(attr::OptimizeAttr::None | attr::OptimizeAttr::Size) => false,
Some(attr::OptimizeAttr::Speed) => true,
}
});

Expand Down
12 changes: 7 additions & 5 deletions compiler/rustc_codegen_ssa/src/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
}
});

codegen_fn_attrs.optimize = attrs.iter().fold(OptimizeAttr::None, |ia, attr| {
codegen_fn_attrs.optimize = attrs.iter().fold(None, |ia, attr| {
if !attr.has_name(sym::optimize) {
return ia;
}
Expand All @@ -573,14 +573,16 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
inline_span = Some(attr.span);
if items.len() != 1 {
err(attr.span, "expected one argument");
OptimizeAttr::None
None
} else if list_contains_name(items, sym::size) {
OptimizeAttr::Size
Some(OptimizeAttr::Size)
} else if list_contains_name(items, sym::speed) {
OptimizeAttr::Speed
Some(OptimizeAttr::Speed)
} else if list_contains_name(items, sym::none) {
Some(OptimizeAttr::None)
} else {
err(items[0].span(), "invalid argument");
OptimizeAttr::None
None
}
}
Some(MetaItemKind::NameValue(_)) => ia,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
),
// RFC 2412
gated!(
optimize, Normal, template!(List: "size|speed"), ErrorPreceding,
optimize, Normal, template!(List: "none|size|speed"), ErrorPreceding,
EncodeCrossCrate::No, optimize_attribute, experimental!(optimize)
),

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ pub struct CodegenFnAttrs {
pub flags: CodegenFnAttrFlags,
/// Parsed representation of the `#[inline]` attribute
pub inline: InlineAttr,
/// Parsed representation of the `#[optimize]` attribute
pub optimize: OptimizeAttr,
/// Parsed representation of the `#[optimize]` attribute if present
pub optimize: Option<OptimizeAttr>,
/// The `#[export_name = "..."]` attribute, indicating a custom symbol a
/// function should be exported under
pub export_name: Option<Symbol>,
Expand Down Expand Up @@ -137,7 +137,7 @@ impl CodegenFnAttrs {
CodegenFnAttrs {
flags: CodegenFnAttrFlags::empty(),
inline: InlineAttr::None,
optimize: OptimizeAttr::None,
optimize: None,
export_name: None,
link_name: None,
link_ordinal: None,
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,9 @@ pub struct Body<'tcx> {
/// If `-Cinstrument-coverage` is not active, or if an individual function
/// is not eligible for coverage, then this should always be `None`.
pub function_coverage_info: Option<Box<coverage::FunctionCoverageInfo>>,

/// Whether optimization is disabled by `#[optimize(none)]`
pub optimization_disabled: bool,
}

impl<'tcx> Body<'tcx> {
Expand All @@ -457,6 +460,7 @@ impl<'tcx> Body<'tcx> {
span: Span,
coroutine: Option<Box<CoroutineInfo<'tcx>>>,
tainted_by_errors: Option<ErrorGuaranteed>,
optimization_disabled: bool,
) -> Self {
// We need `arg_count` locals, and one for the return place.
assert!(
Expand Down Expand Up @@ -486,6 +490,7 @@ impl<'tcx> Body<'tcx> {
tainted_by_errors,
coverage_info_hi: None,
function_coverage_info: None,
optimization_disabled,
};
body.is_polymorphic = body.has_non_region_param();
body
Expand Down Expand Up @@ -517,6 +522,7 @@ impl<'tcx> Body<'tcx> {
tainted_by_errors: None,
coverage_info_hi: None,
function_coverage_info: None,
optimization_disabled: false,
};
body.is_polymorphic = body.has_non_region_param();
body
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir_build/src/build/custom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ pub(super) fn build_custom_mir<'tcx>(
pass_count: 0,
coverage_info_hi: None,
function_coverage_info: None,
optimization_disabled: false,
};

body.local_decls.push(LocalDecl::new(return_ty, return_ty_span));
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_mir_build/src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,7 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) -
span,
coroutine,
Some(guar),
false,
)
}

Expand Down Expand Up @@ -794,6 +795,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}

let def_id = self.def_id.to_def_id();
let optimization_disabled = if self.tcx.def_kind(def_id).has_codegen_attrs() {
self.tcx.codegen_fn_attrs(def_id).optimize.as_ref().is_some_and(|o| o.is_none())
} else {
false
};

let mut body = Body::new(
MirSource::item(self.def_id.to_def_id()),
self.cfg.basic_blocks,
Expand All @@ -805,6 +813,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.fn_span,
self.coroutine,
None,
optimization_disabled,
);
body.coverage_info_hi = self.coverage_info.map(|b| b.into_done());
body
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_mir_transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,10 @@ fn run_runtime_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
}

fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if body.optimization_disabled {
return;
}

fn o1<T>(x: T) -> WithMinOptLevel<T> {
WithMinOptLevel(1, x)
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir_transform/src/promote_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,7 @@ fn promote_candidates<'tcx>(
body.span,
None,
body.tainted_by_errors,
body.optimization_disabled,
);
promoted.phase = MirPhase::Analysis(AnalysisPhase::Initial);

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir_transform/src/shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ fn new_body<'tcx>(
None,
// FIXME(compiler-errors): is this correct?
None,
false,
);
// Shims do not directly mention any consts.
body.set_required_consts(Vec::new());
Expand Down
13 changes: 13 additions & 0 deletions tests/codegen/optimize-attr-1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@ pub fn nothing() -> i32 {
2 + 2
}

// CHECK-LABEL: define{{.*}}i32 @none
// CHECK-SAME: [[NONE_ATTRS:#[0-9]+]]
// SIZE-OPT: alloca
// SPEED-OPT: alloca
#[no_mangle]
#[optimize(none)]
pub fn none() -> i32 {
let arr = [0, 1, 2, 3, 4];
arr[4]
}

// CHECK-LABEL: define{{.*}}i32 @size
// CHECK-SAME: [[SIZE_ATTRS:#[0-9]+]]
// SIZE-OPT: ret i32 6
Expand All @@ -39,8 +50,10 @@ pub fn speed() -> i32 {

// NO-OPT-DAG: attributes [[SIZE_ATTRS]] = {{.*}}minsize{{.*}}optsize{{.*}}
// SPEED-OPT-DAG: attributes [[SIZE_ATTRS]] = {{.*}}minsize{{.*}}optsize{{.*}}
// SPEED-OPT-DAG: attributes [[NONE_ATTRS]] = {{.*}}optnone{{.*}}
// SIZE-OPT-DAG: attributes [[NOTHING_ATTRS]] = {{.*}}optsize{{.*}}
// SIZE-OPT-DAG: attributes [[SIZE_ATTRS]] = {{.*}}minsize{{.*}}optsize{{.*}}
// SIZE-OPT-DAG: attributes [[NONE_ATTRS]] = {{.*}}optnone{{.*}}

// SIZE-OPT: attributes [[SPEED_ATTRS]]
// SIZE-OPT-NOT: minsize
Expand Down
3 changes: 3 additions & 0 deletions tests/ui/feature-gates/feature-gate-optimize_attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ fn size() {}
#[optimize(speed)] //~ ERROR the `#[optimize]` attribute is an experimental feature
fn speed() {}

#[optimize(none)] //~ ERROR the `#[optimize]` attribute is an experimental feature
fn none() {}

#[optimize(banana)]
//~^ ERROR the `#[optimize]` attribute is an experimental feature
//~| ERROR E0722
Expand Down
14 changes: 12 additions & 2 deletions tests/ui/feature-gates/feature-gate-optimize_attribute.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ LL | #[optimize(speed)]
error[E0658]: the `#[optimize]` attribute is an experimental feature
--> $DIR/feature-gate-optimize_attribute.rs:13:1
|
LL | #[optimize(none)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #54882 <https://github.com/rust-lang/rust/issues/54882> for more information
= help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: the `#[optimize]` attribute is an experimental feature
--> $DIR/feature-gate-optimize_attribute.rs:16:1
|
LL | #[optimize(banana)]
| ^^^^^^^^^^^^^^^^^^^
|
Expand All @@ -49,12 +59,12 @@ LL | #[optimize(banana)]
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0722]: invalid argument
--> $DIR/feature-gate-optimize_attribute.rs:13:12
--> $DIR/feature-gate-optimize_attribute.rs:16:12
|
LL | #[optimize(banana)]
| ^^^^^^

error: aborting due to 6 previous errors
error: aborting due to 7 previous errors

Some errors have detailed explanations: E0658, E0722.
For more information about an error, try `rustc --explain E0658`.

0 comments on commit 976f3e0

Please sign in to comment.