예제 #1
0
파일: backend.py 프로젝트: gouarin/pythran
    def gen_for(self, node, target, local_iter, local_iter_decl, loop_body):
        """
        Create For representation on iterator for Cxx generation.

        Examples
        --------
        >> "omp parallel for"
        >> for i in xrange(10):
        >>     ... do things ...

        Becomes

        >> "omp parallel for shared(__iterX)"
        >> for(decltype(__iterX)::iterator __targetX = __iterX.begin();
               __targetX < __iterX.end(); ++__targetX)
        >>         typename decltype(__targetX)::reference i = *__targetX;
        >>     ... do things ...

        It the case of not local variable, typing for `i` disappear and typing
        is removed for iterator in case of yields statement in function.
        """
        # Choose target variable for iterator (which is iterator type)
        local_target = "__target{0}".format(len(self.break_handlers))
        local_target_decl = NamedType(
            "typename decltype({0})::iterator".format(local_iter))

        # For yield function, all variables are globals.
        if self.yields:
            self.extra_declarations.append((
                local_target,
                local_target_decl,
            ))
            local_target_decl = ""

        # If variable is local to the for body it's a ref to the iterator value
        # type
        if node.target.id in self.scope[node] and not self.yields:
            self.ldecls = {d for d in self.ldecls if d.id != node.target.id}
            local_type = "typename decltype({})::reference ".format(
                local_target)
        else:
            local_type = ""

        # Assign iterable value
        loop_body_prelude = Statement("{} {}= *{}".format(
            local_type, target, local_target))

        # Create the loop
        loop = For(
            "{0} {1} = {2}.begin()".format(local_target_decl, local_target,
                                           local_iter),
            "{0} < {1}.end()".format(local_target,
                                     local_iter), "++{0}".format(local_target),
            Block([loop_body_prelude, loop_body]))
        return [self.process_omp_attachements(node, loop)]
예제 #2
0
파일: backend.py 프로젝트: sthagen/pythran
    def gen_for(self, node, target, local_iter, local_iter_decl, loop_body):
        """
        Create For representation on iterator for Cxx generation.

        Examples
        --------
        >> "omp parallel for"
        >> for i in range(10):
        >>     ... do things ...

        Becomes

        >> "omp parallel for shared(__iterX)"
        >> for(decltype(__iterX)::iterator __targetX = __iterX.begin();
               __targetX < __iterX.end(); ++__targetX)
        >>         auto&& i = *__targetX;
        >>     ... do things ...

        It the case of not local variable, typing for `i` disappear and typing
        is removed for iterator in case of yields statement in function.
        """
        # Choose target variable for iterator (which is iterator type)
        local_target = "__target{0}".format(id(node))
        local_target_decl = self.types.builder.IteratorOfType(local_iter_decl)

        islocal = (node.target.id not in self.openmp_deps and
                   node.target.id in self.scope[node] and
                   not hasattr(self, 'yields'))
        # If variable is local to the for body it's a ref to the iterator value
        # type
        if islocal:
            local_type = "auto&&"
            self.ldecls.remove(node.target.id)
        else:
            local_type = ""

        # Assign iterable value
        loop_body_prelude = Statement("{} {}= *{}".format(local_type,
                                                          target,
                                                          local_target))

        # Create the loop
        assign = self.make_assign(local_target_decl, local_target, local_iter)
        loop = For("{}.begin()".format(assign),
                   "{0} < {1}.end()".format(local_target, local_iter),
                   "++{0}".format(local_target),
                   Block([loop_body_prelude, loop_body]))
        return [self.process_omp_attachements(node, loop)]
예제 #3
0
파일: backend.py 프로젝트: hmaarrfk/pythran
    def gen_c_for(self, node, local_iter, loop_body):
        """
        Create C For representation for Cxx generation.

        Examples
        --------
        >> for i in xrange(10):
        >>     ... do things ...

        Becomes

        >> for(long i = 0, __targetX = 10; i < __targetX; i += 1)
        >>     ... do things ...

        Or

        >> for i in xrange(10, 0, -1):
        >>     ... do things ...

        Becomes

        >> for(long i = 10, __targetX = 0; i > __targetX; i += -1)
        >>     ... do things ...


        It the case of not local variable, typing for `i` disappear
        """
        args = node.iter.args
        step = "1L" if len(args) <= 2 else self.visit(args[2])
        if len(args) == 1:
            lower_bound = "0L"
            upper_value = self.visit(args[0])
        else:
            lower_bound = self.visit(args[0])
            upper_value = self.visit(args[1])

        upper_bound = "__target{0}".format(id(node))

        upper_type = iter_type = "long "

        # If variable is local to the for body keep it local...
        if node.target.id in self.scope[node] and not hasattr(self, 'yields'):
            self.ldecls.remove(node.target.id)
            loop = list()
        else:
            # For yield function, upper_bound is globals.
            iter_type = ""
            # Back one step to keep Python behavior (except for break)
            loop = [
                If("{} == {}".format(local_iter, upper_bound),
                   Statement("{} -= {}".format(local_iter, step)))
            ]

        comparison = self.handle_real_loop_comparison(args, loop, local_iter,
                                                      upper_bound, step)

        forloop = For("{0} {1}={2}".format(iter_type, local_iter, lower_bound),
                      comparison, "{0} += {1}".format(local_iter,
                                                      step), loop_body)

        loop.insert(0, self.process_omp_attachements(node, forloop))

        # Store upper bound value
        assgnt = self.make_assign(upper_type, upper_bound, upper_value)
        header = [Statement(assgnt)]
        return header, loop
예제 #4
0
파일: backend.py 프로젝트: pbrunet/pythran
    def gen_c_for(self, node, local_iter, loop_body):
        """
        Create C For representation for Cxx generation.

        Examples
        --------
        >> for i in xrange(10):
        >>     ... do things ...

        Becomes

        >> for(long i = 0, __targetX = 10; i < __targetX; i += 1)
        >>     ... do things ...

        Or

        >> for i in xrange(10, 0, -1):
        >>     ... do things ...

        Becomes

        >> for(long i = 10, __targetX = 0; i > __targetX; i += -1)
        >>     ... do things ...

        Or

        >> for i in xrange(a, b, c):
        >>     ... do things ...

        Becomes

        >> std::function<bool(int, int)> __cmpX = std::less<long>();
        >> if(c < 0)
        >>     __cmpX = std::greater<long>();
        >> for(long i = a, __targetX = b; __cmpX(i, __targetX); i += c)
        >>     ... do things ...

        It the case of not local variable, typing for `i` disappear
        """
        args = node.iter.args
        step = "1L" if len(args) <= 2 else self.visit(args[2])
        if len(args) == 1:
            lower_bound = "0L"
            upper_value = self.visit(args[0])
        else:
            lower_bound = self.visit(args[0])
            upper_value = self.visit(args[1])

        upper_bound = "__target{0}".format(len(self.break_handlers))

        upper_type = iter_type = "long "

        # If variable is local to the for body keep it local...
        if node.target.id in self.scope[node] and not self.yields:
            self.ldecls = {d for d in self.ldecls if d.id != node.target.id}
            loop = list()
        else:
            # For yield function, upper_bound is globals.
            if self.yields:
                self.extra_declarations.append((upper_bound, upper_type))
                upper_type = ""
            iter_type = ""
            # Back one step to keep Python behavior (except for break)
            loop = [
                If("{} == {}".format(local_iter, upper_bound),
                   Statement("{} -= {}".format(local_iter, step)))
            ]

        comparison, for_pos = self.handle_real_loop_comparison(
            args, loop, local_iter, upper_bound, step)

        forloop = For(
            "{0} {1} = {2}".format(iter_type, local_iter, lower_bound),
            comparison, "{0} += {1}".format(local_iter, step), loop_body)

        loop.insert(for_pos, self.process_omp_attachements(node, forloop))

        # Store upper bound value
        header = [
            Statement("{0} {1} = {2}".format(upper_type, upper_bound,
                                             upper_value))
        ]
        return header, loop