Generalize flag carrying SDNodes beyond binary ops. NFC.
ClosedPublic

Authored by aemerson on Apr 26 2017, 3:02 AM.

Details

Summary

The flags have been moved into SDNode, and the BinaryWithFlagsSDNode class has been removed. The flags also contain a new "defined" state to allow intersecting between defined flags, and those which have just been default-constructed but never set. As a result of these changes, flags are now passed by value, so all the users have been updated.

This also paves the way to easily extend flags to 3 operand nodes.

Diff Detail

Repository
rL LLVM
aemerson created this revision.Apr 26 2017, 3:02 AM

The flags args needs to be added to unary op getNode via SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef<SDValue> Ops, const SDNodeFlags *Flags)

aemerson updated this revision to Diff 96724.Apr 26 2017, 6:23 AM

Added more patch context.

Is there an advantage to this vs. just putting the flags in the base SDNode class? We're going to eventually want to use the flags for more than unary and binary nodes (eg, FMA), so I'd prefer to just go directly to that step.

Is there an advantage to this vs. just putting the flags in the base SDNode class? We're going to eventually want to use the flags for more than unary and binary nodes (eg, FMA), so I'd prefer to just go directly to that step.

I'm not the original author of the code but I think this is due to the extra 2 bytes of storage needed for the flags in each SDNode. With the current solution we only incur this cost if we have flags to store.

Is there an advantage to this vs. just putting the flags in the base SDNode class? We're going to eventually want to use the flags for more than unary and binary nodes (eg, FMA), so I'd prefer to just go directly to that step.

I'm not the original author of the code but I think this is due to the extra 2 bytes of storage needed for the flags in each SDNode. With the current solution we only incur this cost if we have flags to store.

It's been a long time since D8900, but IIRC, the size argument was actually moot because we have "free" bytes based on the struct alignment (at least on common 64-bit systems). As mentioned there, the fact that the flags were only on binops was a limitation that we wanted to lift even back then, but it just hasn't been done yet. If you can do that in this patch, it would be great. :)

Is there an advantage to this vs. just putting the flags in the base SDNode class? We're going to eventually want to use the flags for more than unary and binary nodes (eg, FMA), so I'd prefer to just go directly to that step.

I'm not the original author of the code but I think this is due to the extra 2 bytes of storage needed for the flags in each SDNode. With the current solution we only incur this cost if we have flags to store.

It's been a long time since D8900, but IIRC, the size argument was actually moot because we have "free" bytes based on the struct alignment (at least on common 64-bit systems). As mentioned there, the fact that the flags were only on binops was a limitation that we wanted to lift even back then, but it just hasn't been done yet. If you can do that in this patch, it would be great. :)

Sure, I'll look at doing that.

aemerson updated this revision to Diff 96907.Apr 27 2017, 6:19 AM
aemerson edited the summary of this revision. (Show Details)

Rebased and updated with requested changes. Flags are now in SDNode, with an additional "defined" state bit to preserve semantics when intersecting flags.

LGTM and cleans up some interactions nicely, I've gone ahead and added Justin here in case he wants to comment.

Seems we haven't seen Justin active for a few weeks. @spatel are you ok for this to go in?

spatel added inline comments.Apr 28 2017, 3:43 PM
include/llvm/CodeGen/SelectionDAGNodes.h
429–431 ↗(On Diff #96907)

Do we also need to check that 'this' struct isDefined?

if (!AnyDefined)
  return;

Or are the flags guaranteed defined for whatever node is making this call?

aemerson added inline comments.Apr 28 2017, 3:51 PM
include/llvm/CodeGen/SelectionDAGNodes.h
429–431 ↗(On Diff #96907)

The intersection can only zero out bits, and if the current flags aren't defined then this operation won't have any effect since they're already zero.

spatel accepted this revision.Apr 28 2017, 4:04 PM

LGTM - thanks for fixing this!

See inline comment for one minor potential diff.

lib/CodeGen/SelectionDAG/SelectionDAG.cpp
5964 ↗(On Diff #96907)

Should we wait to make this change until there is a transform that uses it (and therefore a test to prove it)?

This revision is now accepted and ready to land.Apr 28 2017, 4:04 PM
aemerson added inline comments.May 1 2017, 7:59 AM
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
5964 ↗(On Diff #96907)

Makes sense, I'll move this change to the next patch in the series.

This revision was automatically updated to reflect the committed changes.