This is an archive of the discontinued LLVM Phabricator instance.

Fix hardcoded stack probe space
AbandonedPublic

Authored by majnemer on Dec 16 2014, 11:12 AM.

Details

Summary

The LLVM stack probe space (e.g. used for issuing chkstk() calls when compiling to Windows targets) is hard coded to 4096 bytes. However, in order to suppress chkstk() calls, it should be possible to specify a minimum value for issuing stack probe calls that is greater than 4096 bytes.

This code makes the number of bytes that variables can occupy before a stack probe is initiated configurable.

This should fix http://llvm.org/bugs/show_bug.cgi?id=21895

Diff Detail

Repository
rL LLVM

Event Timeline

AndrewH updated this revision to Diff 17344.Dec 16 2014, 11:12 AM
AndrewH retitled this revision from to Fix hardcoded stack probe space.
AndrewH updated this object.
AndrewH edited the test plan for this revision. (Show Details)
AndrewH set the repository for this revision to rL LLVM.
AndrewH updated this object.
AndrewH added a subscriber: Unknown Object (MLST).
majnemer added inline comments.
lib/Target/X86/X86Subtarget.cpp
230

Please indent this.

AndrewH updated this revision to Diff 17389.Dec 17 2014, 6:22 AM

Use spaces instead of tabs.

I took the liberty to add some reviewers based on the commit history. Is anything blocking this? I would be happy to help.

hans accepted this revision.Dec 19 2014, 10:05 AM
hans added a reviewer: hans.
hans added a subscriber: hans.

Looks good to me with the comment below.

lib/Target/X86/X86Subtarget.h
283–285

I think the parameter should be named StackProbeSizeOverride here?

This revision is now accepted and ready to land.Dec 19 2014, 10:05 AM
hans requested changes to this revision.Dec 19 2014, 10:12 AM
hans edited edge metadata.

Sorry, forgot to mention that this needs to be tested.

Look in the test/ directory for tests using -stack-alignment=. It should be possible to test this similarly.

This revision now requires changes to proceed.Dec 19 2014, 10:12 AM
AndrewH updated this revision to Diff 17498.Dec 19 2014, 10:12 AM
AndrewH edited edge metadata.

Fixed parameter naming in method prototype, thanks!

Testing: OK, I will look into that.

AndrewH updated this revision to Diff 17620.Dec 24 2014, 1:02 AM
AndrewH edited edge metadata.

Fixed handling of -stack-probe-size=0. In contrast to the stack alignment override, zero is a valid value for the stack probe size override (i.e. always generate stack probing calls, regardless of how many bytes the local variables occupy). Unfortunately that means a little bit more management overhead, as there is no magic value for the stack probe size that indicates that the users wants to use the default size. On the plus side, the driver does not need to know any internals, like that the default page size is 4096 bytes.

Added test cases.

What happens if we do LTO? Don't we need to record the probe size on the function?

It wouldn't make sense to make it a command line flag if we supported this on a per function basis.

What happens if we do LTO?

Well, if nothing else is specified, it will take the default stack probe size; that means that the behavior with LTO is as it was before.

Don't we need to record the probe size on the function?

Great suggestion! That might be useful.

It wouldn't make sense to make it a command line flag if we supported this on a per function basis.

I think that the stack alignment is also tracked on a per function basis, and there is still a command line flag for overriding that.

My aim is currently to get MSVC's /Gs into LLVM, and I cannot see how one could do that without a command line flag.

I will look how the stack alignment is specified when using LTO and will report back if that is also useful in this case.

AndrewH updated this revision to Diff 17631.Dec 24 2014, 8:27 PM

This revision adds the StackProbeSize function attribute, which behaves similarly to the already existing StackAlignment attribute.

What happens if we do LTO?

Well, if nothing else is specified, it will take the default stack probe size; that means that the behavior with LTO is as it was before.

Sure, but MSVC also supports LTO (under the name LTCG). I'd imagine that they have some sort of behavior when a function with probe size X gets inlined into a function with probe size Y. My guess would be that they'd just take the max of the two functions.

Don't we need to record the probe size on the function?

Great suggestion! That might be useful.

It wouldn't make sense to make it a command line flag if we supported this on a per function basis.

I think that the stack alignment is also tracked on a per function basis, and there is still a command line flag for overriding that.

My aim is currently to get MSVC's /Gs into LLVM, and I cannot see how one could do that without a command line flag.

Well, we need a command line flag at the clang level. I don't see why we would need one at the LLVM level because clang can translate the /Gs value into a function attribute.

I will look how the stack alignment is specified when using LTO and will report back if that is also useful in this case.

AndrewH updated this revision to Diff 17634.Dec 25 2014, 9:39 PM

Well, we need a command line flag at the clang level. I don't see why we would need one at the LLVM level because clang can translate the /Gs value into a function attribute.

This revision has now those command line flags removed. Furthermore, the stackprobesize(n) function attribute is only added iff clang has received an overriding flag (specified via -stack-probe-size=n or /Gsn).

If LLVM generates code in the X86 target, is uses the default stack probe size if the function has no stackprobesize(n) function attribute, otherwise it uses the stack probe size of n.

Sure, but MSVC also supports LTO (under the name LTCG). I'd imagine that they have some sort of behavior when a function with probe size X gets inlined into a function with probe size Y. My guess would be that they'd just take the max of the two functions.

Unfortunately, I must admit that I do not see myself capable of that task, as I am pretty unfamiliar with LTO in LLVM. This revision implements /Gs when LTO is not used, and shows the same behavior for code generation as before when LTO is used. Can this or a later revision be accepted with such a behavior? That would of course only be a partial fix for the initial bug report, but I think would be useful nonetheless.

majnemer added inline comments.Dec 25 2014, 9:55 PM
include/llvm/Target/TargetOptions.h
182

This seems unused.

AndrewH updated this revision to Diff 17641.Dec 26 2014, 2:52 PM

This seems unused.

Yup, correct! It was used in D6685, but is not needed anymore. Updated revision.

reames edited edge metadata.Jan 2 2015, 2:34 PM

Minor drive by comments. I'm explicitly deferring giving a LGTM to previous reviewers.

@majnemer -- I would suggest we let this land without addressing your LTO concerns. While I agree that's an issue, this is a strict improvement over what we have. If someone files a bug, adding the inliner logic wouldn't be too hard and I'd probably even get to it.

lib/Target/X86/X86FrameLowering.cpp
540

Why not use: Fn->hasFnAttribute and Fn->getFnAttribute

lib/Target/X86/X86Subtarget.cpp
232

Your comment here is unclear. Specifically, many x86 targets support variable page sizes. I think what you want here is document the fact that we're *assuming* the page size for a page of stack space is *at least* 4k.

I'm not sure having this extracted as a named constant adds anything here.

lib/Target/X86/X86Subtarget.h
301

I might name this getDefaultStackProbeSize just to make it clear it's overridable.

AndrewH updated this revision to Diff 17772.Jan 3 2015, 5:04 PM
AndrewH edited edge metadata.

Why not use: Fn->hasFnAttribute and Fn->getFnAttribute

Done.

Your comment here is unclear. Specifically, many x86 targets support variable page sizes. I think what you want here is document the fact that we're *assuming* the page size for a page of stack space is *at least* 4k.

I read a little bit up on this topic and you are correct. Updated comment.

I'm not sure having this extracted as a named constant adds anything here.

Before this commit X86FrameLowering::emitPrologue had a similarly named constant. So I thought it would be good style in LLVM and adapted it in my last revisions. Removed named constant.

I might name this getDefaultStackProbeSize just to make it clear it's overridable.

Done.

This is looking great so far.

Please update the LangRef with your new function attribute, the file is docs/LangRef.rst.

It should go with all the others: http://llvm.org/docs/LangRef.html#function-attributes
Be sure to mention that this attribute only has an effect on specific targets (MingW, Cygwin, MSVC) and that other targets will ignore the attribute.

lib/Target/X86/X86FrameLowering.cpp
532–533

Please format this according to the style guide, the brace should be on the same line as the if.

lib/Target/X86/X86Subtarget.h
237

This should start with a capital letter.

AndrewH updated this revision to Diff 17778.Jan 4 2015, 1:45 PM

Please format this according to the style guide, the brace should be on the same line as the if.

Done.

This should start with a capital letter.

Done.

Please update the LangRef with your new function attribute, the file is docs/LangRef.rst.

Done.

majnemer accepted this revision.Jan 4 2015, 9:33 PM
majnemer added a reviewer: majnemer.

LGTM with nits.

Thanks for your hard work on this!

lib/IR/Attributes.cpp
563

Can this be a range-based for loop?

AndrewH updated this revision to Diff 17800.Jan 5 2015, 7:40 AM
AndrewH edited edge metadata.

Can this be a range-based for loop?

Yep, fixed.

AndrewH updated this revision to Diff 17801.Jan 5 2015, 7:49 AM

Sorry, I changed code in the wrong function. Fixed again.

Do you need someone to apply this patch for you?

Do you need someone to apply this patch for you?

Yes, that would be great.

I found that this patch could be made considerably simpler, I've attached
my version of it.

Andrew, let me know what you think.

Andrew, let me know what you think.

Looks great. If you apply this patch it to trunk, I can continue with clang integration at D6685.

majnemer accepted this revision.Jan 7 2015, 10:16 AM
majnemer commandeered this revision.
majnemer edited edge metadata.
majnemer edited reviewers, added: AndrewH; removed: majnemer.

Committed in rL225360.

majnemer accepted this revision.Jan 7 2015, 10:17 AM
majnemer abandoned this revision.
majnemer added a reviewer: majnemer.