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 }