This is an archive of the discontinued LLVM Phabricator instance.

Update InstCombine to transform aggregate stores into scalar stores.
ClosedPublic

Authored by deadalnix on Feb 19 2015, 8:58 PM.

Details

Summary

This is a first step toward getting proper support for aggregate loads and stores.

Diff Detail

Event Timeline

deadalnix updated this revision to Diff 20372.Feb 19 2015, 8:58 PM
deadalnix retitled this revision from to Add a pass to transform aggregate loads and stores into scalar loads and stores..
deadalnix updated this object.
deadalnix edited the test plan for this revision. (Show Details)
deadalnix added a reviewer: reames.
reames edited edge metadata.Feb 20 2015, 12:18 PM

This needs to go to llvm-commits. I'll review once that's done. I don't see anything major on a quick scan, but I haven't given it a careful read yet either.

What do you expect me to do except posting this in llvm-commit ?

I think this is pretty safe to get that in. This is straightforward and does not do much, but would serve as a base to continue the work.

Nit picks inline. This is really close to ready for submission. The only change I'd really like to see is the change from BasicBlockPass to FunctionPass and the removal of dead member variables.

lib/Transforms/Scalar/AggregateMemAccessRemoval.cpp
11 ↗(On Diff #20372)

Grammar. Possibly: "This transforms removes load ans stores of aggregate type by replacing them with equivalent scalar loads and stores."

Also, not that this doesn't handle *all* aggregate loads and stores (yet.)

36 ↗(On Diff #20372)

Its more canonical to use a FunctionPass and a foreach loop using inst_range.

38 ↗(On Diff #20372)

I don't think either of these are used in this version of the code?

45 ↗(On Diff #20372)

What's this using line for?

60 ↗(On Diff #20372)

If you use a function pass, this initialization function can just disappear. Along with the member variables.

reames edited edge metadata.Feb 24 2015, 10:13 AM
reames added a subscriber: Unknown Object (MLST).

See review comments.

deadalnix updated this revision to Diff 20723.Feb 25 2015, 6:02 PM

Make this a Function pass and address various comments. Removed many instance fields that where not necessary anymore.

My primary question is why this isn't just an instcombine, using insertvalue / extractvalue to reconnect the aggregates?

reames added a comment.Mar 3 2015, 9:24 AM

My primary question is why this isn't just an instcombine, using insertvalue / extractvalue to reconnect the aggregates?

@chandlerc - Because we talked about that last time and it was rejected for some reason I don't really remember. I would strongly prefer we land this in something close to it's current form and then iterate in tree. This has topic has been stalled on census for months. Honestly, I sorta of agree with you, but let's revisit that separately.

@deadalnix - LGTM w/nits applied.

lib/Transforms/Scalar/AggregateMemAccessRemoval.cpp
91 ↗(On Diff #20723)

You might want to make sure the size of the element is the size of the struct, otherwise we're loosing dereferencability information here.

95 ↗(On Diff #20723)

Add a TODO about preserving metadata please.

102 ↗(On Diff #20723)

This should be handled via an outer worklist not recursion, but please fix this as a separate change.

Actually, sorry, you're not testing this at all. *Delete* this line and then let's revisit in another change.

118 ↗(On Diff #20723)

Add a test for this case please.

deadalnix added inline comments.Mar 3 2015, 7:56 PM
lib/Transforms/Scalar/AggregateMemAccessRemoval.cpp
102 ↗(On Diff #20723)

What is wrong with using recursion here ?

118 ↗(On Diff #20723)

I'm not sure if this is possible at all. This is more a sanity check than anything else. You can't store/load opaque structs to begin with.

deadalnix added inline comments.Mar 3 2015, 8:01 PM
lib/Transforms/Scalar/AggregateMemAccessRemoval.cpp
91 ↗(On Diff #20723)

Is that possible that they differ for a one element struct ? I can add this as an assert because I don't think this possible at all that it does not match.

102 ↗(On Diff #20723)

Also, this was tested in the whole diff. As only one element struct are supported now, I could write a test, but that would be very redundant with what already exists in D7607 .

deadalnix updated this revision to Diff 21172.Mar 3 2015, 8:32 PM

Add assert to check size match.
Rebase and update load test (as load syntax changed).

mehdi_amini added inline comments.
lib/Transforms/Scalar/AggregateMemAccessRemoval.cpp
102 ↗(On Diff #20723)

I don't like the approach "commit and fix in a separate change", unless there is a good reason and the "change" is already ready to follow. This is not a good process, and it build technical debt. Please do it right before committing.

Recursion is never a good idea unless you can prove that you won't explode the stack. LLVM is used in embedded environment where the stack size is limited. Even on a regular PC, you don't want to crash because you have a very long sequence of instruction and you recurse blindly.

deadalnix added inline comments.Mar 3 2015, 11:56 PM
lib/Transforms/Scalar/AggregateMemAccessRemoval.cpp
102 ↗(On Diff #20723)

Well ok but:
1/ There is the whole diff to begin with, I've been asked to cut a minimal chunk of it to get review. Now you got to understand that, because it is minimal, it won't contains the whole thhing, pretty much by definition. You guys needs to agree on what the process is here. Either we get it in in one piece or in several, but we can't have both at once.
2/ There is bunch of code that recurse on what aggregate type contains already. If this is going to stack overflow, this is going to with this recursion or not. Additionnaly, you'd have to be doign fairly bizantine stuff to get aggregate nested so deep that you get a stack overflow. You'd have to have something like a struct of a struct of a struct of a struct .... of one element enough time to get a stack overflow.

deadalnix updated this revision to Diff 21236.Mar 4 2015, 2:47 PM
  • Rebase
  • Create load and store with align directly instead of adding it later.
  • Add comment about the recursion
deadalnix updated this revision to Diff 21330.Mar 5 2015, 9:16 PM

Move all the things to InstCombine. Also, limit myself to store, as to keep thing minimal while we agree on the design.

deadalnix retitled this revision from Add a pass to transform aggregate loads and stores into scalar loads and stores. to Update InstCombine to transform aggregate stores into scalar stores..Mar 5 2015, 9:17 PM
deadalnix updated this object.
reames added a comment.Mar 6 2015, 3:46 PM

I'm okay with what's here once my fairly minor comments are addressed, but let's wait for Chandler to take a look as well.

(And thank you again for sticking it through a long review process!)

lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
804

Rather than returning bool, please return the new Instruction or nullptr. This will allow us to add that new instruction to the worklist and will solve the deeply nested struct thing you were trying to address with recursion in the previous patch.

Alternatively, you could simple add the newly created store to the worklist within this function. I have no strong preference, but I suspect Chandler may care. It might be good to let him comment before actually making either change.

809

nit: Value *V

You should probably run this through clang-format.

818

Add a comment here that highlights the fact that the wrapped value can be smaller than the FCA and that we are possibly loosing dereferencability information here. We're okay with that for now, but it would be good to have it documented.

test/Transforms/InstCombine/aggregate-store.ll
15 ↗(On Diff #21330)

Once you get the new stores onto the worklist, please add a test case for the nested struct case.

deadalnix updated this revision to Diff 21407.Mar 6 2015, 4:05 PM

Add a test for struct in struct.
Fix pointer declaration style.

deadalnix added inline comments.Mar 6 2015, 4:07 PM
lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
804

None of this is not required, the builder sue a custom inserted that do it already. As for the bool return, I followed convention existing in the file.

818

It does not appear to be possible in the case where we have struct with one element.

deadalnix updated this revision to Diff 21504.Mar 9 2015, 11:41 AM

Rebase
Friendly ping as the last requested update was done late on friday, so most likely is lost deep down in everybody's queue at this point.

reames added inline comments.Mar 9 2015, 4:46 PM
lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
804

I forgot about the custom inserter and the surrounding code appears to use a mixture of implicit and explicit adds. Comment withdrawn.

818

Ok. I haven't thought about this hard, but this seems likely to be true. Even if not, it's not a big deal at the moment.

chandlerc accepted this revision.Mar 10 2015, 2:38 PM
chandlerc added a reviewer: chandlerc.

LGTM, feel free to commit.

One nit, I would name the test case just "fca-decomposition" or something so we can add both load and store test cases to a single file.

This revision is now accepted and ready to land.Mar 10 2015, 2:38 PM
deadalnix updated this revision to Diff 21871.Mar 12 2015, 1:13 PM
deadalnix edited edge metadata.

Rebase and rename test

arc land

Is telling me that I can't land and

git svn dcommit

Ask me for my password (which ?). I've been through http://llvm.org/docs/Phabricator.html but couldn't find what i was looking for. What is the expected setup ?

majnemer added inline comments.
lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
815

Please write this as StructType *ST