Index: include/clang/Driver/CLCompatOptions.td =================================================================== --- include/clang/Driver/CLCompatOptions.td +++ include/clang/Driver/CLCompatOptions.td @@ -62,6 +62,8 @@ def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Disable emission of RTTI data">; def _SLASH_GF_ : CLFlag<"GF-">, HelpText<"Disable string pooling">, Alias; +def _SLASH_Gs : CLJoined<"Gs">, HelpText<"Set stack probe size">, + Alias; def _SLASH_Gy : CLFlag<"Gy">, HelpText<"Put each function in its own section">, Alias; def _SLASH_Gy_ : CLFlag<"Gy-">, HelpText<"Don't put each function in its own section">, @@ -252,7 +254,6 @@ def _SLASH_Gm_ : CLFlag<"Gm-">; def _SLASH_Gr : CLFlag<"Gr">; def _SLASH_GS : CLFlag<"GS">; -def _SLASH_Gs : CLJoined<"Gs">; def _SLASH_GT : CLFlag<"GT">; def _SLASH_GX : CLFlag<"GX">; def _SLASH_Gv : CLFlag<"Gv">; Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1106,6 +1106,8 @@ HelpText<"Force realign the stack at entry to every function">; def mstack_alignment : Joined<["-"], "mstack-alignment=">, Group, Flags<[CC1Option]>, HelpText<"Set the stack alignment">; +def mstack_probe_size : Joined<["-"], "mstack-probe-size=">, Group, Flags<[CC1Option]>, + HelpText<"Set the stack probe size">; def mthread_model : Separate<["-"], "mthread-model">, Group, Flags<[CC1Option]>, HelpText<"The thread model to use, e.g. posix, single (posix by default)">; Index: include/clang/Frontend/CodeGenOptions.def =================================================================== --- include/clang/Frontend/CodeGenOptions.def +++ include/clang/Frontend/CodeGenOptions.def @@ -138,6 +138,11 @@ ///< .ctors. VALUE_CODEGENOPT(StackAlignment , 32, 0) ///< Overrides default stack ///< alignment, if not 0. +CODEGENOPT(IsStackProbeSizeOverridden, 1, 0) ///< Controls whether to use the + ///< overridden or the default + ///< stack probe size. +VALUE_CODEGENOPT(StackProbeSize , 32, 0) ///< Overrides default stack + ///< probe size, even if 0. CODEGENOPT(DebugColumnInfo, 1, 0) ///< Whether or not to use column information ///< in debug info. Index: lib/CodeGen/TargetInfo.cpp =================================================================== --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -1617,6 +1617,9 @@ bool d, bool p, bool w, unsigned RegParms) : X86_32TargetCodeGenInfo(CGT, d, p, w, RegParms) {} + void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &CGM) const override; + void getDependentLibraryOption(llvm::StringRef Lib, llvm::SmallString<24> &Opt) const override { Opt = "/DEFAULTLIB:"; @@ -1630,6 +1633,33 @@ } }; +void AddStackProbeSizeTargetAttribute(const Decl *D, + llvm::GlobalValue *GV, + CodeGen::CodeGenModule &CGM) +{ + if (const FunctionDecl *FD = dyn_cast(D)) { + if (CGM.getCodeGenOpts().IsStackProbeSizeOverridden) { + llvm::Function *Fn = cast(GV); + llvm::AttrBuilder B; + + B.addStackProbeSizeAttr(CGM.getCodeGenOpts().StackProbeSize); + + Fn->addAttributes(llvm::AttributeSet::FunctionIndex, + llvm::AttributeSet::get(CGM.getLLVMContext(), + llvm::AttributeSet::FunctionIndex, + B)); + } + } +} + +void WinX86_32TargetCodeGenInfo::SetTargetAttributes(const Decl *D, + llvm::GlobalValue *GV, + CodeGen::CodeGenModule &CGM) const { + X86_32TargetCodeGenInfo::SetTargetAttributes(D, GV, CGM); + + AddStackProbeSizeTargetAttribute(D, GV, CGM); +} + class WinX86_64TargetCodeGenInfo : public TargetCodeGenInfo { bool HasAVX; public: @@ -1636,6 +1666,9 @@ WinX86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool HasAVX) : TargetCodeGenInfo(new WinX86_64ABIInfo(CGT)), HasAVX(HasAVX) {} + void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &CGM) const override; + int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override { return 7; } @@ -1667,7 +1700,12 @@ } }; +void WinX86_64TargetCodeGenInfo::SetTargetAttributes(const Decl *D, + llvm::GlobalValue *GV, + CodeGen::CodeGenModule &CGM) const { + AddStackProbeSizeTargetAttribute(D, GV, CGM); } +} void X86_64ABIInfo::postMerge(unsigned AggregateSize, Class &Lo, Class &Hi) const { Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -3711,6 +3711,15 @@ CmdArgs.push_back(Args.MakeArgString("-mstack-alignment=" + alignment)); } + if (Args.hasArg(options::OPT_mstack_probe_size)) { + StringRef size = Args.getLastArgValue(options::OPT_mstack_probe_size); + + if(!size.empty()) + CmdArgs.push_back(Args.MakeArgString("-mstack-probe-size=" + size)); + else + CmdArgs.push_back("-mstack-probe-size=0"); + } + if (getToolChain().getTriple().getArch() == llvm::Triple::aarch64 || getToolChain().getTriple().getArch() == llvm::Triple::aarch64_be) CmdArgs.push_back("-fallow-half-arguments-and-returns"); Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -508,6 +508,18 @@ Opts.StackAlignment = StackAlignment; } + if (Arg *A = Args.getLastArg(OPT_mstack_probe_size)) { + StringRef Val = A->getValue(); + unsigned StackProbeSize = Opts.StackProbeSize; + Val.getAsInteger(0, StackProbeSize); + Opts.StackProbeSize = StackProbeSize; + Opts.IsStackProbeSizeOverridden = true; + } + else + { + Opts.IsStackProbeSizeOverridden = false; + } + if (Arg *A = Args.getLastArg(OPT_fobjc_dispatch_method_EQ)) { StringRef Name = A->getValue(); unsigned Method = llvm::StringSwitch(Name) Index: test/Driver/cl-options.c =================================================================== --- test/Driver/cl-options.c +++ test/Driver/cl-options.c @@ -42,6 +42,13 @@ // RUN: %clang_cl /Gy /Gy- -### -- %s 2>&1 | FileCheck -check-prefix=Gy_ %s // Gy_-NOT: -ffunction-sections +// RUN: %clang_cl /Gs -### -- %s 2>&1 | FileCheck -check-prefix=Gs %s +// Gs: "-mstack-probe-size=0" +// RUN: %clang_cl /Gs0 -### -- %s 2>&1 | FileCheck -check-prefix=Gs0 %s +// Gs0: "-mstack-probe-size=0" +// RUN: %clang_cl /Gs4096 -### -- %s 2>&1 | FileCheck -check-prefix=Gs4096 %s +// Gs4096: "-mstack-probe-size=4096" + // RUN: %clang_cl /Gw -### -- %s 2>&1 | FileCheck -check-prefix=Gw %s // Gw: -fdata-sections @@ -249,7 +256,6 @@ // RUN: /Gm- \ // RUN: /Gr \ // RUN: /GS \ -// RUN: /Gs1000 \ // RUN: /GT \ // RUN: /GX \ // RUN: /Gv \