This is an archive of the discontinued LLVM Phabricator instance.

[RISCV] Preserve stack space for outgoing arguments when the function contain variable size objects
ClosedPublic

Authored by shiva0217 on Feb 26 2018, 12:19 AM.

Details

Summary

When the function contains variable size objects:
E.g.

bar (int x)
{

char p[x];

push outgoing variables for foo.
call foo

}

We need to generate stack adjustment instructions for outgoing arguments by
eliminateCallFramePseudoInstr when the function contains variable size
objects to avoid outgoing variables corrupt the variable size object.

Default hasReservedCallFrame will return !hasFP().
We don't want to generate extra sp adjustment instructions when hasFP()
return true, So We override hasReservedCallFrame as !hasVarSizedObjects().

Diff Detail

Repository
rL LLVM

Event Timeline

shiva0217 created this revision.Feb 26 2018, 12:19 AM
asb added a comment.Mar 1 2018, 6:07 AM

The extra sp adjustments introduced in calling-conv.ll and vararg.ll seem unnecessary - are they?

I think the test case you add could be simplified substantially, which makes the problem fixed by this patch somewhat more clear:

declare void @func(i8*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32)       
                                                                                     
; Check that outgoing arguments passed on the stack do not corrupt a                 
; variable-sized stack object.                                                       
define void @alloca_callframe(i32 %n) nounwind {                                     
  %1 = alloca i8, i32 %n                                                             
  call void @func(i8* %1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8,           
                  i32 9, i32 10, i32 11, i32 12)                                     
  ret void                                                                           
}
shiva0217 updated this revision to Diff 136666.Mar 1 2018, 6:50 PM
shiva0217 edited the summary of this revision. (Show Details)

Hi Alex. Default hasReservedCallFrame will return !hasFP(), so these cases will generate extra sp adjustment, we could override hasReservedCallFrame as !hasVarSizedObjects() to avoid this and thanks for update the test case which make it more clean and clear!

asb added a comment.Mar 2 2018, 2:55 AM

Hi Alex. Default hasReservedCallFrame will return !hasFP(), so these cases will generate extra sp adjustment, we could override hasReservedCallFrame as !hasVarSizedObjects() to avoid this and thanks for update the test case which make it more clean and clear!

That sounds like the right thing to do, and would avoid the (minor) codegen regression. Could you update to make that change? Thanks.

shiva0217 updated this revision to Diff 136950.Mar 4 2018, 11:07 PM

Hi Alex. The patch has been updated. The codgen result in calling-conv.ll:caller_many_scalars function with FP has changed due to we override the hasReservedCallFrame function. According to the logic in determineFrameLayout, the SP adjustment will change from 32 to 16. It seems that we could also remove the logic in determineFrameLayout relative to variable size objects because eliminateCallFramePseudoInstr could handle it, right?

shiva0217 updated this revision to Diff 136953.Mar 5 2018, 12:49 AM

Update test case alloca.ll

asb added a comment.Mar 14 2018, 9:23 AM

Thanks for making those changes Shiva . The fact we can simplify determineFrameLayout is a good observation.

I've added a few comments, which I think are all comment or formatting related. With those resolved, this looks good to me.

I certainly can't see any unexpected codegen changes when compiling the GCC torture suite with this. Although I'm happy with this and happy for you to commit once resolving the formatting/comment suggestions: if anyone else following this has time to give a second look I'd appreciate it. This is a fiddly part of the codebase, so the more people checking the better.

lib/Target/RISCV/RISCVFrameLowering.cpp
235–239 ↗(On Diff #136953)

I don't think copy+pasting the description from TargetFrameLowering.h adds much. It would be better to explain what is different about the RISC-V implementation (which is presumably that fact that there is no reserved call frame when there are varsized objects).

I know this is copied from elsewhere in LLVM, but also note that current guidance for Doxygen comments in LLVM is _not_ to repeat the function name at the beginning of the comment https://llvm.org/docs/CodingStandards.html#doxygen-use-in-documentation-comments

240–241 ↗(On Diff #136953)

Nit: clang-format is happy for this to be on one line

245 ↗(On Diff #136953)

Nit: fill stop after comment

246–248 ↗(On Diff #136953)

Nit: clang-format suggests the following:

MachineBasicBlock::iterator RISCVFrameLowering::eliminateCallFramePseudoInstr(
    MachineFunction &MF, MachineBasicBlock &MBB,
    MachineBasicBlock::iterator MI) const {
253–257 ↗(On Diff #136953)

I wonder if this comment could be improved to better explain _why_ this logic is doing what it does. It's certainly true that this helps avoid poisoning of an alloca area due to outgoing arguments, but it's perhaps difficult for someone reading this code to see why. Does the following seem accurate to you?

"""
If space has not been reserved for a call frame, ADJCALLSTACKDOWN and ADJCALLSTACKUP must be converted to instructions manipulating the stack pointer. This is necessary when there is a variable length stack allocation (e.g. alloca), which means it's not possible to allocate space for outgoing arguments from within the function prologue.
"""

261–263 ↗(On Diff #136953)

Nit: If it were me, I'd probably just write "Ensure the stack remains aligned after adjustment.", but opinions vary on what is 'obvious' and the level of detail to put in a comment - so whichever you prefer.

test/CodeGen/RISCV/alloca.ll
68–70 ↗(On Diff #136953)

Nit: Should ideally have a new line after the declare void @func line, and these lines shouldn't be indented.

asb accepted this revision.Mar 14 2018, 9:26 AM
This revision is now accepted and ready to land.Mar 14 2018, 9:26 AM
shiva0217 updated this revision to Diff 138487.Mar 14 2018, 7:04 PM

Update patch to address the comments.

Hi Alex. Yes, it's a fiddly part. I'll leave the patch to see if there have other concerned. If there're no new comments, I'll commit the patch on next Monday.

This revision was automatically updated to reflect the committed changes.