source: parabix-LLVM/llvm_git/lib/Target/X86/X86ParabixISelLowering.h @ 4136

Last change on this file since 4136 was 4136, checked in by linmengl, 5 years ago

long stream addition for i128

File size: 11.6 KB
Line 
1//===-- X86ParabixISelLowering.h - X86 DAG Lowering Interface ---*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the interface that Parabix uses on X86
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef X86PARABIXISELLOWERING_H
15#define X86PARABIXISELLOWERING_H
16
17#include "X86Subtarget.h"
18#include "llvm/CodeGen/CallingConvLower.h"
19#include "llvm/CodeGen/SelectionDAG.h"
20#include "llvm/Target/TargetLowering.h"
21#include "llvm/Target/TargetOptions.h"
22#include "llvm/ADT/ArrayRef.h"
23#include "llvm/ADT/SmallVector.h"
24#include "llvm/IR/Intrinsics.h"
25#include "llvm/Support/MathExtras.h"
26#include <string>
27
28namespace llvm {
29  class SDNodeTreeBuilder
30  {
31    SDValue Op;
32    SelectionDAG *DAG;
33    SDLoc dl;
34  public:
35    SDNodeTreeBuilder(SDValue BaseOp, SelectionDAG *_DAG)
36      : Op(BaseOp), DAG(_DAG), dl(BaseOp) {}
37
38    SDNodeTreeBuilder(SelectionDAG *_DAG, SDLoc _dl)
39      : DAG(_DAG), dl(_dl) {}
40
41    //use the same OpCode with Op
42    SDValue DoOp(MVT VT, SDValue Op0, SDValue Op1) {
43      if (Op0.getSimpleValueType() != VT)
44        Op0 = BITCAST(Op0, VT);
45      if (Op1.getSimpleValueType() != VT)
46        Op1 = BITCAST(Op1, VT);
47
48      if (Op.getOpcode() == ISD::SETCC)
49        return DAG->getNode(ISD::SETCC, dl, VT, Op0, Op1, Op.getOperand(2));
50
51      return DAG->getNode(Op.getOpcode(), dl, VT, Op0, Op1);
52    }
53
54    SDValue BITCAST(SDValue A, MVT VT) {
55      return DAG->getNode(ISD::BITCAST, dl, VT, A);
56    }
57
58    SDValue TRUNCATE(SDValue A, MVT VT) {
59      return DAG->getNode(ISD::TRUNCATE, dl, VT, A);
60    }
61
62    SDValue Constant(int Num, MVT NumType = MVT::i32) {
63      return DAG->getConstant(Num, NumType);
64    }
65
66    SDValue Constant(std::string I64String, MVT NumType) {
67      assert(NumType.getScalarType() == MVT::i64 &&
68             "Constant from I64String has wrong NumType");
69      assert(I64String.size() == 64 &&
70             "I64String should be binary number");
71
72      int NumElts = NumType.getVectorNumElements();
73
74      APInt MaskInt64(64, I64String, 2);
75      SDValue MaskNode64 = DAG->getConstant(MaskInt64, MVT::i64);
76      SmallVector<SDValue, 4> Pool;
77      for (int i = 0; i < NumElts; ++i) Pool.push_back(MaskNode64);
78
79      return BUILD_VECTOR(NumType, Pool);
80    }
81
82    SDValue ConstantVector(MVT VT, int ElemVal) {
83      assert(VT.isVector() && "ConstantVector only return vector type");
84
85      SDValue Elem = Constant(ElemVal, VT.getVectorElementType());
86      SmallVector<SDValue, 32> Pool;
87      for (unsigned i = 0; i < VT.getVectorNumElements(); ++i)
88        Pool.push_back(Elem);
89
90      return BUILD_VECTOR(VT, Pool);
91    }
92
93    SDValue Undef(EVT VT) {
94      return DAG->getUNDEF(VT);
95    }
96
97    SDValue BUILD_VECTOR(MVT VT, ArrayRef<SDValue> Elements) {
98      assert(VT.isVector() && "not building vector");
99
100      unsigned NumElems = VT.getVectorNumElements();
101      assert(Elements.size() == NumElems);
102
103      return DAG->getNode(ISD::BUILD_VECTOR, dl, VT, Elements);
104    }
105
106    SDValue EXTRACT_VECTOR_ELT(SDValue Vec, SDValue Idx) {
107      MVT VT = Vec.getSimpleValueType();
108      MVT EltVT = VT.getVectorElementType();
109      if (EltVT == MVT::i1)
110        EltVT = MVT::i8;
111
112      return DAG->getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Vec, Idx);
113    }
114
115    SDValue EXTRACT_VECTOR_ELT(SDValue Vec, unsigned Idx) {
116      return EXTRACT_VECTOR_ELT(Vec, Constant(Idx));
117    }
118
119    SDValue INSERT_VECTOR_ELT(SDValue Vec, SDValue Elt, SDValue Idx) {
120      MVT VT = Vec.getSimpleValueType();
121      return DAG->getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Vec, Elt, Idx);
122    }
123
124    // int Mask[] = {...}, call with &Mask[0]
125    SDValue VECTOR_SHUFFLE(SDValue Vec0, SDValue Vec1, const int * Mask) {
126      MVT VT = Vec0.getSimpleValueType();
127      return DAG->getVectorShuffle(VT, dl, Vec0, Vec1, Mask);
128    }
129
130    SDValue SIGN_EXTEND_INREG(SDValue Val, MVT FromVT, MVT ToVT) {
131      return DAG->getNode(ISD::SIGN_EXTEND_INREG, dl, ToVT, Val,
132                          DAG->getValueType(FromVT));
133    }
134
135    SDValue ANY_EXTEND(SDValue Val, MVT ToVT) {
136      return DAG->getNode(ISD::ANY_EXTEND, dl, ToVT, Val);
137    }
138
139    SDValue ZERO_EXTEND(SDValue Val, MVT ToVT) {
140      return DAG->getNode(ISD::ZERO_EXTEND, dl, ToVT, Val);
141    }
142
143    SDValue SIGN_EXTEND(SDValue Val, MVT ToVT) {
144      return DAG->getNode(ISD::SIGN_EXTEND, dl, ToVT, Val);
145    }
146
147    SDValue SELECT(SDValue Cond, SDValue TrueVal, SDValue FalseVal) {
148      MVT VT = TrueVal.getSimpleValueType();
149      return DAG->getNode(ISD::SELECT, dl, VT, Cond, TrueVal, FalseVal);
150    }
151
152    SDValue ADD(SDValue A, SDValue B) {
153      MVT VT = A.getSimpleValueType();
154      return DAG->getNode(ISD::ADD, dl, VT, A, B);
155    }
156
157    SDValue AND(SDValue A, SDValue B) {
158      MVT VT = A.getSimpleValueType();
159      return DAG->getNode(ISD::AND, dl, VT, A, B);
160    }
161
162    SDValue OR(SDValue A, SDValue B) {
163      MVT VT = A.getSimpleValueType();
164      return DAG->getNode(ISD::OR, dl, VT, A, B);
165    }
166
167    SDValue XOR(SDValue A, SDValue B) {
168      MVT VT = A.getSimpleValueType();
169      return DAG->getNode(ISD::XOR, dl, VT, A, B);
170    }
171
172    SDValue NOT(SDValue A) {
173      MVT VT = A.getSimpleValueType();
174      return DAG->getNOT(dl, A, VT);
175    }
176
177    SDValue MUL(SDValue A, SDValue B) {
178      MVT VT = A.getSimpleValueType();
179      return DAG->getNode(ISD::MUL, dl, VT, A, B);
180    }
181
182    SDValue UDIV(SDValue A, SDValue B) {
183      MVT VT = A.getSimpleValueType();
184      return DAG->getNode(ISD::UDIV, dl, VT, A, B);
185    }
186
187    SDValue UREM(SDValue A, SDValue B) {
188      MVT VT = A.getSimpleValueType();
189      return DAG->getNode(ISD::UREM, dl, VT, A, B);
190    }
191
192    SDValue SRL(SDValue A, SDValue Shift) {
193      assert(A.getSimpleValueType().SimpleTy == Shift.getSimpleValueType().SimpleTy &&
194             "SRL value type doesn't match");
195      return DAG->getNode(ISD::SRL, dl, A.getSimpleValueType(), A, Shift);
196    }
197
198    SDValue SHL(SDValue A, SDValue Shift) {
199      assert(A.getSimpleValueType().SimpleTy == Shift.getSimpleValueType().SimpleTy &&
200             "SHL value type doesn't match");
201      return DAG->getNode(ISD::SHL, dl, A.getSimpleValueType(), A, Shift);
202    }
203
204    template <int sh>
205    SDValue SHL(SDValue A) {
206      MVT VT = A.getSimpleValueType();
207      int NumElts = VT.getVectorNumElements();
208
209      SmallVector<SDValue, 16> Pool;
210      SDValue Cst = Constant(sh, VT.getScalarType());
211      for (int i = 0; i < NumElts; i++)
212        Pool.push_back(Cst);
213
214      return SHL(A, BUILD_VECTOR(VT, Pool));
215    }
216
217    SDValue SHL(int sh, SDValue A) {
218      MVT VT = A.getSimpleValueType();
219      int NumElts = VT.getVectorNumElements();
220
221      SmallVector<SDValue, 16> Pool;
222      SDValue Cst = Constant(sh, VT.getScalarType());
223      for (int i = 0; i < NumElts; i++)
224        Pool.push_back(Cst);
225
226      return SHL(A, BUILD_VECTOR(VT, Pool));
227    }
228
229    template <int sh>
230    SDValue SRL(SDValue A) {
231      MVT VT = A.getSimpleValueType();
232      int NumElts = VT.getVectorNumElements();
233
234      SmallVector<SDValue, 16> Pool;
235      SDValue Cst = Constant(sh, VT.getScalarType());
236      for (int i = 0; i < NumElts; i++)
237        Pool.push_back(Cst);
238
239      return SRL(A, BUILD_VECTOR(VT, Pool));
240    }
241
242    SDValue SRL(int sh, SDValue A) {
243      MVT VT = A.getSimpleValueType();
244      int NumElts = VT.getVectorNumElements();
245
246      SmallVector<SDValue, 16> Pool;
247      SDValue Cst = Constant(sh, VT.getScalarType());
248      for (int i = 0; i < NumElts; i++)
249        Pool.push_back(Cst);
250
251      return SRL(A, BUILD_VECTOR(VT, Pool));
252    }
253
254    //C can be ISD::SETNE, ISD::SETLT, etc.
255    SDValue SETCC(SDValue A, SDValue B, ISD::CondCode C) {
256      MVT OpVT = A.getSimpleValueType();
257      MVT VT = MVT::getVectorVT(MVT::i1, OpVT.getVectorNumElements());
258
259      return DAG->getNode(ISD::SETCC, dl, VT, A, B, DAG->getCondCode(C));
260    }
261
262    //High mask of RegisterWidth bits vectors with different field width.
263    //e.g. fieldwidth = 8, mask is 1111000011110000...
264    //return <XX x i64>
265    SDValue HiMask(unsigned RegisterWidth, unsigned FieldWidth) {
266      assert(isPowerOf2_32(FieldWidth) &&
267             isPowerOf2_32(RegisterWidth) &&
268             "all width can only be the power of 2");
269      assert(FieldWidth <= 32 && "HiMask FieldWidth greater than 32");
270
271      //Get i64 mask node
272      std::string mask, finalMask;
273      for (unsigned i = 0; i < FieldWidth/2; i++) mask += "1";
274      for (unsigned i = 0; i < FieldWidth/2; i++) mask += "0";
275      for (unsigned i = 0; i < 64 / mask.size(); i++) finalMask += mask;
276      APInt MaskInt64(64, finalMask, 2);
277      SDValue MaskNode64 = DAG->getConstant(MaskInt64, MVT::i64);
278
279      if (RegisterWidth == 64) {
280        return MaskNode64;
281      }
282      else if (RegisterWidth == 128) {
283        SDValue Pool[] = {MaskNode64, MaskNode64};
284        return BUILD_VECTOR(MVT::v2i64, Pool);
285      }
286      else if (RegisterWidth == 256) {
287        SDValue Pool[] = {MaskNode64, MaskNode64, MaskNode64, MaskNode64};
288        return BUILD_VECTOR(MVT::v4i64, Pool);
289      }
290      else
291        llvm_unreachable("Wrong RegisterWidth in HiMask");
292
293      return SDValue();
294    }
295
296    //X86 specific function
297    SDValue PEXT64(SDValue A, SDValue B) {
298      assert(A.getSimpleValueType() == MVT::i64 &&
299             B.getSimpleValueType() == MVT::i64 &&
300             "PEXT64 only take i64 operands");
301
302      SDValue V = DAG->getNode(ISD::INTRINSIC_WO_CHAIN, dl,
303                              MVT::i64,
304                              DAG->getConstant(Intrinsic::x86_bmi_pext_64, MVT::i32),
305                              A,B);
306      return V;
307    }
308
309    //X86 specific function
310    //Collect sign bit of each 64-bit field into i32
311    SDValue SignMask2x64(SDValue A) {
312      assert(A.getSimpleValueType().getSizeInBits() == 128 &&
313             "SignMask get wrong sized type.");
314      if (A.getSimpleValueType() != MVT::v2f64)
315        A = BITCAST(A, MVT::v2f64);
316
317      SDValue V = DAG->getNode(ISD::INTRINSIC_WO_CHAIN, dl,
318                               MVT::i32,
319                               DAG->getConstant(Intrinsic::x86_sse2_movmsk_pd, MVT::i32),
320                               A);
321      return V;
322    }
323
324    //X86 specific function
325    //Collect sign bit of each 64-bit field into i32
326    SDValue SignMask4x64(SDValue A) {
327      assert(A.getSimpleValueType().getSizeInBits() == 256 &&
328             "SignMask get wrong sized type.");
329      if (A.getSimpleValueType() != MVT::v4f64)
330        A = BITCAST(A, MVT::v4f64);
331
332      SDValue V = DAG->getNode(ISD::INTRINSIC_WO_CHAIN, dl,
333                               MVT::i32,
334                               DAG->getConstant(Intrinsic::x86_avx_movmsk_pd_256, MVT::i32),
335                               A);
336      return V;
337    }
338
339    //simd<1>::ifh
340    //just like SELECT, but for v128i1 vectors. if Mask[i] == 1, A[i] is chosen.
341    //return with the same ValueType of A.
342    SDValue IFH1(SDValue Mask, SDValue A, SDValue B) {
343      assert(A.getValueType().is128BitVector() &&
344             B.getValueType().is128BitVector() &&
345             Mask.getValueType().is128BitVector() &&
346             "IFH1 only take 128 bit vectors");
347
348      MVT VT = A.getSimpleValueType();
349      SDValue NewMask = BITCAST(Mask, MVT::v4i32);
350      SDValue NewOp1  = BITCAST(A, MVT::v4i32);
351      SDValue NewOp2  = BITCAST(B, MVT::v4i32);
352
353      // (NewMask & NewOp1) || (~NewMask & NewOp2)
354      SDValue R = OR(AND(NewMask, NewOp1), AND(NOT(NewMask), NewOp2));
355      return BITCAST(R, VT);
356    }
357
358    SDValue MatchStar(SDValue M, SDValue C) {
359      assert(M.getSimpleValueType().SimpleTy == C.getSimpleValueType().SimpleTy &&
360             "MatchStar operands of different type");
361      return OR(XOR(ADD(AND(M, C), C), C), M);
362    }
363  };
364}
365
366#endif
367
Note: See TracBrowser for help on using the repository browser.