forked from M-Labs/artiq
compiler: generate appropriate landingpad IR
When used together with modified personality function, we got ~20% performance improvement in exception unwinding with zynq.
This commit is contained in:
parent
5e1847e7c1
commit
9f90088fa6
@ -1347,6 +1347,7 @@ class LandingPad(Terminator):
|
||||
def __init__(self, cleanup, name=""):
|
||||
super().__init__([cleanup], builtins.TException(), name)
|
||||
self.types = []
|
||||
self.has_cleanup = True
|
||||
|
||||
def copy(self, mapper):
|
||||
self_copy = super().copy(mapper)
|
||||
|
@ -718,6 +718,8 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
||||
|
||||
cleanup = self.add_block('handler.cleanup')
|
||||
landingpad = dispatcher.append(ir.LandingPad(cleanup))
|
||||
if not any(node.finalbody):
|
||||
landingpad.has_cleanup = False
|
||||
|
||||
handlers = []
|
||||
for handler_node in node.handlers:
|
||||
|
@ -1722,7 +1722,8 @@ class LLVMIRGenerator:
|
||||
def process_LandingPad(self, insn):
|
||||
# Layout on return from landing pad: {%_Unwind_Exception*, %Exception*}
|
||||
lllandingpadty = ll.LiteralStructType([llptr, llptr])
|
||||
lllandingpad = self.llbuilder.landingpad(lllandingpadty, cleanup=True)
|
||||
lllandingpad = self.llbuilder.landingpad(lllandingpadty,
|
||||
cleanup=insn.has_cleanup)
|
||||
llrawexn = self.llbuilder.extract_value(lllandingpad, 1)
|
||||
llexn = self.llbuilder.bitcast(llrawexn, self.llty_of_type(insn.type))
|
||||
llexnnameptr = self.llbuilder.gep(llexn, [self.llindex(0), self.llindex(0)],
|
||||
@ -1731,7 +1732,16 @@ class LLVMIRGenerator:
|
||||
|
||||
for target, typ in insn.clauses():
|
||||
if typ is None:
|
||||
exnname = "" # see the comment in ksupport/eh.rs
|
||||
# we use a null pointer here, similar to how cpp does it
|
||||
# https://llvm.org/docs/ExceptionHandling.html#try-catch
|
||||
# > If @ExcType is null, any exception matches, so the
|
||||
# landingpad should always be entered. This is used for C++
|
||||
# catch-all blocks (“catch (...)”).
|
||||
lllandingpad.add_clause(
|
||||
ll.CatchClause(
|
||||
ll.Constant(lli32, 0).inttoptr(llptr)
|
||||
)
|
||||
)
|
||||
else:
|
||||
exnname = "{}:{}".format(typ.id, typ.name)
|
||||
|
||||
@ -1748,6 +1758,8 @@ class LLVMIRGenerator:
|
||||
lllandingpad.add_clause(ll.CatchClause(llclauseexnnameptr))
|
||||
|
||||
if typ is None:
|
||||
# typ is None means that we match all exceptions, so no need to
|
||||
# compare
|
||||
self.llbuilder.branch(self.map(target))
|
||||
else:
|
||||
llexnlen = self.llbuilder.extract_value(llexnname, 1)
|
||||
@ -1764,6 +1776,9 @@ class LLVMIRGenerator:
|
||||
self.llbuilder.branch(self.map(target))
|
||||
|
||||
if self.llbuilder.basic_block.terminator is None:
|
||||
if insn.has_cleanup:
|
||||
self.llbuilder.branch(self.map(insn.cleanup()))
|
||||
else:
|
||||
self.llbuilder.resume(lllandingpad)
|
||||
|
||||
return llexn
|
||||
|
Loading…
Reference in New Issue
Block a user