Mercurial > hg > CbC > CbC_llvm
comparison lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp @ 121:803732b1fca8
LLVM 5.0
author | kono |
---|---|
date | Fri, 27 Oct 2017 17:07:41 +0900 |
parents | 1172e4bd9c6f |
children | 3a76565eade5 |
comparison
equal
deleted
inserted
replaced
120:1172e4bd9c6f | 121:803732b1fca8 |
---|---|
1 //===-- LegalizeVectorOps.cpp - Implement SelectionDAG::LegalizeVectors ---===// | 1 //===- LegalizeVectorOps.cpp - Implement SelectionDAG::LegalizeVectors ----===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
25 // with illegal types, so it's okay to put off legalizing them until | 25 // with illegal types, so it's okay to put off legalizing them until |
26 // SelectionDAG::Legalize runs. | 26 // SelectionDAG::Legalize runs. |
27 // | 27 // |
28 //===----------------------------------------------------------------------===// | 28 //===----------------------------------------------------------------------===// |
29 | 29 |
30 #include "llvm/ADT/APInt.h" | |
31 #include "llvm/ADT/DenseMap.h" | |
32 #include "llvm/ADT/SmallVector.h" | |
33 #include "llvm/CodeGen/ISDOpcodes.h" | |
34 #include "llvm/CodeGen/MachineMemOperand.h" | |
35 #include "llvm/CodeGen/MachineValueType.h" | |
30 #include "llvm/CodeGen/SelectionDAG.h" | 36 #include "llvm/CodeGen/SelectionDAG.h" |
37 #include "llvm/CodeGen/SelectionDAGNodes.h" | |
38 #include "llvm/CodeGen/ValueTypes.h" | |
39 #include "llvm/IR/DataLayout.h" | |
40 #include "llvm/Support/Casting.h" | |
41 #include "llvm/Support/Compiler.h" | |
42 #include "llvm/Support/ErrorHandling.h" | |
43 #include "llvm/Support/MathExtras.h" | |
31 #include "llvm/Target/TargetLowering.h" | 44 #include "llvm/Target/TargetLowering.h" |
45 #include <cassert> | |
46 #include <cstdint> | |
47 #include <iterator> | |
48 #include <utility> | |
49 | |
32 using namespace llvm; | 50 using namespace llvm; |
33 | 51 |
34 namespace { | 52 namespace { |
53 | |
35 class VectorLegalizer { | 54 class VectorLegalizer { |
36 SelectionDAG& DAG; | 55 SelectionDAG& DAG; |
37 const TargetLowering &TLI; | 56 const TargetLowering &TLI; |
38 bool Changed; // Keep track of whether anything changed | 57 bool Changed = false; // Keep track of whether anything changed |
39 | 58 |
40 /// For nodes that are of legal width, and that have more than one use, this | 59 /// For nodes that are of legal width, and that have more than one use, this |
41 /// map indicates what regularized operand to use. This allows us to avoid | 60 /// map indicates what regularized operand to use. This allows us to avoid |
42 /// legalizing the same thing more than once. | 61 /// legalizing the same thing more than once. |
43 SmallDenseMap<SDValue, SDValue, 64> LegalizedNodes; | 62 SmallDenseMap<SDValue, SDValue, 64> LegalizedNodes; |
103 SDValue ExpandVSELECT(SDValue Op); | 122 SDValue ExpandVSELECT(SDValue Op); |
104 SDValue ExpandSELECT(SDValue Op); | 123 SDValue ExpandSELECT(SDValue Op); |
105 SDValue ExpandLoad(SDValue Op); | 124 SDValue ExpandLoad(SDValue Op); |
106 SDValue ExpandStore(SDValue Op); | 125 SDValue ExpandStore(SDValue Op); |
107 SDValue ExpandFNEG(SDValue Op); | 126 SDValue ExpandFNEG(SDValue Op); |
127 SDValue ExpandFSUB(SDValue Op); | |
108 SDValue ExpandBITREVERSE(SDValue Op); | 128 SDValue ExpandBITREVERSE(SDValue Op); |
109 SDValue ExpandCTLZ(SDValue Op); | 129 SDValue ExpandCTLZ(SDValue Op); |
110 SDValue ExpandCTTZ_ZERO_UNDEF(SDValue Op); | 130 SDValue ExpandCTTZ_ZERO_UNDEF(SDValue Op); |
111 | 131 |
112 /// \brief Implements vector promotion. | 132 /// \brief Implements vector promotion. |
125 /// It is promoted to the next size up integer type. The result is then | 145 /// It is promoted to the next size up integer type. The result is then |
126 /// truncated back to the original type. | 146 /// truncated back to the original type. |
127 SDValue PromoteFP_TO_INT(SDValue Op, bool isSigned); | 147 SDValue PromoteFP_TO_INT(SDValue Op, bool isSigned); |
128 | 148 |
129 public: | 149 public: |
150 VectorLegalizer(SelectionDAG& dag) : | |
151 DAG(dag), TLI(dag.getTargetLoweringInfo()) {} | |
152 | |
130 /// \brief Begin legalizer the vector operations in the DAG. | 153 /// \brief Begin legalizer the vector operations in the DAG. |
131 bool Run(); | 154 bool Run(); |
132 VectorLegalizer(SelectionDAG& dag) : | |
133 DAG(dag), TLI(dag.getTargetLoweringInfo()), Changed(false) {} | |
134 }; | 155 }; |
156 | |
157 } // end anonymous namespace | |
135 | 158 |
136 bool VectorLegalizer::Run() { | 159 bool VectorLegalizer::Run() { |
137 // Before we start legalizing vector nodes, check if there are any vectors. | 160 // Before we start legalizing vector nodes, check if there are any vectors. |
138 bool HasVectors = false; | 161 bool HasVectors = false; |
139 for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(), | 162 for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(), |
222 "There are still live users of the old chain!"); | 245 "There are still live users of the old chain!"); |
223 return LegalizeOp(Lowered); | 246 return LegalizeOp(Lowered); |
224 } | 247 } |
225 return TranslateLegalizeResults(Op, Lowered); | 248 return TranslateLegalizeResults(Op, Lowered); |
226 } | 249 } |
250 LLVM_FALLTHROUGH; | |
227 case TargetLowering::Expand: | 251 case TargetLowering::Expand: |
228 Changed = true; | 252 Changed = true; |
229 return LegalizeOp(ExpandLoad(Op)); | 253 return LegalizeOp(ExpandLoad(Op)); |
230 } | 254 } |
231 } else if (Op.getOpcode() == ISD::STORE) { | 255 } else if (Op.getOpcode() == ISD::STORE) { |
331 case ISD::ZERO_EXTEND_VECTOR_INREG: | 355 case ISD::ZERO_EXTEND_VECTOR_INREG: |
332 case ISD::SMIN: | 356 case ISD::SMIN: |
333 case ISD::SMAX: | 357 case ISD::SMAX: |
334 case ISD::UMIN: | 358 case ISD::UMIN: |
335 case ISD::UMAX: | 359 case ISD::UMAX: |
360 case ISD::SMUL_LOHI: | |
361 case ISD::UMUL_LOHI: | |
336 QueryType = Node->getValueType(0); | 362 QueryType = Node->getValueType(0); |
337 break; | 363 break; |
338 case ISD::FP_ROUND_INREG: | 364 case ISD::FP_ROUND_INREG: |
339 QueryType = cast<VTSDNode>(Node->getOperand(1))->getVT(); | 365 QueryType = cast<VTSDNode>(Node->getOperand(1))->getVT(); |
340 break; | 366 break; |
471 "Can't promote a vector with multiple results!"); | 497 "Can't promote a vector with multiple results!"); |
472 EVT VT = Op.getValueType(); | 498 EVT VT = Op.getValueType(); |
473 | 499 |
474 EVT NewVT; | 500 EVT NewVT; |
475 unsigned NewOpc; | 501 unsigned NewOpc; |
476 while (1) { | 502 while (true) { |
477 NewVT = VT.widenIntegerVectorElementType(*DAG.getContext()); | 503 NewVT = VT.widenIntegerVectorElementType(*DAG.getContext()); |
478 assert(NewVT.isSimple() && "Promoting to a non-simple vector type!"); | 504 assert(NewVT.isSimple() && "Promoting to a non-simple vector type!"); |
479 if (TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NewVT)) { | 505 if (TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NewVT)) { |
480 NewOpc = ISD::FP_TO_SINT; | 506 NewOpc = ISD::FP_TO_SINT; |
481 break; | 507 break; |
489 SDLoc loc(Op); | 515 SDLoc loc(Op); |
490 SDValue promoted = DAG.getNode(NewOpc, SDLoc(Op), NewVT, Op.getOperand(0)); | 516 SDValue promoted = DAG.getNode(NewOpc, SDLoc(Op), NewVT, Op.getOperand(0)); |
491 return DAG.getNode(ISD::TRUNCATE, SDLoc(Op), VT, promoted); | 517 return DAG.getNode(ISD::TRUNCATE, SDLoc(Op), VT, promoted); |
492 } | 518 } |
493 | 519 |
494 | |
495 SDValue VectorLegalizer::ExpandLoad(SDValue Op) { | 520 SDValue VectorLegalizer::ExpandLoad(SDValue Op) { |
496 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode()); | 521 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode()); |
497 | 522 |
498 EVT SrcVT = LD->getMemoryVT(); | 523 EVT SrcVT = LD->getMemoryVT(); |
499 EVT SrcEltVT = SrcVT.getScalarType(); | 524 EVT SrcEltVT = SrcVT.getScalarType(); |
500 unsigned NumElem = SrcVT.getVectorNumElements(); | 525 unsigned NumElem = SrcVT.getVectorNumElements(); |
501 | |
502 | 526 |
503 SDValue NewChain; | 527 SDValue NewChain; |
504 SDValue Value; | 528 SDValue Value; |
505 if (SrcVT.getVectorNumElements() > 1 && !SrcEltVT.isByteSized()) { | 529 if (SrcVT.getVectorNumElements() > 1 && !SrcEltVT.isByteSized()) { |
506 SDLoc dl(Op); | 530 SDLoc dl(Op); |
617 } | 641 } |
618 Vals.push_back(Lo); | 642 Vals.push_back(Lo); |
619 } | 643 } |
620 | 644 |
621 NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, LoadChains); | 645 NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, LoadChains); |
622 Value = DAG.getNode(ISD::BUILD_VECTOR, dl, | 646 Value = DAG.getBuildVector(Op.getNode()->getValueType(0), dl, Vals); |
623 Op.getNode()->getValueType(0), Vals); | |
624 } else { | 647 } else { |
625 SDValue Scalarized = TLI.scalarizeVectorLoad(LD, DAG); | 648 SDValue Scalarized = TLI.scalarizeVectorLoad(LD, DAG); |
626 | 649 |
627 NewChain = Scalarized.getValue(1); | 650 NewChain = Scalarized.getValue(1); |
628 Value = Scalarized.getValue(0); | 651 Value = Scalarized.getValue(0); |
688 return ExpandSELECT(Op); | 711 return ExpandSELECT(Op); |
689 case ISD::UINT_TO_FP: | 712 case ISD::UINT_TO_FP: |
690 return ExpandUINT_TO_FLOAT(Op); | 713 return ExpandUINT_TO_FLOAT(Op); |
691 case ISD::FNEG: | 714 case ISD::FNEG: |
692 return ExpandFNEG(Op); | 715 return ExpandFNEG(Op); |
716 case ISD::FSUB: | |
717 return ExpandFSUB(Op); | |
693 case ISD::SETCC: | 718 case ISD::SETCC: |
694 return UnrollVSETCC(Op); | 719 return UnrollVSETCC(Op); |
695 case ISD::BITREVERSE: | 720 case ISD::BITREVERSE: |
696 return ExpandBITREVERSE(Op); | 721 return ExpandBITREVERSE(Op); |
697 case ISD::CTLZ: | 722 case ISD::CTLZ: |
716 SDValue Op2 = Op.getOperand(2); | 741 SDValue Op2 = Op.getOperand(2); |
717 | 742 |
718 assert(VT.isVector() && !Mask.getValueType().isVector() | 743 assert(VT.isVector() && !Mask.getValueType().isVector() |
719 && Op1.getValueType() == Op2.getValueType() && "Invalid type"); | 744 && Op1.getValueType() == Op2.getValueType() && "Invalid type"); |
720 | 745 |
721 unsigned NumElem = VT.getVectorNumElements(); | |
722 | |
723 // If we can't even use the basic vector operations of | 746 // If we can't even use the basic vector operations of |
724 // AND,OR,XOR, we will have to scalarize the op. | 747 // AND,OR,XOR, we will have to scalarize the op. |
725 // Notice that the operation may be 'promoted' which means that it is | 748 // Notice that the operation may be 'promoted' which means that it is |
726 // 'bitcasted' to another type which is handled. | 749 // 'bitcasted' to another type which is handled. |
727 // Also, we need to be able to construct a splat vector using BUILD_VECTOR. | 750 // Also, we need to be able to construct a splat vector using BUILD_VECTOR. |
741 DAG.getConstant(APInt::getAllOnesValue(BitTy.getSizeInBits()), DL, | 764 DAG.getConstant(APInt::getAllOnesValue(BitTy.getSizeInBits()), DL, |
742 BitTy), | 765 BitTy), |
743 DAG.getConstant(0, DL, BitTy)); | 766 DAG.getConstant(0, DL, BitTy)); |
744 | 767 |
745 // Broadcast the mask so that the entire vector is all-one or all zero. | 768 // Broadcast the mask so that the entire vector is all-one or all zero. |
746 SmallVector<SDValue, 8> Ops(NumElem, Mask); | 769 Mask = DAG.getSplatBuildVector(MaskTy, DL, Mask); |
747 Mask = DAG.getNode(ISD::BUILD_VECTOR, DL, MaskTy, Ops); | |
748 | 770 |
749 // Bitcast the operands to be the same type as the mask. | 771 // Bitcast the operands to be the same type as the mask. |
750 // This is needed when we select between FP types because | 772 // This is needed when we select between FP types because |
751 // the mask is a vector of integers. | 773 // the mask is a vector of integers. |
752 Op1 = DAG.getNode(ISD::BITCAST, DL, MaskTy, Op1); | 774 Op1 = DAG.getNode(ISD::BITCAST, DL, MaskTy, Op1); |
1018 SDValue Zero = DAG.getConstantFP(-0.0, DL, Op.getValueType()); | 1040 SDValue Zero = DAG.getConstantFP(-0.0, DL, Op.getValueType()); |
1019 // TODO: If FNEG had fast-math-flags, they'd get propagated to this FSUB. | 1041 // TODO: If FNEG had fast-math-flags, they'd get propagated to this FSUB. |
1020 return DAG.getNode(ISD::FSUB, DL, Op.getValueType(), | 1042 return DAG.getNode(ISD::FSUB, DL, Op.getValueType(), |
1021 Zero, Op.getOperand(0)); | 1043 Zero, Op.getOperand(0)); |
1022 } | 1044 } |
1045 return DAG.UnrollVectorOp(Op.getNode()); | |
1046 } | |
1047 | |
1048 SDValue VectorLegalizer::ExpandFSUB(SDValue Op) { | |
1049 // For floating-point values, (a-b) is the same as a+(-b). If FNEG is legal, | |
1050 // we can defer this to operation legalization where it will be lowered as | |
1051 // a+(-b). | |
1052 EVT VT = Op.getValueType(); | |
1053 if (TLI.isOperationLegalOrCustom(ISD::FNEG, VT) && | |
1054 TLI.isOperationLegalOrCustom(ISD::FADD, VT)) | |
1055 return Op; // Defer to LegalizeDAG | |
1056 | |
1023 return DAG.UnrollVectorOp(Op.getNode()); | 1057 return DAG.UnrollVectorOp(Op.getNode()); |
1024 } | 1058 } |
1025 | 1059 |
1026 SDValue VectorLegalizer::ExpandCTLZ(SDValue Op) { | 1060 SDValue VectorLegalizer::ExpandCTLZ(SDValue Op) { |
1027 EVT VT = Op.getValueType(); | 1061 EVT VT = Op.getValueType(); |
1098 Ops[i] = DAG.getSelect(dl, EltVT, Ops[i], | 1132 Ops[i] = DAG.getSelect(dl, EltVT, Ops[i], |
1099 DAG.getConstant(APInt::getAllOnesValue | 1133 DAG.getConstant(APInt::getAllOnesValue |
1100 (EltVT.getSizeInBits()), dl, EltVT), | 1134 (EltVT.getSizeInBits()), dl, EltVT), |
1101 DAG.getConstant(0, dl, EltVT)); | 1135 DAG.getConstant(0, dl, EltVT)); |
1102 } | 1136 } |
1103 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, Ops); | 1137 return DAG.getBuildVector(VT, dl, Ops); |
1104 } | |
1105 | |
1106 } | 1138 } |
1107 | 1139 |
1108 bool SelectionDAG::LegalizeVectors() { | 1140 bool SelectionDAG::LegalizeVectors() { |
1109 return VectorLegalizer(*this).Run(); | 1141 return VectorLegalizer(*this).Run(); |
1110 } | 1142 } |