1
Fork 0

Change InlineAsm to allow multiple targets instead

This commit is contained in:
Gary Guo 2023-12-26 15:28:42 +00:00
parent 7152993aa8
commit b044aaa905
23 changed files with 125 additions and 96 deletions

View file

@ -1718,13 +1718,13 @@ mod size_asserts {
use super::*;
use rustc_data_structures::static_assert_size;
// tidy-alphabetical-start
static_assert_size!(BasicBlockData<'_>, 136);
static_assert_size!(BasicBlockData<'_>, 144);
static_assert_size!(LocalDecl<'_>, 40);
static_assert_size!(SourceScopeData<'_>, 72);
static_assert_size!(Statement<'_>, 32);
static_assert_size!(StatementKind<'_>, 16);
static_assert_size!(Terminator<'_>, 104);
static_assert_size!(TerminatorKind<'_>, 88);
static_assert_size!(Terminator<'_>, 112);
static_assert_size!(TerminatorKind<'_>, 96);
static_assert_size!(VarDebugInfo<'_>, 88);
// tidy-alphabetical-end
}

View file

@ -7,7 +7,7 @@ use std::path::{Path, PathBuf};
use crate::mir::interpret::ConstAllocation;
use super::graphviz::write_mir_fn_graphviz;
use rustc_ast::InlineAsmTemplatePiece;
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_middle::mir::interpret::{
alloc_range, read_target_uint, AllocBytes, AllocId, Allocation, GlobalAlloc, Pointer,
Provenance,
@ -868,16 +868,19 @@ impl<'tcx> TerminatorKind<'tcx> {
vec!["real".into(), "unwind".into()]
}
FalseUnwind { unwind: _, .. } => vec!["real".into()],
InlineAsm { destination: Some(_), unwind: UnwindAction::Cleanup(_), .. } => {
vec!["return".into(), "unwind".into()]
InlineAsm { options, ref targets, unwind, .. } => {
let mut vec = Vec::with_capacity(targets.len() + 1);
if !options.contains(InlineAsmOptions::NORETURN) {
vec.push("return".into());
}
vec.resize(targets.len(), "label".into());
if let UnwindAction::Cleanup(_) = unwind {
vec.push("unwind".into());
}
vec
}
InlineAsm { destination: Some(_), unwind: _, .. } => {
vec!["return".into()]
}
InlineAsm { destination: None, unwind: UnwindAction::Cleanup(_), .. } => {
vec!["unwind".into()]
}
InlineAsm { destination: None, unwind: _, .. } => vec![],
}
}
}

View file

@ -793,9 +793,10 @@ pub enum TerminatorKind<'tcx> {
/// used to map assembler errors back to the line in the source code.
line_spans: &'tcx [Span],
/// Destination block after the inline assembly returns, unless it is
/// diverging (InlineAsmOptions::NORETURN).
destination: Option<BasicBlock>,
/// Valid targets for the inline assembly.
/// The first element is the fallthrough destination, unless
/// InlineAsmOptions::NORETURN is set.
targets: Vec<BasicBlock>,
/// Action to be taken if the inline assembly unwinds. This is present
/// if and only if InlineAsmOptions::MAY_UNWIND is set.

View file

@ -374,8 +374,7 @@ impl<'tcx> TerminatorKind<'tcx> {
| Yield { resume: ref t, drop: Some(u), .. }
| Drop { target: ref t, unwind: UnwindAction::Cleanup(u), .. }
| Assert { target: ref t, unwind: UnwindAction::Cleanup(u), .. }
| FalseUnwind { real_target: ref t, unwind: UnwindAction::Cleanup(u) }
| InlineAsm { destination: Some(ref t), unwind: UnwindAction::Cleanup(u), .. } => {
| FalseUnwind { real_target: ref t, unwind: UnwindAction::Cleanup(u) } => {
slice::from_ref(t).into_iter().copied().chain(Some(u))
}
Goto { target: ref t }
@ -384,9 +383,7 @@ impl<'tcx> TerminatorKind<'tcx> {
| Yield { resume: ref t, drop: None, .. }
| Drop { target: ref t, unwind: _, .. }
| Assert { target: ref t, unwind: _, .. }
| FalseUnwind { real_target: ref t, unwind: _ }
| InlineAsm { destination: None, unwind: UnwindAction::Cleanup(ref t), .. }
| InlineAsm { destination: Some(ref t), unwind: _, .. } => {
| FalseUnwind { real_target: ref t, unwind: _ } => {
slice::from_ref(t).into_iter().copied().chain(None)
}
UnwindResume
@ -394,10 +391,11 @@ impl<'tcx> TerminatorKind<'tcx> {
| CoroutineDrop
| Return
| Unreachable
| Call { target: None, unwind: _, .. }
| InlineAsm { destination: None, unwind: _, .. } => {
(&[]).into_iter().copied().chain(None)
| Call { target: None, unwind: _, .. } => (&[]).into_iter().copied().chain(None),
InlineAsm { ref targets, unwind: UnwindAction::Cleanup(u), .. } => {
targets.iter().copied().chain(Some(u))
}
InlineAsm { ref targets, unwind: _, .. } => targets.iter().copied().chain(None),
SwitchInt { ref targets, .. } => targets.targets.iter().copied().chain(None),
FalseEdge { ref real_target, imaginary_target } => {
slice::from_ref(real_target).into_iter().copied().chain(Some(imaginary_target))
@ -413,21 +411,16 @@ impl<'tcx> TerminatorKind<'tcx> {
| Yield { resume: ref mut t, drop: Some(ref mut u), .. }
| Drop { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. }
| Assert { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. }
| FalseUnwind { real_target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u) }
| InlineAsm {
destination: Some(ref mut t),
unwind: UnwindAction::Cleanup(ref mut u),
..
} => slice::from_mut(t).into_iter().chain(Some(u)),
| FalseUnwind { real_target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u) } => {
slice::from_mut(t).into_iter().chain(Some(u))
}
Goto { target: ref mut t }
| Call { target: None, unwind: UnwindAction::Cleanup(ref mut t), .. }
| Call { target: Some(ref mut t), unwind: _, .. }
| Yield { resume: ref mut t, drop: None, .. }
| Drop { target: ref mut t, unwind: _, .. }
| Assert { target: ref mut t, unwind: _, .. }
| FalseUnwind { real_target: ref mut t, unwind: _ }
| InlineAsm { destination: None, unwind: UnwindAction::Cleanup(ref mut t), .. }
| InlineAsm { destination: Some(ref mut t), unwind: _, .. } => {
| FalseUnwind { real_target: ref mut t, unwind: _ } => {
slice::from_mut(t).into_iter().chain(None)
}
UnwindResume
@ -435,8 +428,11 @@ impl<'tcx> TerminatorKind<'tcx> {
| CoroutineDrop
| Return
| Unreachable
| Call { target: None, unwind: _, .. }
| InlineAsm { destination: None, unwind: _, .. } => (&mut []).into_iter().chain(None),
| Call { target: None, unwind: _, .. } => (&mut []).into_iter().chain(None),
InlineAsm { ref mut targets, unwind: UnwindAction::Cleanup(ref mut u), .. } => {
targets.iter_mut().chain(Some(u))
}
InlineAsm { ref mut targets, unwind: _, .. } => targets.iter_mut().chain(None),
SwitchInt { ref mut targets, .. } => targets.targets.iter_mut().chain(None),
FalseEdge { ref mut real_target, ref mut imaginary_target } => {
slice::from_mut(real_target).into_iter().chain(Some(imaginary_target))
@ -511,7 +507,7 @@ pub enum TerminatorEdges<'mir, 'tcx> {
Double(BasicBlock, BasicBlock),
/// Special action for `Yield`, `Call` and `InlineAsm` terminators.
AssignOnReturn {
return_: Option<BasicBlock>,
return_: &'mir [BasicBlock],
/// The cleanup block, if it exists.
cleanup: Option<BasicBlock>,
place: CallReturnPlaces<'mir, 'tcx>,
@ -575,31 +571,37 @@ impl<'tcx> TerminatorKind<'tcx> {
TerminatorEdges::Double(real_target, imaginary_target)
}
Yield { resume: target, drop, resume_arg, value: _ } => {
Yield { resume: ref target, drop, resume_arg, value: _ } => {
TerminatorEdges::AssignOnReturn {
return_: Some(target),
return_: slice::from_ref(target),
cleanup: drop,
place: CallReturnPlaces::Yield(resume_arg),
}
}
Call { unwind, destination, target, func: _, args: _, fn_span: _, call_source: _ } => {
TerminatorEdges::AssignOnReturn {
return_: target,
cleanup: unwind.cleanup_block(),
place: CallReturnPlaces::Call(destination),
}
}
Call {
unwind,
destination,
ref target,
func: _,
args: _,
fn_span: _,
call_source: _,
} => TerminatorEdges::AssignOnReturn {
return_: target.as_ref().map(slice::from_ref).unwrap_or_default(),
cleanup: unwind.cleanup_block(),
place: CallReturnPlaces::Call(destination),
},
InlineAsm {
template: _,
ref operands,
options: _,
line_spans: _,
destination,
ref targets,
unwind,
} => TerminatorEdges::AssignOnReturn {
return_: destination,
return_: targets,
cleanup: unwind.cleanup_block(),
place: CallReturnPlaces::InlineAsm(operands),
},

View file

@ -565,7 +565,7 @@ macro_rules! make_mir_visitor {
operands,
options: _,
line_spans: _,
destination: _,
targets: _,
unwind: _,
} => {
for op in operands {