コード例 #1
0
 def visit_If(self, node):
     test = self.visit(node.test)
     body = cpp.Block([self.visit(x) for x in node.body])
     if node.orelse == []:
         orelse = None
     else:
         orelse = cpp.Block([self.visit(x) for x in node.orelse])
     return cpp.IfConv(test, body, orelse)
コード例 #2
0
        def visit_Block(self, node):
            #print "visiting Block...."
            if self.inside_for:
                old_scope = self.in_new_scope
                self.in_new_scope = True
                #print "visiting block in ", node
                contents = [self.visit(x) for x in node.contents]
                retnode = cpp.Block(contents=[x for x in contents if x != None])
                self.in_new_scope = old_scope
            else:
                self.inside_for = True
                contents = [self.visit(x) for x in node.contents]
                retnode = cpp.Block(contents=[x for x in contents if x != None])

            return retnode
コード例 #3
0
 def visit_FunctionDef(self, node):
     debug_print("In FunctionDef:")
     debug_print(ast.dump(node))
     debug_print("----")
     return cpp.FunctionBody(cpp.FunctionDeclaration(cpp.Value("void",
                                                               node.name),
                                                     self.visit(node.args)),
                             cpp.Block([self.visit(x) for x in node.body]))
コード例 #4
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
コード例 #5
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