├── CodeGenLLVM.py ├── MUDA.py ├── PyGotham Slides.pdf ├── PyllvmError.py ├── README.md ├── SymbolTable.py ├── Thesis.pdf ├── TypeInference.py ├── VecTypes.py ├── __init__.py ├── cpp_python_wrapper ├── TupleSet.h ├── hello.cpp ├── hello.o ├── hello.py ├── hello.so ├── makefile ├── python_example.cpp ├── python_example.o ├── python_example.so └── testC.h ├── experiments ├── float_print.bc ├── int_print.bc └── test_llvm.cpp ├── llvm_bm.sh ├── lots_test.py ├── mmath.py ├── pyllvm.py └── tp_tests ├── bayes.py ├── compile_numba ├── numba_timer.py ├── set1 │ ├── np_bayes.py │ ├── np_kmeans.py │ ├── np_linreg.py │ └── np_logreg.py └── set2 │ ├── np2_bayes.py │ ├── np2_kmeans.py │ ├── np2_linreg.py │ └── np2_logreg.py ├── kmeans.py ├── linreg.py ├── llvm_clang ├── bayes.cpp ├── cpp_bayes.bc ├── cpp_kmeans.bc ├── cpp_linreg.bc ├── cpp_logreg.bc ├── kmeans.cpp ├── linreg.cpp ├── llvm_bm.sh ├── logreg.cpp └── run_llvm_bm_cl.sh ├── llvm_numba ├── numba_genLLVM.py ├── numba_llvm_bayes.bc └── numba_llvm_bayes.py ├── llvm_pyllvm ├── bayes.bc ├── kmeans.bc ├── linreg.bc ├── llvm_bm.sh ├── logreg.bc └── run_llvm_bm_pl.sh ├── logreg.py └── timer.py /MUDA.py: -------------------------------------------------------------------------------- 1 | import struct 2 | import math 3 | from PyllvmError import * 4 | def f2b(f): 5 | """ 6 | float to 32bit int 7 | """ 8 | return struct.unpack('I', struct.pack('f', f))[0] 9 | 10 | def b2f(b): 11 | """ 12 | 32bit int to float 13 | """ 14 | return struct.unpack('f', struct.pack('I', b))[0] 15 | 16 | class vec(object): 17 | """ 18 | <4 x float> 19 | """ 20 | 21 | def __init__(self, *args): 22 | 23 | v = [] 24 | 25 | if len(args) == 4: 26 | # vec(1.0, 2.0, 3.0, 4.0) 27 | 28 | for a in args: 29 | assert isinstance(a, float), ("Arg must be a float type, but %s(%s) is given" % (a, type(a))) 30 | 31 | v.append(a) 32 | 33 | elif len(args) == 1: 34 | if isinstance(args[0], list): 35 | # vec([1.0, 2.0, 3.0, 4.0]) 36 | v = args[0] 37 | 38 | elif isinstance(args[0], float): 39 | # vec(1.0) 40 | v.append(args[0]) 41 | v.append(args[0]) 42 | v.append(args[0]) 43 | v.append(args[0]) 44 | 45 | else: 46 | raise PyllvmError("MUDA: Unsupported input for vec():", args) 47 | 48 | elif len(args) == 0: 49 | # vec() 50 | v = [0.0, 0.0, 0.0, 0.0] 51 | 52 | else: 53 | raise PyllvmError("MUDA: Unsupported input for vec():", args) 54 | 55 | self.value = v 56 | 57 | # self.addSwizzleMethod() 58 | 59 | def __str__(self): 60 | 61 | return str(self.value) 62 | 63 | 64 | def __add__(self, b): 65 | 66 | if not isinstance(b, vec): 67 | raise PyllvmError("MUDA: RHS is not a type of vec") 68 | 69 | tmp = vec([x + y for x, y in zip(self.value, b.value)]) 70 | 71 | return tmp 72 | 73 | 74 | def __sub__(self, b): 75 | 76 | if not isinstance(b, vec): 77 | raise PyllvmError("MUDA: RHS is not a type of vec") 78 | 79 | tmp = vec([x - y for x, y in zip(self.value, b.value)]) 80 | 81 | return tmp 82 | 83 | def __mul__(self, b): 84 | 85 | if not isinstance(b, vec): 86 | raise PyllvmError("MUDA: RHS is not a type of vec") 87 | 88 | tmp = vec([x * y for x, y in zip(self.value, b.value)]) 89 | 90 | return tmp 91 | 92 | def __div__(self, b): 93 | 94 | if not isinstance(b, vec): 95 | raise PyllvmError("MUDA: RHS is not a type of vec") 96 | 97 | tmp = vec([x / y for x, y in zip(self.value, b.value)]) 98 | 99 | return tmp 100 | 101 | def __gt__(self, b): 102 | 103 | if not isinstance(b, vec): 104 | raise PyllvmError("MUDA: RHS is not a type of vec") 105 | 106 | r = [0.0, 0.0, 0.0, 0.0] 107 | 108 | for i in range(4): 109 | if self.value[i] > b.value[i]: 110 | r[i] = b2f(0xffffffff) 111 | else: 112 | r[i] = b2f(0x00000000) 113 | 114 | return vec(r) 115 | 116 | def __ge__(self, b): 117 | 118 | if not isinstance(b, vec): 119 | raise PyllvmError("MUDA: RHS is not a type of vec") 120 | 121 | r = [0.0, 0.0, 0.0, 0.0] 122 | 123 | for i in range(4): 124 | if self.value[i] >= b.value[i]: 125 | r[i] = b2f(0xffffffff) 126 | else: 127 | r[i] = b2f(0x00000000) 128 | 129 | return vec(r) 130 | 131 | def __lt__(self, b): 132 | 133 | if not isinstance(b, vec): 134 | raise PyllvmError("MUDA: RHS is not a type of vec") 135 | 136 | r = [0.0, 0.0, 0.0, 0.0] 137 | 138 | for i in range(4): 139 | if self.value[i] < b.value[i]: 140 | r[i] = b2f(0xffffffff) 141 | else: 142 | r[i] = b2f(0x00000000) 143 | 144 | return vec(r) 145 | 146 | def __le__(self, b): 147 | 148 | if not isinstance(b, vec): 149 | raise PyllvmError("MUDA: RHS is not a type of vec") 150 | 151 | r = [0.0, 0.0, 0.0, 0.0] 152 | 153 | for i in range(4): 154 | if self.value[i] <= b.value[i]: 155 | r[i] = b2f(0xffffffff) 156 | else: 157 | r[i] = b2f(0x00000000) 158 | 159 | return vec(r) 160 | 161 | 162 | def __getattr__(self, name): 163 | 164 | # 165 | # Handle swizzle 166 | # 167 | d = { 'x' : 0, 'y' : 1, 'z' : 2, 'w' : 3 } 168 | 169 | assert len(name) < 5, "Invalid attribute: %s" % name 170 | 171 | if len(name) == 1: 172 | return self.value[d[name]] 173 | 174 | v = vec([0.0, 0.0, 0.0, 0.0]) 175 | 176 | for (i, s) in enumerate(name): 177 | if not d.has_key(s): 178 | raise PyllvmError("MUDA: Invalid letter for swizzle:", name) 179 | 180 | v.value[i] = self.value[d[s]] 181 | 182 | for i in range(len(name), 4): 183 | v.value[i] = self.value[d[name[-1]]] 184 | 185 | return v 186 | 187 | 188 | """ 189 | TODO... 190 | 191 | class mstructdef(object): 192 | 193 | def __init__(self, structElements): 194 | 195 | assert isinstance(structElements, dict) 196 | 197 | print structElements 198 | 199 | 200 | class mstruct(object): 201 | 202 | def __init__(self, structDef): 203 | 204 | assert isinstance(structDef, mstructdef) 205 | 206 | 207 | class marray(object): 208 | 209 | def __init__(self, ty, sz): 210 | 211 | self.type = ty 212 | self.size = sz 213 | 214 | self.values = [] 215 | 216 | def __str__(self): 217 | 218 | return str(self.values) 219 | """ 220 | 221 | def GetMUDATypeDic(): 222 | 223 | d = { 224 | 'vec' : vec 225 | } 226 | 227 | return d 228 | 229 | def vsel(a, b, m): 230 | assert isinstance(a, vec) 231 | assert isinstance(b, vec) 232 | assert isinstance(m, vec) 233 | 234 | r = [0.0, 0.0, 0.0, 0.0] 235 | 236 | for i in range(4): 237 | 238 | u = f2b(m.value[i]) 239 | if u == 0xffffffff: 240 | r[i] = b.value[i] 241 | else: # 0x00000000 242 | r[i] = a.value[i] 243 | 244 | return vec(r) 245 | 246 | 247 | # 248 | # Vector math function 249 | # 250 | def vabs(a): 251 | assert isinstance(a, vec) 252 | 253 | v0 = math.fabs(a.value[0]) 254 | v1 = math.fabs(a.value[1]) 255 | v2 = math.fabs(a.value[2]) 256 | v3 = math.fabs(a.value[3]) 257 | 258 | r = vec([v0, v1, v2, v3]) 259 | 260 | return r 261 | 262 | def vexp(a): 263 | assert isinstance(a, vec) 264 | 265 | v0 = math.exp(a.value[0]) 266 | v1 = math.exp(a.value[1]) 267 | v2 = math.exp(a.value[2]) 268 | v3 = math.exp(a.value[3]) 269 | 270 | r = vec([v0, v1, v2, v3]) 271 | 272 | return r 273 | 274 | def vlog(a): 275 | assert isinstance(a, vec) 276 | 277 | v0 = math.log(a.value[0]) 278 | v1 = math.log(a.value[1]) 279 | v2 = math.log(a.value[2]) 280 | v3 = math.log(a.value[3]) 281 | 282 | r = vec([v0, v1, v2, v3]) 283 | 284 | return r 285 | 286 | def vsqrt(a): 287 | assert isinstance(a, vec) 288 | 289 | v0 = math.sqrt(a.value[0]) 290 | v1 = math.sqrt(a.value[1]) 291 | v2 = math.sqrt(a.value[2]) 292 | v3 = math.sqrt(a.value[3]) 293 | 294 | r = vec([v0, v1, v2, v3]) 295 | 296 | return r 297 | 298 | def printf(msg): 299 | 300 | print msg 301 | 302 | 303 | def _testVec(): 304 | 305 | a = vec([1.0, 2.0, 3.0, 4.0]) 306 | 307 | print a 308 | 309 | print a.x 310 | print a.y 311 | print a.z 312 | print a.w 313 | 314 | print a.xy 315 | print a.yz 316 | 317 | b = a.x 318 | 319 | # 320 | # Intrinsic math functions 321 | # 322 | intrinsics = { 323 | # Name : ( ret type , arg types 324 | 'vabs' : ( vec , [ vec ] ) 325 | , 'vexp' : ( vec , [ vec ] ) 326 | , 'vlog' : ( vec , [ vec ] ) 327 | , 'vsqrt' : ( vec , [ vec ] ) 328 | , 'vsel' : ( vec , [ vec, vec, vec ] ) 329 | , 'len' : ( int , [ list ] ) 330 | } 331 | 332 | def GetIntrinsicFunctions(): 333 | return intrinsics 334 | 335 | -------------------------------------------------------------------------------- /PyGotham Slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aherlihy/PythonLLVM/fb91b07d585cb32e9f76a6e9795a1fce005dfab4/PyGotham Slides.pdf -------------------------------------------------------------------------------- /PyllvmError.py: -------------------------------------------------------------------------------- 1 | class PyllvmError(Exception): 2 | #def __init__(self, value): 3 | # self.value = value 4 | #def __str__(self): 5 | # return repr(self.value) 6 | pass 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PythonLLVM 2 | ========== 3 | 4 | LLVM compiler for python 5 | -------------------------------------------------------------------------------- /SymbolTable.py: -------------------------------------------------------------------------------- 1 | from PyllvmError import * 2 | 3 | class Symbol(object): 4 | """ 5 | Structure for symbol with type information. 6 | 7 | >>> s = Symbol("a", float, "variable") 8 | >>> print s 9 | a() 10 | >>> s = Symbol("b", float, "variable", cls = "bora") 11 | >>> print s 12 | b() attrs: cls = bora 13 | >>> import VecTypes 14 | >>> s = Symbol("c", VecTypes.vec, "variable") 15 | >>> print s 16 | c() 17 | """ 18 | 19 | def __init__(self, name, type, kind, dim=None, **kwargs): 20 | 21 | assert type is not None 22 | 23 | #print "; [SymbolTable] add %s(ty= %s, knd = %s)" % (name, type, kind) 24 | self.name = name 25 | self.type = type 26 | self.kind = kind 27 | 28 | self.dim = dim 29 | self.attrs = [] 30 | for (k, v) in kwargs.items(): 31 | self.__dict__[k] = v 32 | self.attrs.append(k) 33 | def getDim(self): 34 | return self.dim 35 | def __str__(self): 36 | 37 | s = "%s(%s)" % (self.name, self.type) 38 | 39 | if len(self.attrs) > 0: 40 | s += " attrs: " 41 | else: 42 | s += " attrs=[]" 43 | 44 | for k in self.attrs: 45 | s += "%s = %s" % (k, self.__dict__[k]) 46 | if k != self.attrs[-1]: s += ", " 47 | 48 | 49 | return s 50 | 51 | 52 | class SymbolTable: 53 | """ 54 | Symbol table 55 | """ 56 | 57 | def __init__(self): 58 | 59 | self.symbols = [('global', {})] # stack of (function scope name, dict) 60 | 61 | self.genNum = 0 62 | 63 | def __str__(self): 64 | """ 65 | s = "[" 66 | for x in self.symbols: 67 | s+=x[0]+"\n" 68 | for z in x[1].keys(): 69 | s+= str(z) + ":" + str(x[1][z]) + "\n" 70 | s+="]" 71 | return s 72 | """ 73 | return str(self.symbols) 74 | 75 | def popScope(self): 76 | 77 | assert len(self.symbols) > 1 78 | 79 | del self.symbols[-1] 80 | 81 | 82 | def pushScope(self, name): 83 | 84 | self.symbols.append((name, {})) 85 | 86 | 87 | def append(self, sym): 88 | 89 | assert isinstance(sym, Symbol) 90 | 91 | d = self.symbols[-1][1] 92 | 93 | 94 | # if d.has_key(sym.name): 95 | # raise Exception("Symbol %s is already defined" % sym.name) 96 | 97 | d[sym.name] = sym 98 | 99 | 100 | def find(self, name): 101 | """ 102 | Find a symbol with name. 103 | If a symbol was not found, return None. 104 | """ 105 | 106 | for i in range(len(self.symbols)): 107 | 108 | d = self.symbols[i][1] 109 | if d.has_key(name): 110 | return d[name] 111 | 112 | return None 113 | 114 | 115 | def lookup(self, name): 116 | """ 117 | Find a symbol with name. 118 | If a symbol was not found, raise a exeption. 119 | """ 120 | 121 | for i in range(len(self.symbols)): 122 | 123 | d = self.symbols[i][1] 124 | if d.has_key(name): 125 | return d[name] 126 | 127 | raise PyllvmError("Symbol Table: Undefine symbol: ", name) 128 | 129 | def genUniqueSymbol(self, type): 130 | """ 131 | Generate unique symbol. 132 | """ 133 | nMax = 1000 134 | 135 | baseName = "tmp" 136 | 137 | done = False 138 | i = 0 139 | while 1: 140 | 141 | name = baseName + str(self.genNum) 142 | 143 | if self.find(name) == None: 144 | 145 | newSym = Symbol(name, type, "variable") 146 | self.append(newSym) 147 | 148 | return newSym 149 | 150 | self.genNum += 1 151 | i += 1 152 | 153 | if i > nMax: 154 | raise PyllvmError("Symbol Table: Can't define unique symbol.") 155 | def returnSymbols(self): 156 | return self.symbols 157 | 158 | -------------------------------------------------------------------------------- /Thesis.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aherlihy/PythonLLVM/fb91b07d585cb32e9f76a6e9795a1fce005dfab4/Thesis.pdf -------------------------------------------------------------------------------- /TypeInference.py: -------------------------------------------------------------------------------- 1 | import re 2 | import compiler 3 | import sys 4 | from SymbolTable import * 5 | from MUDA import * 6 | from mmath import * 7 | from PyllvmError import PyllvmError 8 | class void(object): 9 | """ 10 | Represents void type 11 | """ 12 | def __init__(self): 13 | pass 14 | 15 | 16 | class TypeInference(object): 17 | """ 18 | Simple type inference mechanism for python AST. 19 | >>> t = TypeInference() 20 | >>> t.inferType(compiler.parse("1+3")) 21 | 22 | """ 23 | 24 | def __init__(self, symTable): 25 | assert isinstance(symTable, SymbolTable) 26 | 27 | # First class types 28 | self.typeDic = { 29 | 'int' : int 30 | , 'float' : float 31 | , 'void' : void 32 | , 'list' : str 33 | , 'list' : list 34 | } 35 | 36 | self.typeDic.update(GetMUDATypeDic()) # register MUDA type 37 | 38 | self.symbolTable = symTable 39 | 40 | # Register intrinsic functions from MUDA module 41 | self.intrinsics = GetIntrinsicFunctions() 42 | 43 | for (k, v) in self.intrinsics.items(): 44 | retTy = v[0] 45 | argTys = v[1] 46 | sym = Symbol(k, retTy, "function", argtypes = argTys) 47 | self.symbolTable.append(sym) 48 | 49 | 50 | 51 | def isFloatType(self, ty): 52 | if (ty == float or 53 | ty == vec ): 54 | return True 55 | 56 | return False 57 | 58 | 59 | def isNameOfFirstClassType(self, name): 60 | if self.typeDic.has_key(name): 61 | return self.typeDic[name] 62 | if name[:4]=='list': 63 | return list 64 | if name[:3]=='str': 65 | return str 66 | return None 67 | 68 | def getIntrinsicFunctionFromName(self, name): 69 | #print ";TI--" + sys._getframe().f_code.co_name + "----" 70 | if self.intrinsics.has_key(name): 71 | return self.intrinsics[name] 72 | 73 | return None 74 | 75 | def inferType(self, node): 76 | #print ";TI--" + sys._getframe().f_code.co_name + "----" 77 | """ 78 | Return type if type inference was succeeded, None if failed. 79 | """ 80 | 81 | assert node is not None 82 | 83 | g = re.compile("(\w+)\(.*\)") 84 | op = g.match(str(node)) 85 | 86 | if op == None: 87 | raise PyllvmError("Type Inference: Invalid node name?", str(node)) 88 | 89 | op_name = op.group(1) 90 | 91 | # 92 | # call the method whose name is "infer + ${op_name}" 93 | # 94 | 95 | method_name = "infer%s" % op_name 96 | 97 | if not callable(getattr(self, method_name)): 98 | raise PyllvmError("Type Inference: Unknown node name:", op_name) 99 | 100 | method = getattr(self, method_name) 101 | 102 | return method(node) 103 | 104 | def inferModule(self, node): 105 | #print ";TI--" + sys._getframe().f_code.co_name + "----" 106 | 107 | return self.inferType(node.node) 108 | 109 | def inferReturn(self, node): 110 | return self.inferType(node.value) 111 | 112 | 113 | def inferStmt(self, node): 114 | #print ";TI--" + sys._getframe().f_code.co_name + "----" 115 | 116 | return self.inferType(node.nodes[0]) 117 | 118 | def checkSwizzleLetter(self, name): 119 | #print ";TI--" + sys._getframe().f_code.co_name + "----" 120 | 121 | assert len(name) >= 1 and len(name) < 5 122 | 123 | for s in name: 124 | if not s in ('x', 'y', 'z', 'w'): 125 | raise PyllvmError("Type Inference: Not a swizzle letter:", name) 126 | 127 | return True 128 | 129 | def inferGetattr(self, node): 130 | #print ";TI--" + sys._getframe().f_code.co_name + "----" 131 | """ 132 | a.x 133 | a.xyz 134 | a.xyzw 135 | 136 | node.expr must be a vector type. 137 | """ 138 | 139 | ty = self.inferType(node.expr) 140 | assert ty == vec, "swizzle pattern must be specified for vector variable, but variable has type %s: %s" % (ty, node) 141 | 142 | swizzleName = node.attrname 143 | self.checkSwizzleLetter(swizzleName) 144 | 145 | if len(swizzleName) is 1: 146 | # scalar 147 | if ty == vec: 148 | return float 149 | else: 150 | raise PyllvmError("Type Inference: Unknown type:", ty) 151 | 152 | else: 153 | # vector 154 | return ty 155 | 156 | def inferDiscard(self, node): 157 | #print ";TI--" + sys._getframe().f_code.co_name + "----" 158 | 159 | return self.inferType(node.expr) 160 | 161 | def inferCallFunc(self, node): 162 | #print ";TI--" + sys._getframe().f_code.co_name + "----" 163 | 164 | assert isinstance(node.node, compiler.ast.Name) 165 | 166 | #print "; => CalFunc:", node 167 | # Intrinsic function? 168 | f = self.getIntrinsicFunctionFromName(node.node.name) 169 | if f is not None: 170 | #print "; => Intrinsic:", f 171 | return f[0] 172 | if isIntrinsicMathFunction(node.node.name): 173 | x = GetIntrinsicMathFunctions() 174 | # special case for casting functions 175 | if(node.node.name=='int'): 176 | return int 177 | if(node.node.name=='float'): 178 | return float 179 | if(node.node.name=='range' or node.node.name=='zeros'): 180 | return list 181 | if x.has_key(node.node.name): 182 | #return x[node.node.name][0] 183 | return self.inferType(node.args[0]) 184 | else: 185 | return void 186 | 187 | return self.inferType(node.node) 188 | 189 | 190 | def inferUnarySub(self, node): 191 | #print ";TI--" + sys._getframe().f_code.co_name + "----" 192 | return self.inferType(node.expr) 193 | 194 | def inferAdd(self, node): 195 | #print ";TI--" + sys._getframe().f_code.co_name + "----" 196 | 197 | left = self.inferType(node.left) 198 | right = self.inferType(node.right) 199 | 200 | if left != right: 201 | print "; [type inference] Type mismatch found at line %d: left = %s, right = %s" % (node.lineno, left, right) 202 | print "; node = %s" % (node) 203 | return None 204 | 205 | return left 206 | 207 | 208 | def inferSub(self, node): 209 | #print ";TI--" + sys._getframe().f_code.co_name + "----" 210 | 211 | left = self.inferType(node.left) 212 | right = self.inferType(node.right) 213 | 214 | if left != right: 215 | print "; [type inference] Type mismatch found at line %d: left = %s, right = %s" % (node.lineno, left, right) 216 | print "; node = %s" % (node) 217 | return None 218 | 219 | return left 220 | 221 | def inferMul(self, node): 222 | #print ";TI--" + sys._getframe().f_code.co_name + "----" 223 | 224 | left = self.inferType(node.left) 225 | right = self.inferType(node.right) 226 | 227 | if left != right: 228 | print "; [type inference] Type mismatch found at line %d: left = %s, right = %s" % (node.lineno, left, right) 229 | print "; node = %s" % (node) 230 | return None 231 | 232 | return left 233 | 234 | 235 | def inferDiv(self, node): 236 | #print ";TI--" + sys._getframe().f_code.co_name + "----" 237 | 238 | left = self.inferType(node.left) 239 | right = self.inferType(node.right) 240 | 241 | if left != right: 242 | print "; [type inference] Type mismatch found at line %d: left = %s, right = %s" % (node.lineno, left, right) 243 | print "; node = %s" % (node) 244 | return None 245 | 246 | return left 247 | 248 | def inferAnd(self, node): 249 | return float 250 | def inferOr(self, node): 251 | return float 252 | def inferNot(self, node): 253 | return float 254 | 255 | def inferMod(self, node): 256 | #print ";TI--" + sys._getframe().f_code.co_name + "----" 257 | 258 | left = self.inferType(node.left) 259 | right = self.inferType(node.right) 260 | 261 | if left != right: 262 | print "; [type inference] Type mismatch found at line %d: left = %s, right = %s" % (node.lineno, left, right) 263 | print "; node = %s" % (node) 264 | return None 265 | 266 | return left 267 | 268 | # 269 | # -- Leaf 270 | # 271 | 272 | def inferAssName(self, node): 273 | #print ";TI--" + sys._getframe().f_code.co_name + "----" 274 | 275 | name = node.name 276 | 277 | # Firstly, name of type? 278 | if self.typeDic.has_key(name): 279 | return self.typeDic[name] 280 | 281 | # Next, lookup symbol 282 | # return vec 283 | return None 284 | 285 | def inferName(self, node): 286 | #print ";TI--" + sys._getframe().f_code.co_name + "----" 287 | name = node.name 288 | if(node.name=='True' or node.name=='False'): 289 | return int 290 | # Firstly, name of type? 291 | if self.typeDic.has_key(name): 292 | print "; => found type for ", name, "=", self.typeDic[name] 293 | return self.typeDic[name] 294 | # Next, lookup symbol from the symbol table. 295 | sym = self.symbolTable.find(name) 296 | if sym is not None: 297 | return sym.type 298 | 299 | print "; => not found. name=", name 300 | return None 301 | 302 | def inferCompare(self, node): 303 | #print ";TI--" + sys._getframe().f_code.co_name + "----" 304 | return float 305 | 306 | 307 | def inferConst(self, node): 308 | #print ";TI--" + sys._getframe().f_code.co_name + "----" 309 | 310 | value = node.value 311 | if value == None: 312 | return void 313 | 314 | if isinstance(value, type(1.0)): 315 | return float 316 | 317 | elif isinstance(value, type(1)): 318 | return int 319 | 320 | else: 321 | raise PyllvmError("Type Inference: Unknown type of value:", value) 322 | 323 | def inferSubscript(self, node): 324 | ty = None 325 | if isinstance(node.expr, compiler.ast.Name): 326 | ty = self.symbolTable.find(node.expr.name).getDim()[0] 327 | if isinstance(node.expr, compiler.ast.List): 328 | ty = self.inferType(node.expr.nodes[0]) 329 | if isinstance(node.expr, compiler.ast.CallFunc): 330 | ty = self.symbolTable.find(node.expr.node.name).getDim()[0] 331 | if isinstance(node.expr, compiler.ast.Const): 332 | ty = int 333 | if ty is None: 334 | raise PyllvmError("Type Inference: cannot index into value", node.expr) 335 | return ty 336 | def inferList(self, node): 337 | return list 338 | -------------------------------------------------------------------------------- /VecTypes.py: -------------------------------------------------------------------------------- 1 | import llvm.core 2 | from PyllvmError import * 3 | class vec(object): 4 | """ 5 | <4 x float> 6 | """ 7 | 8 | def __init__(self, *args): 9 | 10 | v = [] 11 | 12 | if len(args) == 4: 13 | # vec(1.0, 2.0, 3.0, 4.0) 14 | 15 | for a in args: 16 | assert isinstance(a, float), ("Arg must be a float type, but %s(%s) is given" % (a, type(a))) 17 | 18 | v.append(a) 19 | 20 | elif len(args) == 1: 21 | if isinstance(args[0], list): 22 | # vec([1.0, 2.0, 3.0, 4.0]) 23 | v = args[0] 24 | 25 | elif isinstance(args[0], float): 26 | # vec(1.0) 27 | v.append(args[0]) 28 | v.append(args[0]) 29 | v.append(args[0]) 30 | v.append(args[0]) 31 | 32 | else: 33 | raise PyllvmError("Unsupported input for vec():", args) 34 | 35 | elif len(args) == 0: 36 | # vec() 37 | v = [0.0, 0.0, 0.0, 0.0] 38 | 39 | else: 40 | raise PyllvmError("Unsupported input for vec():", args) 41 | 42 | self.value = v 43 | 44 | 45 | def __str__(self): 46 | 47 | return str(self.value) 48 | 49 | 50 | def __add__(self, b): 51 | 52 | if not isinstance(b, vec): 53 | raise PyllvmError("RHS is not a type of vec") 54 | 55 | tmp = vec([x + y for x, y in zip(self.value, b.value)]) 56 | 57 | return tmp 58 | 59 | 60 | def __sub__(self, b): 61 | 62 | if not isinstance(b, vec): 63 | raise PyllvmError("RHS is not a type of vec") 64 | 65 | tmp = vec([x - y for x, y in zip(self.value, b.value)]) 66 | 67 | return tmp 68 | 69 | 70 | def swizzle(self, arg): 71 | pass 72 | 73 | 74 | def GetVecTypeDic(): 75 | 76 | d = { 77 | 'vec' : vec 78 | } 79 | 80 | return d 81 | 82 | 83 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aherlihy/PythonLLVM/fb91b07d585cb32e9f76a6e9795a1fce005dfab4/__init__.py -------------------------------------------------------------------------------- /cpp_python_wrapper/TupleSet.h: -------------------------------------------------------------------------------- 1 | #ifndef TUPLE_SET_H 2 | #define TUPLE_SET_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "compiler/ClangCompiler.h" 11 | #include "data/Schema.h" 12 | #include "job/JobValidator.h" 13 | #include "net/Connection.h" 14 | #include "net/TcpConnection.h" 15 | #include "proto/AttributeInfo.pb.h" 16 | #include "proto/ExpressionInfo.pb.h" 17 | #include "proto/JobInfo.pb.h" 18 | #include "util/Logger.h" 19 | #include "util/LogLevel.h" 20 | #include 21 | 22 | using std::string; 23 | 24 | namespace tupleware { 25 | class TupleSet { 26 | public: 27 | TupleSet(Input *in) { 28 | } 29 | 30 | void combine(string funct, string keyFunct) { 31 | ExpressionInfo *expr = new ExpressionInfo(); 32 | expr->set_type(ExpressionInfo::COMBINE); 33 | CombineInfo *ext = expr->MutableExtension(CombineInfo::ext); 34 | ExpressionInfo *extsrc = ext->mutable_source(); 35 | extsrc->CopyFrom(*m_expr); 36 | ext->set_function(funct); 37 | ext->set_key_function(keyFunct); 38 | m_expr = expr; 39 | } 40 | /* 41 | void filter(string funct) { 42 | OperatorInfo *op = new OperatorInfo(); 43 | op->set_type(OperatorInfo::FILTER); 44 | FilterInfo *ext = op->MutableExtension(FilterInfo::ext); 45 | OperatorInfo *extsrc = ext->mutable_source(); 46 | extsrc->CopyFrom(*m_op); 47 | ext->set_function(funct); 48 | m_op = op; 49 | } 50 | 51 | void flatMap(string funct) { 52 | OperatorInfo *op = new OperatorInfo(); 53 | op->set_type(OperatorInfo::FLAT_MAP); 54 | FlatMapInfo *ext = op->MutableExtension(FlatMapInfo::ext); 55 | OperatorInfo *extsrc = ext->mutable_source(); 56 | extsrc->CopyFrom(*m_op); 57 | ext->set_function(funct); 58 | m_op = op; 59 | } 60 | 61 | void group(string funct, string keyFunct) { 62 | OperatorInfo *op = new OperatorInfo(); 63 | op->set_type(OperatorInfo::GROUP); 64 | GroupInfo *ext = op->MutableExtension(GroupInfo::ext); 65 | OperatorInfo *extsrc = ext->mutable_source(); 66 | extsrc->CopyFrom(*m_op); 67 | ext->set_function(funct); 68 | ext->set_key_function(keyFunct); 69 | m_op = op; 70 | } 71 | 72 | void join(TupleSet *other, string funct) { 73 | OperatorInfo *op = new OperatorInfo(); 74 | op->set_type(OperatorInfo::JOIN); 75 | JoinInfo *ext = op->MutableExtension(JoinInfo::ext); 76 | OperatorInfo *extlhs = ext->mutable_left_hand_side(); 77 | extlhs->CopyFrom(*m_op); 78 | OperatorInfo *extrhs = ext->mutable_right_hand_side(); 79 | extrhs->CopyFrom(*other->m_op); 80 | ext->set_function(funct); 81 | m_op = op; 82 | } 83 | */ 84 | void map(string funct) { 85 | ExpressionInfo *expr = new ExpressionInfo(); 86 | expr->set_type(ExpressionInfo::MAP); 87 | MapInfo *ext = expr->MutableExtension(MapInfo::ext); 88 | ExpressionInfo *extsrc = ext->mutable_source(); 89 | extsrc->CopyFrom(*m_expr); 90 | ext->set_function(funct); 91 | m_expr = expr; 92 | } 93 | /* 94 | void merge(TupleSet *other) { 95 | OperatorInfo *op = new OperatorInfo(); 96 | op->set_type(OperatorInfo::MERGE); 97 | MergeInfo *ext = op->MutableExtension(MergeInfo::ext); 98 | OperatorInfo *extlhs = ext->mutable_left_hand_side(); 99 | extlhs->CopyFrom(*m_op); 100 | OperatorInfo *extrhs = ext->mutable_right_hand_side(); 101 | extrhs->CopyFrom(*other->m_op); 102 | m_op = op; 103 | } 104 | 105 | void peek(int limit) { 106 | OperatorInfo *op = new OperatorInfo(); 107 | op->set_type(OperatorInfo::PEEK); 108 | PeekInfo *ext = op->MutableExtension(PeekInfo::ext); 109 | OperatorInfo *extsrc = ext->mutable_source(); 110 | extsrc->CopyFrom(*m_op); 111 | ext->set_limit(limit); 112 | m_op = op; 113 | } 114 | */ 115 | void reduce(string funct, string keyFunct) { 116 | ExpressionInfo *expr = new ExpressionInfo(); 117 | expr->set_type(ExpressionInfo::REDUCE); 118 | ReduceInfo *ext = expr->MutableExtension(ReduceInfo::ext); 119 | ExpressionInfo *extsrc = ext->mutable_source(); 120 | extsrc->CopyFrom(*m_expr); 121 | ext->set_function(funct); 122 | ext->set_key_function(keyFunct); 123 | //ext->set_is_parallel(isParallel); 124 | m_expr = expr; 125 | } 126 | 127 | void evaluate(string addr, string functDir) { 128 | int jport = TcpConnection::JOB_PORT; 129 | TcpConnection *jconn = TcpConnection::push(addr, jport); 130 | jconn->open(CONNECT); 131 | 132 | //job 133 | JobInfo *job = new JobInfo(); 134 | job->set_client("test"); 135 | job->set_allocated_expression(m_expr); 136 | 137 | //UDFs 138 | DIR *dir; 139 | if (functDir.length() > 0 140 | || (dir = opendir(functDir.c_str())) == NULL) { 141 | Logger::log(FATAL, __FILE__, __LINE__, "bad function directory"); 142 | return; 143 | } 144 | else { 145 | struct dirent *file; 146 | struct stat filestat; 147 | while ((file = readdir(dir))) { 148 | string filename = functDir + "/" + file->d_name; 149 | if (stat(filename.c_str(), &filestat) 150 | || S_ISDIR(filestat.st_mode)) 151 | continue; 152 | 153 | string functName = file->d_name; 154 | functName = functName.substr(0, functName.find(".")); 155 | FunctionInfo *funct = job->add_function(); 156 | funct->set_name(functName); 157 | funct->set_llvm(ClangCompiler::compile(filename)); 158 | 159 | ifstream rdr; 160 | rdr.open(filename); 161 | if (rdr.is_open()) { 162 | string line; 163 | while (!rdr.eof()) { 164 | int pos = 0; 165 | getline(rdr, line); 166 | pos = line.find("@", pos); 167 | if (pos != string::npos) { 168 | string type = line.substr(pos + 1); 169 | AttributeInfo *attr = funct->add_attribute(); 170 | if (type.compare("double") == 0) 171 | attr->set_type(AttributeInfo::DOUBLE); 172 | else if (type.compare("float") == 0) 173 | attr->set_type(AttributeInfo::FLOAT); 174 | else if (type.compare("int") == 0) 175 | attr->set_type(AttributeInfo::INT); 176 | else if (type.compare("string") == 0) { 177 | attr->set_type(AttributeInfo::STRING); 178 | attr->set_length(30); 179 | } 180 | } 181 | } 182 | rdr.close(); 183 | } 184 | } 185 | closedir(dir); 186 | 187 | if (!JobValidator::isValid(job)) 188 | return; 189 | 190 | jconn->send(job); 191 | } 192 | jconn->close(); 193 | delete job; 194 | 195 | int rport = TcpConnection::RESULT_PORT; 196 | TcpConnection *rconn = NULL; 197 | } 198 | protected: 199 | ExpressionInfo *m_expr; 200 | 201 | void addAttribute(Schema *sch, int attrNum, AttributeInfo *attr) { 202 | switch (sch->getType(attrNum)) { 203 | case DOUBLE: 204 | attr->set_type(AttributeInfo::DOUBLE); 205 | break; 206 | case FLOAT: 207 | attr->set_type(AttributeInfo::FLOAT); 208 | break; 209 | case INT: 210 | attr->set_type(AttributeInfo::INT); 211 | break; 212 | case STRING: 213 | attr->set_type(AttributeInfo::STRING); 214 | attr->set_length(sch->getLength(attrNum)); 215 | break; 216 | default: 217 | break; 218 | } 219 | } 220 | }; 221 | 222 | // expose classes/functions to python 223 | BOOST_PYTHON_MODULE(python_example) 224 | { 225 | class_("Input"); 226 | class_("TupleSet", init()) 227 | .def("combine", &TupleSet::combine) 228 | .def("map", &TupleSet::map) 229 | .def("reduce", &TupleSet::reduce) 230 | .def("evaluate", &TupleSet::evaluate) 231 | ; 232 | } 233 | #endif 234 | -------------------------------------------------------------------------------- /cpp_python_wrapper/hello.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | char const* greet() 4 | { 5 | return "hello, world YAY"; 6 | } 7 | 8 | BOOST_PYTHON_MODULE(hello) 9 | { 10 | using namespace boost::python; 11 | def("greet", greet); 12 | } 13 | -------------------------------------------------------------------------------- /cpp_python_wrapper/hello.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aherlihy/PythonLLVM/fb91b07d585cb32e9f76a6e9795a1fce005dfab4/cpp_python_wrapper/hello.o -------------------------------------------------------------------------------- /cpp_python_wrapper/hello.py: -------------------------------------------------------------------------------- 1 | import hello 2 | print hello.greet() 3 | -------------------------------------------------------------------------------- /cpp_python_wrapper/hello.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aherlihy/PythonLLVM/fb91b07d585cb32e9f76a6e9795a1fce005dfab4/cpp_python_wrapper/hello.so -------------------------------------------------------------------------------- /cpp_python_wrapper/makefile: -------------------------------------------------------------------------------- 1 | PYTHON_VERSION = 2.7 2 | PYTHON_INCLUDE = /usr/include/python$(PYTHON_VERSION) 3 | 4 | # location of the Boost Python include files and library 5 | 6 | BOOST_INC = /usr/include 7 | BOOST_LIB = /usr/lib 8 | 9 | # compile mesh classes 10 | TARGET = python_example 11 | 12 | $(TARGET).so: $(TARGET).o 13 | g++ -shared -Wl,--export-dynamic $(TARGET).o -L$(BOOST_LIB) -lboost_python -L/usr/lib/python$(PYTHON_VERSION)/config -lpython$(PYTHON_VERSION) -o $(TARGET).so 14 | $(TARGET).o: $(TARGET).cpp 15 | g++ -I$(PYTHON_INCLUDE) -I$(BOOST_INC) -fPIC -c $(TARGET).cpp 16 | -------------------------------------------------------------------------------- /cpp_python_wrapper/python_example.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "testC.h" 3 | using namespace boost::python; 4 | 5 | /* 6 | Virtual methods 7 | any base class that has a virtual function that's going to be overridden in Python and 8 | called polymorphically from C++, it needs to be wrapped with a boost::python::wrapper<...> 9 | 10 | To extend class in python: 11 | >>> base = Base() 12 | >>> class Derived(Base): 13 | ... def f(self): 14 | ... return 42 15 | ... 16 | >>> derived = Derived() 17 | */ 18 | 19 | // inheriting pure virtual functions 20 | struct PureBase { 21 | PureBase() {} 22 | virtual ~PureBase() {} 23 | virtual int f() = 0; 24 | }; 25 | struct testA { 26 | testA(testC c) {} 27 | int testing() { return 1; } 28 | }; 29 | struct PureBaseWrap : PureBase, wrapper 30 | { 31 | int f() 32 | { 33 | return this->get_override("f")(); 34 | } 35 | }; 36 | // inheriting virtual functions with default definitions 37 | struct DefaultBase 38 | { 39 | virtual ~DefaultBase() {} 40 | virtual int f() { return 0; } 41 | }; 42 | struct DefaultBaseWrap : DefaultBase, wrapper 43 | { 44 | int f() 45 | { 46 | if (override f = this->get_override("f")) 47 | return f(); // *note* 48 | return DefaultBase::f(); 49 | } 50 | 51 | int default_f() { return this->DefaultBase::f(); } 52 | }; 53 | 54 | // Derived can inherit from PureBase or from DefaultBase 55 | struct Derived : DefaultBase /*PureBase*/ { 56 | // multiple constructors 57 | Derived() {} 58 | Derived(std::string msg): msg(msg) {} 59 | Derived(double, double) {} 60 | // getters and setters 61 | void set(std::string msg) { this->msg = msg; } 62 | std::string get() { return msg; } 63 | // attributes 64 | std::string msg; 65 | std::string const name; 66 | int value; 67 | // overridden method 68 | virtual int f() { return value; } 69 | }; 70 | 71 | // polymorphic function args (pass C++ defined-class to functions) 72 | void b(DefaultBase* /* PureBase* */) {} 73 | void d(Derived*) {} 74 | DefaultBase* /* PureBase* */factory() { return new Derived("factory world"); } 75 | 76 | // expose classes/functions to python 77 | BOOST_PYTHON_MODULE(python_example) 78 | { 79 | /* 80 | class definitions: 81 | bases<...> identifies the superclass(s) 82 | - World will inherit all of PureBase's methods 83 | - if PureBase is polymorphic: World instances passed to python as PureBase ptr/refs 84 | can be used where ptr/refs of World are expected 85 | init<...>() exposes the constructor 86 | pure_virtual indicates which methods are pure virtual 87 | */ 88 | class_("testC") 89 | ; 90 | class_("testA", init()) 91 | .def("testing", &testA::testing) 92 | ; 93 | class_("PureBase") 94 | .def("f", pure_virtual(&PureBase::f)) 95 | ; 96 | class_("DefaultBase") 97 | .def("f", &DefaultBase::f, &DefaultBaseWrap::default_f) 98 | ; 99 | class_ >("Derived", init()) 100 | // alternative constructor: 101 | .def(init()) 102 | // member functions: 103 | .def("get", &Derived::get) 104 | .def("set", &Derived::set) 105 | // member variables: 106 | .def_readonly("name", &Derived::name) 107 | .def_readwrite("value", &Derived::value) 108 | // properties (i.e. getters/setters): 109 | .add_property("rovalue", &Derived::get) 110 | .add_property("rwvalue", &Derived::get, &Derived::set); 111 | 112 | /* 113 | external functions: polymorphism! 114 | both b and d can take in factory() as an argument 115 | */ 116 | def("b", b); 117 | def("d", d); 118 | // tell Python to take ownership of factory's result 119 | def("factory", factory, 120 | return_value_policy()); 121 | 122 | } 123 | -------------------------------------------------------------------------------- /cpp_python_wrapper/python_example.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aherlihy/PythonLLVM/fb91b07d585cb32e9f76a6e9795a1fce005dfab4/cpp_python_wrapper/python_example.o -------------------------------------------------------------------------------- /cpp_python_wrapper/python_example.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aherlihy/PythonLLVM/fb91b07d585cb32e9f76a6e9795a1fce005dfab4/cpp_python_wrapper/python_example.so -------------------------------------------------------------------------------- /cpp_python_wrapper/testC.h: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace boost::python; 3 | class testC 4 | { 5 | }; 6 | -------------------------------------------------------------------------------- /experiments/float_print.bc: -------------------------------------------------------------------------------- 1 | ; PRINT FLOAT 2 | 3 | %0 = load float* %x, align 4 4 | %conv = fpext float %0 to double 5 | %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), double %conv) 6 | ret i32 0 7 | } 8 | 9 | @.str = private unnamed_addr constant [3 x i8] c"%f\00", align 1 10 | declare i32 @printf(i8*, ...) #0 11 | 12 | -------------------------------------------------------------------------------- /experiments/int_print.bc: -------------------------------------------------------------------------------- 1 | 2 | ; ADD PRINTLINE 3 | 4 | %0 = load i32* %x, align 4 ; set %0 to x 5 | %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), i32 %0) 6 | ret i32 %tmp14 ; return t14 7 | } 8 | 9 | 10 | @.str = private unnamed_addr constant [3 x i8] c"%i\00", align 1 11 | declare i32 @printf(i8*, ...) #0 12 | 13 | -------------------------------------------------------------------------------- /experiments/test_llvm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define DATA 10 8 | #define DIMS 5 9 | #define VALS 10 10 | #define LABELS 10 11 | #define COUNTS (LABELS + LABELS * DIMS * VALS) 12 | #define SIZE (COUNTS * sizeof(int)) 13 | using std::cout; 14 | using std::getline; 15 | using std::ifstream; 16 | using std::istringstream; 17 | using std::string; 18 | 19 | inline void init(string file, char **data, int *counts) { 20 | 21 | ifstream f(file.c_str()); 22 | if (f.is_open()) { 23 | string line; 24 | int n; 25 | char c; 26 | for (int i = 0; i < DATA && getline(f, line); i++) { 27 | istringstream buff(line); 28 | data[i] = new char[DIMS + 1]; 29 | for (int j = 0; j < DIMS; j++) { 30 | buff >> n >> c; 31 | data[i][j] = (char) n; 32 | } 33 | buff >> n; 34 | data[i][DIMS] = (char) n; 35 | } 36 | f.close(); 37 | } 38 | } 39 | 40 | void naive_bayes(char *data, int *counts, int dims, int vals, int labels){ 41 | char label = data[dims]; 42 | ++counts[label]; 43 | int offset = labels + label * dims * vals; 44 | for (int j = 0; j < dims; j++) 45 | ++counts[offset + j * vals + data[j]]; 46 | } 47 | 48 | 49 | int main() { 50 | 51 | char **data = new char*[DATA]; 52 | int *counts = new int[COUNTS]; 53 | string file = "test.tmp"; 54 | init(file, data, counts); 55 | printf("data=%i, dims=%i, vals=%i, labels=%i\n", DATA, DIMS, VALS, LABELS); 56 | for (int i = 0; i < DATA; i++) 57 | naive_bayes(data[i], counts, DIMS, VALS, LABELS); 58 | 59 | printf("data:%p\n", data); 60 | } 61 | -------------------------------------------------------------------------------- /llvm_bm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for i in {1..2500} 4 | do 5 | lli $1 6 | done 7 | -------------------------------------------------------------------------------- /lots_test.py: -------------------------------------------------------------------------------- 1 | from MUDA import * 2 | from math import * 3 | # FUNCTION ARGS+RET 4 | 5 | # INT 6 | def iret(i=int): 7 | return i+1 8 | # FLOAT 9 | def fret(f=float): 10 | return 1.0000+f 11 | # VEC 12 | def vret(v=vec): 13 | return v 14 | # LIST 15 | def lretv5(lv5=listf5): 16 | return lv5 17 | # LIST 18 | def lreti8(li8=listi8): 19 | return li8 20 | # STR 21 | def sret(s=listi5): 22 | return s 23 | # SUB 24 | def lsubi(isub=int, lsi=listf5): 25 | return lsi[isub] 26 | def lsubf(isubf=int, lsf=listi8): 27 | return lsf[isubf]+isubf 28 | # FUNC 29 | def ffret(): 30 | return fret(1.00) 31 | def firet(): 32 | return iret(1) 33 | def fvret(): 34 | return vret(vec([4.0,2.0,2.4,1.0])) 35 | def flret(): 36 | return lretv5([1.0,2.0,3.0,4.0,5.0]) 37 | def f2lret(): 38 | return [1.0,2.0] 39 | def fliret(): 40 | return [9,99] 41 | def fsret(): 42 | return sret('hello') 43 | # ALL 44 | def ifvret(i=int, v=vec, f=float, l=listf2, s=listi5): 45 | print f 46 | print v 47 | print i 48 | print l 49 | print s 50 | return i+i 51 | # IF/WHILE/CMP 52 | #AND/OR/NOT 53 | def test_if(): 54 | test_if1 = 4 55 | if(4==test_if1 and 5==5): 56 | test_if2 = -1 57 | test_if1 = 9 58 | if(test_if1==9 or 5==6): 59 | test_if2 = -3 60 | test_if1 = 11 61 | else: 62 | test_if2 = -4 63 | test_if1 = 0 64 | return test_if1#ret 11 65 | # NOTE: can't have return type in only one branch 66 | def test_if1(t=int): 67 | if(not t==0): 68 | return 0 69 | return -1 70 | def test_if2(t=int): 71 | y = 0 72 | if(t==0): 73 | y = 10 74 | if((t-1)==0): 75 | y = 12 76 | return y 77 | def test_if3(t=int): 78 | if(t==0): 79 | return 5 80 | return 7 81 | def test_if4(t=int): 82 | if(t==1): 83 | return 5 84 | else: 85 | return 13 86 | return 8 87 | def test_compare(): 88 | a = (1==1) 89 | b = (1.00==1.00) 90 | c = (1>=0) 91 | d = (1.00>=0.00) 92 | e = (0<=1) 93 | fcp = (0.00 <= 1.00) 94 | g = (4!=6) 95 | h = (4.00!=6.00) 96 | z = a+b+c+d+e+fcp+g+h 97 | return z-7.00#ret 1.00 98 | 99 | def test_compare2(): 100 | x = 0 101 | if(0.00): 102 | x = x+1 103 | if(1.00):#y 104 | x = x+1 105 | if(0): 106 | x = x+1 107 | if(1):#y 108 | x = x+1 109 | if([]): 110 | x = x+1 111 | if([1,2,3]):#y 112 | x = x+1 113 | if(iret(-1)): 114 | x = x+1 115 | if(iret(1)):#y 116 | x = x+1 117 | if(fret(-1.0)): 118 | x = x+1 119 | if(fret(1.0)):#y 120 | x = x+1 121 | i1 = 0 122 | i2 = 1 123 | f1 = 0.0 124 | f2 = 1.0 125 | l1 = [] 126 | l2 = [1,2,3] 127 | if(i1): 128 | x = x+1 129 | if(i2):#y 130 | x = x+1 131 | if(f1): 132 | x = x+1 133 | if(f2):#y 134 | x = x+1 135 | if(l1): 136 | x = x+1 137 | if(l2):#y 138 | x = x+1 139 | return x 140 | 141 | 142 | 143 | def test_while(): 144 | test_while1 = 10 145 | while(test_while1>0): 146 | test_while1 = test_while1-1 147 | return test_while1#ret0 148 | 149 | def test_while2(): 150 | test_while1 = 10 151 | while(test_while1>0): 152 | test_while1 = test_while1-1 153 | if(test_while1==5): 154 | return 100 155 | return test_while1#ret100 156 | 157 | # test visitStmt 158 | def test_ret1i(): 159 | x = [9,7,4] 160 | return x 161 | def test_ret2i(): 162 | return [6,7,8] 163 | def test_ret3i(): 164 | return test_ret1i() 165 | def test_ret4i(x=listi3): 166 | print x 167 | def test_ret5i(x=listi3): 168 | return x 169 | def test_ret1f(): 170 | x = [9.1,7.1,4.1] 171 | return x 172 | def test_ret2f(): 173 | return [6.1,7.1,8.1] 174 | def test_ret3f(): 175 | return test_ret1f() 176 | def test_ret4f(x=listf3): 177 | print x 178 | def test_ret5f(x=listf3): 179 | return x 180 | def test_retE(x=listi0): 181 | return [] 182 | 183 | def ret_neg(): 184 | return -100 185 | 186 | def print_bool(b=int): 187 | print b 188 | def get_bool(b=int): 189 | return b 190 | def main(): 191 | # ASSIGN 192 | ri = 5 193 | rf = 5.00 194 | rv = vec([1.00,2.00,3.00,4.00]) 195 | v1 = vec(1.00) 196 | # { 4.0,2.0,3.0,1.0 } 197 | print( rv.w, rv.y, rv.z, rv.x ) 198 | li1 = [1,2,3] 199 | lf1 = [1.4,5.4] 200 | f5 = [1.0,2.0,3.0,4.0,5.0] 201 | i8 = [1,2,3,4,5,6,7,8] 202 | rs = 'hello' 203 | print( ri, rf, rv, v1, li1, lf1, f5, i8, rs ) 204 | # LIST CONSTR and SUB 205 | ll1 = [ri, ri+1, ri+2] #[5,6,7] 206 | ll2 = [li1[0], li1[2]] #[1,3] 207 | ll3 = [[1,2,3][0], ll2[0], fliret()[0]] #[1,1,9] 208 | ll4 = [fliret()[0], fliret()[1]] #[9,99] 209 | ll5 = [fret(3.0), fret(6.0)] #[4.0,7.0] 210 | print( ll1, ll2, ll3, ll4, ll5) 211 | 212 | # FUNC ARGS+RET 213 | xf5 = f5 214 | zf5 = lretv5(xf5) 215 | xi8 = i8 216 | zi8 = lreti8(i8) 217 | zlsi = lsubi(4, f5) 218 | zlsf = lsubf(2, xi8) 219 | # { 6, 6.0, vec:[1.0,2.0,3.0,4.0], vec:[1.0,1.0,1.0,1.0], 'hello' } 220 | print( iret(ri), fret(rf), vret(rv), vret(v1), sret(rs) ) 221 | # { [1.0,2.0,3.0,4.0,5.0], [1.0,2.0,3.0,4.0,5.0], [1,2,3,4,5,6,7,8], 5.0, 5 } 222 | print( xf5, zf5, zi8, zlsi, zlsf ) 223 | # { 2.0, 2, vec:[4.0,2.0,2.4,1.0], [1.0,2.0,4.0,5.0], 'hello' } 224 | print( ffret(), firet(), fvret(), flret(), fsret() ) 225 | 226 | 227 | # PRINTING 228 | # { 5 // 5.0 // vec:[1.0,2.0,3.0,4.0] // [1.4,5.4] // 'hello' } 229 | ifvret( ri, rv, rf, lf1, rs ) 230 | # { 2, [4.0,2.0,4.2,2.0], 2.0, [1.0,2.0], 'hello' } 231 | ifvret( firet(), fvret(), ffret(), f2lret(), fsret() ) 232 | # IF/WHILE/CMP 233 | ift = test_if() 234 | ift1 = test_if1(0) 235 | ift2 = test_if2(0) 236 | ift3 = test_if3(0) 237 | ift4 = test_if4(0) 238 | ift1x = test_if1(1) 239 | ift2x = test_if2(1) 240 | ift3x = test_if3(1) 241 | ift4x = test_if4(1) 242 | # { 11, -1, 10, 5, 13, 0, 12, 7, 5 } 243 | print( ift, ift1, ift2, ift3, ift4, ift1x, ift2x, ift3x, ift4x ) 244 | whilet = test_while() 245 | whilet2 = test_while2() 246 | comparet = test_compare() 247 | comparet2 = test_compare2() 248 | # { 0, 100, 1.0, 88888888 } 249 | print( whilet, whilet2, comparet, comparet2 ) 250 | 251 | # ARRAYS 252 | # INT 253 | # test returning types of lists 254 | 255 | # empty lists 256 | eml = [] 257 | eml1 = test_retE([]) 258 | eml2 = test_retE(eml) 259 | ems = '' 260 | ems1 = test_retE(ems) 261 | ems2 = test_retE('') 262 | 263 | 264 | # { [9,7,4], [6,7,8], [9,7,4] } 265 | print( test_ret1i(), test_ret2i(), test_ret3i() ) 266 | # test passing lists as args 267 | ilst = [10,20,30] 268 | #PRINTING 269 | #{[90,100,110]} 270 | test_ret4i([90,100,110]) 271 | #{ [10,20,30] } 272 | test_ret4i(ilst) 273 | #{ [9,7,4] } 274 | test_ret4i(test_ret3i()) 275 | # test returning lists passed as args 276 | # { [90,100,110], [10,20,30], [9,7,4] } 277 | print( test_ret5i([90,100,110]), test_ret5i(ilst), test_ret5i(test_ret3i()) ) 278 | # FLOAT 279 | # test returning types of lists 280 | # { [9.1,7.1,4.1], [6.1,7.1,8.1], [9.1,7.1,4.1] } 281 | print( test_ret1f(), test_ret2f(), test_ret3f() ) 282 | # test passing lists as args 283 | flst = [10.1,20.1,30.1] 284 | #{ [90.1, 100.1, 110.1] } 285 | test_ret4f([90.1,100.1,110.1]) 286 | #{ [10.1,20.1,30.1] } 287 | test_ret4f(flst) 288 | #{ [9.1, 7.1, 4.1] } 289 | test_ret4f(test_ret3f()) 290 | # test returning lists passed as args 291 | # { [90.1,100.1,110.1], [10.1,20.1,30.1], [9.1,7.1,4.1] 292 | print( test_ret5f([90.1,100.1,110.1]), test_ret5f(flst), test_ret5f(test_ret3f()) ) 293 | 294 | #LEN 295 | ilen = [1,2,3] 296 | flen = [5.3,6.5,3.5,6.3] 297 | slen = 'hello there' 298 | # { 3, 4, 11 } 299 | print( len(ilen), len(flen), len(slen) ) 300 | 301 | x = vec([1.0,1.0,1.0,1.0]) 302 | y = vec([2.0,2.0,3.0,4.0]) 303 | #{ vec[3.0,3.0,4.0,5.0], vec[-1.0, -1.0, -2.0, -3.0], vec[2.0,2.0,3.0,4.0], vec[0.5,0.5,0.3,0.25] } 304 | print (x+y, x-y, x*y, x/y) 305 | # test abs 306 | 307 | print (abs(-9), abs(0), abs(1), abs(-1), abs(ret_neg()), abs(-9.0), abs(8.0), abs(100.0)) 308 | #print(mod(7,2), mod(2,7), mod(10,100), mod(1.0,1.0), mod(8.0,3.0), mod(3.0,8.0)) 309 | print(7%2, 2%7, 10%100, 1.0%1.0, 8.0%3.0, 3.0%8.0) 310 | print(sqrt(100), sqrt(100.0), sqrt(1), sqrt(0), sqrt(-ret_neg())) 311 | print(pow(10,1), pow(5.0,2), pow(8, 2.0), pow(3.0,3.0)) 312 | print(log(100), log(100.0), log(1), log(-ret_neg())) 313 | 314 | aa=0 315 | aa+=1 316 | aa-=4 317 | aa*=-10 318 | print(aa) 319 | print( (1==1.0), (2.0==2) ) 320 | print("bools", True, False, True+True, False+True, get_bool(True), get_bool(False)) 321 | print_bool(True) 322 | print_bool(False) 323 | -------------------------------------------------------------------------------- /mmath.py: -------------------------------------------------------------------------------- 1 | import math 2 | import llvm.core 3 | import compiler 4 | from PyllvmError import * 5 | llTruthType = llvm.core.Type.int(1) 6 | llVoidType = llvm.core.Type.void() 7 | llIntType = llvm.core.Type.int() 8 | llFloatType = llvm.core.Type.float() 9 | llFVec4Type = llvm.core.Type.vector(llFloatType, 4) 10 | llFVec4PtrType = llvm.core.Type.pointer(llFVec4Type) 11 | llIVec4Type = llvm.core.Type.vector(llIntType, 4) 12 | # 13 | # Intrinsic math functions 14 | # 15 | intrinsics = { 16 | # Name : ( ret type , arg types 17 | 'abs' : ( int , [ int ] ) 18 | , 'pow' : ( int , [ int ] ) 19 | , 'exp' : ( int , [ int ] ) 20 | , 'log' : ( int , [ int, int ] ) 21 | , 'sqrt' : ( int , [ int ] ) 22 | , 'mod' : ( int , [ int, int ] ) 23 | , 'int' : ( float , [ int ] ) 24 | , 'float' : ( int , [ float ] ) 25 | , 'range' : ( list , [ int ] ) 26 | , 'zeros' : ( list , [ int ] ) 27 | } 28 | 29 | class mMathFuncs(object): 30 | def __init__(self, codegen): 31 | self.codeGen = codegen 32 | def emitabs(self, node): 33 | if(len(node.args)!=1): 34 | raise PyllvmError("mmath: one argument to abs") 35 | ty = self.codeGen.typer.inferType(node.args[0]) 36 | v = self.codeGen.visit(node.args[0]) 37 | if(ty==int): 38 | return self.codeGen.builder.call(self.codeGen._mabs, [v]) 39 | elif(ty==float): 40 | return self.codeGen.builder.call(self.codeGen._fmabs, [v]) 41 | raise PyllvmError("mmath: unhandled type for abs") 42 | def emitmod(self, node): 43 | if(len(node.args)!=2): 44 | raise PyllvmError("mmath: 2 arguments needed for mod") 45 | lty = self.codeGen.typer.inferType(node.args[0]) 46 | rty = self.codeGen.typer.inferType(node.args[1]) 47 | if lty!=rty: 48 | raise PyllvmError("mmath: both arguments must match type for mod") 49 | l = self.codeGen.visit(node.args[0]) 50 | r = self.codeGen.visit(node.args[1]) 51 | if(rty==int): 52 | return self.codeGen.builder.srem(l, r) 53 | elif(rty==float): 54 | return self.codeGen.builder.frem(l,r) 55 | raise PyllvmError("mmath: unhandled type for mod") 56 | 57 | 58 | def emitpow(self, node): 59 | if(len(node.args)!=2): 60 | raise PyllvmError("mmath: 2 arguments needed for pow") 61 | lty = self.codeGen.typer.inferType(node.args[0]) 62 | rty = self.codeGen.typer.inferType(node.args[1]) 63 | 64 | l = self.codeGen.visit(node.args[0]) 65 | r = self.codeGen.visit(node.args[1]) 66 | if rty == int: 67 | r = self.codeGen.builder.sitofp(r, llFloatType) 68 | elif rty != float: 69 | raise PyllvmError("mmath: exponent must be numerical") 70 | if(lty==int): 71 | l = self.codeGen.builder.sitofp(l, llFloatType) 72 | return self.codeGen.builder.fptosi(self.codeGen.builder.call(self.codeGen._fpow, [l,r]), llIntType) 73 | elif(lty==float): 74 | return self.codeGen.builder.call(self.codeGen._fpow, [l,r]) 75 | raise PyllvmError("mmath: base for exponent must be numerical") 76 | 77 | def emitlog(self, node): 78 | if(len(node.args)!=1): 79 | raise PyllvmError("mmath: one argument to log") 80 | ty = self.codeGen.typer.inferType(node.args[0]) 81 | v = self.codeGen.visit(node.args[0]) 82 | if(ty==int): 83 | l = self.codeGen.builder.sitofp(v, llFloatType) 84 | return self.codeGen.builder.fptosi(self.codeGen.builder.call(self.codeGen._flog, [l]), llIntType) 85 | elif(ty==float): 86 | return self.codeGen.builder.call(self.codeGen._flog, [v]) 87 | raise PyllvmError("mmath: unhandled type for log") 88 | 89 | def emitexp(self, node): 90 | if(len(node.args)!=1): 91 | raise PyllvmError("mmath: one argument to log") 92 | ty = self.codeGen.typer.inferType(node.args[0]) 93 | v = self.codeGen.visit(node.args[0]) 94 | if(ty==int): 95 | l = self.codeGen.builder.sitofp(v, llFloatType) 96 | return self.codeGen.builder.fptosi(self.codeGen.builder.call(self.codeGen._exp, [l]), llIntType) 97 | elif(ty==float): 98 | return self.codeGen.builder.call(self.codeGen._exp, [v]) 99 | raise PyllvmError("mmath: unhandled type for log") 100 | 101 | def emitsqrt(self, node): 102 | if(len(node.args)!=1): 103 | raise PyllvmError("mmath: one argument to sqrt") 104 | ty = self.codeGen.typer.inferType(node.args[0]) 105 | v = self.codeGen.visit(node.args[0]) 106 | if(ty==int): 107 | # first cast int to float, then do float sqrt 108 | i2f = self.codeGen.builder.sitofp(v, llFloatType, 'i2f') 109 | ret = self.codeGen.builder.call(self.codeGen._fsqrt, [i2f]) 110 | return self.codeGen.builder.fptosi(ret, llIntType) 111 | elif(ty==float): 112 | return self.codeGen.builder.call(self.codeGen._fsqrt, [v]) 113 | raise PyllvmError("mmath: unhandled type for sqrt") 114 | 115 | def emitint(self, node): 116 | if(len(node.args)!=1): 117 | raise PyllvmError("mmath: one argument to int") 118 | ty = self.codeGen.typer.inferType(node.args[0]) 119 | v = self.codeGen.visit(node.args[0]) 120 | if(ty==int): 121 | return v 122 | elif(ty==float): 123 | return self.codeGen.builder.fptosi(v, llIntType) 124 | raise PyllvmError("mmath: unhandled type for int") 125 | def emitfloat(self, node): 126 | if(len(node.args)!=1): 127 | raise PyllvmError("mmath: one argument to float") 128 | ty = self.codeGen.typer.inferType(node.args[0]) 129 | v = self.codeGen.visit(node.args[0]) 130 | if(ty==float): 131 | return v 132 | elif(ty==int): 133 | return self.codeGen.builder.sitofp(v, llFloatType) 134 | raise PyllvmError("mmath: unhandled type for float") 135 | 136 | # NOTE: need to pass constants because creating array from dims 137 | def emitrange(self, node): 138 | # get start and end points 139 | ty = self.codeGen.typer.inferType(node.args[0]) 140 | if(ty!=int and ty!= float): 141 | raise PyllvmError("mmath: range needs numerical arguments") 142 | for n in node.args: 143 | if not isinstance(n, compiler.ast.Const): 144 | raise PyllvmError("mmath: need to pass range constant values") 145 | 146 | if len(node.args) == 1: 147 | start = 0 148 | end = int(node.args[0].value) 149 | else: 150 | start = int(node.args[0].value) 151 | end = int(node.args[1].value) 152 | 153 | if(end" 8 | sys.exit(1) 9 | 10 | def compiler(filename): 11 | return pyllvm(filename) 12 | 13 | def main(): 14 | 15 | if len(sys.argv) < 2: 16 | usage() 17 | print compiler(sys.argv[1]) 18 | 19 | if __name__ == '__main__': 20 | main() 21 | -------------------------------------------------------------------------------- /tp_tests/bayes.py: -------------------------------------------------------------------------------- 1 | # Original C++ 2 | #void naive_bayes(char *data, int *counts, int dims, int vals, int labels){ 3 | # char label = data[dims]; 4 | # ++counts[label]; 5 | # int offset = labels + label * dims * vals; 6 | # for (int j = 0; j < dims; j++) 7 | # ++counts[offset + j * vals + data[j]]; 8 | #} 9 | 10 | #listi100=[] 11 | def naive_bayes(data=listi100, counts=listi100,dims=int, vals=int, labels=int): 12 | label = data[dims] 13 | counts[label] += 1 14 | offset = labels + label * dims * vals 15 | c = 0 16 | while(c 2 | void naive_bayes(int* data, int *counts, int dims, int vals, int labels){ 3 | char label = data[dims]; 4 | ++counts[label]; 5 | int offset = labels + label * dims * vals; 6 | for (int j = 0; j <= dims; j++) { 7 | ++counts[(offset + j * vals + data[j])%100]; 8 | } 9 | } 10 | int main() { 11 | int* data = new int[100]; 12 | int* counts = new int[100]; 13 | for(int i=0;i<100;i++) { 14 | data[i]=i; 15 | counts[i]=0; 16 | } 17 | 18 | /* 19 | printf("["); 20 | for(int i=0;i<100;i++) { 21 | printf("%i, ", counts[i]); 22 | } 23 | printf("]\n"); 24 | */ 25 | naive_bayes(data, counts, 99, 1, 1); 26 | delete[] data; 27 | delete[] counts; 28 | return 0; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /tp_tests/llvm_clang/cpp_bayes.bc: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'bayes.cpp' 2 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 3 | target triple = "x86_64-unknown-linux-gnu" 4 | 5 | ; Function Attrs: nounwind uwtable 6 | define void @_Z11naive_bayesPiS_iii(i32* %data, i32* %counts, i32 %dims, i32 %vals, i32 %labels) #0 { 7 | entry: 8 | %data.addr = alloca i32*, align 8 9 | %counts.addr = alloca i32*, align 8 10 | %dims.addr = alloca i32, align 4 11 | %vals.addr = alloca i32, align 4 12 | %labels.addr = alloca i32, align 4 13 | %label = alloca i8, align 1 14 | %offset = alloca i32, align 4 15 | %j = alloca i32, align 4 16 | store i32* %data, i32** %data.addr, align 8 17 | store i32* %counts, i32** %counts.addr, align 8 18 | store i32 %dims, i32* %dims.addr, align 4 19 | store i32 %vals, i32* %vals.addr, align 4 20 | store i32 %labels, i32* %labels.addr, align 4 21 | %0 = load i32* %dims.addr, align 4 22 | %idxprom = sext i32 %0 to i64 23 | %1 = load i32** %data.addr, align 8 24 | %arrayidx = getelementptr inbounds i32* %1, i64 %idxprom 25 | %2 = load i32* %arrayidx, align 4 26 | %conv = trunc i32 %2 to i8 27 | store i8 %conv, i8* %label, align 1 28 | %3 = load i8* %label, align 1 29 | %idxprom1 = sext i8 %3 to i64 30 | %4 = load i32** %counts.addr, align 8 31 | %arrayidx2 = getelementptr inbounds i32* %4, i64 %idxprom1 32 | %5 = load i32* %arrayidx2, align 4 33 | %inc = add nsw i32 %5, 1 34 | store i32 %inc, i32* %arrayidx2, align 4 35 | %6 = load i32* %labels.addr, align 4 36 | %7 = load i8* %label, align 1 37 | %conv3 = sext i8 %7 to i32 38 | %8 = load i32* %dims.addr, align 4 39 | %mul = mul nsw i32 %conv3, %8 40 | %9 = load i32* %vals.addr, align 4 41 | %mul4 = mul nsw i32 %mul, %9 42 | %add = add nsw i32 %6, %mul4 43 | store i32 %add, i32* %offset, align 4 44 | store i32 0, i32* %j, align 4 45 | br label %for.cond 46 | 47 | for.cond: ; preds = %for.inc, %entry 48 | %10 = load i32* %j, align 4 49 | %11 = load i32* %dims.addr, align 4 50 | %cmp = icmp sle i32 %10, %11 51 | br i1 %cmp, label %for.body, label %for.end 52 | 53 | for.body: ; preds = %for.cond 54 | %12 = load i32* %offset, align 4 55 | %13 = load i32* %j, align 4 56 | %14 = load i32* %vals.addr, align 4 57 | %mul5 = mul nsw i32 %13, %14 58 | %add6 = add nsw i32 %12, %mul5 59 | %15 = load i32* %j, align 4 60 | %idxprom7 = sext i32 %15 to i64 61 | %16 = load i32** %data.addr, align 8 62 | %arrayidx8 = getelementptr inbounds i32* %16, i64 %idxprom7 63 | %17 = load i32* %arrayidx8, align 4 64 | %add9 = add nsw i32 %add6, %17 65 | %rem = srem i32 %add9, 100 66 | %idxprom10 = sext i32 %rem to i64 67 | %18 = load i32** %counts.addr, align 8 68 | %arrayidx11 = getelementptr inbounds i32* %18, i64 %idxprom10 69 | %19 = load i32* %arrayidx11, align 4 70 | %inc12 = add nsw i32 %19, 1 71 | store i32 %inc12, i32* %arrayidx11, align 4 72 | br label %for.inc 73 | 74 | for.inc: ; preds = %for.body 75 | %20 = load i32* %j, align 4 76 | %inc13 = add nsw i32 %20, 1 77 | store i32 %inc13, i32* %j, align 4 78 | br label %for.cond 79 | 80 | for.end: ; preds = %for.cond 81 | ret void 82 | } 83 | 84 | ; Function Attrs: uwtable 85 | define i32 @main() #1 { 86 | entry: 87 | %retval = alloca i32, align 4 88 | %data = alloca i32*, align 8 89 | %counts = alloca i32*, align 8 90 | %i = alloca i32, align 4 91 | store i32 0, i32* %retval 92 | %call = call noalias i8* @_Znam(i64 400) 93 | %0 = bitcast i8* %call to i32* 94 | store i32* %0, i32** %data, align 8 95 | %call1 = call noalias i8* @_Znam(i64 400) 96 | %1 = bitcast i8* %call1 to i32* 97 | store i32* %1, i32** %counts, align 8 98 | store i32 0, i32* %i, align 4 99 | br label %for.cond 100 | 101 | for.cond: ; preds = %for.inc, %entry 102 | %2 = load i32* %i, align 4 103 | %cmp = icmp slt i32 %2, 100 104 | br i1 %cmp, label %for.body, label %for.end 105 | 106 | for.body: ; preds = %for.cond 107 | %3 = load i32* %i, align 4 108 | %4 = load i32* %i, align 4 109 | %idxprom = sext i32 %4 to i64 110 | %5 = load i32** %data, align 8 111 | %arrayidx = getelementptr inbounds i32* %5, i64 %idxprom 112 | store i32 %3, i32* %arrayidx, align 4 113 | %6 = load i32* %i, align 4 114 | %idxprom2 = sext i32 %6 to i64 115 | %7 = load i32** %counts, align 8 116 | %arrayidx3 = getelementptr inbounds i32* %7, i64 %idxprom2 117 | store i32 0, i32* %arrayidx3, align 4 118 | br label %for.inc 119 | 120 | for.inc: ; preds = %for.body 121 | %8 = load i32* %i, align 4 122 | %inc = add nsw i32 %8, 1 123 | store i32 %inc, i32* %i, align 4 124 | br label %for.cond 125 | 126 | for.end: ; preds = %for.cond 127 | %9 = load i32** %data, align 8 128 | %10 = load i32** %counts, align 8 129 | call void @_Z11naive_bayesPiS_iii(i32* %9, i32* %10, i32 99, i32 1, i32 1) 130 | %11 = load i32** %data, align 8 131 | %isnull = icmp eq i32* %11, null 132 | br i1 %isnull, label %delete.end, label %delete.notnull 133 | 134 | delete.notnull: ; preds = %for.end 135 | %12 = bitcast i32* %11 to i8* 136 | call void @_ZdaPv(i8* %12) #4 137 | br label %delete.end 138 | 139 | delete.end: ; preds = %delete.notnull, %for.end 140 | %13 = load i32** %counts, align 8 141 | %isnull4 = icmp eq i32* %13, null 142 | br i1 %isnull4, label %delete.end6, label %delete.notnull5 143 | 144 | delete.notnull5: ; preds = %delete.end 145 | %14 = bitcast i32* %13 to i8* 146 | call void @_ZdaPv(i8* %14) #4 147 | br label %delete.end6 148 | 149 | delete.end6: ; preds = %delete.notnull5, %delete.end 150 | ret i32 0 151 | } 152 | 153 | declare noalias i8* @_Znam(i64) #2 154 | 155 | ; Function Attrs: nounwind 156 | declare void @_ZdaPv(i8*) #3 157 | 158 | attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } 159 | attributes #1 = { uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } 160 | attributes #2 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } 161 | attributes #3 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } 162 | attributes #4 = { nounwind } 163 | -------------------------------------------------------------------------------- /tp_tests/llvm_clang/cpp_kmeans.bc: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'kmeans.cpp' 2 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 3 | target triple = "x86_64-unknown-linux-gnu" 4 | 5 | ; Function Attrs: nounwind uwtable 6 | define void @_Z6kmeansiPiS_S_S_S_i(i32 %i, i32* %data, i32* %x, i32* %y, i32* %c, i32* %t, i32 %CENT) #0 { 7 | entry: 8 | %i.addr = alloca i32, align 4 9 | %data.addr = alloca i32*, align 8 10 | %x.addr = alloca i32*, align 8 11 | %y.addr = alloca i32*, align 8 12 | %c.addr = alloca i32*, align 8 13 | %t.addr = alloca i32*, align 8 14 | %CENT.addr = alloca i32, align 4 15 | %xd0 = alloca i32, align 4 16 | %xd1 = alloca i32, align 4 17 | %xd2 = alloca i32, align 4 18 | %yd0 = alloca i32, align 4 19 | %yd1 = alloca i32, align 4 20 | %yd2 = alloca i32, align 4 21 | %d0 = alloca i32, align 4 22 | %d1 = alloca i32, align 4 23 | %d2 = alloca i32, align 4 24 | %min = alloca i32, align 4 25 | %assign = alloca i32, align 4 26 | store i32 %i, i32* %i.addr, align 4 27 | store i32* %data, i32** %data.addr, align 8 28 | store i32* %x, i32** %x.addr, align 8 29 | store i32* %y, i32** %y.addr, align 8 30 | store i32* %c, i32** %c.addr, align 8 31 | store i32* %t, i32** %t.addr, align 8 32 | store i32 %CENT, i32* %CENT.addr, align 4 33 | %0 = load i32** %c.addr, align 8 34 | %arrayidx = getelementptr inbounds i32* %0, i64 0 35 | %1 = load i32* %arrayidx, align 4 36 | %2 = load i32* %i.addr, align 4 37 | %idxprom = sext i32 %2 to i64 38 | %3 = load i32** %x.addr, align 8 39 | %arrayidx1 = getelementptr inbounds i32* %3, i64 %idxprom 40 | %4 = load i32* %arrayidx1, align 4 41 | %sub = sub nsw i32 %1, %4 42 | store i32 %sub, i32* %xd0, align 4 43 | %5 = load i32** %c.addr, align 8 44 | %arrayidx2 = getelementptr inbounds i32* %5, i64 1 45 | %6 = load i32* %arrayidx2, align 4 46 | %7 = load i32* %i.addr, align 4 47 | %idxprom3 = sext i32 %7 to i64 48 | %8 = load i32** %x.addr, align 8 49 | %arrayidx4 = getelementptr inbounds i32* %8, i64 %idxprom3 50 | %9 = load i32* %arrayidx4, align 4 51 | %sub5 = sub nsw i32 %6, %9 52 | store i32 %sub5, i32* %xd1, align 4 53 | %10 = load i32** %c.addr, align 8 54 | %arrayidx6 = getelementptr inbounds i32* %10, i64 2 55 | %11 = load i32* %arrayidx6, align 4 56 | %12 = load i32* %i.addr, align 4 57 | %idxprom7 = sext i32 %12 to i64 58 | %13 = load i32** %x.addr, align 8 59 | %arrayidx8 = getelementptr inbounds i32* %13, i64 %idxprom7 60 | %14 = load i32* %arrayidx8, align 4 61 | %sub9 = sub nsw i32 %11, %14 62 | store i32 %sub9, i32* %xd2, align 4 63 | %15 = load i32** %c.addr, align 8 64 | %arrayidx10 = getelementptr inbounds i32* %15, i64 3 65 | %16 = load i32* %arrayidx10, align 4 66 | %17 = load i32* %i.addr, align 4 67 | %idxprom11 = sext i32 %17 to i64 68 | %18 = load i32** %y.addr, align 8 69 | %arrayidx12 = getelementptr inbounds i32* %18, i64 %idxprom11 70 | %19 = load i32* %arrayidx12, align 4 71 | %sub13 = sub nsw i32 %16, %19 72 | store i32 %sub13, i32* %yd0, align 4 73 | %20 = load i32** %c.addr, align 8 74 | %arrayidx14 = getelementptr inbounds i32* %20, i64 4 75 | %21 = load i32* %arrayidx14, align 4 76 | %22 = load i32* %i.addr, align 4 77 | %idxprom15 = sext i32 %22 to i64 78 | %23 = load i32** %y.addr, align 8 79 | %arrayidx16 = getelementptr inbounds i32* %23, i64 %idxprom15 80 | %24 = load i32* %arrayidx16, align 4 81 | %sub17 = sub nsw i32 %21, %24 82 | store i32 %sub17, i32* %yd1, align 4 83 | %25 = load i32** %c.addr, align 8 84 | %arrayidx18 = getelementptr inbounds i32* %25, i64 5 85 | %26 = load i32* %arrayidx18, align 4 86 | %27 = load i32* %i.addr, align 4 87 | %idxprom19 = sext i32 %27 to i64 88 | %28 = load i32** %y.addr, align 8 89 | %arrayidx20 = getelementptr inbounds i32* %28, i64 %idxprom19 90 | %29 = load i32* %arrayidx20, align 4 91 | %sub21 = sub nsw i32 %26, %29 92 | store i32 %sub21, i32* %yd2, align 4 93 | %30 = load i32* %xd0, align 4 94 | %31 = load i32* %xd0, align 4 95 | %mul = mul nsw i32 %30, %31 96 | %32 = load i32* %yd0, align 4 97 | %33 = load i32* %yd0, align 4 98 | %mul22 = mul nsw i32 %32, %33 99 | %add = add nsw i32 %mul, %mul22 100 | %conv = sitofp i32 %add to double 101 | %call = call double @sqrt(double %conv) #4 102 | %conv23 = fptosi double %call to i32 103 | store i32 %conv23, i32* %d0, align 4 104 | %34 = load i32* %xd1, align 4 105 | %35 = load i32* %xd1, align 4 106 | %mul24 = mul nsw i32 %34, %35 107 | %36 = load i32* %yd1, align 4 108 | %37 = load i32* %yd1, align 4 109 | %mul25 = mul nsw i32 %36, %37 110 | %add26 = add nsw i32 %mul24, %mul25 111 | %conv27 = sitofp i32 %add26 to double 112 | %call28 = call double @sqrt(double %conv27) #4 113 | %conv29 = fptosi double %call28 to i32 114 | store i32 %conv29, i32* %d1, align 4 115 | %38 = load i32* %xd2, align 4 116 | %39 = load i32* %xd2, align 4 117 | %mul30 = mul nsw i32 %38, %39 118 | %40 = load i32* %yd2, align 4 119 | %41 = load i32* %yd2, align 4 120 | %mul31 = mul nsw i32 %40, %41 121 | %add32 = add nsw i32 %mul30, %mul31 122 | %conv33 = sitofp i32 %add32 to double 123 | %call34 = call double @sqrt(double %conv33) #4 124 | %conv35 = fptosi double %call34 to i32 125 | store i32 %conv35, i32* %d2, align 4 126 | %42 = load i32* %d0, align 4 127 | store i32 %42, i32* %min, align 4 128 | store i32 0, i32* %assign, align 4 129 | %43 = load i32* %d1, align 4 130 | %44 = load i32* %min, align 4 131 | %cmp = icmp slt i32 %43, %44 132 | br i1 %cmp, label %if.then, label %if.end 133 | 134 | if.then: ; preds = %entry 135 | %45 = load i32* %d1, align 4 136 | store i32 %45, i32* %min, align 4 137 | store i32 1, i32* %assign, align 4 138 | br label %if.end 139 | 140 | if.end: ; preds = %if.then, %entry 141 | %46 = load i32* %d2, align 4 142 | %47 = load i32* %min, align 4 143 | %cmp36 = icmp slt i32 %46, %47 144 | br i1 %cmp36, label %if.then37, label %if.end38 145 | 146 | if.then37: ; preds = %if.end 147 | store i32 2, i32* %assign, align 4 148 | br label %if.end38 149 | 150 | if.end38: ; preds = %if.then37, %if.end 151 | %48 = load i32* %i.addr, align 4 152 | %idxprom39 = sext i32 %48 to i64 153 | %49 = load i32** %x.addr, align 8 154 | %arrayidx40 = getelementptr inbounds i32* %49, i64 %idxprom39 155 | %50 = load i32* %arrayidx40, align 4 156 | %51 = load i32* %assign, align 4 157 | %idxprom41 = sext i32 %51 to i64 158 | %52 = load i32** %t.addr, align 8 159 | %arrayidx42 = getelementptr inbounds i32* %52, i64 %idxprom41 160 | %53 = load i32* %arrayidx42, align 4 161 | %add43 = add nsw i32 %53, %50 162 | store i32 %add43, i32* %arrayidx42, align 4 163 | %54 = load i32* %i.addr, align 4 164 | %idxprom44 = sext i32 %54 to i64 165 | %55 = load i32** %y.addr, align 8 166 | %arrayidx45 = getelementptr inbounds i32* %55, i64 %idxprom44 167 | %56 = load i32* %arrayidx45, align 4 168 | %57 = load i32* %CENT.addr, align 4 169 | %58 = load i32* %assign, align 4 170 | %add46 = add nsw i32 %57, %58 171 | %idxprom47 = sext i32 %add46 to i64 172 | %59 = load i32** %t.addr, align 8 173 | %arrayidx48 = getelementptr inbounds i32* %59, i64 %idxprom47 174 | %60 = load i32* %arrayidx48, align 4 175 | %add49 = add nsw i32 %60, %56 176 | store i32 %add49, i32* %arrayidx48, align 4 177 | %61 = load i32* %CENT.addr, align 4 178 | %mul50 = mul nsw i32 2, %61 179 | %62 = load i32* %assign, align 4 180 | %add51 = add nsw i32 %mul50, %62 181 | %idxprom52 = sext i32 %add51 to i64 182 | %63 = load i32** %t.addr, align 8 183 | %arrayidx53 = getelementptr inbounds i32* %63, i64 %idxprom52 184 | %64 = load i32* %arrayidx53, align 4 185 | %inc = add nsw i32 %64, 1 186 | store i32 %inc, i32* %arrayidx53, align 4 187 | ret void 188 | } 189 | 190 | ; Function Attrs: nounwind 191 | declare double @sqrt(double) #1 192 | 193 | ; Function Attrs: uwtable 194 | define i32 @main() #2 { 195 | entry: 196 | %retval = alloca i32, align 4 197 | %data = alloca i32*, align 8 198 | %x = alloca i32*, align 8 199 | %y = alloca i32*, align 8 200 | %c = alloca i32*, align 8 201 | %t = alloca i32*, align 8 202 | %i = alloca i32, align 4 203 | store i32 0, i32* %retval 204 | %call = call noalias i8* @_Znam(i64 400) 205 | %0 = bitcast i8* %call to i32* 206 | store i32* %0, i32** %data, align 8 207 | %call1 = call noalias i8* @_Znam(i64 400) 208 | %1 = bitcast i8* %call1 to i32* 209 | store i32* %1, i32** %x, align 8 210 | %call2 = call noalias i8* @_Znam(i64 400) 211 | %2 = bitcast i8* %call2 to i32* 212 | store i32* %2, i32** %y, align 8 213 | %call3 = call noalias i8* @_Znam(i64 400) 214 | %3 = bitcast i8* %call3 to i32* 215 | store i32* %3, i32** %c, align 8 216 | %call4 = call noalias i8* @_Znam(i64 400) 217 | %4 = bitcast i8* %call4 to i32* 218 | store i32* %4, i32** %t, align 8 219 | store i32 0, i32* %i, align 4 220 | br label %for.cond 221 | 222 | for.cond: ; preds = %for.inc, %entry 223 | %5 = load i32* %i, align 4 224 | %cmp = icmp slt i32 %5, 100 225 | br i1 %cmp, label %for.body, label %for.end 226 | 227 | for.body: ; preds = %for.cond 228 | %6 = load i32* %i, align 4 229 | %idxprom = sext i32 %6 to i64 230 | %7 = load i32** %data, align 8 231 | %arrayidx = getelementptr inbounds i32* %7, i64 %idxprom 232 | store i32 8, i32* %arrayidx, align 4 233 | %8 = load i32* %i, align 4 234 | %9 = load i32* %i, align 4 235 | %idxprom5 = sext i32 %9 to i64 236 | %10 = load i32** %x, align 8 237 | %arrayidx6 = getelementptr inbounds i32* %10, i64 %idxprom5 238 | store i32 %8, i32* %arrayidx6, align 4 239 | %11 = load i32* %i, align 4 240 | %12 = load i32* %i, align 4 241 | %idxprom7 = sext i32 %12 to i64 242 | %13 = load i32** %y, align 8 243 | %arrayidx8 = getelementptr inbounds i32* %13, i64 %idxprom7 244 | store i32 %11, i32* %arrayidx8, align 4 245 | %14 = load i32* %i, align 4 246 | %15 = load i32* %i, align 4 247 | %idxprom9 = sext i32 %15 to i64 248 | %16 = load i32** %c, align 8 249 | %arrayidx10 = getelementptr inbounds i32* %16, i64 %idxprom9 250 | store i32 %14, i32* %arrayidx10, align 4 251 | %17 = load i32* %i, align 4 252 | %idxprom11 = sext i32 %17 to i64 253 | %18 = load i32** %t, align 8 254 | %arrayidx12 = getelementptr inbounds i32* %18, i64 %idxprom11 255 | store i32 0, i32* %arrayidx12, align 4 256 | br label %for.inc 257 | 258 | for.inc: ; preds = %for.body 259 | %19 = load i32* %i, align 4 260 | %inc = add nsw i32 %19, 1 261 | store i32 %inc, i32* %i, align 4 262 | br label %for.cond 263 | 264 | for.end: ; preds = %for.cond 265 | %20 = load i32** %data, align 8 266 | %21 = load i32** %x, align 8 267 | %22 = load i32** %y, align 8 268 | %23 = load i32** %c, align 8 269 | %24 = load i32** %t, align 8 270 | call void @_Z6kmeansiPiS_S_S_S_i(i32 99, i32* %20, i32* %21, i32* %22, i32* %23, i32* %24, i32 25) 271 | %25 = load i32** %data, align 8 272 | %isnull = icmp eq i32* %25, null 273 | br i1 %isnull, label %delete.end, label %delete.notnull 274 | 275 | delete.notnull: ; preds = %for.end 276 | %26 = bitcast i32* %25 to i8* 277 | call void @_ZdaPv(i8* %26) #4 278 | br label %delete.end 279 | 280 | delete.end: ; preds = %delete.notnull, %for.end 281 | %27 = load i32** %x, align 8 282 | %isnull13 = icmp eq i32* %27, null 283 | br i1 %isnull13, label %delete.end15, label %delete.notnull14 284 | 285 | delete.notnull14: ; preds = %delete.end 286 | %28 = bitcast i32* %27 to i8* 287 | call void @_ZdaPv(i8* %28) #4 288 | br label %delete.end15 289 | 290 | delete.end15: ; preds = %delete.notnull14, %delete.end 291 | %29 = load i32** %y, align 8 292 | %isnull16 = icmp eq i32* %29, null 293 | br i1 %isnull16, label %delete.end18, label %delete.notnull17 294 | 295 | delete.notnull17: ; preds = %delete.end15 296 | %30 = bitcast i32* %29 to i8* 297 | call void @_ZdaPv(i8* %30) #4 298 | br label %delete.end18 299 | 300 | delete.end18: ; preds = %delete.notnull17, %delete.end15 301 | %31 = load i32** %c, align 8 302 | %isnull19 = icmp eq i32* %31, null 303 | br i1 %isnull19, label %delete.end21, label %delete.notnull20 304 | 305 | delete.notnull20: ; preds = %delete.end18 306 | %32 = bitcast i32* %31 to i8* 307 | call void @_ZdaPv(i8* %32) #4 308 | br label %delete.end21 309 | 310 | delete.end21: ; preds = %delete.notnull20, %delete.end18 311 | %33 = load i32** %t, align 8 312 | %isnull22 = icmp eq i32* %33, null 313 | br i1 %isnull22, label %delete.end24, label %delete.notnull23 314 | 315 | delete.notnull23: ; preds = %delete.end21 316 | %34 = bitcast i32* %33 to i8* 317 | call void @_ZdaPv(i8* %34) #4 318 | br label %delete.end24 319 | 320 | delete.end24: ; preds = %delete.notnull23, %delete.end21 321 | %35 = load i32* %retval 322 | ret i32 %35 323 | } 324 | 325 | declare noalias i8* @_Znam(i64) #3 326 | 327 | ; Function Attrs: nounwind 328 | declare void @_ZdaPv(i8*) #1 329 | 330 | attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } 331 | attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } 332 | attributes #2 = { uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } 333 | attributes #3 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } 334 | attributes #4 = { nounwind } 335 | -------------------------------------------------------------------------------- /tp_tests/llvm_clang/cpp_linreg.bc: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'linreg.cpp' 2 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 3 | target triple = "x86_64-unknown-linux-gnu" 4 | 5 | ; Function Attrs: nounwind uwtable 6 | define void @_Z6linregPfS_S_i(float* %data, float* %w, float* %g, i32 %DIMS) #0 { 7 | entry: 8 | %data.addr = alloca float*, align 8 9 | %w.addr = alloca float*, align 8 10 | %g.addr = alloca float*, align 8 11 | %DIMS.addr = alloca i32, align 4 12 | %dot = alloca float, align 4 13 | %j = alloca i32, align 4 14 | %label = alloca float, align 4 15 | %j6 = alloca i32, align 4 16 | store float* %data, float** %data.addr, align 8 17 | store float* %w, float** %w.addr, align 8 18 | store float* %g, float** %g.addr, align 8 19 | store i32 %DIMS, i32* %DIMS.addr, align 4 20 | store float 0.000000e+00, float* %dot, align 4 21 | store i32 0, i32* %j, align 4 22 | br label %for.cond 23 | 24 | for.cond: ; preds = %for.inc, %entry 25 | %0 = load i32* %j, align 4 26 | %1 = load i32* %DIMS.addr, align 4 27 | %cmp = icmp sle i32 %0, %1 28 | br i1 %cmp, label %for.body, label %for.end 29 | 30 | for.body: ; preds = %for.cond 31 | %2 = load i32* %j, align 4 32 | %idxprom = sext i32 %2 to i64 33 | %3 = load float** %data.addr, align 8 34 | %arrayidx = getelementptr inbounds float* %3, i64 %idxprom 35 | %4 = load float* %arrayidx, align 4 36 | %5 = load i32* %j, align 4 37 | %idxprom1 = sext i32 %5 to i64 38 | %6 = load float** %w.addr, align 8 39 | %arrayidx2 = getelementptr inbounds float* %6, i64 %idxprom1 40 | %7 = load float* %arrayidx2, align 4 41 | %mul = fmul float %4, %7 42 | %8 = load float* %dot, align 4 43 | %add = fadd float %8, %mul 44 | store float %add, float* %dot, align 4 45 | br label %for.inc 46 | 47 | for.inc: ; preds = %for.body 48 | %9 = load i32* %j, align 4 49 | %inc = add nsw i32 %9, 1 50 | store i32 %inc, i32* %j, align 4 51 | br label %for.cond 52 | 53 | for.end: ; preds = %for.cond 54 | %10 = load i32* %DIMS.addr, align 4 55 | %idxprom3 = sext i32 %10 to i64 56 | %11 = load float** %data.addr, align 8 57 | %arrayidx4 = getelementptr inbounds float* %11, i64 %idxprom3 58 | %12 = load float* %arrayidx4, align 4 59 | store float %12, float* %label, align 4 60 | %13 = load float* %label, align 4 61 | %sub = fsub float -0.000000e+00, %13 62 | %14 = load float* %dot, align 4 63 | %mul5 = fmul float %14, %sub 64 | store float %mul5, float* %dot, align 4 65 | store i32 0, i32* %j6, align 4 66 | br label %for.cond7 67 | 68 | for.cond7: ; preds = %for.inc16, %for.end 69 | %15 = load i32* %j6, align 4 70 | %16 = load i32* %DIMS.addr, align 4 71 | %cmp8 = icmp sle i32 %15, %16 72 | br i1 %cmp8, label %for.body9, label %for.end18 73 | 74 | for.body9: ; preds = %for.cond7 75 | %17 = load float* %dot, align 4 76 | %18 = load i32* %j6, align 4 77 | %idxprom10 = sext i32 %18 to i64 78 | %19 = load float** %data.addr, align 8 79 | %arrayidx11 = getelementptr inbounds float* %19, i64 %idxprom10 80 | %20 = load float* %arrayidx11, align 4 81 | %mul12 = fmul float %17, %20 82 | %21 = load i32* %j6, align 4 83 | %idxprom13 = sext i32 %21 to i64 84 | %22 = load float** %g.addr, align 8 85 | %arrayidx14 = getelementptr inbounds float* %22, i64 %idxprom13 86 | %23 = load float* %arrayidx14, align 4 87 | %add15 = fadd float %23, %mul12 88 | store float %add15, float* %arrayidx14, align 4 89 | br label %for.inc16 90 | 91 | for.inc16: ; preds = %for.body9 92 | %24 = load i32* %j6, align 4 93 | %inc17 = add nsw i32 %24, 1 94 | store i32 %inc17, i32* %j6, align 4 95 | br label %for.cond7 96 | 97 | for.end18: ; preds = %for.cond7 98 | ret void 99 | } 100 | 101 | ; Function Attrs: uwtable 102 | define i32 @main() #1 { 103 | entry: 104 | %retval = alloca i32, align 4 105 | %data = alloca float*, align 8 106 | %w = alloca float*, align 8 107 | %g = alloca float*, align 8 108 | %i = alloca i32, align 4 109 | store i32 0, i32* %retval 110 | %call = call noalias i8* @_Znam(i64 400) 111 | %0 = bitcast i8* %call to float* 112 | store float* %0, float** %data, align 8 113 | %call1 = call noalias i8* @_Znam(i64 400) 114 | %1 = bitcast i8* %call1 to float* 115 | store float* %1, float** %w, align 8 116 | %call2 = call noalias i8* @_Znam(i64 400) 117 | %2 = bitcast i8* %call2 to float* 118 | store float* %2, float** %g, align 8 119 | store i32 0, i32* %i, align 4 120 | br label %for.cond 121 | 122 | for.cond: ; preds = %for.inc, %entry 123 | %3 = load i32* %i, align 4 124 | %cmp = icmp slt i32 %3, 100 125 | br i1 %cmp, label %for.body, label %for.end 126 | 127 | for.body: ; preds = %for.cond 128 | %4 = load i32* %i, align 4 129 | %conv = sitofp i32 %4 to float 130 | %5 = load i32* %i, align 4 131 | %idxprom = sext i32 %5 to i64 132 | %6 = load float** %data, align 8 133 | %arrayidx = getelementptr inbounds float* %6, i64 %idxprom 134 | store float %conv, float* %arrayidx, align 4 135 | %7 = load i32* %i, align 4 136 | %idxprom3 = sext i32 %7 to i64 137 | %8 = load float** %w, align 8 138 | %arrayidx4 = getelementptr inbounds float* %8, i64 %idxprom3 139 | store float 0.000000e+00, float* %arrayidx4, align 4 140 | %9 = load i32* %i, align 4 141 | %idxprom5 = sext i32 %9 to i64 142 | %10 = load float** %g, align 8 143 | %arrayidx6 = getelementptr inbounds float* %10, i64 %idxprom5 144 | store float 0.000000e+00, float* %arrayidx6, align 4 145 | br label %for.inc 146 | 147 | for.inc: ; preds = %for.body 148 | %11 = load i32* %i, align 4 149 | %inc = add nsw i32 %11, 1 150 | store i32 %inc, i32* %i, align 4 151 | br label %for.cond 152 | 153 | for.end: ; preds = %for.cond 154 | %12 = load float** %data, align 8 155 | %arrayidx7 = getelementptr inbounds float* %12, i64 99 156 | store float 1.000000e+00, float* %arrayidx7, align 4 157 | %13 = load float** %data, align 8 158 | %14 = load float** %w, align 8 159 | %15 = load float** %g, align 8 160 | call void @_Z6linregPfS_S_i(float* %13, float* %14, float* %15, i32 99) 161 | %16 = load float** %data, align 8 162 | %isnull = icmp eq float* %16, null 163 | br i1 %isnull, label %delete.end, label %delete.notnull 164 | 165 | delete.notnull: ; preds = %for.end 166 | %17 = bitcast float* %16 to i8* 167 | call void @_ZdaPv(i8* %17) #4 168 | br label %delete.end 169 | 170 | delete.end: ; preds = %delete.notnull, %for.end 171 | %18 = load float** %w, align 8 172 | %isnull8 = icmp eq float* %18, null 173 | br i1 %isnull8, label %delete.end10, label %delete.notnull9 174 | 175 | delete.notnull9: ; preds = %delete.end 176 | %19 = bitcast float* %18 to i8* 177 | call void @_ZdaPv(i8* %19) #4 178 | br label %delete.end10 179 | 180 | delete.end10: ; preds = %delete.notnull9, %delete.end 181 | %20 = load float** %g, align 8 182 | %isnull11 = icmp eq float* %20, null 183 | br i1 %isnull11, label %delete.end13, label %delete.notnull12 184 | 185 | delete.notnull12: ; preds = %delete.end10 186 | %21 = bitcast float* %20 to i8* 187 | call void @_ZdaPv(i8* %21) #4 188 | br label %delete.end13 189 | 190 | delete.end13: ; preds = %delete.notnull12, %delete.end10 191 | %22 = load i32* %retval 192 | ret i32 %22 193 | } 194 | 195 | declare noalias i8* @_Znam(i64) #2 196 | 197 | ; Function Attrs: nounwind 198 | declare void @_ZdaPv(i8*) #3 199 | 200 | attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } 201 | attributes #1 = { uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } 202 | attributes #2 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } 203 | attributes #3 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } 204 | attributes #4 = { nounwind } 205 | -------------------------------------------------------------------------------- /tp_tests/llvm_clang/cpp_logreg.bc: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'logreg.cpp' 2 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 3 | target triple = "x86_64-unknown-linux-gnu" 4 | 5 | ; Function Attrs: nounwind uwtable 6 | define void @_Z6logregPfS_S_i(float* %data, float* %g, float* %w, i32 %DIMS) #0 { 7 | entry: 8 | %data.addr = alloca float*, align 8 9 | %g.addr = alloca float*, align 8 10 | %w.addr = alloca float*, align 8 11 | %DIMS.addr = alloca i32, align 4 12 | %dot = alloca float, align 4 13 | %j = alloca i32, align 4 14 | %label = alloca float, align 4 15 | %scale = alloca float, align 4 16 | %j11 = alloca i32, align 4 17 | store float* %data, float** %data.addr, align 8 18 | store float* %g, float** %g.addr, align 8 19 | store float* %w, float** %w.addr, align 8 20 | store i32 %DIMS, i32* %DIMS.addr, align 4 21 | store float 0.000000e+00, float* %dot, align 4 22 | store i32 0, i32* %j, align 4 23 | br label %for.cond 24 | 25 | for.cond: ; preds = %for.inc, %entry 26 | %0 = load i32* %j, align 4 27 | %1 = load i32* %DIMS.addr, align 4 28 | %cmp = icmp slt i32 %0, %1 29 | br i1 %cmp, label %for.body, label %for.end 30 | 31 | for.body: ; preds = %for.cond 32 | %2 = load i32* %j, align 4 33 | %idxprom = sext i32 %2 to i64 34 | %3 = load float** %data.addr, align 8 35 | %arrayidx = getelementptr inbounds float* %3, i64 %idxprom 36 | %4 = load float* %arrayidx, align 4 37 | %5 = load i32* %j, align 4 38 | %idxprom1 = sext i32 %5 to i64 39 | %6 = load float** %w.addr, align 8 40 | %arrayidx2 = getelementptr inbounds float* %6, i64 %idxprom1 41 | %7 = load float* %arrayidx2, align 4 42 | %mul = fmul float %4, %7 43 | %8 = load float* %dot, align 4 44 | %add = fadd float %8, %mul 45 | store float %add, float* %dot, align 4 46 | br label %for.inc 47 | 48 | for.inc: ; preds = %for.body 49 | %9 = load i32* %j, align 4 50 | %inc = add nsw i32 %9, 1 51 | store i32 %inc, i32* %j, align 4 52 | br label %for.cond 53 | 54 | for.end: ; preds = %for.cond 55 | %10 = load i32* %DIMS.addr, align 4 56 | %idxprom3 = sext i32 %10 to i64 57 | %11 = load float** %data.addr, align 8 58 | %arrayidx4 = getelementptr inbounds float* %11, i64 %idxprom3 59 | %12 = load float* %arrayidx4, align 4 60 | store float %12, float* %label, align 4 61 | %13 = load float* %label, align 4 62 | %sub = fsub float -0.000000e+00, %13 63 | %14 = load float* %dot, align 4 64 | %mul5 = fmul float %sub, %14 65 | %conv = fpext float %mul5 to double 66 | %call = call double @exp(double %conv) #4 67 | %add6 = fadd double 1.000000e+00, %call 68 | %div = fdiv double 1.000000e+00, %add6 69 | %sub7 = fsub double %div, 1.000000e+00 70 | %15 = load float* %label, align 4 71 | %conv8 = fpext float %15 to double 72 | %mul9 = fmul double %sub7, %conv8 73 | %conv10 = fptrunc double %mul9 to float 74 | store float %conv10, float* %scale, align 4 75 | store i32 0, i32* %j11, align 4 76 | br label %for.cond12 77 | 78 | for.cond12: ; preds = %for.inc21, %for.end 79 | %16 = load i32* %j11, align 4 80 | %17 = load i32* %DIMS.addr, align 4 81 | %cmp13 = icmp slt i32 %16, %17 82 | br i1 %cmp13, label %for.body14, label %for.end23 83 | 84 | for.body14: ; preds = %for.cond12 85 | %18 = load float* %scale, align 4 86 | %19 = load i32* %j11, align 4 87 | %idxprom15 = sext i32 %19 to i64 88 | %20 = load float** %data.addr, align 8 89 | %arrayidx16 = getelementptr inbounds float* %20, i64 %idxprom15 90 | %21 = load float* %arrayidx16, align 4 91 | %mul17 = fmul float %18, %21 92 | %22 = load i32* %j11, align 4 93 | %idxprom18 = sext i32 %22 to i64 94 | %23 = load float** %g.addr, align 8 95 | %arrayidx19 = getelementptr inbounds float* %23, i64 %idxprom18 96 | %24 = load float* %arrayidx19, align 4 97 | %add20 = fadd float %24, %mul17 98 | store float %add20, float* %arrayidx19, align 4 99 | br label %for.inc21 100 | 101 | for.inc21: ; preds = %for.body14 102 | %25 = load i32* %j11, align 4 103 | %inc22 = add nsw i32 %25, 1 104 | store i32 %inc22, i32* %j11, align 4 105 | br label %for.cond12 106 | 107 | for.end23: ; preds = %for.cond12 108 | ret void 109 | } 110 | 111 | ; Function Attrs: nounwind 112 | declare double @exp(double) #1 113 | 114 | ; Function Attrs: uwtable 115 | define i32 @main() #2 { 116 | entry: 117 | %retval = alloca i32, align 4 118 | %data = alloca float*, align 8 119 | %w = alloca float*, align 8 120 | %g = alloca float*, align 8 121 | %i = alloca i32, align 4 122 | store i32 0, i32* %retval 123 | %call = call noalias i8* @_Znam(i64 400) 124 | %0 = bitcast i8* %call to float* 125 | store float* %0, float** %data, align 8 126 | %call1 = call noalias i8* @_Znam(i64 400) 127 | %1 = bitcast i8* %call1 to float* 128 | store float* %1, float** %w, align 8 129 | %call2 = call noalias i8* @_Znam(i64 400) 130 | %2 = bitcast i8* %call2 to float* 131 | store float* %2, float** %g, align 8 132 | store i32 0, i32* %i, align 4 133 | br label %for.cond 134 | 135 | for.cond: ; preds = %for.inc, %entry 136 | %3 = load i32* %i, align 4 137 | %cmp = icmp slt i32 %3, 100 138 | br i1 %cmp, label %for.body, label %for.end 139 | 140 | for.body: ; preds = %for.cond 141 | %4 = load i32* %i, align 4 142 | %conv = sitofp i32 %4 to float 143 | %5 = load i32* %i, align 4 144 | %idxprom = sext i32 %5 to i64 145 | %6 = load float** %data, align 8 146 | %arrayidx = getelementptr inbounds float* %6, i64 %idxprom 147 | store float %conv, float* %arrayidx, align 4 148 | %7 = load i32* %i, align 4 149 | %conv3 = sitofp i32 %7 to float 150 | %8 = load i32* %i, align 4 151 | %idxprom4 = sext i32 %8 to i64 152 | %9 = load float** %w, align 8 153 | %arrayidx5 = getelementptr inbounds float* %9, i64 %idxprom4 154 | store float %conv3, float* %arrayidx5, align 4 155 | %10 = load i32* %i, align 4 156 | %idxprom6 = sext i32 %10 to i64 157 | %11 = load float** %g, align 8 158 | %arrayidx7 = getelementptr inbounds float* %11, i64 %idxprom6 159 | store float 0.000000e+00, float* %arrayidx7, align 4 160 | br label %for.inc 161 | 162 | for.inc: ; preds = %for.body 163 | %12 = load i32* %i, align 4 164 | %inc = add nsw i32 %12, 1 165 | store i32 %inc, i32* %i, align 4 166 | br label %for.cond 167 | 168 | for.end: ; preds = %for.cond 169 | %13 = load float** %data, align 8 170 | %arrayidx8 = getelementptr inbounds float* %13, i64 99 171 | store float -1.000000e+00, float* %arrayidx8, align 4 172 | %14 = load float** %data, align 8 173 | %15 = load float** %g, align 8 174 | %16 = load float** %w, align 8 175 | call void @_Z6logregPfS_S_i(float* %14, float* %15, float* %16, i32 99) 176 | %17 = load float** %data, align 8 177 | %isnull = icmp eq float* %17, null 178 | br i1 %isnull, label %delete.end, label %delete.notnull 179 | 180 | delete.notnull: ; preds = %for.end 181 | %18 = bitcast float* %17 to i8* 182 | call void @_ZdaPv(i8* %18) #4 183 | br label %delete.end 184 | 185 | delete.end: ; preds = %delete.notnull, %for.end 186 | %19 = load float** %w, align 8 187 | %isnull9 = icmp eq float* %19, null 188 | br i1 %isnull9, label %delete.end11, label %delete.notnull10 189 | 190 | delete.notnull10: ; preds = %delete.end 191 | %20 = bitcast float* %19 to i8* 192 | call void @_ZdaPv(i8* %20) #4 193 | br label %delete.end11 194 | 195 | delete.end11: ; preds = %delete.notnull10, %delete.end 196 | %21 = load float** %g, align 8 197 | %isnull12 = icmp eq float* %21, null 198 | br i1 %isnull12, label %delete.end14, label %delete.notnull13 199 | 200 | delete.notnull13: ; preds = %delete.end11 201 | %22 = bitcast float* %21 to i8* 202 | call void @_ZdaPv(i8* %22) #4 203 | br label %delete.end14 204 | 205 | delete.end14: ; preds = %delete.notnull13, %delete.end11 206 | %23 = load i32* %retval 207 | ret i32 %23 208 | } 209 | 210 | declare noalias i8* @_Znam(i64) #3 211 | 212 | ; Function Attrs: nounwind 213 | declare void @_ZdaPv(i8*) #1 214 | 215 | attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } 216 | attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } 217 | attributes #2 = { uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } 218 | attributes #3 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } 219 | attributes #4 = { nounwind } 220 | -------------------------------------------------------------------------------- /tp_tests/llvm_clang/kmeans.cpp: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | void kmeans(int i, int* data, int* x, int* y, int* c, int* t, int CENT) { 5 | 6 | int xd0 = c[0] - x[i]; 7 | int xd1 = c[1] - x[i]; 8 | int xd2 = c[2] - x[i]; 9 | int yd0 = c[3] - y[i]; 10 | int yd1 = c[4] - y[i]; 11 | int yd2 = c[5] - y[i]; 12 | int d0 = sqrt(xd0 * xd0 + yd0 * yd0); 13 | int d1 = sqrt(xd1 * xd1 + yd1 * yd1); 14 | int d2 = sqrt(xd2 * xd2 + yd2 * yd2); 15 | 16 | int min = d0; 17 | int assign = 0; 18 | if(d1 2 | #import 3 | 4 | void linreg(float* data, float* w, float* g, int DIMS) { 5 | float dot = 0; 6 | for (int j = 0; j <= DIMS; j++) 7 | dot +=data[j] * w[j]; 8 | float label = data[DIMS]; 9 | dot *= -label; 10 | for (int j = 0; j <= DIMS; j++) 11 | g[j] += dot * data[j]; 12 | } 13 | 14 | int main() { 15 | float* data = new float[100]; 16 | float* w = new float[100]; 17 | float* g = new float[100]; 18 | 19 | for(int i=0;i<100;i++) { 20 | data[i]=i; 21 | w[i]=i; 22 | g[i]=0.0; 23 | } 24 | data[99]=1.0; 25 | linreg(data, w, g, 99); 26 | /* 27 | printf("["); 28 | for(int i=0;i<100;i++) { 29 | printf("%f, ", g[i]); 30 | } 31 | printf("]\n"); 32 | */ 33 | delete[] data; 34 | delete[] w; 35 | delete[] g; 36 | } 37 | -------------------------------------------------------------------------------- /tp_tests/llvm_clang/llvm_bm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for i in {1..2500} 4 | do 5 | lli $1 6 | done 7 | -------------------------------------------------------------------------------- /tp_tests/llvm_clang/logreg.cpp: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | #import 4 | 5 | void logreg(float* data, float* g, float* w, int DIMS) { 6 | float dot = 0; 7 | for (int j = 0; j < DIMS; j++) 8 | dot += data[j] * w[j]; 9 | float label = data[DIMS]; 10 | float scale = (1 / (1 + exp(-label * dot)) - 1) * label; 11 | for (int j = 0; j < DIMS; j++) 12 | g[j] += scale * data[j]; 13 | } 14 | 15 | int main() { 16 | float* data = new float[100]; 17 | float* w = new float[100]; 18 | float* g = new float[100]; 19 | 20 | for(int i=0;i<100;i++) { 21 | data[i]=i; 22 | w[i]=i; 23 | g[i]=0.0; 24 | } 25 | data[99]=-1.0; 26 | logreg(data, g, w, 99); 27 | /* 28 | printf("["); 29 | for(int i=0;i<100;i++) { 30 | printf("%f, ", g[i]); 31 | } 32 | printf("]\n"); 33 | */ 34 | delete[] data; 35 | delete[] w; 36 | delete[] g; 37 | } 38 | -------------------------------------------------------------------------------- /tp_tests/llvm_clang/run_llvm_bm_cl.sh: -------------------------------------------------------------------------------- 1 | echo "running bayes..." 2 | time bash llvm_bm.sh cpp_bayes.bc 3 | echo "running kmeans..." 4 | time bash llvm_bm.sh cpp_kmeans.bc 5 | echo "running linreg..." 6 | time bash llvm_bm.sh cpp_linreg.bc 7 | echo "running logreg..." 8 | time bash llvm_bm.sh cpp_logreg.bc 9 | -------------------------------------------------------------------------------- /tp_tests/llvm_numba/numba_genLLVM.py: -------------------------------------------------------------------------------- 1 | import timeit 2 | import sys 3 | from numba import jit 4 | 5 | def run_test(): 6 | from test_numba import main 7 | v = jit(main) 8 | v() 9 | 10 | if __name__ == '__main__': 11 | run_test() 12 | -------------------------------------------------------------------------------- /tp_tests/llvm_numba/numba_llvm_bayes.py: -------------------------------------------------------------------------------- 1 | # Original C++ 2 | #void naive_bayes(char *data, int *counts, int dims, int vals, int labels){ 3 | # char label = data[dims]; 4 | # ++counts[label]; 5 | # int offset = labels + label * dims * vals; 6 | # for (int j = 0; j < dims; j++) 7 | # ++counts[offset + j * vals + data[j]]; 8 | #} 9 | import numba 10 | listi100=[] 11 | @numba.jit 12 | def naive_bayes(data=listi100, counts=listi100,dims=int, vals=int, labels=int): 13 | label = data[dims] 14 | counts[label] += 1 15 | offset = labels + label * dims * vals 16 | c = 0 17 | while(c" 12 | sys.exit(0) 13 | 14 | time = timeit.timeit("run_test()", setup="from __main__ import run_test", number=500) 15 | 16 | print time 17 | --------------------------------------------------------------------------------