This is an archive of the discontinued LLVM Phabricator instance.

[SelectionDAG] Store LeadingZero count in LiveOutInfo instead of KnownBits.
Needs ReviewPublic

Authored by craig.topper on Mar 21 2022, 5:22 PM.

Details

Summary

Previously we stored two APInts for KnownBits. This information is
only ever used to create AssertZExts using the number of known
leading zeros. It's inefficient to store this information in APInt
form.

This patch switches the storage to store the number of leading zeros.

I've also removed the IsValid flag and now rely on default constructing
with the safest values and reseting to the safe values when we need
to invalidate. The IsValid flag was inconsistently used before.
We could default construct entries in LiveRegOut with IsValid=true and
BitWidth=1 instead of default constructing as IsValid=false.

Diff Detail

Event Timeline

craig.topper created this revision.Mar 21 2022, 5:22 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 21 2022, 5:22 PM
craig.topper requested review of this revision.Mar 21 2022, 5:22 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 21 2022, 5:22 PM
Herald added a subscriber: wdng. · View Herald Transcript

How useful would it be to flip this - and generate some kind of ISD::AssertKnownBits node instead of ISD::AssertZext ?

How useful would it be to flip this - and generate some kind of ISD::AssertKnownBits node instead of ISD::AssertZext ?

I'm not sure. One case I do want to look at is trailing zeros for the reccurrence case that shows up in loop unrolling.

loop:
   X = phi [0, preheader], [X.increment, loop]
   ...
   or X, 1
   ...
   or X, 2
   ...
   or X, 3
   ...
   X.increment = add X, 4
   ...
   br loop

X has 2 trailing zero bits so the ORs can be converted back to ADDs.

Adding a trailing zeros field is a straightforward extension to this patch and is still less storage than the 2 APInts. I think we might be able to reuse the AssertAlign node for it.

Alignment, one bit and known negative values would all be nice to have - I'm just not sure if they'd make a huge difference.

Alignment, one bit and known negative values would all be nice to have - I'm just not sure if they'd make a huge difference.

For "one bit" would we have to call isKnownToBeAPowerOfTwo in addition to computeKnownBits?

Alignment, one bit and known negative values would all be nice to have - I'm just not sure if they'd make a huge difference.

For "one bit" would we have to call isKnownToBeAPowerOfTwo in addition to computeKnownBits?

one bit I meant KnownBits::countMaxPopulation() == 1 (i.e. all but one bit is known zero - it might be pow2 or zero)

Something else that we might benefit from is if we can tag when a live out value is known never to be poison/undef - I guess we can do that by adding a freeze.

Alignment, one bit and known negative values would all be nice to have - I'm just not sure if they'd make a huge difference.

For "one bit" would we have to call isKnownToBeAPowerOfTwo in addition to computeKnownBits?

one bit I meant KnownBits::countMaxPopulation() == 1 (i.e. all but one bit is known zero - it might be pow2 or zero)

Having both leading and trailing zeros and their sum being 1 less than the bitwidth would cover this right?

Any objection to this patch? Or do we think we need a fully general cross basic block known bits that we will hook up through something more than AssertZExt someday soon?

I have been meaning to investigate adding a general AssertKnownBits DAG node, but haven't done anything on this yet.

Is your main concern about saving memory in LiveOutInfo classes?

I have been meaning to investigate adding a general AssertKnownBits DAG node, but haven't done anything on this yet.

Is your main concern about saving memory in LiveOutInfo classes?

It saves memory. I think this simplifies how we keep track of this data being valid. We did an odd thing with a single bit KnownBits value before. See the code on line 422 of FunctionLoweringInfo::GetLiveOutRegInfo.

My original motivation was to try to solve the or_is_add problem on phi recurrences in unrolled loops. Those typically are trailing bits related where the phi has an aligned constant start value(usually 0), and that is incremented by an aligned constant. I was going to use matchSimpleRecurrence to detect that pattern in FunctionLoweringInfo's PHI handling then use that information to mark trailing zeros and add an AssertAlign. By explicitly storing trailing zeros and leading zeros separately instead of KnownBits I could restrict exactly when the AssertAlign would be inserted to only the phi case. Just inserting an AssertAlign based on the KnownBits we have now starts breaking lit tests. I haven't looked at it since March.