forked from OSchip/llvm-project
[Hexagon] Refactor the DAG preprocessing code, NFC
Extract individual transformations into their own functions. llvm-svn: 297401
This commit is contained in:
parent
0a2a1311df
commit
fe267a37f4
|
@ -123,6 +123,12 @@ private:
|
|||
bool isAlignedMemNode(const MemSDNode *N) const;
|
||||
bool isPositiveHalfWord(const SDNode *N) const;
|
||||
|
||||
// DAG preprocessing functions.
|
||||
void ppSimplifyOrSelect0(std::vector<SDNode*> &&Nodes);
|
||||
void ppAddrReorderAddShl(std::vector<SDNode*> &&Nodes);
|
||||
void ppAddrRewriteAndSrl(std::vector<SDNode*> &&Nodes);
|
||||
void ppHoistZextI1(std::vector<SDNode*> &&Nodes);
|
||||
|
||||
SmallDenseMap<SDNode *,int> RootWeights;
|
||||
SmallDenseMap<SDNode *,int> RootHeights;
|
||||
SmallDenseMap<const Value *,int> GAUsesInFunction;
|
||||
|
@ -1017,15 +1023,11 @@ static bool isMemOPCandidate(SDNode *I, SDNode *U) {
|
|||
}
|
||||
|
||||
|
||||
void HexagonDAGToDAGISel::PreprocessISelDAG() {
|
||||
// Transform: (or (select c x 0) z) -> (select c (or x z) z)
|
||||
// (or (select c 0 y) z) -> (select c z (or y z))
|
||||
void HexagonDAGToDAGISel::ppSimplifyOrSelect0(std::vector<SDNode*> &&Nodes) {
|
||||
SelectionDAG &DAG = *CurDAG;
|
||||
std::vector<SDNode*> Nodes;
|
||||
for (SDNode &Node : DAG.allnodes())
|
||||
Nodes.push_back(&Node);
|
||||
|
||||
// Simplify: (or (select c x 0) z) -> (select c (or x z) z)
|
||||
// (or (select c 0 y) z) -> (select c z (or y z))
|
||||
// This may not be the right thing for all targets, so do it here.
|
||||
for (auto I : Nodes) {
|
||||
if (I->getOpcode() != ISD::OR)
|
||||
continue;
|
||||
|
@ -1063,13 +1065,17 @@ void HexagonDAGToDAGISel::PreprocessISelDAG() {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transform: (store ch val (add x (add (shl y c) e)))
|
||||
// to: (store ch val (add x (shl (add y d) c))),
|
||||
// where e = (shl d c) for some integer d.
|
||||
// The purpose of this is to enable generation of loads/stores with
|
||||
// shifted addressing mode, i.e. mem(x+y<<#c). For that, the shift
|
||||
// value c must be 0, 1 or 2.
|
||||
void HexagonDAGToDAGISel::ppAddrReorderAddShl(std::vector<SDNode*> &&Nodes) {
|
||||
SelectionDAG &DAG = *CurDAG;
|
||||
|
||||
// Transform: (store ch val (add x (add (shl y c) e)))
|
||||
// to: (store ch val (add x (shl (add y d) c))),
|
||||
// where e = (shl d c) for some integer d.
|
||||
// The purpose of this is to enable generation of loads/stores with
|
||||
// shifted addressing mode, i.e. mem(x+y<<#c). For that, the shift
|
||||
// value c must be 0, 1 or 2.
|
||||
for (auto I : Nodes) {
|
||||
if (I->getOpcode() != ISD::STORE)
|
||||
continue;
|
||||
|
@ -1116,20 +1122,24 @@ void HexagonDAGToDAGISel::PreprocessISelDAG() {
|
|||
SDValue NewShl = DAG.getNode(ISD::SHL, DL, VT, NewAdd, C);
|
||||
ReplaceNode(T0.getNode(), NewShl.getNode());
|
||||
}
|
||||
}
|
||||
|
||||
// Transform: (load ch (add x (and (srl y c) Mask)))
|
||||
// to: (load ch (add x (shl (srl y d) d-c)))
|
||||
// where
|
||||
// Mask = 00..0 111..1 0.0
|
||||
// | | +-- d-c 0s, and d-c is 0, 1 or 2.
|
||||
// | +-------- 1s
|
||||
// +-------------- at most c 0s
|
||||
// Motivating example:
|
||||
// DAG combiner optimizes (add x (shl (srl y 5) 2))
|
||||
// to (add x (and (srl y 3) 1FFFFFFC))
|
||||
// which results in a constant-extended and(##...,lsr). This transformation
|
||||
// undoes this simplification for cases where the shl can be folded into
|
||||
// an addressing mode.
|
||||
void HexagonDAGToDAGISel::ppAddrRewriteAndSrl(std::vector<SDNode*> &&Nodes) {
|
||||
SelectionDAG &DAG = *CurDAG;
|
||||
|
||||
// Transform (load ch (add x (and (srl y c) Mask)))
|
||||
// to: (load ch (add x (shl (srl y d) d-c)))
|
||||
// where
|
||||
// Mask = 00..0 111..1 0.0
|
||||
// | | +-- d-c 0s, and d-c is 0, 1 or 2.
|
||||
// | +-------- 1s
|
||||
// +-------------- at most c 0s
|
||||
// Motivating example:
|
||||
// DAG combiner optimizes (add x (shl (srl y 5) 2))
|
||||
// to (add x (and (srl y 3) 1FFFFFFC))
|
||||
// which results in a constant-extended and(##...,lsr). This transformation
|
||||
// undoes this simplification for cases where the shl can be folded into
|
||||
// an addressing mode.
|
||||
for (SDNode *N : Nodes) {
|
||||
unsigned Opc = N->getOpcode();
|
||||
if (Opc != ISD::LOAD && Opc != ISD::STORE)
|
||||
|
@ -1188,9 +1198,13 @@ void HexagonDAGToDAGISel::PreprocessISelDAG() {
|
|||
SDValue NewShl = DAG.getNode(ISD::SHL, dl, VT, NewSrl, DC);
|
||||
ReplaceNode(T0.getNode(), NewShl.getNode());
|
||||
}
|
||||
}
|
||||
|
||||
// Transform: (op ... (zext i1 c) ...) -> (select c (op ... 0 ...)
|
||||
// (op ... 1 ...))
|
||||
void HexagonDAGToDAGISel::ppHoistZextI1(std::vector<SDNode*> &&Nodes) {
|
||||
SelectionDAG &DAG = *CurDAG;
|
||||
|
||||
// Transform (op (zext (i1 c) t)
|
||||
// to (select c (op 0 t) (op 1 t))
|
||||
for (SDNode *N : Nodes) {
|
||||
unsigned Opc = N->getOpcode();
|
||||
if (Opc != ISD::ZERO_EXTEND)
|
||||
|
@ -1238,6 +1252,49 @@ void HexagonDAGToDAGISel::PreprocessISelDAG() {
|
|||
DAG.ReplaceAllUsesWith(U, Sel.getNode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HexagonDAGToDAGISel::PreprocessISelDAG() {
|
||||
// Repack all nodes before calling each preprocessing function,
|
||||
// because each of them can modify the set of nodes.
|
||||
auto getNodes = [this] () -> std::vector<SDNode*> {
|
||||
std::vector<SDNode*> T;
|
||||
T.reserve(CurDAG->allnodes_size());
|
||||
for (SDNode &N : CurDAG->allnodes())
|
||||
T.push_back(&N);
|
||||
return T;
|
||||
};
|
||||
|
||||
// Transform: (or (select c x 0) z) -> (select c (or x z) z)
|
||||
// (or (select c 0 y) z) -> (select c z (or y z))
|
||||
ppSimplifyOrSelect0(getNodes());
|
||||
|
||||
// Transform: (store ch val (add x (add (shl y c) e)))
|
||||
// to: (store ch val (add x (shl (add y d) c))),
|
||||
// where e = (shl d c) for some integer d.
|
||||
// The purpose of this is to enable generation of loads/stores with
|
||||
// shifted addressing mode, i.e. mem(x+y<<#c). For that, the shift
|
||||
// value c must be 0, 1 or 2.
|
||||
ppAddrReorderAddShl(getNodes());
|
||||
|
||||
// Transform: (load ch (add x (and (srl y c) Mask)))
|
||||
// to: (load ch (add x (shl (srl y d) d-c)))
|
||||
// where
|
||||
// Mask = 00..0 111..1 0.0
|
||||
// | | +-- d-c 0s, and d-c is 0, 1 or 2.
|
||||
// | +-------- 1s
|
||||
// +-------------- at most c 0s
|
||||
// Motivating example:
|
||||
// DAG combiner optimizes (add x (shl (srl y 5) 2))
|
||||
// to (add x (and (srl y 3) 1FFFFFFC))
|
||||
// which results in a constant-extended and(##...,lsr). This transformation
|
||||
// undoes this simplification for cases where the shl can be folded into
|
||||
// an addressing mode.
|
||||
ppAddrRewriteAndSrl(getNodes());
|
||||
|
||||
// Transform: (op ... (zext i1 c) ...) -> (select c (op ... 0 ...)
|
||||
// (op ... 1 ...))
|
||||
ppHoistZextI1(getNodes());
|
||||
|
||||
DEBUG_WITH_TYPE("isel", {
|
||||
dbgs() << "Preprocessed (Hexagon) selection DAG:";
|
||||
|
@ -1247,11 +1304,10 @@ void HexagonDAGToDAGISel::PreprocessISelDAG() {
|
|||
if (EnableAddressRebalancing) {
|
||||
rebalanceAddressTrees();
|
||||
|
||||
DEBUG(
|
||||
dbgs() << "************* SelectionDAG after preprocessing: ***********\n";
|
||||
DEBUG_WITH_TYPE("isel", {
|
||||
dbgs() << "Address tree balanced selection DAG:";
|
||||
CurDAG->dump();
|
||||
dbgs() << "************* End SelectionDAG after preprocessing ********\n";
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue