Index: include/llvm/Target/TargetOptions.h =================================================================== --- include/llvm/Target/TargetOptions.h +++ include/llvm/Target/TargetOptions.h @@ -75,6 +75,7 @@ NoZerosInBSS(false), JITEmitDebugInfo(false), JITEmitDebugInfoToDisk(false), GuaranteedTailCallOpt(false), DisableTailCalls(false), StackAlignmentOverride(0), + StackProbeSizeOverride(0), EnableFastISel(false), PositionIndependentExecutable(false), UseInitArray(false), DisableIntegratedAS(false), CompressDebugSections(false), FunctionSections(false), @@ -171,6 +172,9 @@ /// StackAlignmentOverride - Override default stack alignment for target. unsigned StackAlignmentOverride; + /// StackProbeSizeOverride - Override default stack probe size for target. + unsigned StackProbeSizeOverride; + /// EnableFastISel - This flag enables fast-path instruction selection /// which trades away generated code quality in favor of reducing /// compile time. @@ -281,6 +285,7 @@ ARE_EQUAL(GuaranteedTailCallOpt) && ARE_EQUAL(DisableTailCalls) && ARE_EQUAL(StackAlignmentOverride) && + ARE_EQUAL(StackProbeSizeOverride) && ARE_EQUAL(EnableFastISel) && ARE_EQUAL(PositionIndependentExecutable) && ARE_EQUAL(UseInitArray) && Index: lib/Target/X86/X86FrameLowering.cpp =================================================================== --- lib/Target/X86/X86FrameLowering.cpp +++ lib/Target/X86/X86FrameLowering.cpp @@ -502,6 +502,7 @@ !IsWinEH && (MMI.hasDebugInfo() || Fn->needsUnwindTableEntry()); bool UseLEA = STI.useLeaForSP(); unsigned StackAlign = getStackAlignment(); + unsigned StackProbeSize = STI.getStackProbeSize(); unsigned SlotSize = RegInfo->getSlotSize(); unsigned FramePtr = RegInfo->getFrameRegister(MF); const unsigned MachineFramePtr = STI.isTarget64BitILP32() ? @@ -706,8 +707,6 @@ // Adjust stack pointer: ESP -= numbytes. - static const size_t PageSize = 4096; - // Windows and cygwin/mingw require a prologue helper routine when allocating // more than 4K bytes on the stack. Windows uses __chkstk and cygwin/mingw // uses __alloca. __alloca and the 32-bit version of __chkstk will probe the @@ -716,7 +715,7 @@ // responsible for adjusting the stack pointer. Touching the stack at 4K // increments is necessary to ensure that the guard pages used by the OS // virtual memory manager are allocated in correct sequence. - if (NumBytes >= PageSize && UseStackProbe) { + if (NumBytes >= StackProbeSize && UseStackProbe) { const char *StackProbeSymbol; unsigned CallOp; Index: lib/Target/X86/X86Subtarget.h =================================================================== --- lib/Target/X86/X86Subtarget.h +++ lib/Target/X86/X86Subtarget.h @@ -231,6 +231,10 @@ /// entry to the function and which must be maintained by every function. unsigned stackAlignment; + /// stackProbeSize - When exceeding the stack probe size, stack probing + /// functions are inserted if the target requires them. + unsigned stackProbeSize; + /// Max. memset / memcpy size that is turned into rep/movs, rep/stos ops. /// unsigned MaxInlineSizeThreshold; @@ -248,6 +252,9 @@ /// StackAlignOverride - Override the stack alignment. unsigned StackAlignOverride; + /// StackProbeSizeOverride - Override the stack probe size. + unsigned StackProbeSizeOverride; + /// In64BitMode - True if compiling for 64-bit, false for 16-bit or 32-bit. bool In64BitMode; @@ -270,7 +277,7 @@ /// X86Subtarget(const std::string &TT, const std::string &CPU, const std::string &FS, const X86TargetMachine &TM, - unsigned StackAlignOverride); + unsigned StackAlignOverride, unsigned StackProbeSize); const X86TargetLowering *getTargetLowering() const override { return &TLInfo; @@ -292,6 +299,10 @@ /// function for this subtarget. unsigned getStackAlignment() const { return stackAlignment; } + /// getStackProbeSize - Returns the maximum size of stack memory that can be + /// safely accessed without calling stack probing functions. + unsigned getStackProbeSize() const { return stackProbeSize; } + /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size /// that still makes it profitable to inline the call. unsigned getMaxInlineSizeThreshold() const { return MaxInlineSizeThreshold; } Index: lib/Target/X86/X86Subtarget.cpp =================================================================== --- lib/Target/X86/X86Subtarget.cpp +++ lib/Target/X86/X86Subtarget.cpp @@ -225,6 +225,9 @@ else if (isTargetDarwin() || isTargetLinux() || isTargetSolaris() || In64BitMode) stackAlignment = 16; + + if (StackProbeSizeOverride) + stackProbeSize = StackProbeSizeOverride; } void X86Subtarget::initializeEnvironment() { @@ -278,6 +281,9 @@ UseSqrtEst = false; UseReciprocalEst = false; stackAlignment = 4; + // By default, the stack probe size is equal to the page size (4096 bytes) + // for all targets. + stackProbeSize = 4096; // FIXME: this is a known good value for Yonah. How about others? MaxInlineSizeThreshold = 128; } @@ -331,11 +337,13 @@ X86Subtarget::X86Subtarget(const std::string &TT, const std::string &CPU, const std::string &FS, const X86TargetMachine &TM, - unsigned StackAlignOverride) + unsigned StackAlignOverride, + unsigned StackProbeSizeOverride) : X86GenSubtargetInfo(TT, CPU, FS), X86ProcFamily(Others), PICStyle(PICStyles::None), TargetTriple(TT), DL(computeDataLayout(TargetTriple)), StackAlignOverride(StackAlignOverride), + StackProbeSizeOverride(StackProbeSizeOverride), In64BitMode(TargetTriple.getArch() == Triple::x86_64), In32BitMode(TargetTriple.getArch() == Triple::x86 && TargetTriple.getEnvironment() != Triple::CODE16), Index: lib/Target/X86/X86TargetMachine.cpp =================================================================== --- lib/Target/X86/X86TargetMachine.cpp +++ lib/Target/X86/X86TargetMachine.cpp @@ -55,7 +55,8 @@ CodeGenOpt::Level OL) : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), TLOF(createTLOF(Triple(getTargetTriple()))), - Subtarget(TT, CPU, FS, *this, Options.StackAlignmentOverride) { + Subtarget(TT, CPU, FS, *this, Options.StackAlignmentOverride, + Options.StackProbeSizeOverride) { // default to hard float ABI if (Options.FloatABIType == FloatABI::Default) this->Options.FloatABIType = FloatABI::Hard; @@ -106,7 +107,8 @@ // function that reside in TargetOptions. resetTargetOptions(F); I = llvm::make_unique(TargetTriple, CPU, FS, *this, - Options.StackAlignmentOverride); + Options.StackAlignmentOverride, + Options.StackProbeSizeOverride); } return I.get(); }