Example #1
0
 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
Example #2
0
def regBinaryIntOp(name, instr, type):
    ltype = type.llvm(None)
    mIntpair = types.Product(types.Int, types.Int)
    intpair = mIntpair.llvm(None)
    sig = '%s @%s(%%voidptr, %s %%args)' % (ltype, name, intpair)
    lines = [inst.extractvalue(intpair, '%args', 0, '%x'),
             inst.extractvalue(intpair, '%args', 1, '%y'),
             '%%result = %s %%Int %%x, %%y' % instr,
             inst.ret(ltype, '%result')]
    reg(name, types.Arrow(mIntpair, type), lu.formatFunctionDef(sig, lines, 0))
Example #3
0
def closureDestructorDefinition(name, clType, items, cx):
    sig = 'void %s(%%voidptr %%cl)' % name
    clTypeFull = closureTypeFull(clType, cx)
    body = []
    for i, (ltype, unrefCode, reg) in enumerate(items):
        unrefCode = unrefCode(cx)
        if unrefCode:
            body += [inst.extractvalue(clType, '%stuff', i, reg)] + unrefCode
    if body:
        body = [
            inst.bitcast('%voidptr', lt.Pointer(clTypeFull, cx), '%cl', '%p'),
            inst.structGEP('%p', clTypeFull, '%stuffP', 2),
            inst.load(clType, '%stuffP', '%stuff')
        ] + body
    body += ['call void @free(%voidptr %cl)', inst.ret()]
    return lu.formatFunctionDef(sig, body, cx.llvmVersion)
Example #4
0
 def getDestructor(self, mtype):  # for sum types
     smtype = self.canonicalStr(mtype)
     if smtype in self.destructors:
         return self.destructors[smtype]
     name = self.destructor()
     self.destructors[smtype] = name
     self.useBuiltin('~free')
     dbody = ['; ' + smtype] + mem.sumDestructorBody(mtype, self)
     sig = 'void %s(%s %%object)' % (name, mtype.llvm(self))
     dbody += mem.getPtrToRefcount('%object', 'i1*', self, '%prefc') + [
         inst.bitcast('%size_t*', '%voidptr', '%prefc', '%pvoid'),
         'call void @free(%voidptr %pvoid)',
         inst.ret()
     ]
     self.destructorDefinitions.append(
         formatFunctionDef(sig, dbody, self.llvmVersion))
     return name
Example #5
0
''')

reg('ml_getchar', types.Arrow(types.Unit(), types.Int), '''
declare i32 @getchar()
define %Int @ml_getchar(%voidptr, %Unit)
{
    %c32 = call i32 @getchar()
    %c64 = sext i32 %c32 to %Int
    ret %Int %c64
}
''')

reg('integer_negate', types.Arrow(types.Int, types.Int),
    lu.formatFunctionDef('%Int @integer_negate(%voidptr, %Int %n)',
        [inst.sub_nsw('%Int', 0, '%n', '%result'),
         inst.ret('%Int', '%result')], 0))

reg('~malloc', None, 'declare %voidptr @malloc(%size_t)')
reg('~free', None, 'declare void @free(%voidptr)')

def regBinaryIntOp(name, instr, type):
    ltype = type.llvm(None)
    mIntpair = types.Product(types.Int, types.Int)
    intpair = mIntpair.llvm(None)
    sig = '%s @%s(%%voidptr, %s %%args)' % (ltype, name, intpair)
    lines = [inst.extractvalue(intpair, '%args', 0, '%x'),
             inst.extractvalue(intpair, '%args', 1, '%y'),
             '%%result = %s %%Int %%x, %%y' % instr,
             inst.ret(ltype, '%result')]
    reg(name, types.Arrow(mIntpair, type), lu.formatFunctionDef(sig, lines, 0))
    
Example #6
0
    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)