Skip to content

Commit 126910a

Browse files
committed
Change InlineAsm to allow multiple targets instead
1 parent d32c2f0 commit 126910a

File tree

18 files changed

+89
-63
lines changed

18 files changed

+89
-63
lines changed

compiler/rustc_borrowck/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,7 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
724724
operands,
725725
options: _,
726726
line_spans: _,
727-
destination: _,
727+
targets: _,
728728
unwind: _,
729729
} => {
730730
for op in operands {

compiler/rustc_borrowck/src/polonius/loan_invalidations.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'cx, 'tcx> {
163163
operands,
164164
options: _,
165165
line_spans: _,
166-
destination: _,
166+
targets: _,
167167
unwind: _,
168168
} => {
169169
for op in operands {

compiler/rustc_borrowck/src/type_check/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1669,8 +1669,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
16691669
self.assert_iscleanup(body, block_data, real_target, is_cleanup);
16701670
self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup);
16711671
}
1672-
TerminatorKind::InlineAsm { destination, unwind, .. } => {
1673-
if let Some(target) = destination {
1672+
TerminatorKind::InlineAsm { ref targets, unwind, .. } => {
1673+
for &target in targets {
16741674
self.assert_iscleanup(body, block_data, target, is_cleanup);
16751675
}
16761676
self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup);

compiler/rustc_codegen_ssa/src/mir/block.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1276,7 +1276,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
12761276
ref operands,
12771277
options,
12781278
line_spans,
1279-
destination,
1279+
ref targets,
12801280
unwind,
12811281
} => self.codegen_asm_terminator(
12821282
helper,
@@ -1286,7 +1286,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
12861286
operands,
12871287
options,
12881288
line_spans,
1289-
destination,
1289+
targets.get(0).copied(),
12901290
unwind,
12911291
self.instance,
12921292
mergeable_succ(),

compiler/rustc_const_eval/src/interpret/terminator.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -224,13 +224,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
224224
terminator.kind
225225
),
226226

227-
InlineAsm { template, ref operands, options, destination, .. } => {
227+
InlineAsm { template, ref operands, options, ref targets, .. } => {
228228
M::eval_inline_asm(self, template, operands, options)?;
229229
if options.contains(InlineAsmOptions::NORETURN) {
230230
throw_ub_custom!(fluent::const_eval_noreturn_asm_returned);
231231
}
232232
self.go_to_block(
233-
destination
233+
targets
234+
.get(0)
235+
.copied()
234236
.expect("InlineAsm terminators without noreturn must have a destination"),
235237
)
236238
}

compiler/rustc_const_eval/src/transform/validate.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -481,9 +481,9 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
481481
self.check_edge(location, *real_target, EdgeKind::Normal);
482482
self.check_unwind_edge(location, *unwind);
483483
}
484-
TerminatorKind::InlineAsm { destination, unwind, .. } => {
485-
if let Some(destination) = destination {
486-
self.check_edge(location, *destination, EdgeKind::Normal);
484+
TerminatorKind::InlineAsm { targets, unwind, .. } => {
485+
for &target in targets {
486+
self.check_edge(location, target, EdgeKind::Normal);
487487
}
488488
self.check_unwind_edge(location, *unwind);
489489
}

compiler/rustc_middle/src/mir/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1651,13 +1651,13 @@ mod size_asserts {
16511651
use super::*;
16521652
use rustc_data_structures::static_assert_size;
16531653
// tidy-alphabetical-start
1654-
static_assert_size!(BasicBlockData<'_>, 136);
1654+
static_assert_size!(BasicBlockData<'_>, 144);
16551655
static_assert_size!(LocalDecl<'_>, 40);
16561656
static_assert_size!(SourceScopeData<'_>, 72);
16571657
static_assert_size!(Statement<'_>, 32);
16581658
static_assert_size!(StatementKind<'_>, 16);
1659-
static_assert_size!(Terminator<'_>, 104);
1660-
static_assert_size!(TerminatorKind<'_>, 88);
1659+
static_assert_size!(Terminator<'_>, 112);
1660+
static_assert_size!(TerminatorKind<'_>, 96);
16611661
static_assert_size!(VarDebugInfo<'_>, 88);
16621662
// tidy-alphabetical-end
16631663
}

compiler/rustc_middle/src/mir/pretty.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::path::{Path, PathBuf};
66

77
use super::graphviz::write_mir_fn_graphviz;
88
use super::spanview::write_mir_fn_spanview;
9-
use rustc_ast::InlineAsmTemplatePiece;
9+
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
1010
use rustc_middle::mir::interpret::{
1111
alloc_range, read_target_uint, AllocBytes, AllocId, Allocation, GlobalAlloc, Pointer,
1212
Provenance,
@@ -895,16 +895,19 @@ impl<'tcx> TerminatorKind<'tcx> {
895895
vec!["real".into(), "unwind".into()]
896896
}
897897
FalseUnwind { unwind: _, .. } => vec!["real".into()],
898-
InlineAsm { destination: Some(_), unwind: UnwindAction::Cleanup(_), .. } => {
899-
vec!["return".into(), "unwind".into()]
898+
InlineAsm { options, ref targets, unwind, .. } => {
899+
let mut vec = Vec::with_capacity(targets.len() + 1);
900+
if !options.contains(InlineAsmOptions::NORETURN) {
901+
vec.push("return".into());
900902
}
901-
InlineAsm { destination: Some(_), unwind: _, .. } => {
902-
vec!["return".into()]
903+
vec.resize(targets.len(), "unwind".into());
904+
905+
if let UnwindAction::Cleanup(_) = unwind {
906+
vec.push("unwind".into());
903907
}
904-
InlineAsm { destination: None, unwind: UnwindAction::Cleanup(_), .. } => {
905-
vec!["unwind".into()]
908+
909+
vec
906910
}
907-
InlineAsm { destination: None, unwind: _, .. } => vec![],
908911
}
909912
}
910913
}

compiler/rustc_middle/src/mir/syntax.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -790,9 +790,10 @@ pub enum TerminatorKind<'tcx> {
790790
/// used to map assembler errors back to the line in the source code.
791791
line_spans: &'tcx [Span],
792792

793-
/// Destination block after the inline assembly returns, unless it is
794-
/// diverging (InlineAsmOptions::NORETURN).
795-
destination: Option<BasicBlock>,
793+
/// Valid targets for the inline assembly.
794+
/// The first element is the fallthrough destination, unless
795+
/// InlineAsmOptions::NORETURN is set.
796+
targets: Vec<BasicBlock>,
796797

797798
/// Action to be taken if the inline assembly unwinds. This is present
798799
/// if and only if InlineAsmOptions::MAY_UNWIND is set.

compiler/rustc_middle/src/mir/terminator.rs

+24-22
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,7 @@ impl<'tcx> TerminatorKind<'tcx> {
358358
| Yield { resume: ref t, drop: Some(u), .. }
359359
| Drop { target: ref t, unwind: UnwindAction::Cleanup(u), .. }
360360
| Assert { target: ref t, unwind: UnwindAction::Cleanup(u), .. }
361-
| FalseUnwind { real_target: ref t, unwind: UnwindAction::Cleanup(u) }
362-
| InlineAsm { destination: Some(ref t), unwind: UnwindAction::Cleanup(u), .. } => {
361+
| FalseUnwind { real_target: ref t, unwind: UnwindAction::Cleanup(u) } => {
363362
slice::from_ref(t).into_iter().copied().chain(Some(u))
364363
}
365364
Goto { target: ref t }
@@ -368,20 +367,19 @@ impl<'tcx> TerminatorKind<'tcx> {
368367
| Yield { resume: ref t, drop: None, .. }
369368
| Drop { target: ref t, unwind: _, .. }
370369
| Assert { target: ref t, unwind: _, .. }
371-
| FalseUnwind { real_target: ref t, unwind: _ }
372-
| InlineAsm { destination: None, unwind: UnwindAction::Cleanup(ref t), .. }
373-
| InlineAsm { destination: Some(ref t), unwind: _, .. } => {
370+
| FalseUnwind { real_target: ref t, unwind: _ } => {
374371
slice::from_ref(t).into_iter().copied().chain(None)
375372
}
376373
UnwindResume
377374
| UnwindTerminate(_)
378375
| CoroutineDrop
379376
| Return
380377
| Unreachable
381-
| Call { target: None, unwind: _, .. }
382-
| InlineAsm { destination: None, unwind: _, .. } => {
383-
(&[]).into_iter().copied().chain(None)
378+
| Call { target: None, unwind: _, .. } => (&[]).into_iter().copied().chain(None),
379+
InlineAsm { ref targets, unwind: UnwindAction::Cleanup(u), .. } => {
380+
targets.iter().copied().chain(Some(u))
384381
}
382+
InlineAsm { ref targets, unwind: _, .. } => targets.iter().copied().chain(None),
385383
SwitchInt { ref targets, .. } => targets.targets.iter().copied().chain(None),
386384
FalseEdge { ref real_target, imaginary_target } => {
387385
slice::from_ref(real_target).into_iter().copied().chain(Some(imaginary_target))
@@ -396,30 +394,28 @@ impl<'tcx> TerminatorKind<'tcx> {
396394
| Yield { resume: ref mut t, drop: Some(ref mut u), .. }
397395
| Drop { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. }
398396
| Assert { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. }
399-
| FalseUnwind { real_target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u) }
400-
| InlineAsm {
401-
destination: Some(ref mut t),
402-
unwind: UnwindAction::Cleanup(ref mut u),
403-
..
404-
} => slice::from_mut(t).into_iter().chain(Some(u)),
397+
| FalseUnwind { real_target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u) } => {
398+
slice::from_mut(t).into_iter().chain(Some(u))
399+
}
405400
Goto { target: ref mut t }
406401
| Call { target: None, unwind: UnwindAction::Cleanup(ref mut t), .. }
407402
| Call { target: Some(ref mut t), unwind: _, .. }
408403
| Yield { resume: ref mut t, drop: None, .. }
409404
| Drop { target: ref mut t, unwind: _, .. }
410405
| Assert { target: ref mut t, unwind: _, .. }
411-
| FalseUnwind { real_target: ref mut t, unwind: _ }
412-
| InlineAsm { destination: None, unwind: UnwindAction::Cleanup(ref mut t), .. }
413-
| InlineAsm { destination: Some(ref mut t), unwind: _, .. } => {
406+
| FalseUnwind { real_target: ref mut t, unwind: _ } => {
414407
slice::from_mut(t).into_iter().chain(None)
415408
}
416409
UnwindResume
417410
| UnwindTerminate(_)
418411
| CoroutineDrop
419412
| Return
420413
| Unreachable
421-
| Call { target: None, unwind: _, .. }
422-
| InlineAsm { destination: None, unwind: _, .. } => (&mut []).into_iter().chain(None),
414+
| Call { target: None, unwind: _, .. } => (&mut []).into_iter().chain(None),
415+
InlineAsm { ref mut targets, unwind: UnwindAction::Cleanup(ref mut u), .. } => {
416+
targets.iter_mut().chain(Some(u))
417+
}
418+
InlineAsm { ref mut targets, unwind: _, .. } => targets.iter_mut().chain(None),
423419
SwitchInt { ref mut targets, .. } => targets.targets.iter_mut().chain(None),
424420
FalseEdge { ref mut real_target, ref mut imaginary_target } => {
425421
slice::from_mut(real_target).into_iter().chain(Some(imaginary_target))
@@ -495,6 +491,12 @@ pub enum TerminatorEdges<'mir, 'tcx> {
495491
cleanup: Option<BasicBlock>,
496492
place: CallReturnPlaces<'mir, 'tcx>,
497493
},
494+
/// Special action for `InlineAsm` terminators.
495+
InlineAsm {
496+
targets: &'mir [BasicBlock],
497+
cleanup: Option<BasicBlock>,
498+
place: CallReturnPlaces<'mir, 'tcx>,
499+
},
498500
/// Special edge for `SwitchInt`.
499501
SwitchInt { targets: &'mir SwitchTargets, discr: &'mir Operand<'tcx> },
500502
}
@@ -575,10 +577,10 @@ impl<'tcx> TerminatorKind<'tcx> {
575577
ref operands,
576578
options: _,
577579
line_spans: _,
578-
destination,
580+
ref targets,
579581
unwind,
580-
} => TerminatorEdges::AssignOnReturn {
581-
return_: destination,
582+
} => TerminatorEdges::InlineAsm {
583+
targets,
582584
cleanup: unwind.cleanup_block(),
583585
place: CallReturnPlaces::InlineAsm(operands),
584586
},

compiler/rustc_middle/src/mir/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ macro_rules! make_mir_visitor {
563563
operands,
564564
options: _,
565565
line_spans: _,
566-
destination: _,
566+
targets: _,
567567
unwind: _,
568568
} => {
569569
for op in operands {

compiler/rustc_mir_build/src/build/expr/into.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -468,10 +468,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
468468
operands,
469469
options,
470470
line_spans,
471-
destination: if options.contains(InlineAsmOptions::NORETURN) {
472-
None
471+
targets: if options.contains(InlineAsmOptions::NORETURN) {
472+
Vec::new()
473473
} else {
474-
Some(destination_block)
474+
vec![destination_block]
475475
},
476476
unwind: if options.contains(InlineAsmOptions::MAY_UNWIND) {
477477
UnwindAction::Continue

compiler/rustc_mir_build/src/lints.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,10 @@ impl<'mir, 'tcx, C: TerminatorClassifier<'tcx>> TriColorVisitor<BasicBlocks<'tcx
198198
| TerminatorKind::Unreachable
199199
| TerminatorKind::Yield { .. } => ControlFlow::Break(NonRecursive),
200200

201-
// A diverging InlineAsm is treated as non-recursing
202-
TerminatorKind::InlineAsm { destination, .. } => {
203-
if destination.is_some() {
201+
// A InlineAsm without targets (diverging and contains no labels)
202+
// is treated as non-recursing.
203+
TerminatorKind::InlineAsm { ref targets, .. } => {
204+
if !targets.is_empty() {
204205
ControlFlow::Continue(())
205206
} else {
206207
ControlFlow::Break(NonRecursive)

compiler/rustc_mir_dataflow/src/framework/direction.rs

+17-3
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,9 @@ impl Direction for Backward {
242242
propagate(pred, &tmp);
243243
}
244244

245-
mir::TerminatorKind::InlineAsm {
246-
destination: Some(dest), ref operands, ..
247-
} if dest == bb => {
245+
mir::TerminatorKind::InlineAsm { ref targets, ref operands, .. }
246+
if targets.contains(&bb) =>
247+
{
248248
let mut tmp = exit_state.clone();
249249
analysis.apply_call_return_effect(
250250
&mut tmp,
@@ -496,6 +496,20 @@ impl Direction for Forward {
496496
propagate(return_, exit_state);
497497
}
498498
}
499+
TerminatorEdges::InlineAsm { targets, cleanup, place } => {
500+
// This must be done *first*, otherwise the unwind path will see the assignments.
501+
if let Some(cleanup) = cleanup {
502+
propagate(cleanup, exit_state);
503+
}
504+
505+
if !targets.is_empty() {
506+
analysis.apply_call_return_effect(exit_state, bb, place);
507+
508+
for &target in targets {
509+
propagate(target, exit_state);
510+
}
511+
}
512+
}
499513
TerminatorEdges::SwitchInt { targets, discr } => {
500514
let mut applier = ForwardSwitchIntEdgeEffectsApplier {
501515
exit_state,

compiler/rustc_mir_dataflow/src/framework/graphviz.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,9 @@ where
299299
})?;
300300
}
301301

302-
mir::TerminatorKind::InlineAsm { destination: Some(_), ref operands, .. } => {
302+
mir::TerminatorKind::InlineAsm { ref targets, ref operands, .. }
303+
if !targets.is_empty() =>
304+
{
303305
self.write_row(w, "", "(on successful return)", |this, w, fmt| {
304306
let state_on_unwind = this.results.get().clone();
305307
this.results.apply_custom_effect(|analysis, state| {

compiler/rustc_mir_dataflow/src/move_paths/builder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
481481
ref operands,
482482
options: _,
483483
line_spans: _,
484-
destination: _,
484+
targets: _,
485485
unwind: _,
486486
} => {
487487
for op in operands {

compiler/rustc_mir_transform/src/inline.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1010,8 +1010,8 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> {
10101010
{
10111011
bug!("False unwinds should have been removed before inlining")
10121012
}
1013-
TerminatorKind::InlineAsm { ref mut destination, ref mut unwind, .. } => {
1014-
if let Some(ref mut tgt) = *destination {
1013+
TerminatorKind::InlineAsm { ref mut targets, ref mut unwind, .. } => {
1014+
for tgt in targets.iter_mut() {
10151015
*tgt = self.map_block(*tgt);
10161016
}
10171017
*unwind = self.map_unwind(*unwind);

compiler/rustc_smir/src/rustc_smir/convert/mir.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -628,14 +628,15 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
628628
operands,
629629
options,
630630
line_spans,
631-
destination,
631+
targets,
632632
unwind,
633633
} => TerminatorKind::InlineAsm {
634634
template: format!("{template:?}"),
635635
operands: operands.iter().map(|operand| operand.stable(tables)).collect(),
636636
options: format!("{options:?}"),
637637
line_spans: format!("{line_spans:?}"),
638-
destination: destination.map(|d| d.as_usize()),
638+
// FIXME: Figure out how to do labels in SMIR
639+
destination: targets.first().map(|d| d.as_usize()),
639640
unwind: unwind.stable(tables),
640641
},
641642
mir::TerminatorKind::Yield { .. }

0 commit comments

Comments
 (0)