Improve usage of lifetime intrinsics in match expressions
The allocas used in match expression currently don't get good lifetime markers, in fact they only get lifetime start markers, because their lifetimes don't match to cleanup scopes. While the bindings themselves are bog standard and just need a matching pair of start and end markers, they might need them twice, once for a guard clause and once for the match body. The __llmatch alloca OTOH needs a single lifetime start marker, but when there's a guard clause, it needs two end markers, because its lifetime ends either when the guard doesn't match or after the match body. With these intrinsics in place, LLVM can now, for example, optimize code like this: ````rust enum E { A1(int), A2(int), A3(int), A4(int), } pub fn variants(x: E) { match x { A1(m) => bar(&m), A2(m) => bar(&m), A3(m) => bar(&m), A4(m) => bar(&m), } } ```` To a single call to bar, using only a single stack slot. It still fails to eliminate some of checks. ````gas .Ltmp5: .cfi_def_cfa_offset 16 movb (%rdi), %al testb %al, %al je .LBB3_5 movzbl %al, %eax cmpl $1, %eax je .LBB3_5 cmpl $2, %eax .LBB3_5: movq 8(%rdi), %rax movq %rax, (%rsp) leaq (%rsp), %rdi callq _ZN3bar20hcb7a0d8be8e17e37daaE@PLT popq %rax retq ````
Showing
想要评论请 注册 或 登录