source: parabix-LLVM/scripts/mkValueTypes.py @ 6297

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

move templates and gen.py into folder scripts

File size: 13.5 KB
Line 
1#
2# Generate MachineValueType.h and ValueTypes.td
3#
4# Rob Cameron   May 16, 2014
5
6
7from string import Template
8import re
9import os
10import shutil
11
12
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
25def calculateTypeData(maxwidth, minvecwidth=32):
26    enumTypeLine = "\t%s\t\t%s,\n"
27    defTypeLine = "def %s\t: ValueType<%s , %s>;\n"
28    enumStringLine = "  case MVT::%s:     return \"MVT::%s\";\n"
29    fw = 1
30    fws = []
31    while (fw <= maxwidth): fws.append(fw); fw = fw * 2
32
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'] = ''
41    VTmap['int_type_enum_strings'] = ''
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)
49        VTmap['int_type_enum_strings'] += enumStringLine % (iType, iType)
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
58
59    enumVal = enumVal + 6
60    VTmap['integer_vector_type_lines'] = ''
61    VTmap['int_vector_value_type_defs'] = ''
62    VTmap['int_vector_value_enum_strings'] = ''
63    for fw in fws:
64        for fieldcount in [f for f in fws if f * fw <= maxwidth and f * fw >= minvecwidth]:
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)
69            VTmap['int_vector_value_enum_strings'] += enumStringLine % (vType, vType)
70            VectorSizeMap[fw * fieldcount].append(vType)
71            VectorFieldSizeMap[fw].append(vType)
72    VTmap['first_integer_vector_type'] = "v%si%s" % (minvecwidth/fws[0], fws[0])
73    VTmap['last_integer_vector_type'] = vType
74    VTmap['float_vector_type_lines'] = ''
75    VTmap['float_vector_value_type_defs'] = ''
76    VTmap['float_vector_value_enum_strings'] = ''
77    for fpfw in [16,32,64]:
78        for fieldcount in [f for f in fws if f * fpfw <= maxwidth]:
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)
83            VTmap['float_vector_value_enum_strings'] += enumStringLine % (vType, vType)
84            VectorSizeMap[fpfw * fieldcount].append(vType)
85            VectorFieldSizeMap[fpfw].append(vType)
86    VTmap['first_float_vector_type'] = "v%sf%s" % (1, 16)
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
104
105def make_isXXXBitFunctions(VectorSizeMap):
106    fns = ""
107    for s in sorted(VectorSizeMap.keys()):
108        tests = ["SimpleTy == MVT::%s" % t for t in VectorSizeMap[s]]
109        if tests != []: testexpr = " ||\n\t\t".join(tests)
110        else: testexpr = 0
111        fns += Template(isXXXBitVectorTemplate).substitute(width=repr(s), typetest=testexpr)
112    return fns
113
114getVectorElementTypeTemplate = r"""
115    MVT getVectorElementType() const {
116        switch (SimpleTy) {
117        default:
118            llvm_unreachable("Not a vector MVT!");
119        ${vector_element_type_cases}
120      }
121    }
122
123"""
124
125
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!");
142      ${vector_element_num_cases}
143      }
144    }
145
146    """
147vecNumRe = re.compile("v([0-9]+)[if][0-9]+")
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))
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.");
185      ${size_in_bits_cases}
186      case x86mmx: return 64;
187      case f80 :  return 80;
188      case f128:
189      case ppcf128: return 128;
190      }
191    }
192
193"""
194def make_getSizeInBits(VectorSizeMap):
195    sCases = ""
196    for s in sorted(VectorSizeMap.keys()):
197        vCases = ["case %s:" % v for v in VectorSizeMap[s]]
198        sCases += "      case i%s: " % s
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);
209      ${integer_VT_cases}
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
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
271def makeMachineValueType_h(maxwidth, minwidth=32):
272    f = open('MachineValueType.h.pytemplate')
273    t = Template(f.read())
274    f.close()
275    (VTmap, VectorSizeMap, VectorFieldSizeMap) = calculateTypeData(maxwidth, minwidth)
276    VTmap['isParabixValue'] = make_isParabixValue(VectorSizeMap)
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)
284    if os.path.exists("MachineValueType.h") and not os.path.exists("MachineValueType.h.bak"):
285        shutil.move("MachineValueType.h", "MachineValueType.h.bak")
286    f = open("MachineValueType.h", "w")
287    f.write(content)
288    f.close()
289
290def makeValueTypes_td(maxwidth, minwidth=32):
291    f = open('ValueTypes.td.pytemplate')
292    t = Template(f.read())
293    f.close()
294    (VTmap, VectorSizeMap, VectorFieldSizeMap) = calculateTypeData(maxwidth, minwidth)
295    content = t.substitute(VTmap)
296    if os.path.exists("ValueTypes.td") and  not os.path.exists("ValueTypes.td.bak"):
297        shutil.move("ValueTypes.td", "ValueTypes.td.bak")
298    f = open("ValueTypes.td", "w")
299    f.write(content)
300    f.close()
301
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
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
323            res += "  case MVT::{0}:   return VectorType::get(Type::".format(tpname)
324            if fieldtype > 64 or fieldtype == 2 or fieldtype == 4:
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
336                continue
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
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
366if __name__ == '__main__':
367    makeMachineValueType_h(1024, 1)
368    makeValueTypes_td(1024, 1)
369    makeCodeGenTarget_cpp(1024, 1)
370    makeValueTypes_cpp(1024, 1)
371    print "MachineValueType.h, CodeGenTarget.cpp and ValueTypes.td generated."
Note: See TracBrowser for help on using the repository browser.