[PATCH] D47735: [DAGCombiner] Create rotates more aggressively
Roman Lebedev via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 10 15:33:34 PDT 2019
lebedev.ri requested changes to this revision.
lebedev.ri added a comment.
This revision now requires changes to proceed.
After thinking about it, i think it may make sense to have this after all.
I left some comments.
Also, it would be good to have some compile-time stats comparison here.
I really think you want do add some safety limits from the getgo.
E.g. would it make sense to have more than 8 levels of these `or`s?
More than 256 nodes? Etc.
================
Comment at: lib/CodeGen/SelectionDAG/DAGCombiner.cpp:5499-5500
+SDNode *DAGCombiner::ReassociateOrForRotate(SDValue Op0, SDValue Op1,
+ const SDLoc &dl) {
+ EVT VT = Op0.getValueType();
+ if (!hasOperation(ISD::ROTL, VT) && !hasOperation(ISD::ROTR, VT))
----------------
Do you want to assert that you start with `ISD::OR`?
================
Comment at: lib/CodeGen/SelectionDAG/DAGCombiner.cpp:5504
+
+ // Expand all single-use ORs into a list (OredOps).
+ SmallVector<SDValue,8> OredOps;
----------------
This comment should be next to the loop itself.
It would be best to explain the data structures here instead.
================
Comment at: lib/CodeGen/SelectionDAG/DAGCombiner.cpp:5516-5527
+ } else
+ OredOps.push_back(V);
+ }
+
+ // Since only shifts of the same SDValue can end up paired up into a rotate,
+ // create separate lists of shifts for each shifted value.
+ DenseMap<int,SmallVector<unsigned,8>> OpMap;
----------------
Can you not do this
```
if (Opc == ISD::SHL || Opc == ISD::SRL)
OpMap[V.getOperand(0)->getNodeId()].push_back(I);
```
inside
```
} else
OredOps.push_back(V);
```
?
One less loop.
================
Comment at: lib/CodeGen/SelectionDAG/DAGCombiner.cpp:5521
+ // Since only shifts of the same SDValue can end up paired up into a rotate,
+ // create separate lists of shifts for each shifted value.
+ DenseMap<int,SmallVector<unsigned,8>> OpMap;
----------------
```
// for each shifted value, create a list of shifts.
```
================
Comment at: lib/CodeGen/SelectionDAG/DAGCombiner.cpp:5522
+ // create separate lists of shifts for each shifted value.
+ DenseMap<int,SmallVector<unsigned,8>> OpMap;
+ for (unsigned I = 0, E = OredOps.size(); I != E; ++I) {
----------------
This data structure really needs a better name/description.
================
Comment at: lib/CodeGen/SelectionDAG/DAGCombiner.cpp:5538-5539
+
+ for (auto P : OpMap) {
+ auto &Shifts = P.second;
+ assert(!Shifts.empty() && "OpMap should not have empty lists");
----------------
I'm not sure whether or not `auto` is good here..
================
Comment at: lib/CodeGen/SelectionDAG/DAGCombiner.cpp:5541
+ assert(!Shifts.empty() && "OpMap should not have empty lists");
+ llvm::sort(Shifts.begin(), Shifts.end(), OpcOrder);
+ // The list of shifts should only have SHL and SRL on it grouped into
----------------
Do we care about the order within those two groups? Is this still good in reverse-iteration mode?
================
Comment at: lib/CodeGen/SelectionDAG/DAGCombiner.cpp:5542-5545
+ // The list of shifts should only have SHL and SRL on it grouped into
+ // two contiguous segments. Find the beginning of the second segment.
+ auto Boundary = std::upper_bound(std::next(Shifts.begin()), Shifts.end(),
+ Shifts.front(), OpcOrder);
----------------
`llvm::partition_point()`?
================
Comment at: lib/CodeGen/SelectionDAG/DAGCombiner.cpp:5547-5549
+ for (unsigned I = 0, E = Boundary - Shifts.begin(); I != E; ++I) {
+ for (unsigned J = E, F = Shifts.size(); J != F; ++J) {
+ SDValue &OI = OredOps[Shifts[I]], &OJ = OredOps[Shifts[J]];
----------------
I'm not sure what is going on here, would be good to have a high-level description comment.
================
Comment at: lib/CodeGen/SelectionDAG/DAGCombiner.cpp:5552
+ continue;
+ if (SDNode *T = MatchRotate(OI, OJ, dl)) {
+ OredOps.push_back(SDValue(T, 0));
----------------
Early `continue`?
================
Comment at: lib/CodeGen/SelectionDAG/DAGCombiner.cpp:5569
+ return nullptr;
+
+ auto OredEnd = remove_if(OredOps, [](SDValue V) { return !bool(V); });
----------------
Likewise, this really needs to have a high-level description comment.
Repository:
rL LLVM
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D47735/new/
https://reviews.llvm.org/D47735
More information about the llvm-commits
mailing list