Rollup merge of #93261 - bjorn3:cg_ssa_refactor6, r=cjgillot
Some unwinding related cg_ssa cleanups These should make it a bit easier for alternative codegen backends to implement unwinding.
This commit is contained in:
commit
ada77e94ab
5 changed files with 63 additions and 75 deletions
|
@ -956,29 +956,24 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
unsafe { llvm::LLVMBuildInsertValue(self.llbuilder, agg_val, elt, idx as c_uint, UNNAMED) }
|
||||
}
|
||||
|
||||
fn landing_pad(
|
||||
&mut self,
|
||||
ty: &'ll Type,
|
||||
pers_fn: &'ll Value,
|
||||
num_clauses: usize,
|
||||
) -> &'ll Value {
|
||||
// Use LLVMSetPersonalityFn to set the personality. It supports arbitrary Consts while,
|
||||
// LLVMBuildLandingPad requires the argument to be a Function (as of LLVM 12). The
|
||||
// personality lives on the parent function anyway.
|
||||
self.set_personality_fn(pers_fn);
|
||||
fn set_personality_fn(&mut self, personality: &'ll Value) {
|
||||
unsafe {
|
||||
llvm::LLVMBuildLandingPad(self.llbuilder, ty, None, num_clauses as c_uint, UNNAMED)
|
||||
llvm::LLVMSetPersonalityFn(self.llfn(), personality);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_cleanup(&mut self, landing_pad: &'ll Value) {
|
||||
fn cleanup_landing_pad(&mut self, ty: &'ll Type, pers_fn: &'ll Value) -> &'ll Value {
|
||||
let landing_pad = self.landing_pad(ty, pers_fn, 1 /* FIXME should this be 0? */);
|
||||
unsafe {
|
||||
llvm::LLVMSetCleanup(landing_pad, llvm::True);
|
||||
}
|
||||
landing_pad
|
||||
}
|
||||
|
||||
fn resume(&mut self, exn: &'ll Value) -> &'ll Value {
|
||||
unsafe { llvm::LLVMBuildResume(self.llbuilder, exn) }
|
||||
fn resume(&mut self, exn: &'ll Value) {
|
||||
unsafe {
|
||||
llvm::LLVMBuildResume(self.llbuilder, exn);
|
||||
}
|
||||
}
|
||||
|
||||
fn cleanup_pad(&mut self, parent: Option<&'ll Value>, args: &[&'ll Value]) -> Funclet<'ll> {
|
||||
|
@ -995,14 +990,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
Funclet::new(ret.expect("LLVM does not have support for cleanuppad"))
|
||||
}
|
||||
|
||||
fn cleanup_ret(
|
||||
&mut self,
|
||||
funclet: &Funclet<'ll>,
|
||||
unwind: Option<&'ll BasicBlock>,
|
||||
) -> &'ll Value {
|
||||
let ret =
|
||||
unsafe { llvm::LLVMRustBuildCleanupRet(self.llbuilder, funclet.cleanuppad(), unwind) };
|
||||
ret.expect("LLVM does not have support for cleanupret")
|
||||
fn cleanup_ret(&mut self, funclet: &Funclet<'ll>, unwind: Option<&'ll BasicBlock>) {
|
||||
unsafe {
|
||||
llvm::LLVMRustBuildCleanupRet(self.llbuilder, funclet.cleanuppad(), unwind)
|
||||
.expect("LLVM does not have support for cleanupret");
|
||||
}
|
||||
}
|
||||
|
||||
fn catch_pad(&mut self, parent: &'ll Value, args: &[&'ll Value]) -> Funclet<'ll> {
|
||||
|
@ -1023,7 +1015,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
&mut self,
|
||||
parent: Option<&'ll Value>,
|
||||
unwind: Option<&'ll BasicBlock>,
|
||||
num_handlers: usize,
|
||||
handlers: &[&'ll BasicBlock],
|
||||
) -> &'ll Value {
|
||||
let name = cstr!("catchswitch");
|
||||
let ret = unsafe {
|
||||
|
@ -1031,23 +1023,17 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
self.llbuilder,
|
||||
parent,
|
||||
unwind,
|
||||
num_handlers as c_uint,
|
||||
handlers.len() as c_uint,
|
||||
name.as_ptr(),
|
||||
)
|
||||
};
|
||||
ret.expect("LLVM does not have support for catchswitch")
|
||||
}
|
||||
|
||||
fn add_handler(&mut self, catch_switch: &'ll Value, handler: &'ll BasicBlock) {
|
||||
unsafe {
|
||||
llvm::LLVMRustAddHandler(catch_switch, handler);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_personality_fn(&mut self, personality: &'ll Value) {
|
||||
unsafe {
|
||||
llvm::LLVMSetPersonalityFn(self.llfn(), personality);
|
||||
let ret = ret.expect("LLVM does not have support for catchswitch");
|
||||
for handler in handlers {
|
||||
unsafe {
|
||||
llvm::LLVMRustAddHandler(ret, handler);
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
// Atomic Operations
|
||||
|
@ -1478,4 +1464,19 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn landing_pad(
|
||||
&mut self,
|
||||
ty: &'ll Type,
|
||||
pers_fn: &'ll Value,
|
||||
num_clauses: usize,
|
||||
) -> &'ll Value {
|
||||
// Use LLVMSetPersonalityFn to set the personality. It supports arbitrary Consts while,
|
||||
// LLVMBuildLandingPad requires the argument to be a Function (as of LLVM 12). The
|
||||
// personality lives on the parent function anyway.
|
||||
self.set_personality_fn(pers_fn);
|
||||
unsafe {
|
||||
llvm::LLVMBuildLandingPad(self.llbuilder, ty, None, num_clauses as c_uint, UNNAMED)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -525,9 +525,8 @@ fn codegen_msvc_try<'ll>(
|
|||
|
||||
normal.ret(bx.const_i32(0));
|
||||
|
||||
let cs = catchswitch.catch_switch(None, None, 2);
|
||||
catchswitch.add_handler(cs, catchpad_rust.llbb());
|
||||
catchswitch.add_handler(cs, catchpad_foreign.llbb());
|
||||
let cs =
|
||||
catchswitch.catch_switch(None, None, &[catchpad_rust.llbb(), catchpad_foreign.llbb()]);
|
||||
|
||||
// We can't use the TypeDescriptor defined in libpanic_unwind because it
|
||||
// might be in another DLL and the SEH encoding only supports specifying
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue