This is an archive of the discontinued LLVM Phabricator instance.

don't force SP-relative addressing for statepoints when the offset is not statically known
ClosedPublic

Authored by carnaval on Jun 11 2016, 12:39 PM.

Details

Summary

Prioritize addresses relative to the stack pointer in the stackmap, but fallback gracefully to other modes of addressing if the offset to the stack pointer is not a known constant.

Diff Detail

Repository
rL LLVM

Event Timeline

carnaval updated this revision to Diff 60442.Jun 11 2016, 12:39 PM
carnaval retitled this revision from to statepoint fixes.
carnaval updated this object.
carnaval added a reviewer: sanjoy.
carnaval added subscribers: thanm, sanjoy.
carnaval updated this revision to Diff 60443.Jun 11 2016, 12:54 PM

add context according to local customs

sanjoy requested changes to this revision.Jun 12 2016, 2:22 PM
sanjoy edited edge metadata.

Hi,

I'm happy to review these (and thanks for the patches!) but can you please split these up into three patches?

include/llvm/Target/TargetFrameLowering.h
255 ↗(On Diff #60443)

Why not return an Optional<int>?

This revision now requires changes to proceed.Jun 12 2016, 2:22 PM
carnaval updated this revision to Diff 60528.Jun 13 2016, 8:16 AM
carnaval retitled this revision from statepoint fixes to don't force SP-relative addressing for statepoints when the offset is not statically known.
carnaval edited edge metadata.
sanjoy requested changes to this revision.Jun 13 2016, 11:26 AM
sanjoy edited edge metadata.
sanjoy added inline comments.
include/llvm/Target/TargetFrameLowering.h
257 ↗(On Diff #60528)

Just return None;

lib/CodeGen/AsmPrinter/WinException.cpp
304 ↗(On Diff #60528)

No need to use braces here. Also, this indent looks weird -- is it clang-formatted?

Note: you can also use *TFI.getFrameIndexReferenceFromSP(*Asm->MF, FrameIndex, UnusedReg) instead of getValue.

lib/CodeGen/PrologEpilogInserter.cpp
1102 ↗(On Diff #60528)

I'd suggest pushing the hasReservedCallFrame check into getFrameIndexReferenceFromSP -- getFrameIndexReferenceFromSP be returning None or a valid offset.

1105 ↗(On Diff #60528)

Note: instead of if (X.hasValue()) you can also do if (X). Since Optional<T> does not auto-convert to T (you need to use its operator* or getValue()) there are no messy cases around e.g. an Optional<int> containing 0 as its value looking like it has no value etc.

lib/Target/X86/X86FrameLowering.cpp
1766 ↗(On Diff #60528)

Use return None; and remove the braces.

1805 ↗(On Diff #60528)

You don't need to explicitly create an Optional<int>, you can just return Offset + StackSize.

test/CodeGen/X86/statepoint-nosp.ll
2 ↗(On Diff #60528)

You'll need a REQUIRES: asserts here otherwise the test will fail on product builds that don't have -debug-only.

This revision now requires changes to proceed.Jun 13 2016, 11:26 AM

Btw, here are our coding standards, in case that helps: http://llvm.org/docs/CodingStandards.html

carnaval updated this revision to Diff 60580.Jun 13 2016, 12:33 PM
carnaval updated this object.
carnaval edited edge metadata.
carnaval marked an inline comment as done.

re: putting the hasReservedCallFrame check
I don't think it's possible since the other use site of this function (in WinException) seem to actually use it in that case. I'm assuming that in this context it's guaranteed that the offset will only be interpreted relative to the stack pointer on function entry.
I've added a comment to reflect that at the getFrameIndexReferenceFromSP declaration.

sanjoy added a subscriber: rnk.Jun 13 2016, 1:23 PM

re: putting the hasReservedCallFrame check
I don't think it's possible since the other use site of this function (in WinException) seem to actually use it in that case. I'm assuming that in this context it's guaranteed that the offset will only be interpreted relative to the stack pointer on function entry.

@rnk -- can you confirm if the above is intentional? If it is, then lgtm else lets move hasReservedCallFrame into getFrameIndexReferenceFromSP.

include/llvm/Target/TargetFrameLowering.h
252 ↗(On Diff #60580)

I'd change the language a little bit to say ".. except that the 'base register' will always be RSP and the offset is from the value of RSP after the function prologue"

WinEH does not expect getFrameIndexReferenceFromSP to return a result which is dynamically correct from an arbitrary program point.
The result of getFrameIndexReferenceFromSP goes into data, not code. The idea is that the exception handling runtime wants to know the offset of the exception object relative to what the SP is after the prologue is set up.
The runtime uses CFI to recreate the stack pointer at prologue start; that, coupled with the offset, is utilized to initialize stuff like catch objects.

Given what @majnemer said, do you mind adding a boolean to the getFrameIndexReferenceFromSP API as bool AllowSPAdjustment with the semantic that if it is true then the offset returned is correct only based off of the SP on entry, while if it is false then the offset (if any returned) has to be correct for the SP at arbitrary program points after the prologue? Currently the API is such that other than documentation there is nothing that will force a user to carefully think about which variant they want.

carnaval updated this revision to Diff 60623.Jun 13 2016, 4:05 PM
carnaval edited edge metadata.

add AllowSPAdjustment

sanjoy accepted this revision.Jun 13 2016, 4:14 PM
sanjoy edited edge metadata.

lgtm modulo very minor stuff

lib/CodeGen/PrologEpilogInserter.cpp
1098 ↗(On Diff #60623)

Reflow this comment?

lib/Target/X86/X86FrameLowering.cpp
1767 ↗(On Diff #60623)

Start with uppercase.

test/CodeGen/X86/statepoint-nosp.ll
7 ↗(On Diff #60623)

This should probably go into test/CodeGen/X86/deopt-bundles.ll.

This revision is now accepted and ready to land.Jun 13 2016, 4:14 PM
majnemer edited edge metadata.Jun 13 2016, 4:15 PM
majnemer added a subscriber: llvm-commits.
majnemer added inline comments.Jun 13 2016, 4:18 PM
lib/CodeGen/PrologEpilogInserter.cpp
1101 ↗(On Diff #60623)

Please do something like /*AllowSPAdjustment=*/false so that readers can figure out what the bool parameter does.

1105–1106 ↗(On Diff #60623)

I'd flip the sense of the comparison around.

carnaval updated this revision to Diff 60626.Jun 13 2016, 4:39 PM

address comments
move test to an existing file

This revision was automatically updated to reflect the committed changes.
rnk added a comment.Jun 15 2016, 8:28 AM

Is it really necessary to prefer SP-relative offsets from FP-relative offsets? Is there any reason not to standardize on getFrameIndexReference? You can always get SP-relative offsets by disabling frame pointers.

Assuming we need SP-relative offsets, I think it would be cleaner to expose an API on TargetFrameLowering that prefers returning SP-relative offsets if possible, rather than having an API that might fail. The base TargetFrameLowering implementation can delegate directly to getFrameIndexReference, and targets like X86 can implement the preference for SP-relative offsets.

In D21259#458739, @rnk wrote:

Is it really necessary to prefer SP-relative offsets from FP-relative offsets? Is there any reason not to standardize on getFrameIndexReference? You can always get SP-relative offsets by disabling frame pointers.

Assuming we need SP-relative offsets, I think it would be cleaner to expose an API on TargetFrameLowering that prefers returning SP-relative offsets if possible, rather than having an API that might fail. The base TargetFrameLowering implementation can delegate directly to getFrameIndexReference, and targets like X86 can implement the preference for SP-relative offsets.

We do want to prefer SP relative offsets, even when we're preserving frame pointers. But I like your second idea, I'll put up a patch for review soon.