From 000b36c505a8865322c376486791cdee8f38d0c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Wed, 12 Jan 2022 00:00:00 +0000 Subject: [PATCH] Remove deprecated LLVM-style inline assembly --- compiler/rustc_ast/src/ast.rs | 39 +-- compiler/rustc_ast/src/mut_visit.rs | 17 - compiler/rustc_ast/src/visit.rs | 8 - compiler/rustc_ast_lowering/src/expr.rs | 33 -- .../rustc_ast_passes/src/ast_validation.rs | 9 - compiler/rustc_ast_pretty/src/pprust/state.rs | 56 ---- compiler/rustc_borrowck/src/dataflow.rs | 9 - compiler/rustc_borrowck/src/def_use.rs | 3 - compiler/rustc_borrowck/src/invalidation.rs | 27 +- compiler/rustc_borrowck/src/lib.rs | 36 +-- compiler/rustc_borrowck/src/type_check/mod.rs | 1 - compiler/rustc_builtin_macros/src/asm.rs | 9 - compiler/rustc_builtin_macros/src/lib.rs | 2 - compiler/rustc_builtin_macros/src/llvm_asm.rs | 303 ------------------ compiler/rustc_codegen_cranelift/src/base.rs | 12 - .../rustc_codegen_cranelift/src/constant.rs | 2 +- compiler/rustc_codegen_gcc/src/asm.rs | 12 - compiler/rustc_codegen_llvm/src/asm.rs | 107 +------ compiler/rustc_codegen_llvm/src/intrinsic.rs | 3 +- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 11 +- compiler/rustc_codegen_ssa/src/mir/analyze.rs | 1 - .../rustc_codegen_ssa/src/mir/statement.rs | 47 --- compiler/rustc_codegen_ssa/src/traits/asm.rs | 10 - .../rustc_const_eval/src/interpret/step.rs | 2 - .../src/transform/check_consts/check.rs | 4 - .../src/transform/validate.rs | 1 - compiler/rustc_hir/src/arena.rs | 1 - compiler/rustc_hir/src/hir.rs | 39 +-- compiler/rustc_hir/src/intravisit.rs | 4 - compiler/rustc_hir_pretty/src/lib.rs | 61 ---- compiler/rustc_middle/src/mir/mod.rs | 14 - compiler/rustc_middle/src/mir/spanview.rs | 1 - compiler/rustc_middle/src/mir/visit.rs | 18 -- compiler/rustc_middle/src/thir.rs | 6 - compiler/rustc_middle/src/thir/visit.rs | 8 - .../rustc_middle/src/ty/structural_impls.rs | 1 - .../src/build/expr/as_place.rs | 1 - .../src/build/expr/as_rvalue.rs | 1 - .../src/build/expr/category.rs | 3 +- .../rustc_mir_build/src/build/expr/into.rs | 4 +- .../rustc_mir_build/src/build/expr/stmt.rs | 32 -- .../rustc_mir_build/src/check_unsafety.rs | 3 +- compiler/rustc_mir_build/src/thir/cx/expr.rs | 6 - .../rustc_mir_dataflow/src/impls/liveness.rs | 1 - .../src/impls/storage_liveness.rs | 5 - .../src/move_paths/builder.rs | 11 - .../rustc_mir_transform/src/check_unsafety.rs | 5 - .../rustc_mir_transform/src/const_prop.rs | 3 +- .../rustc_mir_transform/src/coverage/spans.rs | 1 - compiler/rustc_mir_transform/src/dest_prop.rs | 19 -- compiler/rustc_mir_transform/src/generator.rs | 3 - .../src/remove_noop_landing_pads.rs | 1 - .../src/separate_const_switch.rs | 8 - compiler/rustc_mir_transform/src/simplify.rs | 3 +- .../rustc_mir_transform/src/simplify_try.rs | 4 - .../src/unreachable_prop.rs | 13 +- compiler/rustc_passes/src/liveness.rs | 36 --- compiler/rustc_passes/src/naked_functions.rs | 16 - compiler/rustc_span/src/symbol.rs | 1 - .../src/traits/const_evaluatable.rs | 2 +- compiler/rustc_typeck/src/check/expr.rs | 6 - compiler/rustc_typeck/src/expr_use_visitor.rs | 12 - .../rustc_typeck/src/mem_categorization.rs | 1 - library/core/src/lib.rs | 1 - library/core/src/macros/mod.rs | 26 -- library/core/src/prelude/v1.rs | 4 +- library/std/src/lib.rs | 5 +- library/std/src/prelude/v1.rs | 5 +- 68 files changed, 27 insertions(+), 1132 deletions(-) delete mode 100644 compiler/rustc_builtin_macros/src/llvm_asm.rs diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index a2d32cdc00fb0..079b9e43373fa 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -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, @@ -1423,8 +1423,6 @@ pub enum ExprKind { /// Output of the `asm!()` macro. InlineAsm(P), - /// Output of the `llvm_asm!()` macro. - LlvmInlineAsm(P), /// A macro invocation; pre-expansion. MacCall(MacCall), @@ -2076,41 +2074,6 @@ pub struct InlineAsm { pub line_spans: Vec, } -/// 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, - 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, - pub inputs: Vec<(Symbol, P)>, - pub clobbers: Vec, - 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)`. diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 9ef78aaf6673a..564a8a8c8729e 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1350,23 +1350,6 @@ pub fn noop_visit_expr( 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(); diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 6840f092da61b..0b95270a4e1ef 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -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); } diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 75f384405bb2b..15bf1a5a2ab73 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -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)), @@ -1284,38 +1283,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(), diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 6237a01f69435..45920bb27d5b6 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -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 { diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index fa9a20f2e0358..f4fc2789d9e90 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -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(); diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index 15372ec1534fe..f0036f09c3881 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -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, @@ -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(..) diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs index 70acbc9ee2dbc..eec994f88b96e 100644 --- a/compiler/rustc_borrowck/src/def_use.rs +++ b/compiler/rustc_borrowck/src/def_use.rs @@ -16,9 +16,6 @@ pub fn categorize(context: PlaceContext) -> Option { 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 diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs index c03e4d8a44890..820fc2e7e4a07 100644 --- a/compiler/rustc_borrowck/src/invalidation.rs +++ b/compiler/rustc_borrowck/src/invalidation.rs @@ -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, + Read, ReadKind, ReadOrWrite, Reservation, Shallow, Write, WriteKind, }; pub(super) fn generate_invalidates<'tcx>( @@ -67,30 +66,6 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { 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); - } - } StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { ref src, ref dst, diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index fe34d6e7ca9dd..c9fc7b690c1b5 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -40,7 +40,6 @@ use either::Either; use smallvec::SmallVec; use std::cell::RefCell; use std::collections::BTreeMap; -use std::iter; use std::mem; use std::rc::Rc; @@ -55,7 +54,7 @@ use rustc_mir_dataflow::MoveDataParamEnv; use self::diagnostics::{AccessKind, RegionName}; use self::location::LocationTable; use self::prefixes::PrefixSet; -use self::MutateMode::{JustWrite, WriteAndRead}; +use self::MutateMode::JustWrite; use facts::AllFacts; use self::path_utils::*; @@ -653,39 +652,6 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx StatementKind::SetDiscriminant { place, variant_index: _ } => { self.mutate_place(location, (**place, span), Shallow(None), JustWrite, flow_state); } - StatementKind::LlvmInlineAsm(ref 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, o.span), - (Deep, Read(ReadKind::Copy)), - LocalMutationIsAllowed::No, - flow_state, - ); - self.check_if_path_or_subpath_is_moved( - location, - InitializationRequiringAction::Use, - (output.as_ref(), o.span), - flow_state, - ); - } else { - self.mutate_place( - location, - (*output, o.span), - if o.is_rw { Deep } else { Shallow(None) }, - if o.is_rw { WriteAndRead } else { JustWrite }, - flow_state, - ); - } - } - for (_, input) in asm.inputs.iter() { - self.consume_operand(location, (input, span), flow_state); - } - } - StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { .. }) => { diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 1f745f977d4c4..a58d506eebb3d 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1477,7 +1477,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { StatementKind::FakeRead(..) | StatementKind::StorageLive(..) | StatementKind::StorageDead(..) - | StatementKind::LlvmInlineAsm { .. } | StatementKind::Retag { .. } | StatementKind::Coverage(..) | StatementKind::Nop => {} diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 1a93b9be99ead..304c74e6326af 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -50,15 +50,6 @@ pub fn parse_asm_args<'a>( return Err(diag.struct_span_err(sp, "requires at least a template string argument")); } - // Detect use of the legacy llvm_asm! syntax (which used to be called asm!) - if !is_global_asm && p.look_ahead(1, |t| *t == token::Colon || *t == token::ModSep) { - let mut err = - diag.struct_span_err(sp, "the legacy LLVM-style asm! syntax is no longer supported"); - err.note("consider migrating to the new asm! syntax specified in RFC 2873"); - err.note("alternatively, switch to llvm_asm! to keep your code working as it is"); - return Err(err); - } - let first_template = p.parse_expr()?; let mut args = AsmArgs { templates: vec![first_template], diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 8c3ef2864f485..65f785b9097e7 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -33,7 +33,6 @@ mod env; mod format; mod format_foreign; mod global_allocator; -mod llvm_asm; mod log_syntax; mod panic; mod source_util; @@ -78,7 +77,6 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { include_str: source_util::expand_include_str, include: source_util::expand_include, line: source_util::expand_line, - llvm_asm: llvm_asm::expand_llvm_asm, log_syntax: log_syntax::expand_log_syntax, module_path: source_util::expand_mod, option_env: env::expand_option_env, diff --git a/compiler/rustc_builtin_macros/src/llvm_asm.rs b/compiler/rustc_builtin_macros/src/llvm_asm.rs deleted file mode 100644 index d72bfa660e58f..0000000000000 --- a/compiler/rustc_builtin_macros/src/llvm_asm.rs +++ /dev/null @@ -1,303 +0,0 @@ -// Llvm-style inline assembly support. -// -use State::*; - -use rustc_ast as ast; -use rustc_ast::ptr::P; -use rustc_ast::token::{self, Token}; -use rustc_ast::tokenstream::{self, TokenStream}; -use rustc_ast::LlvmAsmDialect; -use rustc_errors::{struct_span_err, DiagnosticBuilder, PResult}; -use rustc_expand::base::*; -use rustc_parse::parser::Parser; -use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_span::Span; - -enum State { - Asm, - Outputs, - Inputs, - Clobbers, - Options, - StateNone, -} - -impl State { - fn next(&self) -> State { - match *self { - Asm => Outputs, - Outputs => Inputs, - Inputs => Clobbers, - Clobbers => Options, - Options => StateNone, - StateNone => StateNone, - } - } -} - -const OPTIONS: &[Symbol] = &[sym::volatile, sym::alignstack, sym::intel]; - -pub fn expand_llvm_asm<'cx>( - cx: &'cx mut ExtCtxt<'_>, - sp: Span, - tts: TokenStream, -) -> Box { - let mut inline_asm = match parse_inline_asm(cx, sp, tts) { - Ok(Some(inline_asm)) => inline_asm, - Ok(None) => return DummyResult::any(sp), - Err(mut err) => { - err.emit(); - return DummyResult::any(sp); - } - }; - - // If there are no outputs, the inline assembly is executed just for its side effects, - // so ensure that it is volatile - if inline_asm.outputs.is_empty() { - inline_asm.volatile = true; - } - - MacEager::expr(P(ast::Expr { - id: ast::DUMMY_NODE_ID, - kind: ast::ExprKind::LlvmInlineAsm(P(inline_asm)), - span: cx.with_def_site_ctxt(sp), - attrs: ast::AttrVec::new(), - tokens: None, - })) -} - -fn parse_asm_str<'a>(p: &mut Parser<'a>) -> PResult<'a, Symbol> { - match p.parse_str_lit() { - Ok(str_lit) => Ok(str_lit.symbol_unescaped), - Err(opt_lit) => { - let span = opt_lit.map_or(p.token.span, |lit| lit.span); - let mut err = p.sess.span_diagnostic.struct_span_err(span, "expected string literal"); - err.span_label(span, "not a string literal"); - Err(err) - } - } -} - -fn parse_inline_asm<'a>( - cx: &mut ExtCtxt<'a>, - sp: Span, - tts: TokenStream, -) -> Result, DiagnosticBuilder<'a>> { - // Split the tts before the first colon, to avoid `llvm_asm!("x": y)` being - // parsed as `llvm_asm!(z)` with `z = "x": y` which is type ascription. - let first_colon = tts - .trees() - .position(|tt| { - matches!( - tt, - tokenstream::TokenTree::Token(Token { kind: token::Colon | token::ModSep, .. }) - ) - }) - .unwrap_or(tts.len()); - let mut p = cx.new_parser_from_tts(tts.trees().skip(first_colon).collect()); - let mut asm = kw::Empty; - let mut asm_str_style = None; - let mut outputs = Vec::new(); - let mut inputs = Vec::new(); - let mut clobs = Vec::new(); - let mut volatile = false; - let mut alignstack = false; - let mut dialect = LlvmAsmDialect::Att; - - let mut state = Asm; - - 'statement: loop { - match state { - Asm => { - if asm_str_style.is_some() { - // If we already have a string with instructions, - // ending up in Asm state again is an error. - return Err(struct_span_err!( - cx.sess.parse_sess.span_diagnostic, - sp, - E0660, - "malformed inline assembly" - )); - } - // Nested parser, stop before the first colon (see above). - let mut p2 = cx.new_parser_from_tts(tts.trees().take(first_colon).collect()); - - if p2.token == token::Eof { - let mut err = - cx.struct_span_err(sp, "macro requires a string literal as an argument"); - err.span_label(sp, "string literal required"); - return Err(err); - } - - let expr = p2.parse_expr()?; - let (s, style) = - match expr_to_string(cx, expr, "inline assembly must be a string literal") { - Some((s, st)) => (s, st), - None => return Ok(None), - }; - - // This is most likely malformed. - if p2.token != token::Eof { - let mut extra_tts = p2.parse_all_token_trees()?; - extra_tts.extend(tts.trees().skip(first_colon)); - p = cx.new_parser_from_tts(extra_tts.into_iter().collect()); - } - - asm = s; - asm_str_style = Some(style); - } - Outputs => { - while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep { - if !outputs.is_empty() { - p.eat(&token::Comma); - } - - let constraint = parse_asm_str(&mut p)?; - - let span = p.prev_token.span; - - p.expect(&token::OpenDelim(token::Paren))?; - let expr = p.parse_expr()?; - p.expect(&token::CloseDelim(token::Paren))?; - - // Expands a read+write operand into two operands. - // - // Use '+' modifier when you want the same expression - // to be both an input and an output at the same time. - // It's the opposite of '=&' which means that the memory - // cannot be shared with any other operand (usually when - // a register is clobbered early.) - let constraint_str = constraint.as_str(); - let mut ch = constraint_str.chars(); - let output = match ch.next() { - Some('=') => None, - Some('+') => Some(Symbol::intern(&format!("={}", ch.as_str()))), - _ => { - struct_span_err!( - cx.sess.parse_sess.span_diagnostic, - span, - E0661, - "output operand constraint lacks '=' or '+'" - ) - .emit(); - None - } - }; - - let is_rw = output.is_some(); - let is_indirect = constraint_str.contains('*'); - outputs.push(ast::LlvmInlineAsmOutput { - constraint: output.unwrap_or(constraint), - expr, - is_rw, - is_indirect, - }); - } - } - Inputs => { - while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep { - if !inputs.is_empty() { - p.eat(&token::Comma); - } - - let constraint = parse_asm_str(&mut p)?; - - if constraint.as_str().starts_with('=') { - struct_span_err!( - cx.sess.parse_sess.span_diagnostic, - p.prev_token.span, - E0662, - "input operand constraint contains '='" - ) - .emit(); - } else if constraint.as_str().starts_with('+') { - struct_span_err!( - cx.sess.parse_sess.span_diagnostic, - p.prev_token.span, - E0663, - "input operand constraint contains '+'" - ) - .emit(); - } - - p.expect(&token::OpenDelim(token::Paren))?; - let input = p.parse_expr()?; - p.expect(&token::CloseDelim(token::Paren))?; - - inputs.push((constraint, input)); - } - } - Clobbers => { - while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep { - if !clobs.is_empty() { - p.eat(&token::Comma); - } - - let s = parse_asm_str(&mut p)?; - - if OPTIONS.iter().any(|&opt| s == opt) { - cx.span_warn(p.prev_token.span, "expected a clobber, found an option"); - } else if s.as_str().starts_with('{') || s.as_str().ends_with('}') { - struct_span_err!( - cx.sess.parse_sess.span_diagnostic, - p.prev_token.span, - E0664, - "clobber should not be surrounded by braces" - ) - .emit(); - } - - clobs.push(s); - } - } - Options => { - let option = parse_asm_str(&mut p)?; - - if option == sym::volatile { - // Indicates that the inline assembly has side effects - // and must not be optimized out along with its outputs. - volatile = true; - } else if option == sym::alignstack { - alignstack = true; - } else if option == sym::intel { - dialect = LlvmAsmDialect::Intel; - } else { - cx.span_warn(p.prev_token.span, "unrecognized option"); - } - - if p.token == token::Comma { - p.eat(&token::Comma); - } - } - StateNone => (), - } - - loop { - // MOD_SEP is a double colon '::' without space in between. - // When encountered, the state must be advanced twice. - match (&p.token.kind, state.next(), state.next().next()) { - (&token::Colon, StateNone, _) | (&token::ModSep, _, StateNone) => { - p.bump(); - break 'statement; - } - (&token::Colon, st, _) | (&token::ModSep, _, st) => { - p.bump(); - state = st; - } - (&token::Eof, ..) => break 'statement, - _ => break, - } - } - } - - Ok(Some(ast::LlvmInlineAsm { - asm, - asm_str_style: asm_str_style.unwrap(), - outputs, - inputs, - clobbers: clobs, - volatile, - alignstack, - dialect, - })) -} diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index b16f5af66f249..5a889734f215b 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -749,18 +749,6 @@ fn codegen_stmt<'tcx>( | StatementKind::Retag { .. } | StatementKind::AscribeUserType(..) => {} - StatementKind::LlvmInlineAsm(asm) => { - match asm.asm.asm.as_str().trim() { - "" => { - // Black box - } - _ => fx.tcx.sess.span_fatal( - stmt.source_info.span, - "Legacy `llvm_asm!` inline assembly is not supported. \ - Try using the new `asm!` instead.", - ), - } - } StatementKind::Coverage { .. } => fx.tcx.sess.fatal("-Zcoverage is unimplemented"), StatementKind::CopyNonOverlapping(inner) => { let dst = codegen_operand(fx, &inner.dst); diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 9a6c45ae98d5f..7ef09a1a6141d 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -506,7 +506,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( { return None; } - StatementKind::LlvmInlineAsm(_) | StatementKind::CopyNonOverlapping(_) => { + StatementKind::CopyNonOverlapping(_) => { return None; } // conservative handling StatementKind::Assign(_) diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index 453bcd601d3fe..d620b24e0677a 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -4,7 +4,6 @@ use rustc_codegen_ssa::mir::operand::OperandValue; use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::{AsmBuilderMethods, AsmMethods, BaseTypeMethods, BuilderMethods, GlobalAsmOperandRef, InlineAsmOperandRef}; -use rustc_hir::LlvmInlineAsmInner; use rustc_middle::{bug, ty::Instance}; use rustc_span::{Span, Symbol}; use rustc_target::asm::*; @@ -106,17 +105,6 @@ enum ConstraintOrRegister { impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { - fn codegen_llvm_inline_asm(&mut self, _ia: &LlvmInlineAsmInner, _outputs: Vec>>, _inputs: Vec>, span: Span) -> bool { - self.sess().struct_span_err(span, "GCC backend does not support `llvm_asm!`") - .help("consider using the `asm!` macro instead") - .emit(); - - // We return `true` even if we've failed to generate the asm - // because we want to suppress the "malformed inline assembly" error - // generated by the frontend. - true - } - fn codegen_inline_asm(&mut self, template: &[InlineAsmTemplatePiece], rust_operands: &[InlineAsmOperandRef<'tcx, Self>], options: InlineAsmOptions, span: &[Span], _instance: Instance<'_>, _dest_catch_funclet: Option<(Self::BasicBlock, Self::BasicBlock, Option<&Self::Funclet>)>) { if options.contains(InlineAsmOptions::MAY_UNWIND) { self.sess() diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index caf16c1939df0..8335f841bec56 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -7,13 +7,10 @@ use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; -use rustc_ast::LlvmAsmDialect; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_codegen_ssa::mir::operand::OperandValue; -use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::*; use rustc_data_structures::fx::FxHashMap; -use rustc_hir as hir; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::{bug, span_bug, ty::Instance}; use rustc_span::{Pos, Span, Symbol}; @@ -24,100 +21,6 @@ use libc::{c_char, c_uint}; use tracing::debug; impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { - fn codegen_llvm_inline_asm( - &mut self, - ia: &hir::LlvmInlineAsmInner, - outputs: Vec>, - mut inputs: Vec<&'ll Value>, - span: Span, - ) -> bool { - let mut ext_constraints = vec![]; - let mut output_types = vec![]; - - // Prepare the output operands - let mut indirect_outputs = vec![]; - for (i, (out, &place)) in ia.outputs.iter().zip(&outputs).enumerate() { - if out.is_rw { - let operand = self.load_operand(place); - if let OperandValue::Immediate(_) = operand.val { - inputs.push(operand.immediate()); - } - ext_constraints.push(i.to_string()); - } - if out.is_indirect { - let operand = self.load_operand(place); - if let OperandValue::Immediate(_) = operand.val { - indirect_outputs.push(operand.immediate()); - } - } else { - output_types.push(place.layout.llvm_type(self.cx)); - } - } - if !indirect_outputs.is_empty() { - indirect_outputs.extend_from_slice(&inputs); - inputs = indirect_outputs; - } - - let clobbers = ia.clobbers.iter().map(|s| format!("~{{{}}}", &s)); - - // Default per-arch clobbers - // Basically what clang does - let arch_clobbers = match &self.sess().target.arch[..] { - "x86" | "x86_64" => &["~{dirflag}", "~{fpsr}", "~{flags}"][..], - "mips" | "mips64" => &["~{$1}"], - _ => &[], - }; - - let all_constraints = ia - .outputs - .iter() - .map(|out| out.constraint.to_string()) - .chain(ia.inputs.iter().map(|s| s.to_string())) - .chain(ext_constraints) - .chain(clobbers) - .chain(arch_clobbers.iter().map(|s| (*s).to_string())) - .collect::>() - .join(","); - - debug!("Asm Constraints: {}", &all_constraints); - - // Depending on how many outputs we have, the return type is different - let num_outputs = output_types.len(); - let output_type = match num_outputs { - 0 => self.type_void(), - 1 => output_types[0], - _ => self.type_struct(&output_types, false), - }; - - let asm = ia.asm.as_str(); - let r = inline_asm_call( - self, - &asm, - &all_constraints, - &inputs, - output_type, - ia.volatile, - ia.alignstack, - ia.dialect, - &[span], - false, - None, - ); - if r.is_none() { - return false; - } - let r = r.unwrap(); - - // Again, based on how many outputs we have - let outputs = ia.outputs.iter().zip(&outputs).filter(|&(o, _)| !o.is_indirect); - for (i, (_, &place)) in outputs.enumerate() { - let v = if num_outputs == 1 { r } else { self.extract_value(r, i as u64) }; - OperandValue::Immediate(v).store(self, place); - } - - true - } - fn codegen_inline_asm( &mut self, template: &[InlineAsmTemplatePiece], @@ -349,9 +252,9 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { InlineAsmArch::X86 | InlineAsmArch::X86_64 if !options.contains(InlineAsmOptions::ATT_SYNTAX) => { - LlvmAsmDialect::Intel + llvm::AsmDialect::Intel } - _ => LlvmAsmDialect::Att, + _ => llvm::AsmDialect::Att, }; let result = inline_asm_call( self, @@ -455,7 +358,7 @@ pub(crate) fn inline_asm_call<'ll>( output: &'ll llvm::Type, volatile: bool, alignstack: bool, - dia: LlvmAsmDialect, + dia: llvm::AsmDialect, line_spans: &[Span], unwind: bool, dest_catch_funclet: Option<( @@ -498,7 +401,7 @@ pub(crate) fn inline_asm_call<'ll>( cons.len(), volatile, alignstack, - llvm::AsmDialect::from_generic(dia), + dia, can_throw, ); @@ -522,7 +425,7 @@ pub(crate) fn inline_asm_call<'ll>( // we just encode the start position of each line. // FIXME: Figure out a way to pass the entire line spans. let mut srcloc = vec![]; - if dia == LlvmAsmDialect::Intel && line_spans.len() > 1 { + if dia == llvm::AsmDialect::Intel && line_spans.len() > 1 { // LLVM inserts an extra line to add the ".intel_syntax", so add // a dummy srcloc entry for it. // diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 1e795efa2e1bf..cebb6d13c4e9f 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -7,7 +7,6 @@ use crate::type_of::LayoutLlvmExt; use crate::va_arg::emit_va_arg; use crate::value::Value; -use rustc_ast as ast; use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh}; use rustc_codegen_ssa::common::span_invalid_monomorphization_error; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; @@ -351,7 +350,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { self.type_void(), true, false, - ast::LlvmAsmDialect::Att, + llvm::AsmDialect::Att, &[span], false, None, diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index f2782f84f557b..bc8d7b3e9e21c 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -423,22 +423,13 @@ pub enum MetadataType { } /// LLVMRustAsmDialect -#[derive(Copy, Clone)] +#[derive(Copy, Clone, PartialEq)] #[repr(C)] pub enum AsmDialect { Att, Intel, } -impl AsmDialect { - pub fn from_generic(asm: rustc_ast::LlvmAsmDialect) -> Self { - match asm { - rustc_ast::LlvmAsmDialect::Att => AsmDialect::Att, - rustc_ast::LlvmAsmDialect::Intel => AsmDialect::Intel, - } - } -} - /// LLVMRustCodeGenOptLevel #[derive(Copy, Clone, PartialEq)] #[repr(C)] diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index b1b3f1d6d81b9..d768d4920c5b4 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -211,7 +211,6 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> PlaceContext::MutatingUse( MutatingUseContext::Store - | MutatingUseContext::LlvmAsmOutput | MutatingUseContext::AsmOutput | MutatingUseContext::Borrow | MutatingUseContext::AddressOf diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs index 2c96987d3399e..773dc2adcfa0c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/statement.rs +++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs @@ -1,9 +1,7 @@ -use rustc_errors::struct_span_err; use rustc_middle::mir; use super::FunctionCx; use super::LocalRef; -use super::OperandValue; use crate::traits::BuilderMethods; use crate::traits::*; @@ -66,51 +64,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } bx } - mir::StatementKind::LlvmInlineAsm(ref asm) => { - let outputs = asm - .outputs - .iter() - .map(|output| self.codegen_place(&mut bx, output.as_ref())) - .collect(); - - let input_vals = asm.inputs.iter().fold( - Vec::with_capacity(asm.inputs.len()), - |mut acc, (span, input)| { - let op = self.codegen_operand(&mut bx, input); - if let OperandValue::Immediate(_) = op.val { - acc.push(op.immediate()); - } else { - struct_span_err!( - bx.sess(), - span.to_owned(), - E0669, - "invalid value for constraint in inline assembly" - ) - .emit(); - } - acc - }, - ); - - if input_vals.len() == asm.inputs.len() { - let res = bx.codegen_llvm_inline_asm( - &asm.asm, - outputs, - input_vals, - statement.source_info.span, - ); - if !res { - struct_span_err!( - bx.sess(), - statement.source_info.span, - E0668, - "malformed inline assembly" - ) - .emit(); - } - } - bx - } mir::StatementKind::Coverage(box ref coverage) => { self.codegen_coverage(&mut bx, coverage.clone(), statement.source_info.scope); bx diff --git a/compiler/rustc_codegen_ssa/src/traits/asm.rs b/compiler/rustc_codegen_ssa/src/traits/asm.rs index 65f3c754d2dcc..11111a7974410 100644 --- a/compiler/rustc_codegen_ssa/src/traits/asm.rs +++ b/compiler/rustc_codegen_ssa/src/traits/asm.rs @@ -3,7 +3,6 @@ use crate::mir::operand::OperandRef; use crate::mir::place::PlaceRef; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir::def_id::DefId; -use rustc_hir::LlvmInlineAsmInner; use rustc_middle::ty::Instance; use rustc_span::Span; use rustc_target::asm::InlineAsmRegOrRegClass; @@ -42,15 +41,6 @@ pub enum GlobalAsmOperandRef { } pub trait AsmBuilderMethods<'tcx>: BackendTypes { - /// Take an inline assembly expression and splat it out via LLVM - fn codegen_llvm_inline_asm( - &mut self, - ia: &LlvmInlineAsmInner, - outputs: Vec>, - inputs: Vec, - span: Span, - ) -> bool; - /// Take an inline assembly expression and splat it out via LLVM fn codegen_inline_asm( &mut self, diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 3daa1d3c2b3e8..57ba9b4099232 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -140,8 +140,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Defined to do nothing. These are added by optimization passes, to avoid changing the // size of MIR constantly. Nop => {} - - LlvmInlineAsm { .. } => throw_unsup_format!("inline assembly is not supported"), } self.stack_mut()[frame_idx].loc.as_mut().unwrap().statement_index += 1; diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index dd749c0393473..f619af051ca7b 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -752,10 +752,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { self.super_statement(statement, location); match statement.kind { - StatementKind::LlvmInlineAsm { .. } => { - self.check_op(ops::InlineAsm); - } - StatementKind::Assign(..) | StatementKind::SetDiscriminant { .. } | StatementKind::FakeRead(..) diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index c3f81a3ab838f..22ef0b2dda506 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -352,7 +352,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { StatementKind::SetDiscriminant { .. } | StatementKind::StorageLive(..) | StatementKind::StorageDead(..) - | StatementKind::LlvmInlineAsm(..) | StatementKind::Retag(_, _) | StatementKind::Coverage(_) | StatementKind::Nop => {} diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index edad00ed6a2fe..27ec461906419 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -30,7 +30,6 @@ macro_rules! arena_types { [] impl_item_ref: rustc_hir::ImplItemRef, [] item: rustc_hir::Item<'tcx>, [] inline_asm: rustc_hir::InlineAsm<'tcx>, - [] llvm_inline_asm: rustc_hir::LlvmInlineAsm<'tcx>, [] local: rustc_hir::Local<'tcx>, [] mod_: rustc_hir::Mod<'tcx>, [] owner_info: rustc_hir::OwnerInfo<'tcx>, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index f03d8eea40bb3..0d6ef7734e49b 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -5,8 +5,8 @@ use crate::intravisit::FnKind; use crate::LangItem; use rustc_ast::util::parser::ExprPrecedence; -use rustc_ast::{self as ast, CrateSugar, LlvmAsmDialect}; -use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, StrStyle, TraitObjectSyntax, UintTy}; +use rustc_ast::{self as ast, CrateSugar}; +use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, TraitObjectSyntax, UintTy}; pub use rustc_ast::{BorrowKind, ImplPolarity, IsAuto}; pub use rustc_ast::{CaptureBy, Movability, Mutability}; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; @@ -1471,7 +1471,6 @@ impl Expr<'_> { ExprKind::Continue(..) => ExprPrecedence::Continue, ExprKind::Ret(..) => ExprPrecedence::Ret, ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm, - ExprKind::LlvmInlineAsm(..) => ExprPrecedence::InlineAsm, ExprKind::Struct(..) => ExprPrecedence::Struct, ExprKind::Repeat(..) => ExprPrecedence::Repeat, ExprKind::Yield(..) => ExprPrecedence::Yield, @@ -1531,7 +1530,6 @@ impl Expr<'_> { | ExprKind::Loop(..) | ExprKind::Assign(..) | ExprKind::InlineAsm(..) - | ExprKind::LlvmInlineAsm(..) | ExprKind::AssignOp(..) | ExprKind::Lit(_) | ExprKind::ConstBlock(..) @@ -1614,7 +1612,6 @@ impl Expr<'_> { | ExprKind::Loop(..) | ExprKind::Assign(..) | ExprKind::InlineAsm(..) - | ExprKind::LlvmInlineAsm(..) | ExprKind::AssignOp(..) | ExprKind::ConstBlock(..) | ExprKind::Box(..) @@ -1755,8 +1752,6 @@ pub enum ExprKind<'hir> { /// Inline assembly (from `asm!`), with its outputs and inputs. InlineAsm(&'hir InlineAsm<'hir>), - /// Inline assembly (from `llvm_asm!`), with its outputs and inputs. - LlvmInlineAsm(&'hir LlvmInlineAsm<'hir>), /// A struct or struct-like variant literal expression. /// @@ -2368,36 +2363,6 @@ pub struct InlineAsm<'hir> { pub line_spans: &'hir [Span], } -#[derive(Copy, Clone, Encodable, Decodable, Debug, Hash, HashStable_Generic, PartialEq)] -pub struct LlvmInlineAsmOutput { - pub constraint: Symbol, - pub is_rw: bool, - pub is_indirect: bool, - pub span: Span, -} - -// NOTE(eddyb) This is used within MIR as well, so unlike the rest of the HIR, -// it needs to be `Clone` and `Decodable` and use plain `Vec` instead of -// arena-allocated slice. -#[derive(Clone, Encodable, Decodable, Debug, Hash, HashStable_Generic, PartialEq)] -pub struct LlvmInlineAsmInner { - pub asm: Symbol, - pub asm_str_style: StrStyle, - pub outputs: Vec, - pub inputs: Vec, - pub clobbers: Vec, - pub volatile: bool, - pub alignstack: bool, - pub dialect: LlvmAsmDialect, -} - -#[derive(Debug, HashStable_Generic)] -pub struct LlvmInlineAsm<'hir> { - pub inner: LlvmInlineAsmInner, - pub outputs_exprs: &'hir [Expr<'hir>], - pub inputs_exprs: &'hir [Expr<'hir>], -} - /// Represents a parameter in a function header. #[derive(Debug, HashStable_Generic)] pub struct Param<'hir> { diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index d0eee422202af..ca64af2c93cbf 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1251,10 +1251,6 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) ExprKind::InlineAsm(ref asm) => { walk_inline_asm(visitor, asm); } - ExprKind::LlvmInlineAsm(ref asm) => { - walk_list!(visitor, visit_expr, asm.outputs_exprs); - walk_list!(visitor, visit_expr, asm.inputs_exprs); - } ExprKind::Yield(ref subexpression, _) => { visitor.visit_expr(subexpression); } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 4c9e2d7fe42b1..bf2dae5edf16d 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1581,67 +1581,6 @@ impl<'a> State<'a> { self.word("asm!"); self.print_inline_asm(asm); } - hir::ExprKind::LlvmInlineAsm(ref a) => { - let i = &a.inner; - self.word("llvm_asm!"); - self.popen(); - self.print_symbol(i.asm, i.asm_str_style); - self.word_space(":"); - - let mut out_idx = 0; - self.commasep(Inconsistent, &i.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(&a.outputs_exprs[out_idx]); - s.pclose(); - out_idx += 1; - }); - self.space(); - self.word_space(":"); - - let mut in_idx = 0; - self.commasep(Inconsistent, &i.inputs, |s, &co| { - s.print_symbol(co, ast::StrStyle::Cooked); - s.popen(); - s.print_expr(&a.inputs_exprs[in_idx]); - s.pclose(); - in_idx += 1; - }); - self.space(); - self.word_space(":"); - - self.commasep(Inconsistent, &i.clobbers, |s, &co| { - s.print_symbol(co, ast::StrStyle::Cooked); - }); - - let mut options = vec![]; - if i.volatile { - options.push("volatile"); - } - if i.alignstack { - options.push("alignstack"); - } - if i.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(); - } hir::ExprKind::Yield(ref expr, _) => { self.word_space("yield"); self.print_expr_maybe_paren(&expr, parser::PREC_JUMP); diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 6d1d9dd9720d4..38c379919d289 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1565,10 +1565,6 @@ pub enum StatementKind<'tcx> { /// End the current live range for the storage of the local. StorageDead(Local), - /// Executes a piece of inline Assembly. Stored in a Box to keep the size - /// of `StatementKind` low. - LlvmInlineAsm(Box>), - /// Retag references in the given place, ensuring they got fresh tags. This is /// part of the Stacked Borrows model. These statements are currently only interpreted /// by miri and only generated when "-Z mir-emit-retag" is passed. @@ -1688,13 +1684,6 @@ pub enum FakeReadCause { ForIndex, } -#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable)] -pub struct LlvmInlineAsm<'tcx> { - pub asm: hir::LlvmInlineAsmInner, - pub outputs: Box<[Place<'tcx>]>, - pub inputs: Box<[(Span, Operand<'tcx>)]>, -} - impl Debug for Statement<'_> { fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { use self::StatementKind::*; @@ -1719,9 +1708,6 @@ impl Debug for Statement<'_> { SetDiscriminant { ref place, variant_index } => { write!(fmt, "discriminant({:?}) = {:?}", place, variant_index) } - LlvmInlineAsm(ref asm) => { - write!(fmt, "llvm_asm!({:?} : {:?} : {:?})", asm.asm, asm.outputs, asm.inputs) - } AscribeUserType(box (ref place, ref c_ty), ref variance) => { write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty) } diff --git a/compiler/rustc_middle/src/mir/spanview.rs b/compiler/rustc_middle/src/mir/spanview.rs index 507f9971981b0..589e1579d39bf 100644 --- a/compiler/rustc_middle/src/mir/spanview.rs +++ b/compiler/rustc_middle/src/mir/spanview.rs @@ -245,7 +245,6 @@ pub fn statement_kind_name(statement: &Statement<'_>) -> &'static str { SetDiscriminant { .. } => "SetDiscriminant", StorageLive(..) => "StorageLive", StorageDead(..) => "StorageDead", - LlvmInlineAsm(..) => "LlvmInlineAsm", Retag(..) => "Retag", AscribeUserType(..) => "AscribeUserType", Coverage(..) => "Coverage", diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index f301c68a7c091..4452ac5e3e0d4 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -408,19 +408,6 @@ macro_rules! make_mir_visitor { location ); } - StatementKind::LlvmInlineAsm(asm) => { - for output in & $($mutability)? asm.outputs[..] { - self.visit_place( - output, - PlaceContext::MutatingUse(MutatingUseContext::LlvmAsmOutput), - location - ); - } - for (span, input) in & $($mutability)? asm.inputs[..] { - self.visit_span(span); - self.visit_operand(input, location); - } - } StatementKind::Retag(kind, place) => { self.visit_retag(kind, place, location); } @@ -1178,10 +1165,6 @@ pub enum NonMutatingUseContext { pub enum MutatingUseContext { /// Appears as LHS of an assignment. Store, - /// Can often be treated as a `Store`, but needs to be separate because - /// ASM is allowed to read outputs as well, so a `Store`-`LlvmAsmOutput` sequence - /// cannot be simplified the way a `Store`-`Store` can be. - LlvmAsmOutput, /// Output operand of an inline assembly block. AsmOutput, /// Destination of a call. @@ -1271,7 +1254,6 @@ impl PlaceContext { PlaceContext::MutatingUse( MutatingUseContext::Store | MutatingUseContext::Call - | MutatingUseContext::LlvmAsmOutput | MutatingUseContext::AsmOutput, ) ) diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index d2e3ce97d1265..eef42666f2a07 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -431,12 +431,6 @@ pub enum ExprKind<'tcx> { }, /// An expression taking a reference to a thread local. ThreadLocalRef(DefId), - /// Inline LLVM assembly, i.e. `llvm_asm!()`. - LlvmInlineAsm { - asm: &'tcx hir::LlvmInlineAsmInner, - outputs: Box<[ExprId]>, - inputs: Box<[ExprId]>, - }, /// A `yield` expression. Yield { value: ExprId, diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index 7fc15e02fcd30..9f9947341c5c1 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -145,14 +145,6 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp } } ThreadLocalRef(_) => {} - LlvmInlineAsm { ref outputs, ref inputs, asm: _ } => { - for &out_expr in &**outputs { - visitor.visit_expr(&visitor.thir()[out_expr]); - } - for &in_expr in &**inputs { - visitor.visit_expr(&visitor.thir()[in_expr]); - } - } Yield { value } => visitor.visit_expr(&visitor.thir()[value]), } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 98b1a8b4d7631..fe56544dab3be 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -225,7 +225,6 @@ TrivialTypeFoldableAndLiftImpls! { ::rustc_hir::def_id::DefId, ::rustc_hir::def_id::LocalDefId, ::rustc_hir::HirId, - ::rustc_hir::LlvmInlineAsmInner, ::rustc_hir::MatchSource, ::rustc_hir::Mutability, ::rustc_hir::Unsafety, diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index b3126b72bb85c..167b3aaed4695 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -570,7 +570,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { | ExprKind::ConstBlock { .. } | ExprKind::StaticRef { .. } | ExprKind::InlineAsm { .. } - | ExprKind::LlvmInlineAsm { .. } | ExprKind::Yield { .. } | ExprKind::ThreadLocalRef(_) | ExprKind::Call { .. } => { diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 9a86d465f98ca..1dc49256a6a9f 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -350,7 +350,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { | ExprKind::Continue { .. } | ExprKind::Return { .. } | ExprKind::InlineAsm { .. } - | ExprKind::LlvmInlineAsm { .. } | ExprKind::PlaceTypeAscription { .. } | ExprKind::ValueTypeAscription { .. } => { // these do not have corresponding `Rvalue` variants, diff --git a/compiler/rustc_mir_build/src/build/expr/category.rs b/compiler/rustc_mir_build/src/build/expr/category.rs index fcda52e558126..d31f6ed93840a 100644 --- a/compiler/rustc_mir_build/src/build/expr/category.rs +++ b/compiler/rustc_mir_build/src/build/expr/category.rs @@ -67,8 +67,7 @@ impl Category { | ExprKind::Repeat { .. } | ExprKind::Assign { .. } | ExprKind::AssignOp { .. } - | ExprKind::ThreadLocalRef(_) - | ExprKind::LlvmInlineAsm { .. } => Some(Category::Rvalue(RvalueFunc::AsRvalue)), + | ExprKind::ThreadLocalRef(_) => Some(Category::Rvalue(RvalueFunc::AsRvalue)), ExprKind::ConstBlock { .. } | ExprKind::Literal { .. } | ExprKind::StaticRef { .. } => { Some(Category::Constant) diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index d9896ff5ac93e..43060ecfced12 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -477,9 +477,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } // These cases don't actually need a destination - ExprKind::Assign { .. } - | ExprKind::AssignOp { .. } - | ExprKind::LlvmInlineAsm { .. } => { + ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => { unpack!(block = this.stmt_expr(block, expr, None)); this.cfg.push_assign_unit(block, source_info, destination, this.tcx); block.unit() diff --git a/compiler/rustc_mir_build/src/build/expr/stmt.rs b/compiler/rustc_mir_build/src/build/expr/stmt.rs index 4245535450a27..7419c5b2f7588 100644 --- a/compiler/rustc_mir_build/src/build/expr/stmt.rs +++ b/compiler/rustc_mir_build/src/build/expr/stmt.rs @@ -101,38 +101,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { BreakableTarget::Return, source_info, ), - ExprKind::LlvmInlineAsm { asm, ref outputs, ref inputs } => { - debug!("stmt_expr LlvmInlineAsm block_context.push(SubExpr) : {:?}", expr); - this.block_context.push(BlockFrame::SubExpr); - let outputs = outputs - .into_iter() - .copied() - .map(|output| unpack!(block = this.as_place(block, &this.thir[output]))) - .collect::>() - .into_boxed_slice(); - let inputs = inputs - .into_iter() - .copied() - .map(|input| { - let input = &this.thir[input]; - (input.span, unpack!(block = this.as_local_operand(block, &input))) - }) - .collect::>() - .into_boxed_slice(); - this.cfg.push( - block, - Statement { - source_info, - kind: StatementKind::LlvmInlineAsm(Box::new(LlvmInlineAsm { - asm: asm.clone(), - outputs, - inputs, - })), - }, - ); - this.block_context.pop(); - block.unit() - } _ => { assert!( statement_scope.is_some(), diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 7940bd1f33dc1..8ca2449cea9c4 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -329,7 +329,6 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { | ExprKind::Box { .. } | ExprKind::If { .. } | ExprKind::InlineAsm { .. } - | ExprKind::LlvmInlineAsm { .. } | ExprKind::LogicalOp { .. } | ExprKind::Use { .. } => { // We don't need to save the old value and restore it @@ -377,7 +376,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { self.requires_unsafe(expr.span, DerefOfRawPointer); } } - ExprKind::InlineAsm { .. } | ExprKind::LlvmInlineAsm { .. } => { + ExprKind::InlineAsm { .. } => { self.requires_unsafe(expr.span, UseOfInlineAssembly); } ExprKind::Adt(box Adt { diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index bdde6b4a356c1..6865dd202cf9e 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -570,12 +570,6 @@ impl<'tcx> Cx<'tcx> { line_spans: asm.line_spans, }, - hir::ExprKind::LlvmInlineAsm(ref asm) => ExprKind::LlvmInlineAsm { - asm: &asm.inner, - outputs: self.mirror_exprs(asm.outputs_exprs), - inputs: self.mirror_exprs(asm.inputs_exprs), - }, - hir::ExprKind::ConstBlock(ref anon_const) => { let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id); let value = ty::Const::from_inline_const(self.tcx, anon_const_def_id); diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs index 65c388f8124a3..4871320fdb5c0 100644 --- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs @@ -176,7 +176,6 @@ impl DefUse { // All other contexts are uses... PlaceContext::MutatingUse( MutatingUseContext::AddressOf - | MutatingUseContext::LlvmAsmOutput | MutatingUseContext::Borrow | MutatingUseContext::Drop | MutatingUseContext::Retag, diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs index 896377f2bc307..60cde6546dcfc 100644 --- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs @@ -134,11 +134,6 @@ impl<'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tc | StatementKind::SetDiscriminant { box place, .. } => { trans.gen(place.local); } - StatementKind::LlvmInlineAsm(asm) => { - for place in &*asm.outputs { - trans.gen(place.local); - } - } // Nothing to do for these. Match exhaustively so this fails to compile when new // variants are added. diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 2e00b4f9a5e7c..26bbc34e780bb 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -4,7 +4,6 @@ use rustc_middle::mir::*; use rustc_middle::ty::{self, TyCtxt}; use smallvec::{smallvec, SmallVec}; -use std::iter; use std::mem; use super::abs_domain::Lift; @@ -293,16 +292,6 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { StatementKind::FakeRead(box (_, place)) => { self.create_move_path(*place); } - StatementKind::LlvmInlineAsm(ref asm) => { - for (output, kind) in iter::zip(&*asm.outputs, &asm.asm.outputs) { - if !kind.is_indirect { - self.gather_init(output.as_ref(), InitKind::Deep); - } - } - for (_, input) in asm.inputs.iter() { - self.gather_operand(input); - } - } StatementKind::StorageLive(_) => {} StatementKind::StorageDead(local) => { self.gather_move(Place::from(*local)); diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index a40c4d1c3662b..4a773c5772dab 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -104,10 +104,6 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { // safe (at least as emitted during MIR construction) } - StatementKind::LlvmInlineAsm { .. } => self.require_unsafe( - UnsafetyViolationKind::General, - UnsafetyViolationDetails::UseOfInlineAssembly, - ), StatementKind::CopyNonOverlapping(..) => unreachable!(), } self.super_statement(statement, location); @@ -208,7 +204,6 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { MutatingUseContext::Store | MutatingUseContext::Drop | MutatingUseContext::AsmOutput - | MutatingUseContext::LlvmAsmOutput ) ); // If this is just an assignment, determine if the assigned type needs dropping. diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index e3ff6ad45490d..7649fafc35504 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -1035,8 +1035,7 @@ impl Visitor<'_> for CanConstProp { // These could be propagated with a smarter analysis or just some careful thinking about // whether they'd be fine right now. - MutatingUse(MutatingUseContext::LlvmAsmOutput) - | MutatingUse(MutatingUseContext::Yield) + MutatingUse(MutatingUseContext::Yield) | MutatingUse(MutatingUseContext::Drop) | MutatingUse(MutatingUseContext::Retag) // These can't ever be propagated under any scheme, as we can't reason about indirect diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index b5356a817f7ac..a9161580bc681 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -835,7 +835,6 @@ pub(super) fn filtered_statement_span(statement: &Statement<'_>) -> Option | StatementKind::CopyNonOverlapping(..) | StatementKind::Assign(_) | StatementKind::SetDiscriminant { .. } - | StatementKind::LlvmInlineAsm(_) | StatementKind::Retag(_, _) | StatementKind::AscribeUserType(_, _) => { Some(statement.source_info.span) diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 2b382468be0f5..d469be7464144 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -534,25 +534,6 @@ impl<'a> Conflicts<'a> { // eliminate the resulting self-assignments automatically. StatementKind::Assign(_) => {} - StatementKind::LlvmInlineAsm(asm) => { - // Inputs and outputs must not overlap. - for (_, input) in &*asm.inputs { - if let Some(in_place) = input.place() { - if !in_place.is_indirect() { - for out_place in &*asm.outputs { - if !out_place.is_indirect() && !in_place.is_indirect() { - self.record_local_conflict( - in_place.local, - out_place.local, - "aliasing llvm_asm! operands", - ); - } - } - } - } - } - } - StatementKind::SetDiscriminant { .. } | StatementKind::StorageLive(..) | StatementKind::StorageDead(..) diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 08247e6f22af1..433a1c6ad67cc 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -1449,9 +1449,6 @@ impl<'tcx> Visitor<'tcx> for EnsureGeneratorFieldAssignmentsNeverAlias<'_> { self.check_assigned_place(*lhs, |this| this.visit_rvalue(rhs, location)); } - // FIXME: Does `llvm_asm!` have any aliasing requirements? - StatementKind::LlvmInlineAsm(_) => {} - StatementKind::FakeRead(..) | StatementKind::SetDiscriminant { .. } | StatementKind::StorageLive(_) diff --git a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs index 2a73e341f1653..77fb092d5806f 100644 --- a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs +++ b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs @@ -50,7 +50,6 @@ impl RemoveNoopLandingPads { StatementKind::Assign { .. } | StatementKind::SetDiscriminant { .. } - | StatementKind::LlvmInlineAsm { .. } | StatementKind::CopyNonOverlapping(..) | StatementKind::Retag { .. } => { return false; diff --git a/compiler/rustc_mir_transform/src/separate_const_switch.rs b/compiler/rustc_mir_transform/src/separate_const_switch.rs index 612fce71f9167..d265720e18296 100644 --- a/compiler/rustc_mir_transform/src/separate_const_switch.rs +++ b/compiler/rustc_mir_transform/src/separate_const_switch.rs @@ -239,10 +239,6 @@ fn is_likely_const<'tcx>(mut tracked_place: Place<'tcx>, block: &BasicBlockData< } } - // If inline assembly is found, we probably should - // not try to analyze the code - StatementKind::LlvmInlineAsm(_) => return false, - // These statements have no influence on the place // we are interested in StatementKind::FakeRead(_) @@ -320,10 +316,6 @@ fn find_determining_place<'tcx>( | StatementKind::CopyNonOverlapping(_) | StatementKind::Nop => {} - // If inline assembly is found, we probably should - // not try to analyze the code - StatementKind::LlvmInlineAsm(_) => return None, - // If the discriminant is set, it is always set // as a constant, so the job is already done. // As we are **ignoring projections**, if the place diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 7992124bacd43..7e0c8e233e9e8 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -483,8 +483,7 @@ impl UsedLocals { impl<'tcx> Visitor<'tcx> for UsedLocals { fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { match statement.kind { - StatementKind::LlvmInlineAsm(..) - | StatementKind::CopyNonOverlapping(..) + StatementKind::CopyNonOverlapping(..) | StatementKind::Retag(..) | StatementKind::Coverage(..) | StatementKind::FakeRead(..) diff --git a/compiler/rustc_mir_transform/src/simplify_try.rs b/compiler/rustc_mir_transform/src/simplify_try.rs index 7761d4006d3db..d5507fcc78cad 100644 --- a/compiler/rustc_mir_transform/src/simplify_try.rs +++ b/compiler/rustc_mir_transform/src/simplify_try.rs @@ -631,10 +631,6 @@ impl<'tcx> SimplifyBranchSameOptimizationFinder<'_, 'tcx> { .filter(|(_, bb)| { // Reaching `unreachable` is UB so assume it doesn't happen. bb.terminator().kind != TerminatorKind::Unreachable - // But `asm!(...)` could abort the program, - // so we cannot assume that the `unreachable` terminator itself is reachable. - // FIXME(Centril): use a normalization pass instead of a check. - || bb.statements.iter().any(|stmt| matches!(stmt.kind, StatementKind::LlvmInlineAsm(..))) }) .peekable(); diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs index 9e755ab141a48..f916ca36217b4 100644 --- a/compiler/rustc_mir_transform/src/unreachable_prop.rs +++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs @@ -23,23 +23,14 @@ impl MirPass<'_> for UnreachablePropagation { for (bb, bb_data) in traversal::postorder(body) { let terminator = bb_data.terminator(); - // HACK: If the block contains any asm statement it is not regarded as unreachable. - // This is a temporary solution that handles possibly diverging asm statements. - // Accompanying testcases: mir-opt/unreachable_asm.rs and mir-opt/unreachable_asm_2.rs - let asm_stmt_in_block = || { - bb_data.statements.iter().any(|stmt: &Statement<'_>| { - matches!(stmt.kind, StatementKind::LlvmInlineAsm(..)) - }) - }; - - if terminator.kind == TerminatorKind::Unreachable && !asm_stmt_in_block() { + if terminator.kind == TerminatorKind::Unreachable { unreachable_blocks.insert(bb); } else { let is_unreachable = |succ: BasicBlock| unreachable_blocks.contains(&succ); let terminator_kind_opt = remove_successors(&terminator.kind, is_unreachable); if let Some(terminator_kind) = terminator_kind_opt { - if terminator_kind == TerminatorKind::Unreachable && !asm_stmt_in_block() { + if terminator_kind == TerminatorKind::Unreachable { unreachable_blocks.insert(bb); } replacements.insert(bb, terminator_kind); diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 9ee305b712f61..4660d04788594 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -103,7 +103,6 @@ use rustc_span::Span; use std::collections::VecDeque; use std::io; use std::io::prelude::*; -use std::iter; use std::rc::Rc; mod rwu_table; @@ -470,7 +469,6 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> { | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) | hir::ExprKind::InlineAsm(..) - | hir::ExprKind::LlvmInlineAsm(..) | hir::ExprKind::Box(..) | hir::ExprKind::Type(..) | hir::ExprKind::Err @@ -1091,26 +1089,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { succ } - hir::ExprKind::LlvmInlineAsm(ref asm) => { - let ia = &asm.inner; - let outputs = asm.outputs_exprs; - let inputs = asm.inputs_exprs; - let succ = iter::zip(&ia.outputs, outputs).rev().fold(succ, |succ, (o, output)| { - // see comment on places - // in propagate_through_place_components() - if o.is_indirect { - self.propagate_through_expr(output, succ) - } else { - let acc = if o.is_rw { ACC_WRITE | ACC_READ } else { ACC_WRITE }; - let succ = self.write_place(output, succ, acc); - self.propagate_through_place_components(output, succ) - } - }); - - // Inputs are executed first. Propagate last because of rev order - self.propagate_through_exprs(inputs, succ) - } - hir::ExprKind::Lit(..) | hir::ExprKind::ConstBlock(..) | hir::ExprKind::Err @@ -1387,20 +1365,6 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr<'tcx>) { } } - hir::ExprKind::LlvmInlineAsm(ref asm) => { - for input in asm.inputs_exprs { - this.visit_expr(input); - } - - // Output operands must be places - for (o, output) in iter::zip(&asm.inner.outputs, asm.outputs_exprs) { - if !o.is_indirect { - this.check_place(output); - } - this.visit_expr(output); - } - } - hir::ExprKind::Let(let_expr) => { this.check_unused_vars_in_pat(let_expr.pat, None, |_, _, _, _| {}); } diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index 07cb165d79670..dd14dce4b5b83 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -236,22 +236,6 @@ impl<'tcx> CheckInlineAssembly<'tcx> { self.check_inline_asm(expr.hir_id, asm, span); } - ExprKind::LlvmInlineAsm(..) => { - self.items.push((ItemKind::Asm, span)); - self.tcx.struct_span_lint_hir( - UNSUPPORTED_NAKED_FUNCTIONS, - expr.hir_id, - span, - |lint| { - lint.build( - "the LLVM-style inline assembly is unsupported in naked functions", - ) - .help("use the new asm! syntax specified in RFC 2873") - .emit(); - }, - ); - } - ExprKind::DropTemps(..) | ExprKind::Block(..) | ExprKind::Err => { hir::intravisit::walk_expr(self, expr); } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 84cf8878af809..9b906a735dba7 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -786,7 +786,6 @@ symbols! { linkage, lint_reasons, literal, - llvm_asm, load, loaded_from_disk, local, diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 0ea3a18ca34fa..76e51b8d7d93b 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -480,7 +480,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { // let expressions imply control flow ExprKind::Match { .. } | ExprKind::If { .. } | ExprKind::Let { .. } => self.error(node.span, "control flow is not supported in generic constants")?, - ExprKind::LlvmInlineAsm { .. } | ExprKind::InlineAsm { .. } => { + ExprKind::InlineAsm { .. } => { self.error(node.span, "assembly is not supported in generic constants")? } diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 14180526d846b..3b6e87b6a88eb 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -282,12 +282,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, &[]), ExprKind::InlineAsm(asm) => self.check_expr_asm(asm), - ExprKind::LlvmInlineAsm(asm) => { - for expr in asm.outputs_exprs.iter().chain(asm.inputs_exprs.iter()) { - self.check_expr(expr); - } - tcx.mk_unit() - } ExprKind::Break(destination, ref expr_opt) => { self.check_expr_break(destination, expr_opt.as_deref(), expr) } diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index 1ae0ff3036471..564aac4825a57 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -17,7 +17,6 @@ use rustc_middle::hir::place::ProjectionKind; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::{self, adjustment, AdtKind, Ty, TyCtxt}; use rustc_target::abi::VariantIdx; -use std::iter; use crate::mem_categorization as mc; @@ -360,17 +359,6 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } } - hir::ExprKind::LlvmInlineAsm(ia) => { - for (o, output) in iter::zip(&ia.inner.outputs, ia.outputs_exprs) { - if o.is_indirect { - self.consume_expr(output); - } else { - self.mutate_expr(output); - } - } - self.consume_exprs(ia.inputs_exprs); - } - hir::ExprKind::Continue(..) | hir::ExprKind::Lit(..) | hir::ExprKind::ConstBlock(..) diff --git a/compiler/rustc_typeck/src/mem_categorization.rs b/compiler/rustc_typeck/src/mem_categorization.rs index 440ce04e61a27..2c2d2be8bb514 100644 --- a/compiler/rustc_typeck/src/mem_categorization.rs +++ b/compiler/rustc_typeck/src/mem_categorization.rs @@ -378,7 +378,6 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) | hir::ExprKind::InlineAsm(..) - | hir::ExprKind::LlvmInlineAsm(..) | hir::ExprKind::Box(..) | hir::ExprKind::Err => Ok(self.cat_rvalue(expr.hir_id, expr.span, expr_ty)), } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 4bd94e3ce3915..d8ac816fb15a0 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -180,7 +180,6 @@ #![feature(intrinsics)] #![feature(lang_items)] #![feature(link_llvm_intrinsics)] -#![feature(llvm_asm)] #![feature(min_specialization)] #![feature(mixed_integer_ops)] #![feature(must_not_suspend)] diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index d8f6c85e428cd..5184eb91bf3f4 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1373,32 +1373,6 @@ pub(crate) mod builtin { ($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }}; } - /// LLVM-style inline assembly. - /// - /// Read the [unstable book] for the usage. - /// - /// [unstable book]: ../unstable-book/library-features/llvm-asm.html - #[unstable( - feature = "llvm_asm", - issue = "70173", - reason = "prefer using the new asm! syntax instead" - )] - #[rustc_deprecated( - since = "1.56", - reason = "will be removed from the compiler, use asm! instead" - )] - #[rustc_builtin_macro] - #[macro_export] - macro_rules! llvm_asm { - ("assembly template" - : $("output"(operand),)* - : $("input"(operand),)* - : $("clobbers",)* - : $("options",)*) => { - /* compiler built-in */ - }; - } - /// Prints passed tokens into the standard output. #[unstable( feature = "log_syntax", diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs index 0fb8846288bee..d91289fad2009 100644 --- a/library/core/src/prelude/v1.rs +++ b/library/core/src/prelude/v1.rs @@ -56,8 +56,8 @@ pub use crate::hash::macros::Hash; #[doc(no_inline)] pub use crate::{ assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args, - format_args_nl, include, include_bytes, include_str, line, llvm_asm, log_syntax, module_path, - option_env, stringify, trace_macros, + format_args_nl, include, include_bytes, include_str, line, log_syntax, module_path, option_env, + stringify, trace_macros, }; #[unstable( diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 4ba4e2a528e60..51d5f1cd4e1e0 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -294,7 +294,6 @@ #![feature(intra_doc_pointers)] #![feature(lang_items)] #![feature(linkage)] -#![feature(llvm_asm)] #![feature(log_syntax)] #![feature(map_try_insert)] #![feature(maybe_uninit_extra)] @@ -572,8 +571,8 @@ pub use core::{ #[allow(deprecated)] pub use core::{ assert, assert_matches, cfg, column, compile_error, concat, concat_idents, const_format_args, - env, file, format_args, format_args_nl, include, include_bytes, include_str, line, llvm_asm, - log_syntax, module_path, option_env, stringify, trace_macros, + env, file, format_args, format_args_nl, include, include_bytes, include_str, line, log_syntax, + module_path, option_env, stringify, trace_macros, }; #[unstable( diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs index b52bcdfca9e07..53124daa3a683 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/v1.rs @@ -40,9 +40,8 @@ pub use crate::result::Result::{self, Err, Ok}; #[doc(no_inline)] pub use core::prelude::v1::{ assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args, - format_args_nl, include, include_bytes, include_str, line, llvm_asm, log_syntax, module_path, - option_env, stringify, trace_macros, Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, - PartialOrd, + format_args_nl, include, include_bytes, include_str, line, log_syntax, module_path, option_env, + stringify, trace_macros, Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd, }; #[unstable(