llvm.org GIT mirror llvm / 5b05711
Merging r227519: ------------------------------------------------------------------------ r227519 | reid | 2015-01-29 18:58:04 -0500 (Thu, 29 Jan 2015) | 10 lines x86: Fix large model calls to __chkstk for dynamic allocas In the large code model, we now put __chkstk in %r11 before calling it. Refactor the code so that we only do this once. Simplify things by using __chkstk_ms instead of __chkstk on cygming. We already use that symbol in the prolog emission, and it simplifies our logic. Second half of PR18582. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_36@236378 91177308-0d34-0410-b5e6-96231b3b80d8 Tom Stellard 4 years ago
5 changed file(s) with 85 addition(s) and 88 deletion(s). Raw diff Collapse all Expand all
374374 return false;
375375 }
376376
377 void X86FrameLowering::getStackProbeFunction(const MachineFunction &MF,
378 const X86Subtarget &STI,
379 unsigned &CallOp,
380 const char *&Symbol) {
381 if (STI.is64Bit())
382 CallOp = MF.getTarget().getCodeModel() == CodeModel::Large
383 ? X86::CALL64r
384 : X86::W64ALLOCA;
377 void X86FrameLowering::emitStackProbeCall(MachineFunction &MF,
378 MachineBasicBlock &MBB,
379 MachineBasicBlock::iterator MBBI,
380 DebugLoc DL) {
381 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
382 const X86Subtarget &STI = MF.getTarget().getSubtarget();
383 bool Is64Bit = STI.is64Bit();
384 bool IsLargeCodeModel = MF.getTarget().getCodeModel() == CodeModel::Large;
385 const X86RegisterInfo *RegInfo =
386 static_cast(MF.getSubtarget().getRegisterInfo());
387
388 unsigned CallOp;
389 if (Is64Bit)
390 CallOp = IsLargeCodeModel ? X86::CALL64r : X86::CALL64pcrel32;
385391 else
386392 CallOp = X86::CALLpcrel32;
387393
388 if (STI.is64Bit()) {
394 const char *Symbol;
395 if (Is64Bit) {
389396 if (STI.isTargetCygMing()) {
390397 Symbol = "___chkstk_ms";
391398 } else {
395402 Symbol = "_alloca";
396403 else
397404 Symbol = "_chkstk";
405
406 MachineInstrBuilder CI;
407
408 // All current stack probes take AX and SP as input, clobber flags, and
409 // preserve all registers. x86_64 probes leave RSP unmodified.
410 if (Is64Bit && MF.getTarget().getCodeModel() == CodeModel::Large) {
411 // For the large code model, we have to call through a register. Use R11,
412 // as it is scratch in all supported calling conventions.
413 BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64ri), X86::R11)
414 .addExternalSymbol(Symbol);
415 CI = BuildMI(MBB, MBBI, DL, TII.get(CallOp)).addReg(X86::R11);
416 } else {
417 CI = BuildMI(MBB, MBBI, DL, TII.get(CallOp)).addExternalSymbol(Symbol);
418 }
419
420 unsigned AX = Is64Bit ? X86::RAX : X86::EAX;
421 unsigned SP = Is64Bit ? X86::RSP : X86::ESP;
422 CI.addReg(AX, RegState::Implicit)
423 .addReg(SP, RegState::Implicit)
424 .addReg(AX, RegState::Define | RegState::Implicit)
425 .addReg(SP, RegState::Define | RegState::Implicit)
426 .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit);
427
428 if (Is64Bit) {
429 // MSVC x64's __chkstk and cygwin/mingw's ___chkstk_ms do not adjust %rsp
430 // themselves. It also does not clobber %rax so we can reuse it when
431 // adjusting %rsp.
432 BuildMI(MBB, MBBI, DL, TII.get(X86::SUB64rr), X86::RSP)
433 .addReg(X86::RSP)
434 .addReg(X86::RAX);
435 }
398436 }
399437
400438 /// emitPrologue - Push callee-saved registers onto the stack, which
727765 // increments is necessary to ensure that the guard pages used by the OS
728766 // virtual memory manager are allocated in correct sequence.
729767 if (NumBytes >= StackProbeSize && UseStackProbe) {
730 const char *StackProbeSymbol;
731 unsigned CallOp;
732
733 getStackProbeFunction(MF, STI, CallOp, StackProbeSymbol);
734
735768 // Check whether EAX is livein for this function.
736769 bool isEAXAlive = isEAXLiveIn(MF);
737770
760793 .setMIFlag(MachineInstr::FrameSetup);
761794 }
762795
763 if (Is64Bit && MF.getTarget().getCodeModel() == CodeModel::Large) {
764 // For the large code model, we have to call through a register. Use R11,
765 // as it is unused and clobbered by all probe functions.
766 BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64ri), X86::R11)
767 .addExternalSymbol(StackProbeSymbol);
768 BuildMI(MBB, MBBI, DL, TII.get(CallOp))
769 .addReg(X86::R11)
770 .addReg(StackPtr, RegState::Define | RegState::Implicit)
771 .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit)
772 .setMIFlag(MachineInstr::FrameSetup);
773 } else {
774 BuildMI(MBB, MBBI, DL, TII.get(CallOp))
775 .addExternalSymbol(StackProbeSymbol)
776 .addReg(StackPtr, RegState::Define | RegState::Implicit)
777 .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit)
778 .setMIFlag(MachineInstr::FrameSetup);
779 }
780
781 if (Is64Bit) {
782 // MSVC x64's __chkstk and cygwin/mingw's ___chkstk_ms do not adjust %rsp
783 // themself. It also does not clobber %rax so we can reuse it when
784 // adjusting %rsp.
785 BuildMI(MBB, MBBI, DL, TII.get(X86::SUB64rr), StackPtr)
786 .addReg(StackPtr)
787 .addReg(X86::RAX)
788 .setMIFlag(MachineInstr::FrameSetup);
789 }
796 // Save a pointer to the MI where we set AX.
797 MachineBasicBlock::iterator SetRAX = MBBI;
798 --SetRAX;
799
800 // Call __chkstk, __chkstk_ms, or __alloca.
801 emitStackProbeCall(MF, MBB, MBBI, DL);
802
803 // Apply the frame setup flag to all inserted instrs.
804 for (; SetRAX != MBBI; ++SetRAX)
805 SetRAX->setFlag(MachineInstr::FrameSetup);
806
790807 if (isEAXAlive) {
791808 // Restore EAX
792809 MachineInstr *MI = addRegOffset(BuildMI(MF, DL, TII.get(X86::MOV32rm),
2626 explicit X86FrameLowering(StackDirection D, unsigned StackAl, int LAO)
2727 : TargetFrameLowering(StackGrowsDown, StackAl, LAO) {}
2828
29 static void getStackProbeFunction(const MachineFunction &MF,
30 const X86Subtarget &STI, unsigned &CallOp,
31 const char *&Symbol);
29 /// Emit a call to the target's stack probe function. This is required for all
30 /// large stack allocations on Windows. The caller is required to materialize
31 /// the number of bytes to probe in RAX/EAX.
32 static void emitStackProbeCall(MachineFunction &MF, MachineBasicBlock &MBB,
33 MachineBasicBlock::iterator MBBI, DebugLoc DL);
3234
3335 void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB,
3436 MachineBasicBlock::iterator MBBI,
1414 #include "X86ISelLowering.h"
1515 #include "Utils/X86ShuffleDecode.h"
1616 #include "X86CallingConv.h"
17 #include "X86FrameLowering.h"
1718 #include "X86InstrBuilder.h"
1819 #include "X86MachineFunctionInfo.h"
1920 #include "X86TargetMachine.h"
2109021091
2109121092 assert(!Subtarget->isTargetMachO());
2109221093
21093 // The lowering is pretty easy: we're just emitting the call to _alloca. The
21094 // non-trivial part is impdef of ESP.
21095
21096 if (Subtarget->isTargetWin64()) {
21097 if (Subtarget->isTargetCygMing()) {
21098 // ___chkstk(Mingw64):
21099 // Clobbers R10, R11, RAX and EFLAGS.
21100 // Updates RSP.
21101 BuildMI(*BB, MI, DL, TII->get(X86::W64ALLOCA))
21102 .addExternalSymbol("___chkstk")
21103 .addReg(X86::RAX, RegState::Implicit)
21104 .addReg(X86::RSP, RegState::Implicit)
21105 .addReg(X86::RAX, RegState::Define | RegState::Implicit)
21106 .addReg(X86::RSP, RegState::Define | RegState::Implicit)
21107 .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit);
21108 } else {
21109 // __chkstk(MSVCRT): does not update stack pointer.
21110 // Clobbers R10, R11 and EFLAGS.
21111 BuildMI(*BB, MI, DL, TII->get(X86::W64ALLOCA))
21112 .addExternalSymbol("__chkstk")
21113 .addReg(X86::RAX, RegState::Implicit)
21114 .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit);
21115 // RAX has the offset to be subtracted from RSP.
21116 BuildMI(*BB, MI, DL, TII->get(X86::SUB64rr), X86::RSP)
21117 .addReg(X86::RSP)
21118 .addReg(X86::RAX);
21119 }
21120 } else {
21121 const char *StackProbeSymbol = (Subtarget->isTargetKnownWindowsMSVC() ||
21122 Subtarget->isTargetWindowsItanium())
21123 ? "_chkstk"
21124 : "_alloca";
21125
21126 BuildMI(*BB, MI, DL, TII->get(X86::CALLpcrel32))
21127 .addExternalSymbol(StackProbeSymbol)
21128 .addReg(X86::EAX, RegState::Implicit)
21129 .addReg(X86::ESP, RegState::Implicit)
21130 .addReg(X86::EAX, RegState::Define | RegState::Implicit)
21131 .addReg(X86::ESP, RegState::Define | RegState::Implicit)
21132 .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit);
21133 }
21094 X86FrameLowering::emitStackProbeCall(*BB->getParent(), *BB, MI, DL);
2113421095
2113521096 MI->eraseFromParent(); // The pseudo instruction is gone now.
2113621097 return BB;
55 declare x86_stdcallcc void @i(i32 %a)
66
77 define void @g() {
8 ; CHECK-LABEL: _g:
89 %b = alloca inalloca %Foo
910 ; CHECK: movl $8, %eax
1011 ; CHECK: calll __chkstk
0 ; RUN: llc < %s -mcpu=generic -enable-misched=false -mtriple=x86_64-mingw32 | FileCheck %s -check-prefix=M64
11 ; RUN: llc < %s -mcpu=generic -enable-misched=false -mtriple=x86_64-win32 | FileCheck %s -check-prefix=W64
2 ; RUN: llc < %s -mcpu=generic -enable-misched=false -mtriple=x86_64-win32 -code-model=large | FileCheck %s -check-prefix=L64
23 ; RUN: llc < %s -mcpu=generic -enable-misched=false -mtriple=x86_64-win32-macho | FileCheck %s -check-prefix=EFI
34 ; PR8777
45 ; PR8778
2324 ; W64: callq __chkstk
2425 ; W64: subq %rax, %rsp
2526
27 ; Use %r11 for the large model.
28 ; L64: movq %rsp, %rbp
29 ; L64: $4096, %rax
30 ; L64: movabsq $__chkstk, %r11
31 ; L64: callq *%r11
32 ; L64: subq %rax, %rsp
33
2634 ; Freestanding
2735 ; EFI: movq %rsp, %rbp
2836 ; EFI: $[[B0OFS:4096|4104]], %rsp
3240
3341 ; M64: leaq 15(%{{.*}}), %rax
3442 ; M64: andq $-16, %rax
35 ; M64: callq ___chkstk
36 ; M64-NOT: %rsp
43 ; M64: callq ___chkstk_ms
44 ; M64: subq %rax, %rsp
3745 ; M64: movq %rsp, %rax
3846
3947 ; W64: leaq 15(%{{.*}}), %rax
4149 ; W64: callq __chkstk
4250 ; W64: subq %rax, %rsp
4351 ; W64: movq %rsp, %rax
52
53 ; L64: leaq 15(%{{.*}}), %rax
54 ; L64: andq $-16, %rax
55 ; L64: movabsq $__chkstk, %r11
56 ; L64: callq *%r11
57 ; L64: subq %rax, %rsp
58 ; L64: movq %rsp, %rax
4459
4560 ; EFI: leaq 15(%{{.*}}), [[R1:%r.*]]
4661 ; EFI: andq $-16, [[R1]]
8398
8499 ; M64: leaq 15(%{{.*}}), %rax
85100 ; M64: andq $-16, %rax
86 ; M64: callq ___chkstk
101 ; M64: callq ___chkstk_ms
102 ; M64: subq %rax, %rsp
87103 ; M64: movq %rsp, [[R2:%r.*]]
88104 ; M64: andq $-128, [[R2]]
89105 ; M64: movq [[R2]], %rsp