def compile(self, cx, out): funcReg, argReg = cx.local(), cx.local() funcCode = self.function.compile(cx, funcReg) argCode = self.argument.compile(cx, argReg) fptr, cl = cx.local(), cx.local() ftype = cx.s[self.function.type] return funcCode + argCode + \ lu.funcObjFunction(funcReg, ftype, cx, fptr) + \ lu.funcObjClosure(funcReg, ftype, cx, cl) + \ ['%s = call %s %s(%s %s, %s %s)' % (out, ftype.result().llvm(cx), fptr, '%voidptr', cl, ftype.argument().llvm(cx), argReg)] + \ mem.unreference(funcReg, self.function.type, cx) + \ mem.unreference(argReg, self.argument.type, cx)
def compile(self, expr): from mlbuiltins import definition expr.markDepth(0) xreg = self.local() compiled = expr.compile(self, xreg) + mem.unreference( xreg, expr.type, self) + [inst.ret()] out = initial_typedefs + '%%size_t = type %s\n\n' % self.size_t for n in self.freeTypeNums: out += '%%free_type_%d = type i1\n' % n out += '\n' for b in self.builtins: out += definition[b] for nam, tp in self.funcTypeDeclarations.values(): out += '\n' + nam + ' = ' + tp out += '\n\n' for l in self.lambdaDefinitions: out += l out += '\n' for d in self.destructorDefinitions: out += d out += '\n' + formatFunctionDef('void @ml_program()', compiled, self.llvmVersion) out += '\n' + formatFunctionDef( 'i32 @main()', ['call void @ml_program()', 'ret i32 0'], self.llvmVersion) return out
def destructorBody(self, cx): o = [] for i in 0, 1: r = cx.local() o += lu.extractProductElement(self, '%object', i, cx, r) o += memory.unreference(r, self.parms[i], cx) return o
def compile(self, cx, out): psum, pside, p = cx.local(), cx.local(), cx.local() tp = self.type.llvm(cx) sst = lu.sumSideType(tp) return self.expr.compile(cx, psum) + [ inst.bitcast('i1*', '%s*' % sst, psum, pside), inst.structGEP(pside, sst, p, 1), inst.load(tp, p, out)] + mem.reference(out, self.type, cx) + \ mem.unreference(psum, self.expr.type, cx)
def compile(self, cx, out): lt = self.type.llvm(cx) k = (self.var, cx.canonicalStr(self.type)) if k in cx.bindings: return super().compile(cx, out) cx.bindings[k] = (out, lt) ref = mem.reference(out, self.type, cx) cx.bindings2[k] = (lu.reusable(ref, out), lu.reusable(mem.unreference(out, self.type, cx), out)) cx.pushTypeContext(self.type, self.var.type) code = self.var.boundExpr.compile(cx, out) cx.popTypeContext() self.var.instantiationKeys.append(k) self.var.instantiationCode += code if hasattr(self, 'letName'): self.var.instantiationCode.append('; let %s = %s' % (self.letName, out)) return ref
def compile(self, cx, out): name = cx.lamb() arg = cx.local() retLtype = self.type.result().llvm(cx) fsig = '%s %s(%%voidptr %%cl0, %s %s)' % ( retLtype, name, self.type.argument().llvm(cx), arg) fout = cx.local() k = (self.var, cx.canonicalStr(self.var.type)) cx.bindings[k] = (arg, self.var.type.llvm(cx)) cx.bindings2[k] = (lu.reusable(mem.reference(arg, self.var.type, cx), arg), lu.reusable(mem.unreference(arg, self.var.type, cx), arg)) exprCode = self.expr.compile(cx, fout) del cx.bindings[k], cx.bindings2[k] cv0 = set(self.closedVars()) cv = [(var, ltype, cstr, reg) for (var, cstr), (reg, ltype) in cx.bindings.items() if var in cv0] if cv: clTypes = list(zip(*cv))[1] clType = lu.closureType(clTypes, cx) loadClosure = [ '%%clPtr = bitcast %%voidptr %%cl0 to %s*' % clType, inst.load(clType, '%clPtr', '%cl') ] clTypedPtr, clPtr = cx.local(), cx.local() storeClosure = [] builder = 'undef' copiedRegs = set() closureItems = [] for i, (var, ltype, cstr, rBound) in enumerate(cv): reg = cx.local() if rBound in copiedRegs: continue copiedRegs.add(rBound) ref, unref = cx.bindings2[(var, cstr)] closureItems.append((ltype, unref, rBound)) loadClosure.append(inst.extractvalue(clType, '%cl', i, rBound)) storeClosure.append('%s = insertvalue %s %s, %s %s, %d' % (reg, clType, builder, ltype, rBound, i)) builder = reg storeClosure += ref(cx) destruc = cx.closureDestructor() storeClosure += mem.createClosure(clType, builder, destruc, cx, clTypedPtr) storeClosure += [ '%s = bitcast %s* %s to %%voidptr' % (clPtr, clType, clTypedPtr) ] cx.destructorDefinitions.append( mem.closureDestructorDefinition(destruc, clType, closureItems, cx)) else: loadClosure = storeClosure = [] clPtr = 'null' fbody = loadClosure + exprCode + [inst.ret(retLtype, fout)] cx.lambdaDefinitions.append( lu.formatFunctionDef(fsig, fbody, cx.llvmVersion)) return storeClosure + lu.makeFuncObj(name, self.type, clPtr, cx, out)
def compile(self, cx, out): x = cx.local() return self.expr.compile(cx, x) + [ inst.extractvalue(self.expr.type.llvm(cx), x, self.side, out) ] + mem.reference(out, self.type, cx) + mem.unreference( x, self.expr.type, cx)
def compile(self, cx, out): sum = cx.local() return self.expr.compile(cx, sum) + [inst.load('i1', sum, out)] \ + mem.unreference(sum, self.expr.type, cx)