source: parabix-LLVM/mkValueTypes.py @ 3905

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

add float vector support for getTypeForEVT, fix wide integer

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