Changeset 2265 for proto/Compiler


Ignore:
Timestamp:
Aug 6, 2012, 10:25:25 AM (7 years ago)
Author:
cameron
Message:

Recognition logic for special case while optimization

File:
1 edited

Legend:

Unmodified
Added
Removed
  • proto/Compiler/pablo.py

    r2264 r2265  
    335335    self.current_adv_n = 0
    336336    self.last_stmt = None
     337    self.last_stmt_carries = 0
    337338    carry_count = CarryCounter().count(node)
    338339    adv_n_count = adv_nCounter().count(node)
     
    470471    else: return exprnode
    471472  def visit_Assign(self, assignode):
     473      self.last_stmt_carries = CarryCounter().count(assignode)
    472474      self.generic_visit(assignode)
    473475      self.last_stmt = assignode
     
    488490    newIf = ast.If(new_test, ifNode.body, new_else_part)
    489491    self.last_stmt = newIf
     492    self.last_stmt_carries = carries
    490493    return newIf
    491494
     495
     496  def is_while_special_case(self, whileNode):
     497    #
     498    # Special case optimization for pattern:
     499    #   m=pablo.scan...()
     500    #   while m:
     501    #      S
     502    #      m=pablo.scan...()
     503    #
     504    # Determine the original test expression, now encloded in bitblock::any()
     505    original_test_expr = whileNode.test.args[0]
     506    if not isinstance(original_test_expr, ast.Name): return False
     507    test_var = original_test_expr.id
     508    if not isinstance(self.last_stmt, ast.Assign): return False
     509    if not isinstance(whileNode.body[-1], ast.Assign): return False
     510    if len(self.last_stmt.targets) != 1: return False
     511    if len(whileNode.body[-1].targets) != 1: return False
     512    if not isinstance(self.last_stmt.targets[0], ast.Name): return False
     513    if not isinstance(whileNode.body[-1].targets[0], ast.Name): return False
     514    if self.last_stmt.targets[0].id != test_var: return False
     515    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
     519    if CarryCounter().count(whileNode.body[-1]) != 1: return False
     520    return True
     521
    492522  def visit_While(self, whileNode):
     523    # Determine the original test expression, now encloded in bitblock::any()
     524    original_test_expr = whileNode.test.args[0]
    493525    if self.carryout == '':
    494       whileNode.test.args[0] = mkCall("simd_and", [whileNode.test.args[0], ast.Name('EOF_mask', ast.Load())])
     526      whileNode.test.args[0] = mkCall("simd_and", [original_test_expr, ast.Name('EOF_mask', ast.Load())])
    495527    carry_base = self.current_carry
    496528    assert adv_nCounter().count(whileNode) == 0, "Advance(x,n) within while: illegal\n"
     
    498530    #CARRYSET
    499531    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
    500535    carry_arglist = [ast.Num(carry_base), ast.Num(carries)]
    501536    local_carryvar = 'sub' + self.carryvar.id
     
    512547    newIf = ast.If(new_test, whileNode.body + [inner_while], else_part)
    513548    self.last_stmt = newIf
     549    self.last_stmt_carries = carries
    514550    return newIf
    515551
Note: See TracChangeset for help on using the changeset viewer.