Skip to content

Commit

Permalink
Auto merge of #92816 - tmiasko:rm-llvm-asm, r=Amanieu
Browse files Browse the repository at this point in the history
Remove deprecated LLVM-style inline assembly

The `llvm_asm!` was deprecated back in #87590 1.56.0, with intention to remove
it once `asm!` was stabilized, which already happened in #91728 1.59.0. Now it
is time to remove `llvm_asm!` to avoid continued maintenance cost.

Closes #70173.
Closes #92794.
Closes #87612.
Closes #82065.

cc `@rust-lang/wg-inline-asm`

r? `@Amanieu`
  • Loading branch information
bors committed Jan 17, 2022
2 parents 128417f + b085eb0 commit a34c079
Show file tree
Hide file tree
Showing 171 changed files with 235 additions and 3,297 deletions.
39 changes: 1 addition & 38 deletions compiler/rustc_ast/src/ast.rs
Expand Up @@ -1266,7 +1266,7 @@ impl Expr {
ExprKind::Break(..) => ExprPrecedence::Break,
ExprKind::Continue(..) => ExprPrecedence::Continue,
ExprKind::Ret(..) => ExprPrecedence::Ret,
ExprKind::InlineAsm(..) | ExprKind::LlvmInlineAsm(..) => ExprPrecedence::InlineAsm,
ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm,
ExprKind::MacCall(..) => ExprPrecedence::Mac,
ExprKind::Struct(..) => ExprPrecedence::Struct,
ExprKind::Repeat(..) => ExprPrecedence::Repeat,
Expand Down Expand Up @@ -1423,8 +1423,6 @@ pub enum ExprKind {

/// Output of the `asm!()` macro.
InlineAsm(P<InlineAsm>),
/// Output of the `llvm_asm!()` macro.
LlvmInlineAsm(P<LlvmInlineAsm>),

/// A macro invocation; pre-expansion.
MacCall(MacCall),
Expand Down Expand Up @@ -2076,41 +2074,6 @@ pub struct InlineAsm {
pub line_spans: Vec<Span>,
}

/// Inline assembly dialect.
///
/// E.g., `"intel"` as in `llvm_asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`.
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Hash, HashStable_Generic)]
pub enum LlvmAsmDialect {
Att,
Intel,
}

/// LLVM-style inline assembly.
///
/// E.g., `"={eax}"(result)` as in `llvm_asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct LlvmInlineAsmOutput {
pub constraint: Symbol,
pub expr: P<Expr>,
pub is_rw: bool,
pub is_indirect: bool,
}

/// LLVM-style inline assembly.
///
/// E.g., `llvm_asm!("NOP");`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct LlvmInlineAsm {
pub asm: Symbol,
pub asm_str_style: StrStyle,
pub outputs: Vec<LlvmInlineAsmOutput>,
pub inputs: Vec<(Symbol, P<Expr>)>,
pub clobbers: Vec<Symbol>,
pub volatile: bool,
pub alignstack: bool,
pub dialect: LlvmAsmDialect,
}

/// A parameter in a function header.
///
/// E.g., `bar: usize` as in `fn foo(bar: usize)`.
Expand Down
17 changes: 0 additions & 17 deletions compiler/rustc_ast/src/mut_visit.rs
Expand Up @@ -1350,23 +1350,6 @@ pub fn noop_visit_expr<T: MutVisitor>(
visit_opt(expr, |expr| vis.visit_expr(expr));
}
ExprKind::InlineAsm(asm) => noop_visit_inline_asm(asm, vis),
ExprKind::LlvmInlineAsm(asm) => {
let LlvmInlineAsm {
asm: _,
asm_str_style: _,
outputs,
inputs,
clobbers: _,
volatile: _,
alignstack: _,
dialect: _,
} = asm.deref_mut();
for out in outputs {
let LlvmInlineAsmOutput { constraint: _, expr, is_rw: _, is_indirect: _ } = out;
vis.visit_expr(expr);
}
visit_vec(inputs, |(_c, expr)| vis.visit_expr(expr));
}
ExprKind::MacCall(mac) => vis.visit_mac_call(mac),
ExprKind::Struct(se) => {
let StructExpr { qself, path, fields, rest } = se.deref_mut();
Expand Down
8 changes: 0 additions & 8 deletions compiler/rustc_ast/src/visit.rs
Expand Up @@ -864,14 +864,6 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
ExprKind::MacCall(ref mac) => visitor.visit_mac_call(mac),
ExprKind::Paren(ref subexpression) => visitor.visit_expr(subexpression),
ExprKind::InlineAsm(ref asm) => walk_inline_asm(visitor, asm),
ExprKind::LlvmInlineAsm(ref ia) => {
for &(_, ref input) in &ia.inputs {
visitor.visit_expr(input)
}
for output in &ia.outputs {
visitor.visit_expr(&output.expr)
}
}
ExprKind::Yield(ref optional_expression) => {
walk_list!(visitor, visit_expr, optional_expression);
}
Expand Down
33 changes: 0 additions & 33 deletions compiler/rustc_ast_lowering/src/expr.rs
Expand Up @@ -226,7 +226,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
ExprKind::InlineAsm(ref asm) => {
hir::ExprKind::InlineAsm(self.lower_inline_asm(e.span, asm))
}
ExprKind::LlvmInlineAsm(ref asm) => self.lower_expr_llvm_asm(asm),
ExprKind::Struct(ref se) => {
let rest = match &se.rest {
StructRest::Base(e) => Some(self.lower_expr(e)),
Expand Down Expand Up @@ -1286,38 +1285,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
result
}

fn lower_expr_llvm_asm(&mut self, asm: &LlvmInlineAsm) -> hir::ExprKind<'hir> {
let inner = hir::LlvmInlineAsmInner {
inputs: asm.inputs.iter().map(|&(c, _)| c).collect(),
outputs: asm
.outputs
.iter()
.map(|out| hir::LlvmInlineAsmOutput {
constraint: out.constraint,
is_rw: out.is_rw,
is_indirect: out.is_indirect,
span: self.lower_span(out.expr.span),
})
.collect(),
asm: asm.asm,
asm_str_style: asm.asm_str_style,
clobbers: asm.clobbers.clone(),
volatile: asm.volatile,
alignstack: asm.alignstack,
dialect: asm.dialect,
};
let hir_asm = hir::LlvmInlineAsm {
inner,
inputs_exprs: self.arena.alloc_from_iter(
asm.inputs.iter().map(|&(_, ref input)| self.lower_expr_mut(input)),
),
outputs_exprs: self
.arena
.alloc_from_iter(asm.outputs.iter().map(|out| self.lower_expr_mut(&out.expr))),
};
hir::ExprKind::LlvmInlineAsm(self.arena.alloc(hir_asm))
}

fn lower_expr_field(&mut self, f: &ExprField) -> hir::ExprField<'hir> {
hir::ExprField {
hir_id: self.next_id(),
Expand Down
9 changes: 0 additions & 9 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Expand Up @@ -960,15 +960,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
return;
}
ExprKind::Let(..) if !let_allowed => this.ban_let_expr(expr),
ExprKind::LlvmInlineAsm(..) if !this.session.target.allow_asm => {
struct_span_err!(
this.session,
expr.span,
E0472,
"llvm_asm! is unsupported on this target"
)
.emit();
}
ExprKind::Match(expr, arms) => {
this.visit_expr(expr);
for arm in arms {
Expand Down
56 changes: 0 additions & 56 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Expand Up @@ -2168,62 +2168,6 @@ impl<'a> State<'a> {
self.word("asm!");
self.print_inline_asm(a);
}
ast::ExprKind::LlvmInlineAsm(ref a) => {
self.word("llvm_asm!");
self.popen();
self.print_symbol(a.asm, a.asm_str_style);
self.word_space(":");

self.commasep(Inconsistent, &a.outputs, |s, out| {
let constraint = out.constraint.as_str();
let mut ch = constraint.chars();
match ch.next() {
Some('=') if out.is_rw => {
s.print_string(&format!("+{}", ch.as_str()), ast::StrStyle::Cooked)
}
_ => s.print_string(&constraint, ast::StrStyle::Cooked),
}
s.popen();
s.print_expr(&out.expr);
s.pclose();
});
self.space();
self.word_space(":");

self.commasep(Inconsistent, &a.inputs, |s, &(co, ref o)| {
s.print_symbol(co, ast::StrStyle::Cooked);
s.popen();
s.print_expr(o);
s.pclose();
});
self.space();
self.word_space(":");

self.commasep(Inconsistent, &a.clobbers, |s, &co| {
s.print_symbol(co, ast::StrStyle::Cooked);
});

let mut options = vec![];
if a.volatile {
options.push("volatile");
}
if a.alignstack {
options.push("alignstack");
}
if a.dialect == ast::LlvmAsmDialect::Intel {
options.push("intel");
}

if !options.is_empty() {
self.space();
self.word_space(":");
self.commasep(Inconsistent, &options, |s, &co| {
s.print_string(co, ast::StrStyle::Cooked);
});
}

self.pclose();
}
ast::ExprKind::MacCall(ref m) => self.print_mac(m),
ast::ExprKind::Paren(ref e) => {
self.popen();
Expand Down
9 changes: 0 additions & 9 deletions compiler/rustc_borrowck/src/dataflow.rs
Expand Up @@ -8,7 +8,6 @@ use rustc_mir_dataflow::ResultsVisitable;
use rustc_mir_dataflow::{self, fmt::DebugWithContext, CallReturnPlaces, GenKill};
use rustc_mir_dataflow::{Analysis, Direction, Results};
use std::fmt;
use std::iter;

use crate::{
places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext, ToRegionVid,
Expand Down Expand Up @@ -385,14 +384,6 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
self.kill_borrows_on_place(trans, Place::from(local));
}

mir::StatementKind::LlvmInlineAsm(ref asm) => {
for (output, kind) in iter::zip(&*asm.outputs, &asm.asm.outputs) {
if !kind.is_indirect && !kind.is_rw {
self.kill_borrows_on_place(trans, *output);
}
}
}

mir::StatementKind::FakeRead(..)
| mir::StatementKind::SetDiscriminant { .. }
| mir::StatementKind::StorageLive(..)
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_borrowck/src/def_use.rs
Expand Up @@ -16,9 +16,6 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {

PlaceContext::MutatingUse(MutatingUseContext::Store) |

// This is potentially both a def and a use...
PlaceContext::MutatingUse(MutatingUseContext::LlvmAsmOutput) |

// We let Call define the result in both the success and
// unwind cases. This is not really correct, however it
// does not seem to be observable due to the way that we
Expand Down
51 changes: 10 additions & 41 deletions compiler/rustc_borrowck/src/invalidation.rs
Expand Up @@ -5,12 +5,11 @@ use rustc_middle::mir::{BorrowKind, Mutability, Operand};
use rustc_middle::mir::{InlineAsmOperand, Terminator, TerminatorKind};
use rustc_middle::mir::{Statement, StatementKind};
use rustc_middle::ty::TyCtxt;
use std::iter;

use crate::{
borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, path_utils::*, AccessDepth,
Activation, ArtificialField, BorrowIndex, Deep, JustWrite, LocalMutationIsAllowed, MutateMode,
Read, ReadKind, ReadOrWrite, Reservation, Shallow, Write, WriteAndRead, WriteKind,
Activation, ArtificialField, BorrowIndex, Deep, LocalMutationIsAllowed, Read, ReadKind,
ReadOrWrite, Reservation, Shallow, Write, WriteKind,
};

pub(super) fn generate_invalidates<'tcx>(
Expand Down Expand Up @@ -59,37 +58,13 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
StatementKind::Assign(box (lhs, rhs)) => {
self.consume_rvalue(location, rhs);

self.mutate_place(location, *lhs, Shallow(None), JustWrite);
self.mutate_place(location, *lhs, Shallow(None));
}
StatementKind::FakeRead(box (_, _)) => {
// Only relevant for initialized/liveness/safety checks.
}
StatementKind::SetDiscriminant { place, variant_index: _ } => {
self.mutate_place(location, **place, Shallow(None), JustWrite);
}
StatementKind::LlvmInlineAsm(asm) => {
for (o, output) in iter::zip(&asm.asm.outputs, &*asm.outputs) {
if o.is_indirect {
// FIXME(eddyb) indirect inline asm outputs should
// be encoded through MIR place derefs instead.
self.access_place(
location,
*output,
(Deep, Read(ReadKind::Copy)),
LocalMutationIsAllowed::No,
);
} else {
self.mutate_place(
location,
*output,
if o.is_rw { Deep } else { Shallow(None) },
if o.is_rw { WriteAndRead } else { JustWrite },
);
}
}
for (_, input) in asm.inputs.iter() {
self.consume_operand(location, input);
}
self.mutate_place(location, **place, Shallow(None));
}
StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
ref src,
Expand Down Expand Up @@ -142,7 +117,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
target: _,
unwind: _,
} => {
self.mutate_place(location, *drop_place, Deep, JustWrite);
self.mutate_place(location, *drop_place, Deep);
self.consume_operand(location, new_value);
}
TerminatorKind::Call {
Expand All @@ -158,7 +133,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
self.consume_operand(location, arg);
}
if let Some((dest, _ /*bb*/)) = destination {
self.mutate_place(location, *dest, Deep, JustWrite);
self.mutate_place(location, *dest, Deep);
}
}
TerminatorKind::Assert { ref cond, expected: _, ref msg, target: _, cleanup: _ } => {
Expand All @@ -181,7 +156,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
}
}

self.mutate_place(location, *resume_arg, Deep, JustWrite);
self.mutate_place(location, *resume_arg, Deep);
}
TerminatorKind::Resume | TerminatorKind::Return | TerminatorKind::GeneratorDrop => {
// Invalidate all borrows of local places
Expand All @@ -208,13 +183,13 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
}
InlineAsmOperand::Out { reg: _, late: _, place, .. } => {
if let Some(place) = place {
self.mutate_place(location, place, Shallow(None), JustWrite);
self.mutate_place(location, place, Shallow(None));
}
}
InlineAsmOperand::InOut { reg: _, late: _, ref in_value, out_place } => {
self.consume_operand(location, in_value);
if let Some(out_place) = out_place {
self.mutate_place(location, out_place, Shallow(None), JustWrite);
self.mutate_place(location, out_place, Shallow(None));
}
}
InlineAsmOperand::Const { value: _ }
Expand All @@ -238,13 +213,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {

impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
/// Simulates mutation of a place.
fn mutate_place(
&mut self,
location: Location,
place: Place<'tcx>,
kind: AccessDepth,
_mode: MutateMode,
) {
fn mutate_place(&mut self, location: Location, place: Place<'tcx>, kind: AccessDepth) {
self.access_place(
location,
place,
Expand Down

0 comments on commit a34c079

Please sign in to comment.