llvm.org GIT mirror llvm / ba9e1e6
Win64: Don't emit unwind info for "leaf" functions (PR30337) According to MSDN (see the PR), functions which don't touch any callee-saved registers (including %rsp) don't need any unwind info. This patch makes LLVM not emit unwind info for such functions, to save binary size. Differential Revision: https://reviews.llvm.org/D24748 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282185 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 4 years ago
9 changed file(s) with 69 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
1919
2020 #include "llvm/ADT/BitVector.h"
2121 #include "llvm/ADT/ilist.h"
22 #include "llvm/ADT/Optional.h"
2223 #include "llvm/CodeGen/MachineBasicBlock.h"
2324 #include "llvm/CodeGen/MachineMemOperand.h"
2425 #include "llvm/IR/DebugLoc.h"
233234 /// True if the function includes any inline assembly.
234235 bool HasInlineAsm = false;
235236
237 /// True if any WinCFI instruction have been emitted in this function.
238 Optional HasWinCFI;
239
236240 /// Current high-level properties of the IR of the function (e.g. is in SSA
237241 /// form or whether registers have been allocated)
238242 MachineFunctionProperties Properties;
371375 HasInlineAsm = B;
372376 }
373377
378 bool hasWinCFI() const {
379 assert(HasWinCFI.hasValue() && "HasWinCFI not set yet!");
380 return *HasWinCFI;
381 }
382 void setHasWinCFI(bool v) { HasWinCFI = v; }
383
374384 /// Get the function properties
375385 const MachineFunctionProperties &getProperties() const { return Properties; }
376386 MachineFunctionProperties &getProperties() { return Properties; }
8989
9090 // If we're not using CFI, we don't want the CFI or the personality, but we
9191 // might want EH tables if we had EH pads.
92 if (!Asm->MAI->usesWindowsCFI()) {
92 if (!Asm->MAI->usesWindowsCFI() || (!MF->hasWinCFI() && !Per)) {
9393 shouldEmitLSDA = hasEHFunclets;
9494 shouldEmitPersonality = false;
9595 return;
934934 STI.isTarget64BitILP32()
935935 ? getX86SubSuperRegister(FramePtr, 64) : FramePtr;
936936 unsigned BasePtr = TRI->getBaseRegister();
937 bool HasWinCFI = false;
937938
938939 // Debug location must be unknown since the first debug location is used
939940 // to determine the end of the prologue.
10621063 }
10631064
10641065 if (NeedsWinCFI) {
1066 HasWinCFI = true;
10651067 BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_PushReg))
10661068 .addImm(FramePtr)
10671069 .setMIFlag(MachineInstr::FrameSetup);
11231125 }
11241126
11251127 if (NeedsWinCFI) {
1128 HasWinCFI = true;
11261129 BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_PushReg)).addImm(Reg).setMIFlag(
11271130 MachineInstr::FrameSetup);
11281131 }
12081211 emitSPUpdate(MBB, MBBI, -(int64_t)NumBytes, /*InEpilogue=*/false);
12091212 }
12101213
1211 if (NeedsWinCFI && NumBytes)
1214 if (NeedsWinCFI && NumBytes) {
1215 HasWinCFI = true;
12121216 BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_StackAlloc))
12131217 .addImm(NumBytes)
12141218 .setMIFlag(MachineInstr::FrameSetup);
1219 }
12151220
12161221 int SEHFrameOffset = 0;
12171222 unsigned SPOrEstablisher;
12581263
12591264 // If this is not a funclet, emit the CFI describing our frame pointer.
12601265 if (NeedsWinCFI && !IsFunclet) {
1266 HasWinCFI = true;
12611267 BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_SetFrame))
12621268 .addImm(FramePtr)
12631269 .addImm(SEHFrameOffset)
12941300 int Offset = getFrameIndexReference(MF, FI, IgnoredFrameReg);
12951301 Offset += SEHFrameOffset;
12961302
1303 HasWinCFI = true;
12971304 BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_SaveXMM))
12981305 .addImm(Reg)
12991306 .addImm(Offset)
13031310 }
13041311 }
13051312
1306 if (NeedsWinCFI)
1313 if (NeedsWinCFI && HasWinCFI)
13071314 BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_EndPrologue))
13081315 .setMIFlag(MachineInstr::FrameSetup);
13091316
13951402 if (Fn->getCallingConv() == CallingConv::X86_INTR)
13961403 BuildMI(MBB, MBBI, DL, TII.get(X86::CLD))
13971404 .setMIFlag(MachineInstr::FrameSetup);
1405
1406 // At this point we know if the function has WinCFI or not.
1407 MF.setHasWinCFI(HasWinCFI);
13981408 }
13991409
14001410 bool X86FrameLowering::canUseLEAForSPInEpilogue(
16291639 // into the epilogue. To cope with that, we insert an epilogue marker here,
16301640 // then replace it with a 'nop' if it ends up immediately after a CALL in the
16311641 // final emitted code.
1632 if (NeedsWinCFI)
1642 if (NeedsWinCFI && MF.hasWinCFI())
16331643 BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_Epilogue));
16341644
16351645 if (!RetOpcode || !isTailCallOpcode(*RetOpcode)) {
14191419 return;
14201420
14211421 case X86::SEH_PushReg:
1422 assert(MF->hasWinCFI() && "SEH_ instruction in function without WinCFI?");
14221423 OutStreamer->EmitWinCFIPushReg(RI->getSEHRegNum(MI->getOperand(0).getImm()));
14231424 return;
14241425
14251426 case X86::SEH_SaveReg:
1427 assert(MF->hasWinCFI() && "SEH_ instruction in function without WinCFI?");
14261428 OutStreamer->EmitWinCFISaveReg(RI->getSEHRegNum(MI->getOperand(0).getImm()),
14271429 MI->getOperand(1).getImm());
14281430 return;
14291431
14301432 case X86::SEH_SaveXMM:
1433 assert(MF->hasWinCFI() && "SEH_ instruction in function without WinCFI?");
14311434 OutStreamer->EmitWinCFISaveXMM(RI->getSEHRegNum(MI->getOperand(0).getImm()),
14321435 MI->getOperand(1).getImm());
14331436 return;
14341437
14351438 case X86::SEH_StackAlloc:
1439 assert(MF->hasWinCFI() && "SEH_ instruction in function without WinCFI?");
14361440 OutStreamer->EmitWinCFIAllocStack(MI->getOperand(0).getImm());
14371441 return;
14381442
14391443 case X86::SEH_SetFrame:
1444 assert(MF->hasWinCFI() && "SEH_ instruction in function without WinCFI?");
14401445 OutStreamer->EmitWinCFISetFrame(RI->getSEHRegNum(MI->getOperand(0).getImm()),
14411446 MI->getOperand(1).getImm());
14421447 return;
14431448
14441449 case X86::SEH_PushFrame:
1450 assert(MF->hasWinCFI() && "SEH_ instruction in function without WinCFI?");
14451451 OutStreamer->EmitWinCFIPushFrame(MI->getOperand(0).getImm());
14461452 return;
14471453
14481454 case X86::SEH_EndPrologue:
1455 assert(MF->hasWinCFI() && "SEH_ instruction in function without WinCFI?");
14491456 OutStreamer->EmitWinCFIEndProlog();
14501457 return;
14511458
14521459 case X86::SEH_Epilogue: {
1460 assert(MF->hasWinCFI() && "SEH_ instruction in function without WinCFI?");
14531461 MachineBasicBlock::const_iterator MBBI(MI);
14541462 // Check if preceded by a call and emit nop if so.
14551463 for (MBBI = PrevCrossBBInst(MBBI);
1010 }
1111
1212 ; CHECK-LABEL: test1{{$}}
13 ; CHECK: .seh_proc test1{{$}}
13 ; CHECK-NOT: .seh_proc test1
1414 ; CHECK: rex64 jmpq *fnptr(%rip)
15 ; CHECK: .seh_endproc
15 ; CHECK-NOT: .seh_endproc
3030 unreachable
3131 }
3232 ; CHECK-LABEL: g:
33 ; CHECK: .seh_proc g
34 ; CHECK: .seh_endproc
33 ; CHECK: ud2
3534
3635 attributes #0 = { nounwind }
170170 }
171171
172172 ; CHECK: "?filt$0@0@main@@": # @"\01?filt$0@0@main@@"
173 ; CHECK: .seh_proc "?filt$0@0@main@@"
174 ; CHECK: .seh_endprologue
175173 ; CHECK: jmp filt # TAILCALL
176 ; CHECK: .seh_handlerdata
177174
178175 declare i32 @filt() #1
179176
77 ret void
88 }
99 ; WIN64-LABEL: foo0:
10 ; WIN64: .seh_proc foo0
11 ; WIN64: .seh_endprologue
10 ; WIN64-NOT: .seh_proc foo0
11 ; WIN64-NOT: .seh_endprologue
1212 ; WIN64: ret
13 ; WIN64: .seh_endproc
13 ; WIN64-NOT: .seh_endproc
1414
1515 ; Checks a small stack allocation
1616 define void @foo1() uwtable {
0 ; RUN: llc < %s -O1 -mtriple=x86_64-pc-win32 | FileCheck %s -check-prefix=ASM
1 ; RUN: llc < %s -O1 -mtriple=x86_64-pc-win32 -filetype=obj -o %t
2 ; RUN: llvm-readobj -unwind %t | FileCheck %s -check-prefix=READOBJ
3
4 declare void @g(i32)
5
6 define i32 @not_leaf(i32) uwtable {
7 entry:
8 call void @g(i32 42)
9 ret i32 42
10
11 ; ASM-LABEL: not_leaf:
12 ; ASM: .seh
13
14 ; READOBJ: RuntimeFunction {
15 ; READOBJ-NEXT: StartAddress: not_leaf
16 ; READOBJ-NEXT: EndAddress: not_leaf
17 }
18
19 define void @leaf_func(i32) uwtable {
20 entry:
21 tail call void @g(i32 42)
22 ret void
23
24 ; A Win64 "leaf" function gets no .seh directives in the asm.
25 ; ASM-LABEL: leaf_func:
26 ; ASM-NOT: .seh
27
28 ; and no unwind info in the object file.
29 ; READOBJ-NOT: leaf_func
30 }