From: Krzysztof Parzyszek Date: Thu, 9 Mar 2017 19:14:23 +0000 (+0000) Subject: [Hexagon] Refactor the DAG preprocessing code, NFC X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6779169075df78a0869031a81bd825237827229c;p=llvm [Hexagon] Refactor the DAG preprocessing code, NFC Extract individual transformations into their own functions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297401 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp index 632f2a3065f..8e10c521a77 100644 --- a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp +++ b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp @@ -123,6 +123,12 @@ private: bool isAlignedMemNode(const MemSDNode *N) const; bool isPositiveHalfWord(const SDNode *N) const; + // DAG preprocessing functions. + void ppSimplifyOrSelect0(std::vector &&Nodes); + void ppAddrReorderAddShl(std::vector &&Nodes); + void ppAddrRewriteAndSrl(std::vector &&Nodes); + void ppHoistZextI1(std::vector &&Nodes); + SmallDenseMap RootWeights; SmallDenseMap RootHeights; SmallDenseMap 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 &&Nodes) { SelectionDAG &DAG = *CurDAG; - std::vector 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 &&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 &&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 &&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 { + std::vector 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"; - ); + }); } }