Skip to content

Commit ade56ba

Browse files
committed
Revert "Auto merge of rust-lang#92816 - tmiasko:rm-llvm-asm, r=Amanieu"
This reverts commit a34c079, reversing changes made to 128417f.
1 parent aa67016 commit ade56ba

File tree

174 files changed

+3437
-211
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

174 files changed

+3437
-211
lines changed

compiler/rustc_ast/src/ast.rs

+38-1
Original file line numberDiff line numberDiff line change
@@ -1267,7 +1267,7 @@ impl Expr {
12671267
ExprKind::Break(..) => ExprPrecedence::Break,
12681268
ExprKind::Continue(..) => ExprPrecedence::Continue,
12691269
ExprKind::Ret(..) => ExprPrecedence::Ret,
1270-
ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm,
1270+
ExprKind::InlineAsm(..) | ExprKind::LlvmInlineAsm(..) => ExprPrecedence::InlineAsm,
12711271
ExprKind::MacCall(..) => ExprPrecedence::Mac,
12721272
ExprKind::Struct(..) => ExprPrecedence::Struct,
12731273
ExprKind::Repeat(..) => ExprPrecedence::Repeat,
@@ -1437,6 +1437,8 @@ pub enum ExprKind {
14371437

14381438
/// Output of the `asm!()` macro.
14391439
InlineAsm(P<InlineAsm>),
1440+
/// Output of the `llvm_asm!()` macro.
1441+
LlvmInlineAsm(P<LlvmInlineAsm>),
14401442

14411443
/// A macro invocation; pre-expansion.
14421444
MacCall(MacCall),
@@ -2107,6 +2109,41 @@ pub struct InlineAsm {
21072109
pub line_spans: Vec<Span>,
21082110
}
21092111

2112+
/// Inline assembly dialect.
2113+
///
2114+
/// E.g., `"intel"` as in `llvm_asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`.
2115+
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Hash, HashStable_Generic)]
2116+
pub enum LlvmAsmDialect {
2117+
Att,
2118+
Intel,
2119+
}
2120+
2121+
/// LLVM-style inline assembly.
2122+
///
2123+
/// E.g., `"={eax}"(result)` as in `llvm_asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`.
2124+
#[derive(Clone, Encodable, Decodable, Debug)]
2125+
pub struct LlvmInlineAsmOutput {
2126+
pub constraint: Symbol,
2127+
pub expr: P<Expr>,
2128+
pub is_rw: bool,
2129+
pub is_indirect: bool,
2130+
}
2131+
2132+
/// LLVM-style inline assembly.
2133+
///
2134+
/// E.g., `llvm_asm!("NOP");`.
2135+
#[derive(Clone, Encodable, Decodable, Debug)]
2136+
pub struct LlvmInlineAsm {
2137+
pub asm: Symbol,
2138+
pub asm_str_style: StrStyle,
2139+
pub outputs: Vec<LlvmInlineAsmOutput>,
2140+
pub inputs: Vec<(Symbol, P<Expr>)>,
2141+
pub clobbers: Vec<Symbol>,
2142+
pub volatile: bool,
2143+
pub alignstack: bool,
2144+
pub dialect: LlvmAsmDialect,
2145+
}
2146+
21102147
/// A parameter in a function header.
21112148
///
21122149
/// E.g., `bar: usize` as in `fn foo(bar: usize)`.

compiler/rustc_ast/src/mut_visit.rs

+17
Original file line numberDiff line numberDiff line change
@@ -1373,6 +1373,23 @@ pub fn noop_visit_expr<T: MutVisitor>(
13731373
visit_opt(expr, |expr| vis.visit_expr(expr));
13741374
}
13751375
ExprKind::InlineAsm(asm) => noop_visit_inline_asm(asm, vis),
1376+
ExprKind::LlvmInlineAsm(asm) => {
1377+
let LlvmInlineAsm {
1378+
asm: _,
1379+
asm_str_style: _,
1380+
outputs,
1381+
inputs,
1382+
clobbers: _,
1383+
volatile: _,
1384+
alignstack: _,
1385+
dialect: _,
1386+
} = asm.deref_mut();
1387+
for out in outputs {
1388+
let LlvmInlineAsmOutput { constraint: _, expr, is_rw: _, is_indirect: _ } = out;
1389+
vis.visit_expr(expr);
1390+
}
1391+
visit_vec(inputs, |(_c, expr)| vis.visit_expr(expr));
1392+
}
13761393
ExprKind::MacCall(mac) => vis.visit_mac_call(mac),
13771394
ExprKind::Struct(se) => {
13781395
let StructExpr { qself, path, fields, rest } = se.deref_mut();

compiler/rustc_ast/src/visit.rs

+8
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,14 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
862862
ExprKind::MacCall(ref mac) => visitor.visit_mac_call(mac),
863863
ExprKind::Paren(ref subexpression) => visitor.visit_expr(subexpression),
864864
ExprKind::InlineAsm(ref asm) => walk_inline_asm(visitor, asm),
865+
ExprKind::LlvmInlineAsm(ref ia) => {
866+
for &(_, ref input) in &ia.inputs {
867+
visitor.visit_expr(input)
868+
}
869+
for output in &ia.outputs {
870+
visitor.visit_expr(&output.expr)
871+
}
872+
}
865873
ExprKind::Yield(ref optional_expression) => {
866874
walk_list!(visitor, visit_expr, optional_expression);
867875
}

compiler/rustc_ast_lowering/src/expr.rs

+33
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
225225
ExprKind::InlineAsm(ref asm) => {
226226
hir::ExprKind::InlineAsm(self.lower_inline_asm(e.span, asm))
227227
}
228+
ExprKind::LlvmInlineAsm(ref asm) => self.lower_expr_llvm_asm(asm),
228229
ExprKind::Struct(ref se) => {
229230
let rest = match &se.rest {
230231
StructRest::Base(e) => Some(self.lower_expr(e)),
@@ -1294,6 +1295,38 @@ impl<'hir> LoweringContext<'_, 'hir> {
12941295
result
12951296
}
12961297

1298+
fn lower_expr_llvm_asm(&mut self, asm: &LlvmInlineAsm) -> hir::ExprKind<'hir> {
1299+
let inner = hir::LlvmInlineAsmInner {
1300+
inputs: asm.inputs.iter().map(|&(c, _)| c).collect(),
1301+
outputs: asm
1302+
.outputs
1303+
.iter()
1304+
.map(|out| hir::LlvmInlineAsmOutput {
1305+
constraint: out.constraint,
1306+
is_rw: out.is_rw,
1307+
is_indirect: out.is_indirect,
1308+
span: self.lower_span(out.expr.span),
1309+
})
1310+
.collect(),
1311+
asm: asm.asm,
1312+
asm_str_style: asm.asm_str_style,
1313+
clobbers: asm.clobbers.clone(),
1314+
volatile: asm.volatile,
1315+
alignstack: asm.alignstack,
1316+
dialect: asm.dialect,
1317+
};
1318+
let hir_asm = hir::LlvmInlineAsm {
1319+
inner,
1320+
inputs_exprs: self.arena.alloc_from_iter(
1321+
asm.inputs.iter().map(|&(_, ref input)| self.lower_expr_mut(input)),
1322+
),
1323+
outputs_exprs: self
1324+
.arena
1325+
.alloc_from_iter(asm.outputs.iter().map(|out| self.lower_expr_mut(&out.expr))),
1326+
};
1327+
hir::ExprKind::LlvmInlineAsm(self.arena.alloc(hir_asm))
1328+
}
1329+
12971330
fn lower_expr_field(&mut self, f: &ExprField) -> hir::ExprField<'hir> {
12981331
hir::ExprField {
12991332
hir_id: self.next_id(),

compiler/rustc_ast_passes/src/ast_validation.rs

+9
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
10221022
ExprKind::Let(..) if let Some(elem) = forbidden_let_reason => {
10231023
this.ban_let_expr(expr, elem);
10241024
},
1025+
ExprKind::LlvmInlineAsm(..) if !this.session.target.allow_asm => {
1026+
struct_span_err!(
1027+
this.session,
1028+
expr.span,
1029+
E0472,
1030+
"llvm_asm! is unsupported on this target"
1031+
)
1032+
.emit();
1033+
}
10251034
ExprKind::Match(scrutinee, arms) => {
10261035
this.visit_expr(scrutinee);
10271036
for arm in arms {

compiler/rustc_ast_pretty/src/pprust/state/expr.rs

+56
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,62 @@ impl<'a> State<'a> {
495495
self.word("asm!");
496496
self.print_inline_asm(a);
497497
}
498+
ast::ExprKind::LlvmInlineAsm(ref a) => {
499+
self.word("llvm_asm!");
500+
self.popen();
501+
self.print_symbol(a.asm, a.asm_str_style);
502+
self.word_space(":");
503+
504+
self.commasep(Inconsistent, &a.outputs, |s, out| {
505+
let constraint = out.constraint.as_str();
506+
let mut ch = constraint.chars();
507+
match ch.next() {
508+
Some('=') if out.is_rw => {
509+
s.print_string(&format!("+{}", ch.as_str()), ast::StrStyle::Cooked)
510+
}
511+
_ => s.print_string(&constraint, ast::StrStyle::Cooked),
512+
}
513+
s.popen();
514+
s.print_expr(&out.expr);
515+
s.pclose();
516+
});
517+
self.space();
518+
self.word_space(":");
519+
520+
self.commasep(Inconsistent, &a.inputs, |s, &(co, ref o)| {
521+
s.print_symbol(co, ast::StrStyle::Cooked);
522+
s.popen();
523+
s.print_expr(o);
524+
s.pclose();
525+
});
526+
self.space();
527+
self.word_space(":");
528+
529+
self.commasep(Inconsistent, &a.clobbers, |s, &co| {
530+
s.print_symbol(co, ast::StrStyle::Cooked);
531+
});
532+
533+
let mut options = vec![];
534+
if a.volatile {
535+
options.push("volatile");
536+
}
537+
if a.alignstack {
538+
options.push("alignstack");
539+
}
540+
if a.dialect == ast::LlvmAsmDialect::Intel {
541+
options.push("intel");
542+
}
543+
544+
if !options.is_empty() {
545+
self.space();
546+
self.word_space(":");
547+
self.commasep(Inconsistent, &options, |s, &co| {
548+
s.print_string(co, ast::StrStyle::Cooked);
549+
});
550+
}
551+
552+
self.pclose();
553+
}
498554
ast::ExprKind::MacCall(ref m) => self.print_mac(m),
499555
ast::ExprKind::Paren(ref e) => {
500556
self.popen();

compiler/rustc_borrowck/src/dataflow.rs

+9
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_mir_dataflow::ResultsVisitable;
88
use rustc_mir_dataflow::{self, fmt::DebugWithContext, CallReturnPlaces, GenKill};
99
use rustc_mir_dataflow::{Analysis, Direction, Results};
1010
use std::fmt;
11+
use std::iter;
1112

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

388+
mir::StatementKind::LlvmInlineAsm(ref asm) => {
389+
for (output, kind) in iter::zip(&*asm.outputs, &asm.asm.outputs) {
390+
if !kind.is_indirect && !kind.is_rw {
391+
self.kill_borrows_on_place(trans, *output);
392+
}
393+
}
394+
}
395+
387396
mir::StatementKind::FakeRead(..)
388397
| mir::StatementKind::SetDiscriminant { .. }
389398
| mir::StatementKind::StorageLive(..)

compiler/rustc_borrowck/src/def_use.rs

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {
1616

1717
PlaceContext::MutatingUse(MutatingUseContext::Store) |
1818

19+
// This is potentially both a def and a use...
20+
PlaceContext::MutatingUse(MutatingUseContext::LlvmAsmOutput) |
21+
1922
// We let Call define the result in both the success and
2023
// unwind cases. This is not really correct, however it
2124
// does not seem to be observable due to the way that we

compiler/rustc_borrowck/src/invalidation.rs

+41-10
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ use rustc_middle::mir::{BorrowKind, Mutability, Operand};
55
use rustc_middle::mir::{InlineAsmOperand, Terminator, TerminatorKind};
66
use rustc_middle::mir::{Statement, StatementKind};
77
use rustc_middle::ty::TyCtxt;
8+
use std::iter;
89

910
use crate::{
1011
borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, path_utils::*, AccessDepth,
11-
Activation, ArtificialField, BorrowIndex, Deep, LocalMutationIsAllowed, Read, ReadKind,
12-
ReadOrWrite, Reservation, Shallow, Write, WriteKind,
12+
Activation, ArtificialField, BorrowIndex, Deep, JustWrite, LocalMutationIsAllowed, MutateMode,
13+
Read, ReadKind, ReadOrWrite, Reservation, Shallow, Write, WriteAndRead, WriteKind,
1314
};
1415

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

61-
self.mutate_place(location, *lhs, Shallow(None));
62+
self.mutate_place(location, *lhs, Shallow(None), JustWrite);
6263
}
6364
StatementKind::FakeRead(box (_, _)) => {
6465
// Only relevant for initialized/liveness/safety checks.
6566
}
6667
StatementKind::SetDiscriminant { place, variant_index: _ } => {
67-
self.mutate_place(location, **place, Shallow(None));
68+
self.mutate_place(location, **place, Shallow(None), JustWrite);
69+
}
70+
StatementKind::LlvmInlineAsm(asm) => {
71+
for (o, output) in iter::zip(&asm.asm.outputs, &*asm.outputs) {
72+
if o.is_indirect {
73+
// FIXME(eddyb) indirect inline asm outputs should
74+
// be encoded through MIR place derefs instead.
75+
self.access_place(
76+
location,
77+
*output,
78+
(Deep, Read(ReadKind::Copy)),
79+
LocalMutationIsAllowed::No,
80+
);
81+
} else {
82+
self.mutate_place(
83+
location,
84+
*output,
85+
if o.is_rw { Deep } else { Shallow(None) },
86+
if o.is_rw { WriteAndRead } else { JustWrite },
87+
);
88+
}
89+
}
90+
for (_, input) in asm.inputs.iter() {
91+
self.consume_operand(location, input);
92+
}
6893
}
6994
StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
7095
ref src,
@@ -117,7 +142,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
117142
target: _,
118143
unwind: _,
119144
} => {
120-
self.mutate_place(location, *drop_place, Deep);
145+
self.mutate_place(location, *drop_place, Deep, JustWrite);
121146
self.consume_operand(location, new_value);
122147
}
123148
TerminatorKind::Call {
@@ -133,7 +158,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
133158
self.consume_operand(location, arg);
134159
}
135160
if let Some((dest, _ /*bb*/)) = destination {
136-
self.mutate_place(location, *dest, Deep);
161+
self.mutate_place(location, *dest, Deep, JustWrite);
137162
}
138163
}
139164
TerminatorKind::Assert { ref cond, expected: _, ref msg, target: _, cleanup: _ } => {
@@ -156,7 +181,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
156181
}
157182
}
158183

159-
self.mutate_place(location, *resume_arg, Deep);
184+
self.mutate_place(location, *resume_arg, Deep, JustWrite);
160185
}
161186
TerminatorKind::Resume | TerminatorKind::Return | TerminatorKind::GeneratorDrop => {
162187
// Invalidate all borrows of local places
@@ -183,13 +208,13 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
183208
}
184209
InlineAsmOperand::Out { reg: _, late: _, place, .. } => {
185210
if let Some(place) = place {
186-
self.mutate_place(location, place, Shallow(None));
211+
self.mutate_place(location, place, Shallow(None), JustWrite);
187212
}
188213
}
189214
InlineAsmOperand::InOut { reg: _, late: _, ref in_value, out_place } => {
190215
self.consume_operand(location, in_value);
191216
if let Some(out_place) = out_place {
192-
self.mutate_place(location, out_place, Shallow(None));
217+
self.mutate_place(location, out_place, Shallow(None), JustWrite);
193218
}
194219
}
195220
InlineAsmOperand::Const { value: _ }
@@ -213,7 +238,13 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
213238

214239
impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
215240
/// Simulates mutation of a place.
216-
fn mutate_place(&mut self, location: Location, place: Place<'tcx>, kind: AccessDepth) {
241+
fn mutate_place(
242+
&mut self,
243+
location: Location,
244+
place: Place<'tcx>,
245+
kind: AccessDepth,
246+
_mode: MutateMode,
247+
) {
217248
self.access_place(
218249
location,
219250
place,

0 commit comments

Comments
 (0)