Esempio n. 1
0
    def match_mems(self, match, loc, mem1, mem2, V1):

        # Go through all variables
        for var1 in V1 | SPECIAL_VARS:

            # Ignored vars
            if self.ignoreret and var1 == VAR_RET:
                continue
            if self.ignoreio and var1 in [VAR_IN, VAR_OUT]:
                continue

            # If var1 not matched yet, build a list of potential matches
            if var1 not in match:
                if var1 in SPECIAL_VARS:
                    match[var1] = set([var1])
                else:
                    match[var1] = {
                        var2
                        for var2 in mem2.keys() if not isprimed(var2)
                    }

            # Check list of potential matches
            newmatch = set([])
            varp1 = prime(var1)
            for var2 in match[var1]:
                varp2 = prime(var2)

                # Get values
                val1 = mem1.get(varp1, UndefValue())
                val2 = mem2.get(varp2, UndefValue())

                # Debug vars
                if self.debugvar == '%s-%s' % (loc, var1):
                    self.debug('VAR %s = %s', var1, val1)
                    self.debug('VAR %s = %s', var2, val2)
                    if isundef(val1) or val1 == val2:
                        self.debug('VAR equal')
                    else:
                        self.debug('VAR unequal')
                    self.debug('')

                # Check if equal
                # TODO: Different equality?
                if isundef(val1) or val1 == val2:
                    newmatch.add(var2)

            # If no match for then done
            if len(newmatch) == 0:
                self.debug("Couldn find match for %s-%s", loc, var1)
                return False
            # Otherwise replace with new matches
            else:
                match[var1] = newmatch

        return True
Esempio n. 2
0
    def procmem(self, mem):
        newmem = dict()

        for var, val in mem.items():
            if isprimed(var):
                var = unprime(var)
                newmem[var] = deepcopy(val)
            else:
                varp = prime(var)
                if varp not in mem:
                    newmem[var] = deepcopy(val)
                    mem[varp] = deepcopy(val)

        return newmem, mem
Esempio n. 3
0
    def procmem(self, mem):
        newmem = dict()

        for var, val in mem.items():
            if isprimed(var):
                var = unprime(var)
                newmem[var] = deepcopy(val)
            else:
                varp = prime(var)
                if varp not in mem:
                    newmem[var] = deepcopy(val)
                    mem[varp] = deepcopy(val)

        return newmem, mem
Esempio n. 4
0
    def islarge(self):
        '''
        Decides if generated repair is large
        (new variable, new statement, swapped statements)
        '''
        
        for fnc, (m, repairs, sm) in self.results.items():
            for rep in repairs:
                
                loc1 = rep.loc1
                var1 = rep.var1
                var2 = rep.var2
                expr1 = rep.expr1
                
                loc2 = sm[loc1]

                # Added/deleted variable
                if var2 == '*':
                    return True
                if var1 == '-':
                    return False

                # Added stmt
                if self.spec.getfnc(fnc).hasexpr(loc1, var1) \
                   and (not self.impl.getfnc(fnc).hasexpr(loc2, var2)):
                    return True

                # Swapped stmts
                #expr1 = self.spec.getfnc(fnc).getexpr(loc1, var1)
                expr2 = self.impl.getfnc(fnc).getexpr(loc2, var2)
                vars1 = expr1.vars()
                vars2 = expr2.vars()

                for var1 in vars1:
                    if isprimed(var1):
                        var1 = unprime(var1)
                        var2m = m[var1]
                        var2mp = prime(var2m)
                        if var2m in vars2 and var2mp not in vars2:
                            return True
                    else:
                        var2m = m[var1]
                        var2mp = prime(var2m)
                        if var2mp in vars2 and var2m not in vars2:
                            return True

        # Nothing found
        return False
Esempio n. 5
0
    def islarge(self):
        '''
        Decides if generated repair is large
        (new variable, new statement, swapped statements)
        '''

        for fnc, (m, repairs, sm) in self.results.items():
            for rep in repairs:

                loc1 = rep.loc1
                var1 = rep.var1
                var2 = rep.var2
                expr1 = rep.expr1

                loc2 = sm[loc1]

                # Added/deleted variable
                if var2 == '*':
                    return True
                if var1 == '-':
                    return False

                # Added stmt
                if self.spec.getfnc(fnc).hasexpr(loc1, var1) \
                   and (not self.impl.getfnc(fnc).hasexpr(loc2, var2)):
                    return True

                # Swapped stmts
                #expr1 = self.spec.getfnc(fnc).getexpr(loc1, var1)
                expr2 = self.impl.getfnc(fnc).getexpr(loc2, var2)
                vars1 = expr1.vars()
                vars2 = expr2.vars()

                for var1 in vars1:
                    if isprimed(var1):
                        var1 = unprime(var1)
                        var2m = m[var1]
                        var2mp = prime(var2m)
                        if var2m in vars2 and var2mp not in vars2:
                            return True
                    else:
                        var2m = m[var1]
                        var2mp = prime(var2m)
                        if var2mp in vars2 and var2m not in vars2:
                            return True

        # Nothing found
        return False
Esempio n. 6
0
    def f(l1, l2):
        if not l1:
            return 0 if (not l2) else 1
        if not l2:
            return 0 if (not l1) else 1

        (t1, v1) = l1
        (t2, v2) = l2

        if t1 != t2:
            return 1

        if t2 == 'V':
            if isprimed(v2):
                v2 = prime(m.get(unprime(v2), 'X'))
            else:
                v2 = m.get(v2, 'X')

        return 0 if v1 == v2 else 1
Esempio n. 7
0
    def f(l1, l2):
        if not l1:
            return 0 if (not l2) else 1
        if not l2:
            return 0 if (not l1) else 1

        (t1, v1) = l1
        (t2, v2) = l2

        if t1 != t2:
            return 1

        if t2 == 'V':
            if isprimed(v2):
                v2 = prime(m.get(unprime(v2), 'X'))
            else:
                v2 = m.get(v2, 'X')

        return 0 if v1 == v2 else 1
Esempio n. 8
0
 def getorder(self, var, expr, m):
     if var == '*' or var in SPECIAL_VARS:
         return []
     vars = expr.vars()
     order = []
     for var2 in vars:
         if isprimed(var2):
             var2 = unprime(var2)
             var2 = m[var2]
             if var2 == '*':
                 continue
             if var == var2:
                 return None
             order.append((var2, var))
         else:
             var2 = m[var2]
             if var2 == '*':
                 continue
             if var != var2 and var2 != '*':
                 order.append((var, var2))
     order.sort()
     return order
Esempio n. 9
0
 def getorder(self, var, expr, m):
     if var == '*' or var in SPECIAL_VARS:
         return []
     vars = expr.vars()
     order = []
     for var2 in vars:
         if isprimed(var2):
             var2 = unprime(var2)
             var2 = m[var2]
             if var2 == '*':
                 continue
             if var == var2:
                 return None
             order.append((var2, var))
         else:
             var2 = m[var2]
             if var2 == '*':
                 continue
             if var != var2 and var2 != '*':
                 order.append((var, var2))
     order.sort()
     return order
Esempio n. 10
0
 def unprimedvars(self, expr):
     return set(map(lambda x: unprime(x)
                    if isprimed(x) else x, expr.vars()))
Esempio n. 11
0
    def gethint(self, expr1, expr2, first=False):
        '''
        Tries to generate some useful hints
        '''

        #  Output
        if self.isout(expr1):
            return self.getouthint(expr1, expr2)

        # Constant
        if isinstance(expr1, Const):
            if isinstance(expr2, Const):
                if expr1.value != expr2.value:
                    return "use the constant '%s' intead of '%s'" % (
                        expr1.value,
                        expr2.value,
                    )
                else:
                    return
            elif isinstance(expr2, Var):
                return "use some constant instead of the variable '%s'" % (
                    expr2.name, )

            else:
                if first:
                    return 'use a just constant'
                else:
                    return

        # Check for changing an order of statement
        vars1 = expr1.vars()
        vars2 = expr2.vars()
        for var1 in vars1:
            if isprimed(var1):
                if unprime(var1) in vars2:
                    return "try changing the order of statements by moving it after the assignment to '%s', or vice-versa" % (
                        unprime(var1), )
            else:
                if prime(var1) in vars2:
                    return "try changing the order of statements by moving it before the assignment to '%s', or vice-versa" % (
                        var1, )

        # Different variable name
        if isinstance(expr1, Var):
            if isinstance(expr2, Var):
                if expr1.name != expr2.name:
                    if expr1.name.startswith('$new'):
                        return "use a different variable instead of '%s'" % (
                            expr2.name, )
                    else:
                        return "use the variable '%s', instead of '%s'" % (
                            expr1.name,
                            expr2.name,
                        )
                else:
                    return
            else:
                if isinstance(expr2, Const):
                    return "replace the constant '%s' by some variable" % (
                        expr2.value, )

                if first:
                    return 'use just a variable'
                else:
                    return

        # Operation comparison
        if isinstance(expr1, Op):

            if isinstance(expr2, Op):

                # Operators
                for opname, ops in self.opdefs:
                    if expr1.name in ops and len(expr1.args) == 2:
                        if expr2.name in ops and len(expr2.args) == 2:

                            same1 = self.issame(expr1.args[0], expr2.args[0])
                            same2 = self.issame(expr1.args[1], expr2.args[1])

                            # Different operators
                            if same1 and same2 and expr1.name != expr2.name:
                                return "use a different %s operator instead of '%s'" % (
                                    opname,
                                    expr2.name,
                                )

                            # Different right side
                            if same1 and expr1.name == expr2.name:
                                h = self.gethint(expr1.args[1], expr2.args[1])
                                if h:
                                    return h

                            # Different left side
                            if same2 and expr1.name == expr2.name:
                                h = self.gethint(expr1.args[0], expr2.args[0])
                                if h:
                                    return h

                            # if first and expr1.name == expr2.name:
                            #     h1 = self.gethint(expr1.args[0], expr2.args[0])
                            #     h2 = self.gethint(expr1.args[1], expr2.args[1])
                            #     if h1 and h2:
                            #         return '%s and %s' % (h1, h2)

            if first and expr1.name == 'ite':
                h = self.ite_hint(expr1, expr2)
                if h:
                    return h

        # Nothing else to do, except to generate a template
        if first:
            t = self.gettemplate(expr1, expr2, outer=True)
            if t:
                return self.templatetext(t)
Esempio n. 12
0
    def match_mems(self, match, loc, mem1, mem2, V1):

        V2 = ({var2 for var2 in mem2.keys() if not isprimed(var2)}
              - SPECIAL_VARS)

        if self.bijective:
            if len(V1 | SPECIAL_VARS) != len(V2 | SPECIAL_VARS):
                self.debug('Not bijective - different number of variables')
                return False

        # Go through all variables
        for var1 in V1 | SPECIAL_VARS:

            # Ignored vars
            if self.ignoreret and var1 == VAR_RET:
                continue
            if self.ignoreio and var1 in [VAR_IN, VAR_OUT]:
                continue

            # If var1 not matched yet, build a list of potential matches
            if var1 not in match:
                if var1 in SPECIAL_VARS:
                    match[var1] = set([var1])
                else:
                    match[var1] = set(V2)

            # Check list of potential matches
            newmatch = set([])
            varp1 = prime(var1)
            for var2 in match[var1]:
                varp2 = prime(var2)

                if var1.startswith('ind#') != var2.startswith('ind#'):
                    continue

                if var1.startswith('iter#') != var2.startswith('iter#'):
                    continue

                # Get values
                val1 = mem1.get(varp1, UndefValue())
                val2 = mem2.get(varp2, UndefValue())

                # Debug vars
                if self.debugvar == '%s-%s' % (loc, var1):
                    self.debug('VAR %s = %s', var1, val1)
                    self.debug('VAR %s = %s', var2, val2)
                    if isundef(val1) or equals(val1, val2):
                        self.debug('VAR equal')
                    else:
                        self.debug('VAR unequal')
                    self.debug('')
                
                # Check if equal
                if isundef(val1) or equals(val1, val2):
                    newmatch.add(var2)

            # If no match for then done
            if len(newmatch) == 0:
                self.debug("Couldn find match for %s-%s", loc, var1)
                return False
            # Otherwise replace with new matches
            else:
                match[var1] = newmatch

        return True
Esempio n. 13
0
def unprimes(x):
    return unprime(x) if isprimed(x) else x
Esempio n. 14
0
 def unprimedvars(self, expr):
     return set(map(lambda x: unprime(x) if isprimed(x) else x,
                    expr.vars()))
Esempio n. 15
0
    def gethint(self, expr1, expr2, first=False):
        '''
        Tries to generate some useful hints
        '''

        #  Output
        if self.isout(expr1):
            return self.getouthint(expr1, expr2)

        # Constant
        if isinstance(expr1, Const):
            if isinstance(expr2, Const):    
                if expr1.value != expr2.value:
                    return "use the constant '%s' intead of '%s'" % (
                        expr1.value, expr2.value,)
                else:
                    return
            elif isinstance(expr2, Var):
                return "use some constant instead of the variable '%s'" % (expr2.name,)
            
            else:
                if first:
                    return 'use a just constant'
                else:
                    return

        # Check for changing an order of statement
        vars1 = expr1.vars()
        vars2 = expr2.vars()
        for var1 in vars1:
            if isprimed(var1):
                if unprime(var1) in vars2:
                    return "try changing the order of statements by moving it after the assignment to '%s', or vice-versa" % (unprime(var1),)
            else:
                if prime(var1) in vars2:
                    return "try changing the order of statements by moving it before the assignment to '%s', or vice-versa" % (var1,)

        # Different variable name
        if isinstance(expr1, Var):
            if isinstance(expr2, Var):
                if expr1.name != expr2.name:
                    if expr1.name.startswith('$new'):
                        return "use a different variable instead of '%s'" % (
                            expr2.name,)
                    else:
                        return "use the variable '%s', instead of '%s'" % (
                            expr1.name, expr2.name,)
                else:
                    return
            else:
                if isinstance(expr2, Const):
                    return "replace the constant '%s' by some variable" % (expr2.value,)
                
                if first:
                    return 'use just a variable'
                else:
                    return

        # Operation comparison
        if isinstance(expr1, Op):

            if isinstance(expr2, Op):
                
                # Operators
                for opname, ops in self.opdefs:
                    if expr1.name in ops and len(expr1.args) == 2:
                        if expr2.name in ops and len(expr2.args) == 2:

                            same1 = self.issame(expr1.args[0], expr2.args[0])
                            same2 = self.issame(expr1.args[1], expr2.args[1])
                
                            # Different operators
                            if same1 and same2 and expr1.name != expr2.name:
                                return "use a different %s operator instead of '%s'" % (
                                    opname, expr2.name,)
                            
                            # Different right side
                            if same1 and expr1.name == expr2.name:
                                h = self.gethint(expr1.args[1], expr2.args[1])
                                if h:
                                    return h

                            # Different left side
                            if same2 and expr1.name == expr2.name:
                                h = self.gethint(expr1.args[0], expr2.args[0])
                                if h:
                                    return h
                                
                            # if first and expr1.name == expr2.name:
                            #     h1 = self.gethint(expr1.args[0], expr2.args[0])
                            #     h2 = self.gethint(expr1.args[1], expr2.args[1])
                            #     if h1 and h2:
                            #         return '%s and %s' % (h1, h2)

            if first and expr1.name == 'ite':
                h = self.ite_hint(expr1, expr2)
                if h:
                    return h

        # Nothing else to do, except to generate a template
        if first:
            t = self.gettemplate(expr1, expr2, outer=True)
            if t:
                return self.templatetext(t)
Esempio n. 16
0
def unprimes(x):
    return unprime(x) if isprimed(x) else x