Changeset 2606


Ignore:
Timestamp:
Nov 4, 2012, 11:37:42 AM (7 years ago)
Author:
cameron
Message:

Make temp assignments for carry-generating built-ins

File:
1 edited

Legend:

Unmodified
Added
Removed
  • proto/Compiler/pablo.py

    r2409 r2606  
    1515
    1616
     17def isCarryGenerating(builtin_fn):
     18   return builtin_fn in ['Advance', 'ScanThru', 'ScanTo', 'AdvanceThenScanThru', 'AdvanceThenScanTo', 'SpanUpTo', 'InclusiveSpan', 'ExclusiveSpan', 'ScanToFirst']
     19def usesCarryInit1(builtin_fn):
     20   return builtin_fn in ['ScanToFirst']
     21def usesCarryCountArgument(builtin_fn):
     22   return builtin_fn in ['Advance']
     23
     24def CarryCountOfFn(fncall, builtin_fnmod_noprefix='pablo'):
     25  if not isinstance(fncall, ast.Call): return 0
     26  if isinstance(fncall.func, ast.Name): fn_name = fncall.func.id
     27  elif isinstance(fncall.func, ast.Attribute) and isinstance(fncall.func.value, ast.Name):
     28    if fncall.func.value.id == builtin_fnmod_noprefix: fn_name = fncall.func.attr
     29    else: return 0
     30  else: return 0
     31  if usesCarryCountArgument(fn_name):
     32    if len(fncall.args) == 1: return 1
     33    else: return 0 #  return fncall.args[1].n  # Possibly count Advance(m, n) as generating n carries.
     34  elif isCarryGenerating(fn_name): return 1
     35  else: return 0
     36   
    1737def is_BuiltIn_Call(fncall, builtin_fnname, builtin_arg_cnt, builtin_fnmod_noprefix='pablo'):
    1838        if isinstance(fncall.func, ast.Name): iscall = fncall.func.id == builtin_fnname
     
    118138        return expr
    119139    else: return callnode
     140
     141
     142
     143#
     144#  Converting expressions involving built-ins to compiled form. 
     145#
     146class TempifyBuiltins(ast.NodeTransformer):
     147    def __init__(self, tempVarpfx = "tempvar"):
     148      self.tempVarCount = 0
     149      self.newTempList = []
     150      self.tempVarPrefix = tempVarpfx
     151    def genVar(self):
     152      newTemp = self.tempVarPrefix + repr(self.tempVarCount)
     153      self.newTempList.append(newTemp)
     154      self.tempVarCount += 1
     155      return newTemp
     156    def tempVars(self):
     157      return self.newTempList
     158    def xfrm(self, t):
     159      self.setUpStmts = []
     160      self.assigNode = None
     161      return self.generic_visit(t)
     162    def is_Assign_value(self, node):
     163      return self.assigNode != None and self.assigNode.value == node
     164    def visit_If(self, ifNode):
     165      outerSetUpStmts = self.setUpStmts
     166      self.setUpStmts = []
     167      self.generic_visit(ifNode)
     168      ifSetUpStmts = self.setUpStmts
     169      self.setUpStmts = outerSetUpStmts
     170      if ifSetUpStmts == []: return ifNode
     171      else: return ifSetUpStmts + [ifNode]
     172    def visit_While(self, whileNode):
     173      outerSetUpStmts = self.setUpStmts
     174      self.setUpStmts = []
     175      self.generic_visit(whileNode)
     176      whileSetUpStmts = self.setUpStmts
     177      self.setUpStmts = outerSetUpStmts
     178      whileNode.body = whileNode.body + whileSetUpStmts
     179      return whileSetUpStmts + [whileNode]
     180    def visit_Assign(self, node):
     181      self.assigNode = node
     182      outerSetUpStmts = self.setUpStmts
     183      self.setUpStmts = []
     184      self.generic_visit(node)
     185      innerSetUpStmts = self.setUpStmts
     186      self.setUpStmts = outerSetUpStmts
     187      return innerSetUpStmts + [node]
     188    def visit_Call(self, callnode):     
     189        self.generic_visit(callnode)
     190        if CarryCountOfFn(callnode) > 0 and not self.is_Assign_value(callnode):
     191        #if not self.is_Assign_value(callnode):
     192            tempVar = ast.Name(self.genVar(), ast.Load())
     193            self.setUpStmts.append(ast.Assign([tempVar], callnode))
     194            return tempVar
     195        else: return callnode
     196
     197
    120198
    121199
     
    265343  def visit_Call(self, callnode):
    266344    self.generic_visit(callnode)
    267     if is_BuiltIn_Call(callnode,'Advance', 1) or is_BuiltIn_Call(callnode,'ScanThru', 2) or is_BuiltIn_Call(callnode,'ScanTo', 2) or is_BuiltIn_Call(callnode,'ScanToFirst', 1) or is_BuiltIn_Call(callnode,'AdvanceThenScanThru', 2) or is_BuiltIn_Call(callnode,'AdvanceThenScanTo', 2) or is_BuiltIn_Call(callnode,'SpanUpTo', 2) or  is_BuiltIn_Call(callnode,'InclusiveSpan', 2) or is_BuiltIn_Call(callnode,'ExclusiveSpan', 2):         
    268       self.carry_count += 1
     345    self.carry_count += CarryCountOfFn(callnode)
    269346  def visit_BinOp(self, exprnode):
    270347    self.generic_visit(exprnode)
     
    9371014                stream_function.initializations = StreamInitializations().xfrm(node)
    9381015               
     1016                t = TempifyBuiltins()
     1017                t.xfrm(node)
     1018                stream_function.declarations += "\n" + BitBlock_decls_from_vars(t.tempVars())
     1019               
    9391020                StringMatchCompiler().xfrm(node)
    9401021                AssertCompiler().xfrm(node)
Note: See TracChangeset for help on using the changeset viewer.