Esempio n. 1
0
    def loop_block(self, node, block_size):
        outer_incr_name = cpp.CName(node.loopvar + node.loopvar)

        new_inner_for = cpp.For(
            node.loopvar,
            outer_incr_name,
            cpp.FunctionCall("min", [cpp.BinOp(outer_incr_name, 
                                               "+", 
                                               cpp.CNumber(block_size-1)), 
                                     node.end]),
            cpp.CNumber(1),
            node.body)

        new_outer_for = cpp.For(
            node.loopvar + node.loopvar,
            node.initial,
            node.end,
            cpp.BinOp(node.increment, "*", cpp.CNumber(block_size)),
            cpp.Block(contents=[new_inner_for]))
        debug_print(new_outer_for)
        return new_outer_for
Esempio n. 2
0
 def visit_CName(self, node):
     #print "node.name is ", node.name
     if node.name == self.loopvar:
         return cpp.BinOp(cpp.CName(self.loopvar), "+", cpp.CNumber(self.increment))
     else:
         return node
Esempio n. 3
0
    def unroll(self, node, factor):
        """Given a For node, unrolls the loop with a given factor.

        If the number of iterations in the given loop is not a multiple of
        the unroll factor, a 'leftover' loop will be generated to run the
        remaining iterations.

        """

        import copy

        # we can't precalculate the number of leftover iterations in the case that
        # the number of iterations are not known a priori, so we build an Expression
        # and let the compiler deal with it
        #leftover_begin = cpp.BinOp(cpp.CNumber(factor),
        #                           "*", 
        #                           cpp.BinOp(cpp.BinOp(node.end, "+", 1), "/", cpp.CNumber(factor)))


        # we begin leftover iterations at factor*( (end-initial+1) / factor ) + initial
        # note that this works due to integer division
        leftover_begin = cpp.BinOp(cpp.BinOp(cpp.BinOp(cpp.BinOp(cpp.BinOp(node.end, "-", node.initial),
                                                 "+",
                                                    cpp.CNumber(1)),
                                           "/",
                                           cpp.CNumber(factor)),
                                     "*",
                                     cpp.CNumber(factor)),
                               "+",
                               node.initial)

        new_limit = cpp.BinOp(node.end, "-", cpp.CNumber(factor-1))
        
#        debug_print("Loop unroller called with ", node.loopvar)
#        debug_print("Number of iterations: ", num_iterations)
#        debug_print("Number of unrolls: ", num_unrolls)
#        debug_print("Leftover iterations: ", leftover)

        new_increment = cpp.BinOp(node.increment, "*", cpp.CNumber(factor))

        new_block = cpp.Block(contents=node.body.contents)
        for x in xrange(1, factor):
            new_extension = copy.deepcopy(node.body)
            new_extension = LoopUnroller.UnrollReplacer(node.loopvar, x).visit(new_extension)
            new_block.extend(new_extension.contents)

        return_block = cpp.UnbracedBlock()

        unrolled_for_node = cpp.For(
            node.loopvar,
            node.initial,
            new_limit,
            #node.end,
            new_increment,
            new_block)

        leftover_for_node = cpp.For(
            node.loopvar,
            leftover_begin,
            node.end,
            node.increment,
            node.body)


        return_block.append(unrolled_for_node)

        # if we *know* this loop has no leftover iterations, then
        # we return without the leftover loop
        if not (isinstance(node.initial, cpp.CNumber) and isinstance(node.end, cpp.CNumber) and
           ((node.end.num - node.initial.num + 1) % factor == 0)):
            return_block.append(leftover_for_node)

        return return_block
Esempio n. 4
0
 def visit_BinOp(self, node):
     return cpp.BinOp(self.visit(node.left),
                      self.visit(node.op),
                      self.visit(node.right))