source: parabix-LLVM/mkValueTypes.py @ 3906

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

add a table of LLVM builtin vector types

File size: 13.5 KB
RevLine 
[3845]1#
2# Generate MachineValueType.h and ValueTypes.td
3#
4# Rob Cameron   May 16, 2014
5
6
7from string import Template
[3852]8import re
9import os
10import shutil
[3845]11
12
[3906]13# LLVM builtin simple value type. From llvm master branch.
14BultinSVT = ['Other', 'i1', 'i8', 'i16', 'i32', 'i64', 'i128',
15             'f16', 'f32', 'f64', 'f80', 'f128', 'ppcf128',
16             'v2i1', 'v4i1', 'v8i1', 'v16i1', 'v32i1', 'v64i1',
17             'v1i8', 'v2i8', 'v4i8', 'v8i8', 'v16i8', 'v32i8',
18             'v1i16', 'v2i16', 'v4i16', 'v8i16', 'v16i16', 'v32i16',
19             'v1i32', 'v2i32', 'v4i32', 'v8i32', 'v16i32',
20             'v1i64', 'v2i64', 'v4i64', 'v8i64', 'v16i64',
21             'v2f16', 'v4f16', 'v8f16', 'v1f32', 'v2f32', 'v4f32', 'v8f32',
22             'v16f32', 'v1f64', 'v2f64', 'v4f64', 'v8f64',
23             'x86mmx', 'Glue', 'isVoid', 'Untyped']
24
[3847]25def calculateTypeData(maxwidth, minvecwidth=32):
[3852]26    enumTypeLine = "\t%s\t\t%s,\n"
[3845]27    defTypeLine = "def %s\t: ValueType<%s , %s>;\n"
[3853]28    enumStringLine = "  case MVT::%s:     return \"MVT::%s\";\n"
[3845]29    fw = 1
30    fws = []
31    while (fw <= maxwidth): fws.append(fw); fw = fw * 2
[3904]32
[3845]33    enumVal = 0
34    VectorSizeMap = {}
35    for f in fws: VectorSizeMap[f] = []
36    VectorFieldSizeMap = {}
37    for f in fws: VectorFieldSizeMap[f] = []
38    VTmap = {}
39    VTmap['integer_type_lines'] = ''
40    VTmap['int_value_type_defs'] = ''
[3853]41    VTmap['int_type_enum_strings'] = ''
[3845]42    intTypes = ""
43    intVecTypes = ""
44    for fw in fws:
45        enumVal += 1
46        iType = "i%s" % fw
47        VTmap['integer_type_lines'] += enumTypeLine % (iType, enumVal)
48        VTmap['int_value_type_defs'] += defTypeLine % (iType, fw, enumVal)
[3853]49        VTmap['int_type_enum_strings'] += enumStringLine % (iType, iType)
[3845]50    VTmap['first_integer_type'] = 'i%s' % fws[0]
51    VTmap['last_integer_type'] = 'i%s' % fws[-1]
52    VTmap['f16'] = enumVal + 1
53    VTmap['f32'] = VTmap['f16'] + 1
54    VTmap['f64'] = VTmap['f32'] + 1
55    VTmap['f80'] = VTmap['f64'] + 1
56    VTmap['f128'] = VTmap['f80'] + 1
57    VTmap['ppcf128'] = VTmap['f128'] + 1
[3852]58
[3845]59    enumVal = enumVal + 6
60    VTmap['integer_vector_type_lines'] = ''
61    VTmap['int_vector_value_type_defs'] = ''
[3853]62    VTmap['int_vector_value_enum_strings'] = ''
[3845]63    for fw in fws:
[3847]64        for fieldcount in [f for f in fws if f * fw <= maxwidth and f * fw >= minvecwidth]:
[3845]65            enumVal += 1
66            vType = "v%si%s" % (fieldcount, fw)
67            VTmap['integer_vector_type_lines'] += enumTypeLine % (vType, enumVal)
68            VTmap['int_vector_value_type_defs'] += defTypeLine % (vType, fieldcount * fw, enumVal)
[3853]69            VTmap['int_vector_value_enum_strings'] += enumStringLine % (vType, vType)
[3845]70            VectorSizeMap[fw * fieldcount].append(vType)
71            VectorFieldSizeMap[fw].append(vType)
[3848]72    VTmap['first_integer_vector_type'] = "v%si%s" % (minvecwidth/fws[0], fws[0])
[3845]73    VTmap['last_integer_vector_type'] = vType
74    VTmap['float_vector_type_lines'] = ''
75    VTmap['float_vector_value_type_defs'] = ''
[3853]76    VTmap['float_vector_value_enum_strings'] = ''
[3845]77    for fpfw in [16,32,64]:
[3846]78        for fieldcount in [f for f in fws if f * fpfw <= maxwidth]:
[3845]79            enumVal += 1
80            vType = "v%sf%s" % (fieldcount, fpfw)
81            VTmap['float_vector_type_lines'] += enumTypeLine % (vType, enumVal)
82            VTmap['float_vector_value_type_defs'] += defTypeLine % (vType, fieldcount * fpfw, enumVal)
[3853]83            VTmap['float_vector_value_enum_strings'] += enumStringLine % (vType, vType)
[3845]84            VectorSizeMap[fpfw * fieldcount].append(vType)
85            VectorFieldSizeMap[fpfw].append(vType)
[3846]86    VTmap['first_float_vector_type'] = "v%sf%s" % (1, 16)
[3845]87    VTmap['last_float_vector_type'] = vType
88    VTmap['x86mmx'] = enumVal + 1
89    VTmap['Glue'] = VTmap['x86mmx'] + 1
90    VTmap['isVoid'] = VTmap['Glue'] + 1
91    VTmap['Untyped'] = VTmap['isVoid'] + 1
92    VTmap['last_value_type'] = VTmap['Untyped'] + 1
93    VTmap['max_value_type'] = ((VTmap['last_value_type'] - 1)/32 + 1)*32
94    return (VTmap, VectorSizeMap, VectorFieldSizeMap)
95
96
97isXXXBitVectorTemplate = r"""
98    /// is${width}BitVector - Return true if this is a ${width}-bit vector type.
99    bool is${width}BitVector() const {
100    return (${typetest});
101    }
102"""
103
[3852]104
[3845]105def make_isXXXBitFunctions(VectorSizeMap):
106    fns = ""
107    for s in sorted(VectorSizeMap.keys()):
108        tests = ["SimpleTy == MVT::%s" % t for t in VectorSizeMap[s]]
[3848]109        if tests != []: testexpr = " ||\n\t\t".join(tests)
110        else: testexpr = 0
[3852]111        fns += Template(isXXXBitVectorTemplate).substitute(width=repr(s), typetest=testexpr)
[3845]112    return fns
113
114getVectorElementTypeTemplate = r"""
115    MVT getVectorElementType() const {
116        switch (SimpleTy) {
117        default:
118            llvm_unreachable("Not a vector MVT!");
[3852]119        ${vector_element_type_cases}
[3845]120      }
121    }
[3852]122
[3845]123"""
124
[3852]125
[3845]126def make_getVectorElementType(VectorFieldSizeMap):
127    tCases = ""
128    for s in sorted(VectorFieldSizeMap.keys()):
129        fCases = ["case %s: " % t for t in VectorFieldSizeMap[s] if t[-3] == 'f']
130        iCases = ["case %s: " % t  for t in VectorFieldSizeMap[s] if t[-3] != 'f']
131        if fCases != []:
132            tCases += "\t%s return f%s;\n" % (" ".join(fCases), s)
133        if iCases != []:
134            tCases += "\t%s return i%s;\n" % (" ".join(iCases), s)
135    return Template(getVectorElementTypeTemplate).substitute(vector_element_type_cases = tCases)
136
137getVectorElementNumElementsTemplate = r"""
138    unsigned getVectorNumElements() const {
139      switch (SimpleTy) {
140      default:
141        llvm_unreachable("Not a vector MVT!");
[3852]142      ${vector_element_num_cases}
[3845]143      }
144    }
[3852]145
[3845]146    """
[3852]147vecNumRe = re.compile("v([0-9]+)[if][0-9]+")
[3904]148def getNumElement(typeString):
149    """
150    return number of elements in a type string
151    e.g. return 32 in v32i1
152    """
153    m = vecNumRe.match(typeString)
154    return int(m.group(1))
[3845]155
156def make_getVectorNumElements(VectorSizeMap):
157    nCases = ""
158    byElemCount = {}
159    for s in sorted(VectorSizeMap.keys()):
160        for t in VectorSizeMap[s]:
161            m = vecNumRe.match(t)
162            e = m.group(1)
163            if not byElemCount.has_key(e): byElemCount[e] = ""
164            byElemCount[e] += "case %s: " % t
165    for e in sorted(byElemCount.keys()):
166        nCases += "      %s return %s;\n" % (byElemCount[e], e)
167    return Template(getVectorElementNumElementsTemplate).substitute(vector_element_num_cases = nCases)
168
169getSizeInBitsTemplate = r"""
170    unsigned getSizeInBits() const {
171    switch (SimpleTy) {
172      default:
173        llvm_unreachable("getSizeInBits called on extended MVT.");
174      case Other:
175        llvm_unreachable("Value type is non-standard value, Other.");
176      case iPTR:
177        llvm_unreachable("Value type size is target-dependent. Ask TLI.");
178      case iPTRAny:
179      case iAny:
180      case fAny:
181      case vAny:
182        llvm_unreachable("Value type is overloaded.");
183      case Metadata:
184        llvm_unreachable("Value type is metadata.");
[3852]185      ${size_in_bits_cases}
[3845]186      case x86mmx: return 64;
187      case f80 :  return 80;
188      case f128:
189      case ppcf128: return 128;
190      }
191    }
[3852]192
[3845]193"""
194def make_getSizeInBits(VectorSizeMap):
195    sCases = ""
196    for s in sorted(VectorSizeMap.keys()):
197        vCases = ["case %s:" % v for v in VectorSizeMap[s]]
[3852]198        sCases += "      case i%s: " % s
[3845]199        if s in [16,32,64]: sCases += "case f%s: " % s
200        sCases += " ".join(vCases)
201        sCases += " return %s;\n" % s
202    return Template(getSizeInBitsTemplate).substitute(size_in_bits_cases = sCases)
203
204getIntegerVTTemplate = r"""
205    static MVT getIntegerVT(unsigned BitWidth) {
206      switch (BitWidth) {
207      default:
208        return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
[3852]209      ${integer_VT_cases}
[3845]210      }
211    }
212"""
213
214def make_getIntegerVT(VectorFieldSizeMap):
215    iCases = ""
216    for s in sorted(VectorFieldSizeMap.keys()):
217        iCases += "      case %s:\n        return MVT::i%s;\n" % (s, s)
218    return Template(getIntegerVTTemplate).substitute(integer_VT_cases = iCases)
219
220
221getVectorVTTemplate = r"""
222    static MVT getVectorVT(MVT VT, unsigned NumElements) {
223      switch (VT.SimpleTy) {
224      default:
225        break;
226${vector_VT_cases}
227      }
228      return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
229    }
230"""
231
232def make_getVectorVT(VectorFieldSizeMap):
233    iCases = ""
234    fCases = ""
235    for s in sorted(VectorFieldSizeMap.keys()):
236        iCases += "      case MVT::i%s:\n" % s
237        for t in VectorFieldSizeMap[s]:
238            if t[-3] != 'f':
239                # integer case
240                m = vecNumRe.match(t)
241                e = m.group(1)
242                iCases += "        if (NumElements == %s)  return MVT::%s;\n" % (e, t)
243        iCases += "        break;\n"
244    for s in [16, 32, 64]:
245        fCases += "      case MVT::f%s:\n" % s
246        for t in VectorFieldSizeMap[s]:
247            if t[-3] == 'f':
248                # float case
249                m = vecNumRe.match(t)
250                e = m.group(1)
251                fCases += "        if (NumElements == %s)  return MVT::%s;\n" % (e, t)
252        fCases += "        break;\n"
253    return Template(getVectorVTTemplate).substitute(vector_VT_cases = iCases+fCases)
254
255
[3906]256def make_isParabixValue(VectorSizeMap):
257    """
258    (SimpleTy == MVT::v16i8 || SimpleTy == MVT::v16i16 || ...)
259    """
260    res = '('
261    for bitwidth in sorted(VectorSizeMap.keys()):
262        for tpname in VectorSizeMap[bitwidth]:
263            if tpname in BultinSVT:
264                continue
265            res += "SimpleTy == MVT::{0} || ".format(tpname)
266    #remove trailing " || "
267    res = res[:-4] + ")"
268    return res
269
270
[3847]271def makeMachineValueType_h(maxwidth, minwidth=32):
[3845]272    f = open('MachineValueType.h.pytemplate')
273    t = Template(f.read())
274    f.close()
[3847]275    (VTmap, VectorSizeMap, VectorFieldSizeMap) = calculateTypeData(maxwidth, minwidth)
[3906]276    VTmap['isParabixValue'] = make_isParabixValue(VectorSizeMap)
[3845]277    VTmap['isXXXBitFunctions'] = make_isXXXBitFunctions(VectorSizeMap)
278    VTmap['getVectorElementType'] = make_getVectorElementType(VectorFieldSizeMap)
279    VTmap['getVectorNumElements'] = make_getVectorNumElements(VectorSizeMap)
280    VTmap['getSizeInBits'] = make_getSizeInBits(VectorSizeMap)
281    VTmap['getIntegerVT'] = make_getIntegerVT(VectorFieldSizeMap)
282    VTmap['getVectorVT'] = make_getVectorVT(VectorFieldSizeMap)
283    content = t.substitute(VTmap)
[3846]284    if os.path.exists("MachineValueType.h") and not os.path.exists("MachineValueType.h.bak"):
[3852]285        shutil.move("MachineValueType.h", "MachineValueType.h.bak")
[3845]286    f = open("MachineValueType.h", "w")
287    f.write(content)
288    f.close()
289
[3847]290def makeValueTypes_td(maxwidth, minwidth=32):
[3845]291    f = open('ValueTypes.td.pytemplate')
292    t = Template(f.read())
293    f.close()
[3847]294    (VTmap, VectorSizeMap, VectorFieldSizeMap) = calculateTypeData(maxwidth, minwidth)
[3845]295    content = t.substitute(VTmap)
[3846]296    if os.path.exists("ValueTypes.td") and  not os.path.exists("ValueTypes.td.bak"):
[3852]297        shutil.move("ValueTypes.td", "ValueTypes.td.bak")
[3845]298    f = open("ValueTypes.td", "w")
299    f.write(content)
300    f.close()
301
[3853]302def makeCodeGenTarget_cpp(maxwidth, minwidth=32):
303    f = open('CodeGenTarget.cpp.pytemplate')
304    t = Template(f.read())
305    f.close()
306    (VTmap, VectorSizeMap, VectorFieldSizeMap) = calculateTypeData(maxwidth, minwidth)
307    content = t.substitute(VTmap)
308    if os.path.exists("CodeGenTarget.cpp") and  not os.path.exists("CodeGenTarget.cpp.bak"):
309        shutil.move("CodeGenTarget.cpp", "CodeGenTarget.cpp.bak")
310    f = open("CodeGenTarget.cpp", "w")
311    f.write(content)
312    f.close()
313
[3904]314def make_getTypeForEVT(VectorSizeMap):
315    res = ''
316    for bitwidth in sorted(VectorSizeMap.keys()):
317        for tpname in VectorSizeMap[bitwidth]:
318            if 'f' in tpname:
319                # only works on integer vectors
320                continue
321            num_elt = getNumElement(tpname)
322            fieldtype = bitwidth / num_elt
[3905]323            res += "  case MVT::{0}:   return VectorType::get(Type::".format(tpname)
[3904]324            if fieldtype > 64 or fieldtype == 2 or fieldtype == 4:
[3905]325                res += "getIntNTy(Context, {0})".format(fieldtype)
326            else:
327                res += "getInt{0}Ty(Context)".format(fieldtype)
328            res += ", {0});\n".format(num_elt)
329
330    res += "\n"
331
332    for bitwidth in sorted(VectorSizeMap.keys()):
333        for tpname in VectorSizeMap[bitwidth]:
334            if 'f' not in tpname:
335                # only works on integer vectors
[3904]336                continue
[3905]337            num_elt = getNumElement(tpname)
338            fieldtype = bitwidth / num_elt
339            res += "  case MVT::{0}:   return VectorType::get(Type::".format(tpname)
340            if fieldtype == 16:
341                res += "getHalfTy"
342            elif fieldtype == 32:
343                res += "getFloatTy"
344            elif fieldtype == 64:
345                res += "getDoubleTy"
346            else:
347                raise Exception("Invalid float type for getTypeForEVT")
348            res += "(Context), {0});\n".format(num_elt)
349
[3904]350    return res
351
352def makeValueTypes_cpp(maxwidth, minwidth=32):
353    f = open('ValueTypes.cpp.pytemplate')
354    t = Template(f.read())
355    f.close()
356    (VTmap, VectorSizeMap, VectorFieldSizeMap) = calculateTypeData(maxwidth, minwidth)
357    VTmap['get_type_for_vector_EVT'] = make_getTypeForEVT(VectorSizeMap)
358    content = t.substitute(VTmap)
359    if os.path.exists("ValueTypes.cpp") and  not os.path.exists("ValueTypes.cpp.bak"):
360        shutil.move("ValueTypes.cpp", "ValueTypes.cpp.bak")
361    f = open("ValueTypes.cpp", "w")
362    f.write(content)
363    f.close()
364    print "ValueTypes.cpp generated."
365
[3845]366if __name__ == '__main__':
[3859]367    makeMachineValueType_h(1024, 1)
368    makeValueTypes_td(1024, 1)
369    makeCodeGenTarget_cpp(1024, 1)
[3904]370    makeValueTypes_cpp(1024, 1)
[3853]371    print "MachineValueType.h, CodeGenTarget.cpp and ValueTypes.td generated."
Note: See TracBrowser for help on using the repository browser.