This is an archive of the discontinued LLVM Phabricator instance.

[Attributor] ValueSimplify Abstract Attribute
ClosedPublic

Authored by uenoku on Aug 29 2019, 11:26 AM.

Details

Summary

This patch introduces initial AAValueSimplify which simplifies a value in a context.

example

  • (for function returned) If all the return values are the same and constant, then we can replace callsite returned with the constant.
  • If an internal function takes the same value(constant) as an argument in the callsite, then we can replace the argument with that constant.

Diff Detail

Repository
rL LLVM

Event Timeline

uenoku created this revision.Aug 29 2019, 11:26 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 29 2019, 11:26 AM

First prototype of value simplify attribute is here. I'll add additional test later.

I like it! First comments inlined.

llvm/lib/Transforms/IPO/Attributor.cpp
2390 ↗(On Diff #217945)

I guess you need to track dependences here somewhere.

2447 ↗(On Diff #217945)

Why unchanged? Don't we have to indicate *any* change in the state? (Same below)

2457 ↗(On Diff #217945)

The associated function needs to have an exact definition as well.

2477 ↗(On Diff #217945)

There is a version that omits the ReturnInst vector if you don't need it.

2496 ↗(On Diff #217945)

GenericValueTraversal time ;)

2500 ↗(On Diff #217945)

I know I started this habit but I now think it is a bad idea to shortcut the classes with using. For one, we don't have nice statistics. Also, the class can derive from the other one and it won't be much more code.

3281 ↗(On Diff #217945)

I think we want this to exists for *all* position kinds.

Think of an indirect call that takes a function pointer. We see a function pointer phi, which resolves to different functions, which we cannot simplify further but we should be able to handle it.

uenoku updated this revision to Diff 218093.Aug 30 2019, 7:14 AM
uenoku marked 6 inline comments as done.

Address comment and refactor.

uenoku added inline comments.Aug 30 2019, 7:26 AM
llvm/lib/Transforms/IPO/Attributor.cpp
2517 ↗(On Diff #218093)

GenericValueTraversal time ;)

About genericValueTraversal, I couldn't come up with generalized way to handle simplification for each instruction. ex)

%call = tail call i32 %fun() ; -> simplified to 1 
%tmp = add i32 %call, 1 ; -> this should be simplified to 2
%tmp2 = mul i32 %tmp, %tmp ;-> this should be simplified to 4

Do you have any idea?

jdoerfert added inline comments.Aug 30 2019, 12:12 PM
llvm/lib/Transforms/IPO/Attributor.cpp
2517 ↗(On Diff #218093)

So, you want to reuse the logic in llvm/lib/Analysis/InstructionSimplify.cpp with the assumptions but we can do that later.

jdoerfert added inline comments.Aug 31 2019, 11:07 AM
llvm/lib/Transforms/IPO/Attributor.cpp
2373 ↗(On Diff #218093)

Can we add more description for the parameters here and maybe rename ExistNone to something more descriptive wrt. what that means.

2413 ↗(On Diff #218093)

Why check for arguments and why check for users? Just replace all users of V with C or do I miss sth?

2431 ↗(On Diff #218093)

No need for this check, I think. we always have an associated function for arguments and even if the definition is not exact, we can use information from the call sites to improve this definition.

2465 ↗(On Diff #218093)

AA...Returned always has an associated function.

2447 ↗(On Diff #217945)

I'm unsure about this. Even if None was not observed we could still lose the information if it was assumed, right? I would prefer to be careful also wrt. to future extensions that could break some invariant here.

2496 ↗(On Diff #217945)

I think the AAValueSimplifyImpl::manifest should be fine here once the attribute specialization is gone. You can test it with some phi tests for example.

uenoku updated this revision to Diff 218262.Sep 1 2019, 7:12 AM

Address comment

uenoku marked 5 inline comments as done.Sep 1 2019, 7:16 AM
uenoku added inline comments.
llvm/lib/Transforms/IPO/Attributor.cpp
2447 ↗(On Diff #217945)

I'm unsure about this. Even if None was not observed we could still lose the information if it was assumed, right?

I agree. I erased them.

jdoerfert added inline comments.Sep 3 2019, 9:05 AM
llvm/lib/Transforms/IPO/Attributor.cpp
2374 ↗(On Diff #218262)

The names below are too confusing, rename one as "existing.." or sth.

2397 ↗(On Diff #218262)

Deal with undef as well and at some point with bitcasts and stuff.

2420 ↗(On Diff #218262)

Add a FIXME for a typecast or add the typecast (+ test).

2436 ↗(On Diff #218262)

No need for this check, I think. ...

2530 ↗(On Diff #218262)

genericValueTraversal above should deal with select and phi, correct? Do we have tests?

jdoerfert added inline comments.Sep 3 2019, 9:08 AM
llvm/lib/Transforms/IPO/Attributor.cpp
2514 ↗(On Diff #218262)

I am unsure. There are more values in the worklist of the genericValueTraversal which we need to visit and which could change things, right?

uenoku marked an inline comment as done.Sep 3 2019, 9:21 AM
uenoku added inline comments.
llvm/lib/Transforms/IPO/Attributor.cpp
2514 ↗(On Diff #218262)

As I look at genericValueTraversal , Stripped is false if associated value is a leaf (then there is no value in the worklist) so I thought it is more convinient to regard this value as simplifed. Is this wrong?

jdoerfert added inline comments.Sep 3 2019, 9:45 AM
llvm/lib/Transforms/IPO/Attributor.cpp
2514 ↗(On Diff #218262)

You are right. Forget my comment.

uenoku updated this revision to Diff 218477.Sep 3 2019, 10:01 AM

Address comment. Add simple test for phi and select.

uenoku marked 8 inline comments as done.Sep 3 2019, 10:03 AM
uenoku added inline comments.
llvm/lib/Transforms/IPO/Attributor.cpp
2530 ↗(On Diff #218262)

Add test in @test-select-phi in value-simplify.ll.

jdoerfert added inline comments.Sep 3 2019, 4:31 PM
llvm/lib/Transforms/IPO/Attributor.cpp
2649 ↗(On Diff #218477)

remove the above three lines.

2670 ↗(On Diff #218477)

Add short documentation here please.

llvm/test/Transforms/FunctionAttrs/value-simplify.ll
97 ↗(On Diff #218477)

Could you make it (or add)
%phi-same = phi i32 [ 1, %if-true ], [ %select-same, %if-false ]

uenoku updated this revision to Diff 218592.Sep 3 2019, 10:21 PM

Address comment and add test for undef.

We should make sure we track statistics properly, e.g., only if the simplified value is different from the original value we track sth.
This would be automatic if simplified value = original value will imply an "invalid state".

llvm/test/Transforms/FunctionAttrs/value-simplify.ll
117 ↗(On Diff #218592)

This should arguably be

`; CHECK: tail call void @use(i32 %phi-not-same)`

The pessimistic fixpoint should probably not revert to nullptr and cause a cascading failure but instead just go back to the original value.

uenoku marked an inline comment as done.Sep 5 2019, 1:31 AM
uenoku added inline comments.
llvm/test/Transforms/FunctionAttrs/value-simplify.ll
117 ↗(On Diff #218592)

This should arguably be

; CHECK: tail call void @use(i32 %phi-not-same)

In genericTraversal, %phi-not-same is decomposed to i32 0, 1 so I think it is not currect.

The pessimistic fixpoint should probably not revert to nullptr and cause a cascading failure but instead just go back to the original value.

It looks good.

jdoerfert added inline comments.Sep 5 2019, 10:15 AM
llvm/test/Transforms/FunctionAttrs/value-simplify.ll
117 ↗(On Diff #218592)

so %phi-not-same is not simplified, right?
But %select-not-same-undef is something or undef and then we should simplify it to "something". That would probably happen just fine if we do not use nullptr as pessimistic value but the original value itself. That is, the worst thing you can simplify an instruction to is itself.

uenoku updated this revision to Diff 218963.Sep 5 2019, 11:54 AM

Change to return the original value when in the pessimistic state.

Change to return the original value when in the pessimistic state.

Did this change the test?

uenoku marked an inline comment as done.Sep 5 2019, 12:01 PM
uenoku added inline comments.
llvm/test/Transforms/FunctionAttrs/value-simplify.ll
117 ↗(On Diff #218592)

so %phi-not-same is not simplified, right?

Yes

But %select-not-same-undef is something or undef and then we should simplify it to "something".

In the simplification of %select-not-same-undef, traversed values are 0, 1, undef and we don't look at %phi-not-same variable itself.

Anyway, I changed to return original value in the pessimistic state and simplified value(always not equals to original value ) in the optimistic state.

Change to return the original value when in the pessimistic state.

Did this change the test?

No. I think it is ok.

jdoerfert added inline comments.Sep 5 2019, 2:24 PM
llvm/test/Transforms/FunctionAttrs/value-simplify.ll
117 ↗(On Diff #218592)

In the simplification of %select-not-same-undef, traversed values are 0, 1, undef and we don't look at %phi-not-same variable itself.

But the possible values for %select-not-same-undef should be [%phi-not-same, undef]. which we can simplify to %phi-not-same.

uenoku marked an inline comment as done.Sep 6 2019, 1:35 AM
uenoku added inline comments.
llvm/test/Transforms/FunctionAttrs/value-simplify.ll
117 ↗(On Diff #218592)

If so we need to change GenericValueTraversal a bit.

jdoerfert added inline comments.Sep 6 2019, 9:55 AM
llvm/test/Transforms/FunctionAttrs/value-simplify.ll
117 ↗(On Diff #218592)

Why? What if the VisitValueCB would never return false?

uenoku marked an inline comment as done.Sep 6 2019, 10:18 AM
uenoku added inline comments.
llvm/test/Transforms/FunctionAttrs/value-simplify.ll
117 ↗(On Diff #218592)

I think GenericValueTraversal is working in following way:

worklist : [%select-not-same-undef]
worklist : [%phi-not-same, undef]
worklist : [i32 1, i32 0, undef]
VisitValueCB(1) ; Simplified Value None -> i32 1
VisitValueCB(0) ; Simplified Value i32 1 -> %select-not-same-undef (revert to orignal)

Then we never call VisitValueCB(%phi-not-same).
If we want to simplify the value to %phi-not-same, we have to change to traverse not leaves but nodes (only direct children).

worklist : [%phi-not-same, undef]
VisitValueCB(%phi-not-same) ; Simplified Value None -> %phi-not-same
VisitValueCB(undef) ; Simplified Value doesn't change
jdoerfert accepted this revision.Sep 6 2019, 10:50 AM

LGTM.

llvm/test/Transforms/FunctionAttrs/value-simplify.ll
117 ↗(On Diff #218592)

I get it now.

We could *not* use the GenericValueTraversal as we actually want to look at selects and phis here. Or we need to track more state and extend GenericValueTraversal. Let's postpone this for a follow up.

This revision is now accepted and ready to land.Sep 6 2019, 10:50 AM
uenoku updated this revision to Diff 219223.Sep 6 2019, 11:52 PM

Minor update.

This revision was automatically updated to reflect the committed changes.