Esempio n. 1
0
 def test_index_var_basic(self):
     b = FakeBox()
     i = IndexVar(b,1,1,0)
     j = IndexVar(b,1,1,0)
     assert i.is_identity()
     assert i.same_variable(j)
     assert i.constant_diff(j) == 0
Esempio n. 2
0
 def __init__(self, index, op, cmp_op, index_vars):
     self.index = index
     self.op = op
     self.cmp_op = cmp_op
     lhs = cmp_op.getarg(0)
     self.lhs = index_vars.get(lhs, None)
     if self.lhs is None:
         self.lhs = IndexVar(lhs)
     #
     rhs = cmp_op.getarg(1)
     self.rhs = index_vars.get(rhs, None)
     if self.rhs is None:
         self.rhs = IndexVar(rhs)
Esempio n. 3
0
 def __init__(self, index, op, cmp_op, index_vars):
     self.index = index
     self.op = op
     self.cmp_op = cmp_op
     lhs = cmp_op.getarg(0)
     self.lhs = index_vars.get(lhs, None)
     if self.lhs is None:
         self.lhs = IndexVar(lhs)
     #
     rhs = cmp_op.getarg(1)
     self.rhs = index_vars.get(rhs, None)
     if self.rhs is None:
         self.rhs = IndexVar(rhs)
Esempio n. 4
0
 def test_index_var_diff(self):
     b = FakeBox()
     i = IndexVar(b, 4, 2, 0)
     j = IndexVar(b, 1, 1, 1)
     assert not i.is_identity()
     assert not j.is_identity()
     assert not i.same_mulfactor(j)
     assert i.constant_diff(j) == -1
Esempio n. 5
0
def memoryref(array, var, mod=(1,1,0), descr=None, raw=False):
    if descr is None:
        descr = FLOAT
    mul, div, off = mod
    op = FakeMemoryRefResOp(array, descr)
    return MemoryRef(op,
                     IndexVar(var, mul, div, off),
                     raw)
Esempio n. 6
0
 def test_index_var_basic(self):
     b = FakeBox()
     i = IndexVar(b, 1, 1, 0)
     j = IndexVar(b, 1, 1, 0)
     assert i.is_identity()
     assert i.same_variable(j)
     assert i.constant_diff(j) == 0
Esempio n. 7
0
 def test_index_var_diff(self):
     b = FakeBox()
     i = IndexVar(b,4,2,0)
     j = IndexVar(b,1,1,1)
     assert not i.is_identity()
     assert not j.is_identity()
     assert not i.same_mulfactor(j)
     assert i.constant_diff(j) == -1
Esempio n. 8
0
def iv(value, coeff=(1, 1, 0)):
    var = IndexVar(value)
    var.coefficient_mul = coeff[0]
    var.coefficient_div = coeff[1]
    var.constant = coeff[2]
    return var
Esempio n. 9
0
class Guard(object):
    """ An object wrapper around a guard. Helps to determine
        if one guard implies another
    """
    _attrs_ = ('index', 'op', 'cmp_op', 'rhs', 'lhs')

    def __init__(self, index, op, cmp_op, index_vars):
        self.index = index
        self.op = op
        self.cmp_op = cmp_op
        lhs = cmp_op.getarg(0)
        self.lhs = index_vars.get(lhs, None)
        if self.lhs is None:
            self.lhs = IndexVar(lhs)
        #
        rhs = cmp_op.getarg(1)
        self.rhs = index_vars.get(rhs, None)
        if self.rhs is None:
            self.rhs = IndexVar(rhs)

    def setindex(self, index):
        self.index = index

    def setoperation(self, op):
        self.op = op

    def setcmp(self, c):
        self.cmp_op = c

    def getleftkey(self):
        return self.lhs.getvariable()

    def getrightkey(self):
        return self.rhs.getvariable()

    def implies(self, guard, opt=None):
        if self.op.getopnum() != guard.op.getopnum():
            return False

        if self.getleftkey() is guard.getleftkey():
            # same operation
            valid, lc = self.lhs.compare(guard.lhs)
            if not valid: return False
            valid, rc = self.rhs.compare(guard.rhs)
            if not valid: return False
            opnum = self.get_compare_opnum()
            if opnum == -1:
                return False
            # x < y  = -1,-2,...
            # x == y = 0
            # x > y  = 1,2,...
            if opnum in (rop.INT_LE, rop.INT_LT):
                return (lc >= 0 and rc <= 0)
            if opnum in (rop.INT_GE, rop.INT_GT):
                return (lc <= 0 and rc >= 0)
        return False

    def transitive_imply(self, other, opt, loop):
        if self.op.getopnum() != other.op.getopnum():
            # stronger restriction, intermixing e.g. <= and < would be possible
            return None
        if self.getleftkey() is not other.getleftkey():
            return None
        if not self.rhs.is_identity():
            # stronger restriction
            return None
        # this is a valid transitive guard that eliminates the loop guard
        opnum = self.transitive_cmpop(self.cmp_op.getopnum())
        box_rhs = self.emit_varops(opt, self.rhs, self.cmp_op.getarg(1))
        other_rhs = self.emit_varops(opt, other.rhs, other.cmp_op.getarg(1))
        compare = ResOperation(opnum, [box_rhs, other_rhs])
        opt.emit_operation(compare)
        # guard
        descr = CompileLoopVersionDescr()
        descr.copy_all_attributes_from(self.op.getdescr())
        descr.rd_vector_info = None # do not copy the accum list
        assert isinstance(descr, AbstractFailDescr)
        guard = ResOperation(self.op.getopnum(), [compare], descr=descr)
        guard.setfailargs(loop.label.getarglist_copy())
        opt.emit_operation(guard)

        return guard

    def transitive_cmpop(self, opnum):
        if opnum == rop.INT_LT:
            return rop.INT_LE
        if opnum == rop.INT_GT:
            return rop.INT_GE
        return opnum

    def get_compare_opnum(self):
        opnum = self.op.getopnum()
        if opnum == rop.GUARD_TRUE:
            return self.cmp_op.getopnum()
        else:
            return self.cmp_op.boolinverse

    def inhert_attributes(self, other):
        myop = self.op
        otherop = other.op
        assert isinstance(otherop, GuardResOp)
        assert isinstance(myop, GuardResOp)
        self.index = other.index

        descr = myop.getdescr()
        descr.copy_all_attributes_from(other.op.getdescr())
        myop.rd_frame_info_list = otherop.rd_frame_info_list
        myop.setfailargs(otherop.getfailargs()[:])
        myop.rd_snapshot = otherop.rd_snapshot

    def emit_varops(self, opt, var, old_arg):
        assert isinstance(var, IndexVar)
        if var.is_identity():
            return var.var
        box = var.emit_operations(opt)
        opt.renamer.start_renaming(old_arg, box)
        return box

    def emit_operations(self, opt):
        # create trace instructions for the index
        lhs = self.emit_varops(opt, self.lhs, self.cmp_op.getarg(0))
        rhs = self.emit_varops(opt, self.rhs, self.cmp_op.getarg(1))
        opnum = self.cmp_op.getopnum()
        cmp_op = ResOperation(opnum, [lhs, rhs])
        opt.emit_operation(cmp_op)
        # emit that actual guard
        guard = ResOperation(self.op.getopnum(), [cmp_op], self.op.getdescr())
        guard.setfailargs(self.op.getfailargs()[:])
        opt.emit_operation(guard)
        self.setindex(opt.operation_position()-1)
        self.setoperation(guard)
        self.setcmp(cmp_op)

    def set_to_none(self, info, loop):
        operations = loop.operations
        assert operations[self.index] is self.op
        operations[self.index] = None
        descr = self.op.getdescr()
        if operations[self.index-1] is self.cmp_op:
            operations[self.index-1] = None

    @staticmethod
    def of(boolarg, operations, index, index_vars):
        guard_op = operations[index]
        cmp_op = guard_op.getarg(0)
        if not (rop.INT_LT <= cmp_op.getopnum() <= rop.INT_GE):
            return None
        return Guard(index, guard_op, cmp_op, index_vars)
Esempio n. 10
0
class Guard(object):
    """ An object wrapper around a guard. Helps to determine
        if one guard implies another
    """
    _attrs_ = ('index', 'op', 'cmp_op', 'rhs', 'lhs')

    def __init__(self, index, op, cmp_op, index_vars):
        self.index = index
        self.op = op
        self.cmp_op = cmp_op
        lhs = cmp_op.getarg(0)
        self.lhs = index_vars.get(lhs, None)
        if self.lhs is None:
            self.lhs = IndexVar(lhs)
        #
        rhs = cmp_op.getarg(1)
        self.rhs = index_vars.get(rhs, None)
        if self.rhs is None:
            self.rhs = IndexVar(rhs)

    def setindex(self, index):
        self.index = index

    def setoperation(self, op):
        self.op = op

    def setcmp(self, c):
        self.cmp_op = c

    def getleftkey(self):
        return self.lhs.getvariable()

    def getrightkey(self):
        return self.rhs.getvariable()

    def implies(self, guard, opt=None):
        if self.op.getopnum() != guard.op.getopnum():
            return False

        if self.getleftkey() is guard.getleftkey():
            # same operation
            valid, lc = self.lhs.compare(guard.lhs)
            if not valid: return False
            valid, rc = self.rhs.compare(guard.rhs)
            if not valid: return False
            opnum = self.get_compare_opnum()
            if opnum == -1:
                return False
            # x < y  = -1,-2,...
            # x == y = 0
            # x > y  = 1,2,...
            if opnum in (rop.INT_LE, rop.INT_LT):
                return (lc >= 0 and rc <= 0)
            if opnum in (rop.INT_GE, rop.INT_GT):
                return (lc <= 0 and rc >= 0)
        return False

    def transitive_imply(self, other, opt, loop):
        if self.op.getopnum() != other.op.getopnum():
            # stronger restriction, intermixing e.g. <= and < would be possible
            return None
        if self.getleftkey() is not other.getleftkey():
            return None
        if not self.rhs.is_identity():
            # stronger restriction
            return None
        # this is a valid transitive guard that eliminates the loop guard
        opnum = self.transitive_cmpop(self.cmp_op.getopnum())
        box_rhs = self.emit_varops(opt, self.rhs, self.cmp_op.getarg(1))
        other_rhs = self.emit_varops(opt, other.rhs, other.cmp_op.getarg(1))
        compare = ResOperation(opnum, [box_rhs, other_rhs])
        opt.emit_operation(compare)
        # guard
        descr = CompileLoopVersionDescr()
        descr.copy_all_attributes_from(self.op.getdescr())
        descr.rd_vector_info = None  # do not copy the accum list
        assert isinstance(descr, AbstractFailDescr)
        guard = ResOperation(self.op.getopnum(), [compare], descr=descr)
        guard.setfailargs(loop.label.getarglist_copy())
        opt.emit_operation(guard)

        return guard

    def transitive_cmpop(self, opnum):
        if opnum == rop.INT_LT:
            return rop.INT_LE
        if opnum == rop.INT_GT:
            return rop.INT_GE
        return opnum

    def get_compare_opnum(self):
        opnum = self.op.getopnum()
        if opnum == rop.GUARD_TRUE:
            return self.cmp_op.getopnum()
        else:
            return self.cmp_op.boolinverse

    def inhert_attributes(self, other):
        myop = self.op
        otherop = other.op
        assert isinstance(otherop, GuardResOp)
        assert isinstance(myop, GuardResOp)
        self.index = other.index

        descr = myop.getdescr()
        descr.copy_all_attributes_from(other.op.getdescr())
        # TODO myop.rd_frame_info_list = otherop.rd_frame_info_list
        myop.setfailargs(otherop.getfailargs()[:])
        # TODO myop.rd_snapshot = otherop.rd_snapshot

    def emit_varops(self, opt, var, old_arg):
        assert isinstance(var, IndexVar)
        if var.is_identity():
            return var.var
        box = var.emit_operations(opt)
        opt.renamer.start_renaming(old_arg, box)
        return box

    def emit_operations(self, opt):
        # create trace instructions for the index
        lhs = self.emit_varops(opt, self.lhs, self.cmp_op.getarg(0))
        rhs = self.emit_varops(opt, self.rhs, self.cmp_op.getarg(1))
        opnum = self.cmp_op.getopnum()
        cmp_op = ResOperation(opnum, [lhs, rhs])
        opt.emit_operation(cmp_op)
        # emit that actual guard
        guard = ResOperation(self.op.getopnum(), [cmp_op], self.op.getdescr())
        guard.setfailargs(self.op.getfailargs()[:])
        opt.emit_operation(guard)
        self.setindex(opt.operation_position() - 1)
        self.setoperation(guard)
        self.setcmp(cmp_op)

    def set_to_none(self, info, loop):
        operations = loop.operations
        assert operations[self.index] is self.op
        operations[self.index] = None
        descr = self.op.getdescr()
        if operations[self.index - 1] is self.cmp_op:
            operations[self.index - 1] = None

    @staticmethod
    def of(boolarg, operations, index, index_vars):
        guard_op = operations[index]
        cmp_op = guard_op.getarg(0)
        if not (rop.INT_LT <= cmp_op.getopnum() <= rop.INT_GE):
            return None
        return Guard(index, guard_op, cmp_op, index_vars)
Esempio n. 11
0
def iv(value, coeff=(1,1,0)):
    var = IndexVar(value)
    var.coefficient_mul = coeff[0]
    var.coefficient_div = coeff[1]
    var.constant = coeff[2]
    return var