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

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

checkin llvm-meng source

File size: 9.9 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 AND(SDValue A, SDValue B) {
153      MVT VT = A.getSimpleValueType();
154      return DAG->getNode(ISD::AND, dl, VT, A, B);
155    }
156
157    SDValue OR(SDValue A, SDValue B) {
158      MVT VT = A.getSimpleValueType();
159      return DAG->getNode(ISD::OR, dl, VT, A, B);
160    }
161
162    SDValue XOR(SDValue A, SDValue B) {
163      MVT VT = A.getSimpleValueType();
164      return DAG->getNode(ISD::XOR, dl, VT, A, B);
165    }
166
167    SDValue NOT(SDValue A) {
168      MVT VT = A.getSimpleValueType();
169      return DAG->getNOT(dl, A, VT);
170    }
171
172    SDValue MUL(SDValue A, SDValue B) {
173      MVT VT = A.getSimpleValueType();
174      return DAG->getNode(ISD::MUL, dl, VT, A, B);
175    }
176
177    SDValue UDIV(SDValue A, SDValue B) {
178      MVT VT = A.getSimpleValueType();
179      return DAG->getNode(ISD::UDIV, dl, VT, A, B);
180    }
181
182    SDValue UREM(SDValue A, SDValue B) {
183      MVT VT = A.getSimpleValueType();
184      return DAG->getNode(ISD::UREM, dl, VT, A, B);
185    }
186
187    SDValue SRL(SDValue A, SDValue Shift) {
188      assert(A.getSimpleValueType().SimpleTy == Shift.getSimpleValueType().SimpleTy &&
189             "SRL value type doesn't match");
190      return DAG->getNode(ISD::SRL, dl, A.getSimpleValueType(), A, Shift);
191    }
192
193    SDValue SHL(SDValue A, SDValue Shift) {
194      assert(A.getSimpleValueType().SimpleTy == Shift.getSimpleValueType().SimpleTy &&
195             "SHL value type doesn't match");
196      return DAG->getNode(ISD::SHL, dl, A.getSimpleValueType(), A, Shift);
197    }
198
199    template <int sh>
200    SDValue SHL(SDValue A) {
201      MVT VT = A.getSimpleValueType();
202      int NumElts = VT.getVectorNumElements();
203
204      SmallVector<SDValue, 16> Pool;
205      SDValue Cst = Constant(sh, VT.getScalarType());
206      for (int i = 0; i < NumElts; i++)
207        Pool.push_back(Cst);
208
209      return SHL(A, BUILD_VECTOR(VT, Pool));
210    }
211
212    SDValue SHL(int sh, SDValue A) {
213      MVT VT = A.getSimpleValueType();
214      int NumElts = VT.getVectorNumElements();
215
216      SmallVector<SDValue, 16> Pool;
217      SDValue Cst = Constant(sh, VT.getScalarType());
218      for (int i = 0; i < NumElts; i++)
219        Pool.push_back(Cst);
220
221      return SHL(A, BUILD_VECTOR(VT, Pool));
222    }
223
224    template <int sh>
225    SDValue SRL(SDValue A) {
226      MVT VT = A.getSimpleValueType();
227      int NumElts = VT.getVectorNumElements();
228
229      SmallVector<SDValue, 16> Pool;
230      SDValue Cst = Constant(sh, VT.getScalarType());
231      for (int i = 0; i < NumElts; i++)
232        Pool.push_back(Cst);
233
234      return SRL(A, BUILD_VECTOR(VT, Pool));
235    }
236
237    SDValue SRL(int sh, SDValue A) {
238      MVT VT = A.getSimpleValueType();
239      int NumElts = VT.getVectorNumElements();
240
241      SmallVector<SDValue, 16> Pool;
242      SDValue Cst = Constant(sh, VT.getScalarType());
243      for (int i = 0; i < NumElts; i++)
244        Pool.push_back(Cst);
245
246      return SRL(A, BUILD_VECTOR(VT, Pool));
247    }
248
249    //High mask of RegisterWidth bits vectors with different field width.
250    //e.g. fieldwidth = 8, mask is 1111000011110000...
251    //return <XX x i64>
252    SDValue HiMask(unsigned RegisterWidth, unsigned FieldWidth) {
253      assert(isPowerOf2_32(FieldWidth) &&
254             isPowerOf2_32(RegisterWidth) &&
255             "all width can only be the power of 2");
256      assert(FieldWidth <= 32 && "HiMask FieldWidth greater than 32");
257
258      //Get i64 mask node
259      std::string mask, finalMask;
260      for (unsigned i = 0; i < FieldWidth/2; i++) mask += "1";
261      for (unsigned i = 0; i < FieldWidth/2; i++) mask += "0";
262      for (unsigned i = 0; i < 64 / mask.size(); i++) finalMask += mask;
263      APInt MaskInt64(64, finalMask, 2);
264      SDValue MaskNode64 = DAG->getConstant(MaskInt64, MVT::i64);
265
266      if (RegisterWidth == 64) {
267        return MaskNode64;
268      }
269      else if (RegisterWidth == 128) {
270        SDValue Pool[] = {MaskNode64, MaskNode64};
271        return BUILD_VECTOR(MVT::v2i64, Pool);
272      }
273      else if (RegisterWidth == 256) {
274        SDValue Pool[] = {MaskNode64, MaskNode64, MaskNode64, MaskNode64};
275        return BUILD_VECTOR(MVT::v4i64, Pool);
276      }
277      else
278        llvm_unreachable("Wrong RegisterWidth in HiMask");
279
280      return SDValue();
281    }
282
283    SDValue PEXT64(SDValue A, SDValue B) {
284      assert(A.getSimpleValueType() == MVT::i64 &&
285             B.getSimpleValueType() == MVT::i64 &&
286             "PEXT64 only take i64 operands");
287
288      SDValue V = DAG->getNode(ISD::INTRINSIC_WO_CHAIN, dl,
289                              MVT::i64,
290                              DAG->getConstant(Intrinsic::x86_bmi_pext_64, MVT::i32),
291                              A,B);
292      return V;
293    }
294
295    //simd<1>::ifh
296    //just like SELECT, but for v128i1 vectors. if Mask[i] == 1, A[i] is chosen.
297    //return with the same ValueType of A.
298    SDValue IFH1(SDValue Mask, SDValue A, SDValue B) {
299      assert(A.getValueType().is128BitVector() &&
300             B.getValueType().is128BitVector() &&
301             Mask.getValueType().is128BitVector() &&
302             "IFH1 only take 128 bit vectors");
303
304      MVT VT = A.getSimpleValueType();
305      SDValue NewMask = BITCAST(Mask, MVT::v4i32);
306      SDValue NewOp1  = BITCAST(A, MVT::v4i32);
307      SDValue NewOp2  = BITCAST(B, MVT::v4i32);
308
309      // (NewMask & NewOp1) || (~NewMask & NewOp2)
310      SDValue R = OR(AND(NewMask, NewOp1), AND(NOT(NewMask), NewOp2));
311      return BITCAST(R, VT);
312    }
313  };
314}
315
316#endif
317
Note: See TracBrowser for help on using the repository browser.