Esempio n. 1
0
def heapRefcountIncrement(addr, ptrType, cx):
    p, count, plus1 = cx.local(), cx.local(), cx.local()
    return getPtrToRefcount(addr, ptrType, cx, p) + [
        inst.load('%size_t', p, count),
        '%s = add nuw %%size_t 1, %s' % (plus1, count),
        inst.store('%size_t', plus1, p)
    ]
Esempio n. 2
0
def heapRefcountDecrement(refcAddr, destroyCode, cx):
    count, minus1, isZero = cx.local(), cx.local(), cx.local()
    return [
        inst.load('%size_t', refcAddr, count),
        '%s = sub nuw %%size_t %s, 1' % (minus1, count),
        '%s = icmp eq %%size_t 0, %s' % (isZero, minus1)
    ] + lu.ifThenElse(isZero, destroyCode,
                      [inst.store('%size_t', minus1, refcAddr)], cx)
Esempio n. 3
0
 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)
Esempio n. 4
0
 def destroySide(i):
     lt_i = mtype.parms[i].llvm(cx)
     sst = lu.sumSideType(lt_i)
     r, sp, mp = cx.local(), cx.local(), cx.local()
     unrefCode = unreference(r, mtype.parms[i], cx)
     if not unrefCode: return []
     return [
         inst.bitcast('i1*', lt.Pointer(sst, cx), '%object', sp),
         inst.structGEP(sp, sst, mp, 1),
         inst.load(lt_i, mp, r)
     ] + unrefCode
Esempio n. 5
0
def destroyClosure(refcAddr, cx):  # assuming nonnull
    cdt = closureDestructorType(cx)
    sizep, funcpp, funcp, voidp = cx.local(), cx.local(), cx.local(), cx.local(
    )
    cx.useBuiltin('~free')
    return [
        inst.linearGEP(refcAddr, '%size_t', sizep, -1),
        inst.bitcast('%size_t*', lt.Pointer(cdt, cx), sizep, funcpp),
        inst.load(cdt, funcpp, funcp),
        inst.bitcast('%size_t*', '%voidptr', sizep, voidp),
        'call void %s(%%voidptr %s)' % (funcp, voidp)
    ]
Esempio n. 6
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)
Esempio n. 7
0
def getSumTypeSelector(s, cx, out):
    return [inst.load('i1', s, out)]
Esempio n. 8
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)
Esempio n. 9
0
 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)