diff options
| author | cynecx <me@cynecx.net> | 2021-09-04 19:25:09 +0200 |
|---|---|---|
| committer | cynecx <me@cynecx.net> | 2021-12-03 23:51:49 +0100 |
| commit | 91021de1f67de546b7ef41e03fc787f03ecf2239 (patch) | |
| tree | 2e809500921ea4bd58327c054b6965579cd74a81 /compiler/rustc_codegen_ssa/src | |
| parent | 491dd1f387e4f0b167e35560a97efc9949304640 (diff) | |
| download | rust-91021de1f67de546b7ef41e03fc787f03ecf2239.tar.gz rust-91021de1f67de546b7ef41e03fc787f03ecf2239.zip | |
LLVM codgen support for unwinding inline assembly
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/analyze.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/block.rs | 62 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/asm.rs | 1 |
3 files changed, 57 insertions, 10 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index c486c19f9c9..0447c02fdec 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -276,9 +276,9 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKi | TerminatorKind::SwitchInt { .. } | TerminatorKind::Yield { .. } | TerminatorKind::FalseEdge { .. } - | TerminatorKind::FalseUnwind { .. } - | TerminatorKind::InlineAsm { .. } => { /* nothing to do */ } + | TerminatorKind::FalseUnwind { .. } => { /* nothing to do */ } TerminatorKind::Call { cleanup: unwind, .. } + | TerminatorKind::InlineAsm { cleanup: unwind, .. } | TerminatorKind::Assert { cleanup: unwind, .. } | TerminatorKind::DropAndReplace { unwind, .. } | TerminatorKind::Drop { unwind, .. } => { diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 495fe13f18c..e914e493269 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -10,6 +10,7 @@ use crate::traits::*; use crate::MemFlags; use rustc_ast as ast; +use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir::lang_items::LangItem; use rustc_index::vec::Idx; use rustc_middle::mir::AssertKind; @@ -174,6 +175,45 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { } } } + + /// Generates inline assembly with optional `destination` and `cleanup`. + fn do_inlineasm<Bx: BuilderMethods<'a, 'tcx>>( + &self, + fx: &mut FunctionCx<'a, 'tcx, Bx>, + bx: &mut Bx, + template: &[InlineAsmTemplatePiece], + operands: &[InlineAsmOperandRef<'tcx, Bx>], + options: InlineAsmOptions, + line_spans: &[Span], + destination: Option<mir::BasicBlock>, + cleanup: Option<mir::BasicBlock>, + instance: Instance<'_>, + ) { + if let Some(cleanup) = cleanup { + let ret_llbb = if let Some(target) = destination { + fx.llbb(target) + } else { + fx.unreachable_block() + }; + + bx.codegen_inline_asm( + template, + &operands, + options, + line_spans, + instance, + Some((ret_llbb, self.llblock(fx, cleanup), self.funclet(fx))), + ); + } else { + bx.codegen_inline_asm(template, &operands, options, line_spans, instance, None); + + if let Some(target) = destination { + self.funclet_br(fx, bx, target); + } else { + bx.unreachable(); + } + } + } } /// Codegen implementations for some terminator variants. @@ -877,6 +917,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { options: ast::InlineAsmOptions, line_spans: &[Span], destination: Option<mir::BasicBlock>, + cleanup: Option<mir::BasicBlock>, instance: Instance<'_>, ) { let span = terminator.source_info.span; @@ -931,13 +972,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }) .collect(); - bx.codegen_inline_asm(template, &operands, options, line_spans, instance); - - if let Some(target) = destination { - helper.funclet_br(self, &mut bx, target); - } else { - bx.unreachable(); - } + helper.do_inlineasm( + self, + &mut bx, + template, + &operands, + options, + line_spans, + destination, + cleanup, + instance, + ); } } @@ -1041,7 +1086,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { options, line_spans, destination, - cleanup: _, // TODO + cleanup, } => { self.codegen_asm_terminator( helper, @@ -1052,6 +1097,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { options, line_spans, destination, + cleanup, self.instance, ); } diff --git a/compiler/rustc_codegen_ssa/src/traits/asm.rs b/compiler/rustc_codegen_ssa/src/traits/asm.rs index 31f539e1b03..65f3c754d2d 100644 --- a/compiler/rustc_codegen_ssa/src/traits/asm.rs +++ b/compiler/rustc_codegen_ssa/src/traits/asm.rs @@ -59,6 +59,7 @@ pub trait AsmBuilderMethods<'tcx>: BackendTypes { options: InlineAsmOptions, line_spans: &[Span], instance: Instance<'_>, + dest_catch_funclet: Option<(Self::BasicBlock, Self::BasicBlock, Option<&Self::Funclet>)>, ); } |
