comparison lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp @ 148:63bd29f05246

merged
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 14 Aug 2019 19:46:37 +0900
parents c2174574ed3a
children
comparison
equal deleted inserted replaced
146:3fc4d5c3e21e 148:63bd29f05246
1 //===-- HexagonISelDAGToDAGHVX.cpp ----------------------------------------===// 1 //===-- HexagonISelDAGToDAGHVX.cpp ----------------------------------------===//
2 // 2 //
3 // The LLVM Compiler Infrastructure 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // 4 // See https://llvm.org/LICENSE.txt for license information.
5 // This file is distributed under the University of Illinois Open Source 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 // License. See LICENSE.TXT for details.
7 // 6 //
8 //===----------------------------------------------------------------------===// 7 //===----------------------------------------------------------------------===//
9 8
10 #include "Hexagon.h" 9 #include "Hexagon.h"
11 #include "HexagonISelDAGToDAG.h" 10 #include "HexagonISelDAGToDAG.h"
118 if (Color == ColorKind::None) 117 if (Color == ColorKind::None)
119 return ColorKind::Red; 118 return ColorKind::Red;
120 return Color == ColorKind::Red ? ColorKind::Black : ColorKind::Red; 119 return Color == ColorKind::Red ? ColorKind::Black : ColorKind::Red;
121 } 120 }
122 121
123 void dump() const; 122 LLVM_DUMP_METHOD void dump() const;
124 123
125 private: 124 private:
126 ArrayRef<Node> Order; 125 ArrayRef<Node> Order;
127 MapType Colors; 126 MapType Colors;
128 std::set<Node> Needed; 127 std::set<Node> Needed;
257 } 256 }
258 Colors[N] = ColorN; 257 Colors[N] = ColorN;
259 Colors[C] = ColorC; 258 Colors[C] = ColorC;
260 } 259 }
261 260
262 // Explicitly assign "None" all all uncolored nodes. 261 // Explicitly assign "None" to all uncolored nodes.
263 for (unsigned I = 0; I != Order.size(); ++I) 262 for (unsigned I = 0; I != Order.size(); ++I)
264 if (Colors.count(I) == 0) 263 if (Colors.count(I) == 0)
265 Colors[I] = ColorKind::None; 264 Colors[I] = ColorKind::None;
266 265
267 return true; 266 return true;
268 } 267 }
269 268
270 LLVM_DUMP_METHOD 269 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
271 void Coloring::dump() const { 270 void Coloring::dump() const {
272 dbgs() << "{ Order: {"; 271 dbgs() << "{ Order: {";
273 for (unsigned I = 0; I != Order.size(); ++I) { 272 for (unsigned I = 0; I != Order.size(); ++I) {
274 Node P = Order[I]; 273 Node P = Order[I];
275 if (P != Ignore) 274 if (P != Ignore)
307 dbgs() << " Colors: {\n"; 306 dbgs() << " Colors: {\n";
308 for (auto C : Colors) 307 for (auto C : Colors)
309 dbgs() << " " << C.first << " -> " << ColorKindToName(C.second) << "\n"; 308 dbgs() << " " << C.first << " -> " << ColorKindToName(C.second) << "\n";
310 dbgs() << " }\n}\n"; 309 dbgs() << " }\n}\n";
311 } 310 }
311 #endif
312 312
313 namespace { 313 namespace {
314 // Base class of for reordering networks. They don't strictly need to be 314 // Base class of for reordering networks. They don't strictly need to be
315 // permutations, as outputs with repeated occurrences of an input element 315 // permutations, as outputs with repeated occurrences of an input element
316 // are allowed. 316 // are allowed.
649 Undef = 0x80000000, 649 Undef = 0x80000000,
650 Index = 0x0FFFFFFF, // Mask of the index value. 650 Index = 0x0FFFFFFF, // Mask of the index value.
651 IndexBits = 28, 651 IndexBits = 28,
652 }; 652 };
653 653
654 LLVM_DUMP_METHOD
654 void print(raw_ostream &OS, const SelectionDAG &G) const; 655 void print(raw_ostream &OS, const SelectionDAG &G) const;
655 656
656 private: 657 private:
657 OpRef(unsigned N) : OpN(N) {} 658 OpRef(unsigned N) : OpN(N) {}
658 }; 659 };
661 NodeTemplate() = default; 662 NodeTemplate() = default;
662 unsigned Opc = 0; 663 unsigned Opc = 0;
663 MVT Ty = MVT::Other; 664 MVT Ty = MVT::Other;
664 std::vector<OpRef> Ops; 665 std::vector<OpRef> Ops;
665 666
666 void print(raw_ostream &OS, const SelectionDAG &G) const; 667 LLVM_DUMP_METHOD void print(raw_ostream &OS, const SelectionDAG &G) const;
667 }; 668 };
668 669
669 struct ResultStack { 670 struct ResultStack {
670 ResultStack(SDNode *Inp) 671 ResultStack(SDNode *Inp)
671 : InpNode(Inp), InpTy(Inp->getValueType(0).getSimpleVT()) {} 672 : InpNode(Inp), InpTy(Inp->getValueType(0).getSimpleVT()) {}
697 BaseType::const_iterator begin() const { return List.begin(); } 698 BaseType::const_iterator begin() const { return List.begin(); }
698 BaseType::const_iterator end() const { return List.end(); } 699 BaseType::const_iterator end() const { return List.end(); }
699 700
700 BaseType List; 701 BaseType List;
701 702
703 LLVM_DUMP_METHOD
702 void print(raw_ostream &OS, const SelectionDAG &G) const; 704 void print(raw_ostream &OS, const SelectionDAG &G) const;
703 }; 705 };
704 } // namespace 706 } // namespace
705 707
708 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
706 void OpRef::print(raw_ostream &OS, const SelectionDAG &G) const { 709 void OpRef::print(raw_ostream &OS, const SelectionDAG &G) const {
707 if (isValue()) { 710 if (isValue()) {
708 OpV.getNode()->print(OS, &G); 711 OpV.getNode()->print(OS, &G);
709 return; 712 return;
710 } 713 }
750 OS << '[' << I << "] "; 753 OS << '[' << I << "] ";
751 List[I].print(OS, G); 754 List[I].print(OS, G);
752 OS << '\n'; 755 OS << '\n';
753 } 756 }
754 } 757 }
758 #endif
755 759
756 namespace { 760 namespace {
757 struct ShuffleMask { 761 struct ShuffleMask {
758 ShuffleMask(ArrayRef<int> M) : Mask(M) { 762 ShuffleMask(ArrayRef<int> M) : Mask(M) {
759 for (unsigned I = 0, E = Mask.size(); I != E; ++I) { 763 for (unsigned I = 0, E = Mask.size(); I != E; ++I) {
774 } 778 }
775 ShuffleMask hi() const { 779 ShuffleMask hi() const {
776 size_t H = Mask.size()/2; 780 size_t H = Mask.size()/2;
777 return ShuffleMask(Mask.take_back(H)); 781 return ShuffleMask(Mask.take_back(H));
778 } 782 }
783
784 void print(raw_ostream &OS) const {
785 OS << "MinSrc:" << MinSrc << ", MaxSrc:" << MaxSrc << " {";
786 for (int M : Mask)
787 OS << ' ' << M;
788 OS << " }";
789 }
779 }; 790 };
780 } // namespace 791 } // namespace
781 792
782 // -------------------------------------------------------------------- 793 // --------------------------------------------------------------------
783 // The HvxSelector class. 794 // The HvxSelector class.
811 return MVT::getVectorVT(ElemTy, NumElems); 822 return MVT::getVectorVT(ElemTy, NumElems);
812 } 823 }
813 824
814 void selectShuffle(SDNode *N); 825 void selectShuffle(SDNode *N);
815 void selectRor(SDNode *N); 826 void selectRor(SDNode *N);
827 void selectVAlign(SDNode *N);
816 828
817 private: 829 private:
818 void materialize(const ResultStack &Results); 830 void materialize(const ResultStack &Results);
819 831
820 SDValue getVectorConstant(ArrayRef<uint8_t> Data, const SDLoc &dl); 832 SDValue getVectorConstant(ArrayRef<uint8_t> Data, const SDLoc &dl);
909 int N = Mask.size(); 921 int N = Mask.size();
910 return 2*Sum == N*(N-1); 922 return 2*Sum == N*(N-1);
911 } 923 }
912 924
913 bool HvxSelector::selectVectorConstants(SDNode *N) { 925 bool HvxSelector::selectVectorConstants(SDNode *N) {
914 // Constant vectors are generated as loads from constant pools or 926 // Constant vectors are generated as loads from constant pools or as
915 // as VSPLATs of a constant value. 927 // splats of a constant value. Since they are generated during the
916 // Since they are generated during the selection process, the main 928 // selection process, the main selection algorithm is not aware of them.
917 // selection algorithm is not aware of them. Select them directly 929 // Select them directly here.
918 // here.
919 SmallVector<SDNode*,4> Nodes; 930 SmallVector<SDNode*,4> Nodes;
920 SetVector<SDNode*> WorkQ; 931 SetVector<SDNode*> WorkQ;
932
933 // The one-use test for VSPLATW's operand may fail due to dead nodes
934 // left over in the DAG.
935 DAG.RemoveDeadNodes();
921 936
922 // The DAG can change (due to CSE) during selection, so cache all the 937 // The DAG can change (due to CSE) during selection, so cache all the
923 // unselected nodes first to avoid traversing a mutating DAG. 938 // unselected nodes first to avoid traversing a mutating DAG.
924 939
925 auto IsNodeToSelect = [] (SDNode *N) { 940 auto IsNodeToSelect = [] (SDNode *N) {
926 if (N->isMachineOpcode()) 941 if (N->isMachineOpcode())
927 return false; 942 return false;
928 unsigned Opc = N->getOpcode(); 943 switch (N->getOpcode()) {
929 if (Opc == HexagonISD::VSPLAT || Opc == HexagonISD::VZERO) 944 case HexagonISD::VZERO:
930 return true; 945 case HexagonISD::VSPLATW:
931 if (Opc == ISD::BITCAST) {
932 // Only select bitcasts of VSPLATs.
933 if (N->getOperand(0).getOpcode() == HexagonISD::VSPLAT)
934 return true; 946 return true;
935 } 947 case ISD::LOAD: {
936 if (Opc == ISD::LOAD) { 948 SDValue Addr = cast<LoadSDNode>(N)->getBasePtr();
937 SDValue Addr = cast<LoadSDNode>(N)->getBasePtr(); 949 unsigned AddrOpc = Addr.getOpcode();
938 unsigned AddrOpc = Addr.getOpcode(); 950 if (AddrOpc == HexagonISD::AT_PCREL || AddrOpc == HexagonISD::CP)
939 if (AddrOpc == HexagonISD::AT_PCREL || AddrOpc == HexagonISD::CP) 951 if (Addr.getOperand(0).getOpcode() == ISD::TargetConstantPool)
940 if (Addr.getOperand(0).getOpcode() == ISD::TargetConstantPool) 952 return true;
941 return true; 953 }
942 } 954 break;
943 return false; 955 }
956 // Make sure to select the operand of VSPLATW.
957 bool IsSplatOp = N->hasOneUse() &&
958 N->use_begin()->getOpcode() == HexagonISD::VSPLATW;
959 return IsSplatOp;
944 }; 960 };
945 961
946 WorkQ.insert(N); 962 WorkQ.insert(N);
947 for (unsigned i = 0; i != WorkQ.size(); ++i) { 963 for (unsigned i = 0; i != WorkQ.size(); ++i) {
948 SDNode *W = WorkQ[i]; 964 SDNode *W = WorkQ[i];
1040 return OpRef::fail(); 1056 return OpRef::fail();
1041 1057
1042 int VecLen = SM.Mask.size(); 1058 int VecLen = SM.Mask.size();
1043 MVT Ty = getSingleVT(MVT::i8); 1059 MVT Ty = getSingleVT(MVT::i8);
1044 1060
1061 auto IsExtSubvector = [] (ShuffleMask M) {
1062 assert(M.MinSrc >= 0 && M.MaxSrc >= 0);
1063 for (int I = 0, E = M.Mask.size(); I != E; ++I) {
1064 if (M.Mask[I] >= 0 && M.Mask[I]-I != M.MinSrc)
1065 return false;
1066 }
1067 return true;
1068 };
1069
1045 if (SM.MaxSrc - SM.MinSrc < int(HwLen)) { 1070 if (SM.MaxSrc - SM.MinSrc < int(HwLen)) {
1071 if (SM.MinSrc == 0 || SM.MinSrc == int(HwLen) || !IsExtSubvector(SM)) {
1072 // If the mask picks elements from only one of the operands, return
1073 // that operand, and update the mask to use index 0 to refer to the
1074 // first element of that operand.
1075 // If the mask extracts a subvector, it will be handled below, so
1076 // skip it here.
1077 if (SM.MaxSrc < int(HwLen)) {
1078 memcpy(NewMask.data(), SM.Mask.data(), sizeof(int)*VecLen);
1079 return Va;
1080 }
1081 if (SM.MinSrc >= int(HwLen)) {
1082 for (int I = 0; I != VecLen; ++I) {
1083 int M = SM.Mask[I];
1084 if (M != -1)
1085 M -= HwLen;
1086 NewMask[I] = M;
1087 }
1088 return Vb;
1089 }
1090 }
1091 int MinSrc = SM.MinSrc;
1046 if (SM.MaxSrc < int(HwLen)) { 1092 if (SM.MaxSrc < int(HwLen)) {
1047 memcpy(NewMask.data(), SM.Mask.data(), sizeof(int)*VecLen); 1093 Vb = Va;
1048 return Va; 1094 } else if (SM.MinSrc > int(HwLen)) {
1049 } 1095 Va = Vb;
1050 if (SM.MinSrc >= int(HwLen)) { 1096 MinSrc = SM.MinSrc - HwLen;
1051 for (int I = 0; I != VecLen; ++I) {
1052 int M = SM.Mask[I];
1053 if (M != -1)
1054 M -= HwLen;
1055 NewMask[I] = M;
1056 }
1057 return Vb;
1058 } 1097 }
1059 const SDLoc &dl(Results.InpNode); 1098 const SDLoc &dl(Results.InpNode);
1060 SDValue S = DAG.getTargetConstant(SM.MinSrc, dl, MVT::i32); 1099 if (isUInt<3>(MinSrc) || isUInt<3>(HwLen-MinSrc)) {
1061 if (isUInt<3>(SM.MinSrc)) { 1100 bool IsRight = isUInt<3>(MinSrc); // Right align.
1062 Results.push(Hexagon::V6_valignbi, Ty, {Vb, Va, S}); 1101 SDValue S = DAG.getTargetConstant(IsRight ? MinSrc : HwLen-MinSrc,
1102 dl, MVT::i32);
1103 unsigned Opc = IsRight ? Hexagon::V6_valignbi
1104 : Hexagon::V6_vlalignbi;
1105 Results.push(Opc, Ty, {Vb, Va, S});
1063 } else { 1106 } else {
1107 SDValue S = DAG.getTargetConstant(MinSrc, dl, MVT::i32);
1064 Results.push(Hexagon::A2_tfrsi, MVT::i32, {S}); 1108 Results.push(Hexagon::A2_tfrsi, MVT::i32, {S});
1065 unsigned Top = Results.top(); 1109 unsigned Top = Results.top();
1066 Results.push(Hexagon::V6_valignb, Ty, {Vb, Va, OpRef::res(Top)}); 1110 Results.push(Hexagon::V6_valignb, Ty, {Vb, Va, OpRef::res(Top)});
1067 } 1111 }
1068 for (int I = 0; I != VecLen; ++I) { 1112 for (int I = 0; I != VecLen; ++I) {
1285 Bytes[I] = 0xFF; 1329 Bytes[I] = 0xFF;
1286 } 1330 }
1287 return vmuxp(Bytes, L, R, Results); 1331 return vmuxp(Bytes, L, R, Results);
1288 } 1332 }
1289 1333
1334 namespace {
1335 struct Deleter : public SelectionDAG::DAGNodeDeletedListener {
1336 template <typename T>
1337 Deleter(SelectionDAG &D, T &C)
1338 : SelectionDAG::DAGNodeDeletedListener(D, [&C] (SDNode *N, SDNode *E) {
1339 C.erase(N);
1340 }) {}
1341 };
1342
1343 template <typename T>
1344 struct NullifyingVector : public T {
1345 DenseMap<SDNode*, SDNode**> Refs;
1346 NullifyingVector(T &&V) : T(V) {
1347 for (unsigned i = 0, e = T::size(); i != e; ++i) {
1348 SDNode *&N = T::operator[](i);
1349 Refs[N] = &N;
1350 }
1351 }
1352 void erase(SDNode *N) {
1353 auto F = Refs.find(N);
1354 if (F != Refs.end())
1355 *F->second = nullptr;
1356 }
1357 };
1358 }
1359
1290 bool HvxSelector::scalarizeShuffle(ArrayRef<int> Mask, const SDLoc &dl, 1360 bool HvxSelector::scalarizeShuffle(ArrayRef<int> Mask, const SDLoc &dl,
1291 MVT ResTy, SDValue Va, SDValue Vb, 1361 MVT ResTy, SDValue Va, SDValue Vb,
1292 SDNode *N) { 1362 SDNode *N) {
1293 DEBUG_WITH_TYPE("isel", {dbgs() << __func__ << '\n';}); 1363 DEBUG_WITH_TYPE("isel", {dbgs() << __func__ << '\n';});
1294 MVT ElemTy = ResTy.getVectorElementType(); 1364 MVT ElemTy = ResTy.getVectorElementType();
1295 assert(ElemTy == MVT::i8); 1365 assert(ElemTy == MVT::i8);
1296 unsigned VecLen = Mask.size(); 1366 unsigned VecLen = Mask.size();
1297 bool HavePairs = (2*HwLen == VecLen); 1367 bool HavePairs = (2*HwLen == VecLen);
1298 MVT SingleTy = getSingleVT(MVT::i8); 1368 MVT SingleTy = getSingleVT(MVT::i8);
1299 1369
1370 // The prior attempts to handle this shuffle may have left a bunch of
1371 // dead nodes in the DAG (such as constants). These nodes will be added
1372 // at the end of DAG's node list, which at that point had already been
1373 // sorted topologically. In the main selection loop, the node list is
1374 // traversed backwards from the root node, which means that any new
1375 // nodes (from the end of the list) will not be visited.
1376 // Scalarization will replace the shuffle node with the scalarized
1377 // expression, and if that expression reused any if the leftoever (dead)
1378 // nodes, these nodes would not be selected (since the "local" selection
1379 // only visits nodes that are not in AllNodes).
1380 // To avoid this issue, remove all dead nodes from the DAG now.
1381 DAG.RemoveDeadNodes();
1382 DenseSet<SDNode*> AllNodes;
1383 for (SDNode &S : DAG.allnodes())
1384 AllNodes.insert(&S);
1385
1386 Deleter DUA(DAG, AllNodes);
1387
1300 SmallVector<SDValue,128> Ops; 1388 SmallVector<SDValue,128> Ops;
1389 LLVMContext &Ctx = *DAG.getContext();
1390 MVT LegalTy = Lower.getTypeToTransformTo(Ctx, ElemTy).getSimpleVT();
1301 for (int I : Mask) { 1391 for (int I : Mask) {
1302 if (I < 0) { 1392 if (I < 0) {
1303 Ops.push_back(ISel.selectUndef(dl, ElemTy)); 1393 Ops.push_back(ISel.selectUndef(dl, LegalTy));
1304 continue; 1394 continue;
1305 } 1395 }
1306 SDValue Vec; 1396 SDValue Vec;
1307 unsigned M = I; 1397 unsigned M = I;
1308 if (M < VecLen) { 1398 if (M < VecLen) {
1318 Vec = DAG.getTargetExtractSubreg(Hexagon::vsub_hi, dl, SingleTy, Vec); 1408 Vec = DAG.getTargetExtractSubreg(Hexagon::vsub_hi, dl, SingleTy, Vec);
1319 M -= HwLen; 1409 M -= HwLen;
1320 } 1410 }
1321 } 1411 }
1322 SDValue Idx = DAG.getConstant(M, dl, MVT::i32); 1412 SDValue Idx = DAG.getConstant(M, dl, MVT::i32);
1323 SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ElemTy, {Vec, Idx}); 1413 SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, LegalTy, {Vec, Idx});
1324 SDValue L = Lower.LowerOperation(Ex, DAG); 1414 SDValue L = Lower.LowerOperation(Ex, DAG);
1325 assert(L.getNode()); 1415 assert(L.getNode());
1326 Ops.push_back(L); 1416 Ops.push_back(L);
1327 } 1417 }
1328 1418
1342 LV = Lower.LowerOperation(BV, DAG); 1432 LV = Lower.LowerOperation(BV, DAG);
1343 } 1433 }
1344 1434
1345 assert(!N->use_empty()); 1435 assert(!N->use_empty());
1346 ISel.ReplaceNode(N, LV.getNode()); 1436 ISel.ReplaceNode(N, LV.getNode());
1347 DAG.RemoveDeadNodes(); 1437
1348 1438 if (AllNodes.count(LV.getNode())) {
1349 std::deque<SDNode*> SubNodes; 1439 DAG.RemoveDeadNodes();
1350 SubNodes.push_back(LV.getNode()); 1440 return true;
1441 }
1442
1443 // The lowered build-vector node will now need to be selected. It needs
1444 // to be done here because this node and its submodes are not included
1445 // in the main selection loop.
1446 // Implement essentially the same topological ordering algorithm as is
1447 // used in SelectionDAGISel.
1448
1449 SetVector<SDNode*> SubNodes, TmpQ;
1450 std::map<SDNode*,unsigned> NumOps;
1451
1452 SubNodes.insert(LV.getNode());
1351 for (unsigned I = 0; I != SubNodes.size(); ++I) { 1453 for (unsigned I = 0; I != SubNodes.size(); ++I) {
1352 for (SDValue Op : SubNodes[I]->ops()) 1454 unsigned OpN = 0;
1353 SubNodes.push_back(Op.getNode()); 1455 SDNode *S = SubNodes[I];
1354 } 1456 for (SDValue Op : S->ops()) {
1355 while (!SubNodes.empty()) { 1457 if (AllNodes.count(Op.getNode()))
1356 SDNode *S = SubNodes.front(); 1458 continue;
1357 SubNodes.pop_front(); 1459 SubNodes.insert(Op.getNode());
1358 if (S->use_empty()) 1460 ++OpN;
1359 continue; 1461 }
1360 // This isn't great, but users need to be selected before any nodes that 1462 NumOps.insert({S, OpN});
1361 // they use. (The reason is to match larger patterns, and avoid nodes that 1463 if (OpN == 0)
1362 // cannot be matched on their own, e.g. ValueType, TokenFactor, etc.). 1464 TmpQ.insert(S);
1363 bool PendingUser = llvm::any_of(S->uses(), [&SubNodes](const SDNode *U) { 1465 }
1364 return llvm::any_of(SubNodes, [U](const SDNode *T) { 1466
1365 return T == U; 1467 for (unsigned I = 0; I != TmpQ.size(); ++I) {
1366 }); 1468 SDNode *S = TmpQ[I];
1367 }); 1469 for (SDNode *U : S->uses()) {
1368 if (PendingUser) 1470 if (!SubNodes.count(U))
1369 SubNodes.push_back(S); 1471 continue;
1370 else 1472 auto F = NumOps.find(U);
1473 assert(F != NumOps.end());
1474 assert(F->second > 0);
1475 if (!--F->second)
1476 TmpQ.insert(F->first);
1477 }
1478 }
1479 assert(SubNodes.size() == TmpQ.size());
1480 NullifyingVector<decltype(TmpQ)::vector_type> Queue(TmpQ.takeVector());
1481
1482 Deleter DUQ(DAG, Queue);
1483 for (SDNode *S : reverse(Queue))
1484 if (S != nullptr)
1371 ISel.Select(S); 1485 ISel.Select(S);
1372 }
1373 1486
1374 DAG.RemoveDeadNodes(); 1487 DAG.RemoveDeadNodes();
1375 return true; 1488 return true;
1376 } 1489 }
1377 1490
1926 << HavePairs << '\n'; 2039 << HavePairs << '\n';
1927 }); 2040 });
1928 // If the mask is all -1's, generate "undef". 2041 // If the mask is all -1's, generate "undef".
1929 if (!UseLeft && !UseRight) { 2042 if (!UseLeft && !UseRight) {
1930 ISel.ReplaceNode(N, ISel.selectUndef(SDLoc(SN), ResTy).getNode()); 2043 ISel.ReplaceNode(N, ISel.selectUndef(SDLoc(SN), ResTy).getNode());
1931 DAG.RemoveDeadNode(N);
1932 return; 2044 return;
1933 } 2045 }
1934 2046
1935 SDValue Vec0 = N->getOperand(0); 2047 SDValue Vec0 = N->getOperand(0);
1936 SDValue Vec1 = N->getOperand(1); 2048 SDValue Vec1 = N->getOperand(1);
1982 2094
1983 if (!NewN) 2095 if (!NewN)
1984 NewN = DAG.getMachineNode(Hexagon::V6_vror, dl, Ty, {VecV, RotV}); 2096 NewN = DAG.getMachineNode(Hexagon::V6_vror, dl, Ty, {VecV, RotV});
1985 2097
1986 ISel.ReplaceNode(N, NewN); 2098 ISel.ReplaceNode(N, NewN);
2099 }
2100
2101 void HvxSelector::selectVAlign(SDNode *N) {
2102 SDValue Vv = N->getOperand(0);
2103 SDValue Vu = N->getOperand(1);
2104 SDValue Rt = N->getOperand(2);
2105 SDNode *NewN = DAG.getMachineNode(Hexagon::V6_valignb, SDLoc(N),
2106 N->getValueType(0), {Vv, Vu, Rt});
2107 ISel.ReplaceNode(N, NewN);
1987 DAG.RemoveDeadNode(N); 2108 DAG.RemoveDeadNode(N);
1988 } 2109 }
1989 2110
1990 void HexagonDAGToDAGISel::SelectHvxShuffle(SDNode *N) { 2111 void HexagonDAGToDAGISel::SelectHvxShuffle(SDNode *N) {
1991 HvxSelector(*this, *CurDAG).selectShuffle(N); 2112 HvxSelector(*this, *CurDAG).selectShuffle(N);
1992 } 2113 }
1993 2114
1994 void HexagonDAGToDAGISel::SelectHvxRor(SDNode *N) { 2115 void HexagonDAGToDAGISel::SelectHvxRor(SDNode *N) {
1995 HvxSelector(*this, *CurDAG).selectRor(N); 2116 HvxSelector(*this, *CurDAG).selectRor(N);
2117 }
2118
2119 void HexagonDAGToDAGISel::SelectHvxVAlign(SDNode *N) {
2120 HvxSelector(*this, *CurDAG).selectVAlign(N);
1996 } 2121 }
1997 2122
1998 void HexagonDAGToDAGISel::SelectV65GatherPred(SDNode *N) { 2123 void HexagonDAGToDAGISel::SelectV65GatherPred(SDNode *N) {
1999 const SDLoc &dl(N); 2124 const SDLoc &dl(N);
2000 SDValue Chain = N->getOperand(0); 2125 SDValue Chain = N->getOperand(0);
2025 2150
2026 SDVTList VTs = CurDAG->getVTList(MVT::Other); 2151 SDVTList VTs = CurDAG->getVTList(MVT::Other);
2027 SDValue Ops[] = { Address, Predicate, Base, Modifier, Offset, Chain }; 2152 SDValue Ops[] = { Address, Predicate, Base, Modifier, Offset, Chain };
2028 SDNode *Result = CurDAG->getMachineNode(Opcode, dl, VTs, Ops); 2153 SDNode *Result = CurDAG->getMachineNode(Opcode, dl, VTs, Ops);
2029 2154
2030 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 2155 MachineMemOperand *MemOp = cast<MemIntrinsicSDNode>(N)->getMemOperand();
2031 MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand(); 2156 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Result), {MemOp});
2032 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1); 2157
2033 2158 ReplaceNode(N, Result);
2034 ReplaceUses(N, Result);
2035 CurDAG->RemoveDeadNode(N);
2036 } 2159 }
2037 2160
2038 void HexagonDAGToDAGISel::SelectV65Gather(SDNode *N) { 2161 void HexagonDAGToDAGISel::SelectV65Gather(SDNode *N) {
2039 const SDLoc &dl(N); 2162 const SDLoc &dl(N);
2040 SDValue Chain = N->getOperand(0); 2163 SDValue Chain = N->getOperand(0);
2064 2187
2065 SDVTList VTs = CurDAG->getVTList(MVT::Other); 2188 SDVTList VTs = CurDAG->getVTList(MVT::Other);
2066 SDValue Ops[] = { Address, Base, Modifier, Offset, Chain }; 2189 SDValue Ops[] = { Address, Base, Modifier, Offset, Chain };
2067 SDNode *Result = CurDAG->getMachineNode(Opcode, dl, VTs, Ops); 2190 SDNode *Result = CurDAG->getMachineNode(Opcode, dl, VTs, Ops);
2068 2191
2069 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 2192 MachineMemOperand *MemOp = cast<MemIntrinsicSDNode>(N)->getMemOperand();
2070 MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand(); 2193 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Result), {MemOp});
2071 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1); 2194
2072 2195 ReplaceNode(N, Result);
2073 ReplaceUses(N, Result);
2074 CurDAG->RemoveDeadNode(N);
2075 } 2196 }
2076 2197
2077 void HexagonDAGToDAGISel::SelectHVXDualOutput(SDNode *N) { 2198 void HexagonDAGToDAGISel::SelectHVXDualOutput(SDNode *N) {
2078 unsigned IID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue(); 2199 unsigned IID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
2079 SDNode *Result; 2200 SDNode *Result;
2112 ReplaceUses(N, Result); 2233 ReplaceUses(N, Result);
2113 ReplaceUses(SDValue(N, 0), SDValue(Result, 0)); 2234 ReplaceUses(SDValue(N, 0), SDValue(Result, 0));
2114 ReplaceUses(SDValue(N, 1), SDValue(Result, 1)); 2235 ReplaceUses(SDValue(N, 1), SDValue(Result, 1));
2115 CurDAG->RemoveDeadNode(N); 2236 CurDAG->RemoveDeadNode(N);
2116 } 2237 }
2117
2118