Changeset 2269 for proto/Compiler


Ignore:
Timestamp:
Aug 6, 2012, 1:45:53 PM (7 years ago)
Author:
cameron
Message:

Implement special-case while optimization

File:
1 edited

Legend:

Unmodified
Added
Removed
  • proto/Compiler/pablo.py

    r2265 r2269  
    514514    if self.last_stmt.targets[0].id != test_var: return False
    515515    if whileNode.body[-1].targets[0].id != test_var: return False
    516     # Probably the following test won't work, because last_stmt is already
    517     # modified.
    518     #if CarryCounter().count(self.last_stmt) != 1: return False
     516    if self.last_stmt_carries != 1: return False
    519517    if CarryCounter().count(whileNode.body[-1]) != 1: return False
    520518    return True
     
    528526    assert adv_nCounter().count(whileNode) == 0, "Advance(x,n) within while: illegal\n"
    529527    carries = CarryCounter().count(whileNode)
     528#   Special Case Recognition
     529    is_special = self.is_while_special_case(whileNode)
    530530    #CARRYSET
    531531    if carries == 0: return whileNode
    532 #   Special Case Recognition and Optimization
    533 #    if self.is_while_special_case(whileNode):
    534 #           print "Special case identified, m = %s\n" % original_test_expr.id
    535     carry_arglist = [ast.Num(carry_base), ast.Num(carries)]
    536532    local_carryvar = 'sub' + self.carryvar.id
    537533    inner_while = CarryIntro(local_carryvar, '', self.carryout).generic_xfrm(copy.deepcopy(whileNode))
     
    542538    inner_while.body.append(final_combine)
    543539    #CARRYSET
     540
     541#   Special Case Optimization
     542    if is_special:
     543      # We combine the final carry into the one preceeding the loop.
     544      combine1 = mkCallStmt(ast.Attribute(self.carryvar, 'CarryCombine1', ast.Load()), [ast.Num(carry_base-1), ast.Num(carry_base+carries-1)])
     545      while_body_extend = [inner_while, combine1]
     546      # The carry test can skip the final case.
     547      carry_test_arglist = [ast.Num(carry_base), ast.Num(carries-1)]
     548    else:
     549      carry_test_arglist = [ast.Num(carry_base), ast.Num(carries)]
     550      while_body_extend = [inner_while]
     551
    544552    if self.carryin == '': new_test = whileNode.test
    545     else: new_test = ast.BoolOp(ast.Or(), [whileNode.test, mkCall(ast.Attribute(self.carryvar, 'CarryTest', ast.Load()), carry_arglist)])
    546     else_part = [mkCallStmt(ast.Attribute(self.carryvar, 'CarryDequeueEnqueue', ast.Load()), carry_arglist)]   
    547     newIf = ast.If(new_test, whileNode.body + [inner_while], else_part)
     553    else: new_test = ast.BoolOp(ast.Or(), [whileNode.test, mkCall(ast.Attribute(self.carryvar, 'CarryTest', ast.Load()), carry_test_arglist)])
     554    else_part = [mkCallStmt(ast.Attribute(self.carryvar, 'CarryDequeueEnqueue', ast.Load()), [ast.Num(carry_base), ast.Num(carries)])]   
     555    newIf = ast.If(new_test, whileNode.body + while_body_extend, else_part)
    548556    self.last_stmt = newIf
    549557    self.last_stmt_carries = carries
Note: See TracChangeset for help on using the changeset viewer.