Skip to content

Commit

Permalink
Revert "Auto merge of rust-lang#92816 - tmiasko:rm-llvm-asm, r=Amanieu"
Browse files Browse the repository at this point in the history
This reverts commit a34c079, reversing
changes made to 128417f.
  • Loading branch information
drmorr0 committed Apr 4, 2022
1 parent aa67016 commit ade56ba
Show file tree
Hide file tree
Showing 174 changed files with 3,437 additions and 211 deletions.
39 changes: 38 additions & 1 deletion compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1267,7 +1267,7 @@ impl Expr {
ExprKind::Break(..) => ExprPrecedence::Break,
ExprKind::Continue(..) => ExprPrecedence::Continue,
ExprKind::Ret(..) => ExprPrecedence::Ret,
ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm,
ExprKind::InlineAsm(..) | ExprKind::LlvmInlineAsm(..) => ExprPrecedence::InlineAsm,
ExprKind::MacCall(..) => ExprPrecedence::Mac,
ExprKind::Struct(..) => ExprPrecedence::Struct,
ExprKind::Repeat(..) => ExprPrecedence::Repeat,
Expand Down Expand Up @@ -1437,6 +1437,8 @@ 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 @@ -2107,6 +2109,41 @@ 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: 17 additions & 0 deletions compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1373,6 +1373,23 @@ 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: 8 additions & 0 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,14 @@ 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: 33 additions & 0 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ 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 @@ -1294,6 +1295,38 @@ 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: 9 additions & 0 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
ExprKind::Let(..) if let Some(elem) = forbidden_let_reason => {
this.ban_let_expr(expr, elem);
},
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(scrutinee, arms) => {
this.visit_expr(scrutinee);
for arm in arms {
Expand Down
56 changes: 56 additions & 0 deletions compiler/rustc_ast_pretty/src/pprust/state/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,62 @@ 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: 9 additions & 0 deletions compiler/rustc_borrowck/src/dataflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ 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 @@ -384,6 +385,14 @@ 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: 3 additions & 0 deletions compiler/rustc_borrowck/src/def_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ 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: 41 additions & 10 deletions compiler/rustc_borrowck/src/invalidation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ 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, LocalMutationIsAllowed, Read, ReadKind,
ReadOrWrite, Reservation, Shallow, Write, WriteKind,
Activation, ArtificialField, BorrowIndex, Deep, JustWrite, LocalMutationIsAllowed, MutateMode,
Read, ReadKind, ReadOrWrite, Reservation, Shallow, Write, WriteAndRead, WriteKind,
};

pub(super) fn generate_invalidates<'tcx>(
Expand Down Expand Up @@ -58,13 +59,37 @@ 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));
self.mutate_place(location, *lhs, Shallow(None), JustWrite);
}
StatementKind::FakeRead(box (_, _)) => {
// Only relevant for initialized/liveness/safety checks.
}
StatementKind::SetDiscriminant { place, variant_index: _ } => {
self.mutate_place(location, **place, Shallow(None));
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,
Expand Down Expand Up @@ -117,7 +142,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
target: _,
unwind: _,
} => {
self.mutate_place(location, *drop_place, Deep);
self.mutate_place(location, *drop_place, Deep, JustWrite);
self.consume_operand(location, new_value);
}
TerminatorKind::Call {
Expand All @@ -133,7 +158,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);
self.mutate_place(location, *dest, Deep, JustWrite);
}
}
TerminatorKind::Assert { ref cond, expected: _, ref msg, target: _, cleanup: _ } => {
Expand All @@ -156,7 +181,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
}
}

self.mutate_place(location, *resume_arg, Deep);
self.mutate_place(location, *resume_arg, Deep, JustWrite);
}
TerminatorKind::Resume | TerminatorKind::Return | TerminatorKind::GeneratorDrop => {
// Invalidate all borrows of local places
Expand All @@ -183,13 +208,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));
self.mutate_place(location, place, Shallow(None), JustWrite);
}
}
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));
self.mutate_place(location, out_place, Shallow(None), JustWrite);
}
}
InlineAsmOperand::Const { value: _ }
Expand All @@ -213,7 +238,13 @@ 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) {
fn mutate_place(
&mut self,
location: Location,
place: Place<'tcx>,
kind: AccessDepth,
_mode: MutateMode,
) {
self.access_place(
location,
place,
Expand Down
Loading

0 comments on commit ade56ba

Please sign in to comment.