This is an archive of the discontinued LLVM Phabricator instance.

[mips] Add support for dynamic stack realignment.
ClosedPublic

Authored by vkalintiris on Mar 26 2015, 6:40 AM.

Details

Summary

With this change we are able to realign the stack dynamically, whenever it
contains objects with alignment requirements that are larger than the
alignment specified from the given ABI.

We have to use the $fp register as the frame pointer when we perform
dynamic stack realignment. In complex stack frames, with variably-sized
objects, we reserve additionally the callee-saved register $s7 as the
base pointer in order to reference locals.

Diff Detail

Repository
rL LLVM

Event Timeline

vkalintiris retitled this revision from to [mips] Add support for dynamic stack realignment..
vkalintiris updated this object.
vkalintiris edited the test plan for this revision. (Show Details)
vkalintiris added a reviewer: dsanders.
vkalintiris added a subscriber: Unknown Object (MLST).

Fix register usage for functions without dynamic stack allocation.

In functions without dynamic stack allocation we were using $fp for
referencing locals. However, in a function's body we have to use $fp only
for referencing inbound arguments and $sp for everything else. I added
some tests that would have caught this case.

dsanders edited edge metadata.Apr 1 2015, 7:50 AM

I haven't finished looking at func_03 - func_10 in the test case yet but here's my comments so far.

Could you add some tests that check the debug info for variables affected by this? I'd like to be sure that the location information is correct.

lib/Target/Mips/MipsFrameLowering.cpp
92–95 ↗(On Diff #22948)

Nit? MFI->isFrameAddressTaken() doesn't seem to come under any of these conditions.

lib/Target/Mips/MipsRegisterInfo.cpp
185–186 ↗(On Diff #22948)

Nit: This is the same as hasBP() we should use that if we can to avoid code duplication.

290–302 ↗(On Diff #22948)

Nit: We should explain these conditions.

305–320 ↗(On Diff #22948)

I think I may be missing something here. The code seems to be saying that if we need realignment but can't do achieve it, then we don't really need it. Shouldn't that at least emit a warning?

I see other targets are silently doing the same thing, so this may be intended but it seems odd.

lib/Target/Mips/MipsSERegisterInfo.cpp
142 ↗(On Diff #22948)

It's not necessary in this patch but we should consider adding inlined members to MipsRegisterInfo rather than duplicating the selection between REG and REG_64 all the time (e.g. getZeroReg(), getFPReg(), getSPReg(), etc.).

143 ↗(On Diff #22948)

Why 'FrameIndex < 0' and not 'MFI->isFixedObjectIndex(FrameIndex)'?

test/CodeGen/Mips/dynamic-stack-realignment.ll
17 ↗(On Diff #22948)

Nit: Could you make it a bit clearer what cases each test covers? I was going to comment that we should check N32/N64's output too but I see that func_02 is covering the N64 case.

22 ↗(On Diff #22948)

I don't think -1024 is correct (but the program will work as far as I can tell). The frame will contain the 8-bytes for $ra/$fp, up to 504-bytes padding, 4-bytes for the alloca'd i32, 4-bytes for the 5th argument to helper_01, and 16-bytes for the reserved space, giving a total of between 32 and 536 bytes for the frame.

At the moment, we seem to be allocating 1024 bytes as well as up to 504 bytes padding. It looks like we're rounding the size of each region of the frame up to the maximum alignment.

We're discussing off-list whether the base pointer and locals with large alignments should be where they currently are. Some of the above issues may be related to the current position of this pointer and region.

48 ↗(On Diff #22948)

We should check the N32 case too.

dsanders added inline comments.Apr 21 2015, 5:18 AM
lib/Target/Mips/MipsSERegisterInfo.cpp
142 ↗(On Diff #22948)

Most of this has been added to MipsABIInfo

test/CodeGen/Mips/dynamic-stack-realignment.ll
22 ↗(On Diff #22948)

We reached the conclusion that we can do better but it's not actually wrong. It's functional but not optimal. Given that the alignment of vectors isn't honoured at the moment (and this breaks pocl), we should proceed with this layout and refine it later.

233–259 ↗(On Diff #22948)

Shouldn't these two cases be errors? We need to align to a large alignment but we can't because we've been told not to realign the stack.

vkalintiris edited edge metadata.

Addressed the first set of comments in the original review request.

vkalintiris added inline comments.Apr 21 2015, 7:26 AM
lib/Target/Mips/MipsRegisterInfo.cpp
185–186 ↗(On Diff #22948)

We need access to a MipsFrameLowering object in order to use hasBP(). I'm not sure but I don't think we can get a reference to this object from inside MipsRegisterInfo.

305–320 ↗(On Diff #22948)

I agree with you on that. IMHO, a better name would be shouldRealignStack() or something similar. I kept this name because I wanted to be consistent with the other targets.

Clarify what happens when we get a request for dynamic stack realignment
if the function has the attribute "no-realign-stack" too.

vkalintiris added a comment.EditedApr 24 2015, 4:09 AM

In reply to comments for lines 233–259@dynamic-stack-realignment.ll (Diff #22948)

I agree with you. However, reporting something back to the user is a little bit more difficult than it seems. The alignment of the objects inside such a function is clamped to that of the stack's alignment based on the given ABI. I moved the check for MF.getFunction()->hasFnAttribute("no-realign-stack") from canRealign() to needsStackRealignment(), in order to make the check more visible and added a comment that explains the whole situation.

dsanders accepted this revision.Jun 1 2015, 3:46 AM
dsanders edited edge metadata.

LGTM with the nits fixed and a warning for the 'needs realignment but can't realign' case.

We'll need to follow up on the overallocation issue but suboptimal is better than non-functional.

lib/Target/Mips/MipsFrameLowering.cpp
92–95 ↗(On Diff #22948)

Done

lib/Target/Mips/MipsRegisterInfo.cpp
185–186 ↗(On Diff #22948)

In that case, could you add a comment indicating it should be the same as hasBP()

290–302 ↗(On Diff #22948)

Done

305–320 ↗(On Diff #22948)

Both spellings have the same issue. If the answer to 'Are we able to realign the stack?' is 'no' then needsStackRealignment()/shouldRealignStack() can return false even though the answer to 'Do we need stack realignment?' is yes.

We should emit a warning when this happens since the users code is very likely to break in this situation.

315–321 ↗(On Diff #24375)

A couple typos:
Unfotunately -> Unfortunately
attirbute -> attribute

lib/Target/Mips/MipsSERegisterInfo.cpp
143 ↗(On Diff #24375)

Nit: Instead of:

ABI.IsN64() ? Mips::S7_64 : Mips::S7;

add a MipsABIInfo::GetBasePtr() and use that.

143 ↗(On Diff #22948)

Done

test/CodeGen/Mips/dynamic-stack-realignment.ll
30 ↗(On Diff #24375)

Nit: Please document the overallocation with a FIXME. This particular case needs a frame of up to between 16 and 512-bytes but currently allocates between 1024 and 1536 bytes.

Likewise for the other examples below.

17 ↗(On Diff #22948)

Done

48 ↗(On Diff #22948)

Done

233–259 ↗(On Diff #22948)

Done (MipsRegisterInfo::needsStackRealignment() has a comment explaining why they aren't errors).

This revision is now accepted and ready to land.Jun 1 2015, 3:46 AM
This revision was automatically updated to reflect the committed changes.