示例#1
0
def precolor(node):
    if classGuard(node, Assign, Phi):
        sym = extractSymbol(node)

        if not sym.has_key('precolor'):
            sym['precolor'] = None

    elif isinstance(node, Div) and isinstance(node.left, Symbol):
        node.left['precolor'] = eax

    elif isinstance(node, Function):
        # This clause pre-colors function arguments with their position on
        # the stack relative to the %ebp register.  The first argument
        # starts 8 bytes above the base pointer.  Each successive argument is
        # 4 bytes above that.

        offset = 8

        for sym in node.argSymbols:
            sym['precolor'] = Mem(offset, 'up', True)

            #Advance to the next argument offset.
            offset += 4

    elif isinstance(node, Return):
        # Values are returned from functions in the %eax register.

        node['precolor'] = eax

    for child in node:
        precolor(child)
示例#2
0
def eliminateDeadStores(node, klass=0):
    newChildren = []

    if isinstance(node, Class):
        klass += 1

    for child in node:
        newChildren.append(eliminateDeadStores(child, klass))

    node.setChildren(flatten(newChildren))

    if isinstance(node, Assign):
        sym = extractSymbol(node.var)

        if sym['reads'] == 0 and klass == 0:
            if classGuard(node.exp, Class, FunctionCall):
                return node

            else:
                return None

        else:
            return node

    elif isinstance(node, Phi) and node.target['reads'] == 0:
        return None

    else:
        return node
示例#3
0
def precolor(node):
	if classGuard(node, Assign, Phi):
		sym = extractSymbol(node)
		
		if not sym.has_key('precolor'):
			sym['precolor'] = None
	
	elif isinstance(node, Div) and isinstance(node.left, Symbol):
		node.left['precolor'] = eax
	
	elif isinstance(node, Function):
		# This clause pre-colors function arguments with their position on
		# the stack relative to the %ebp register.  The first argument
		# starts 8 bytes above the base pointer.  Each successive argument is
		# 4 bytes above that.
		
		offset = 8
		
		for sym in node.argSymbols:
			sym['precolor'] = Mem(offset, 'up', True)
			
			#Advance to the next argument offset.
			offset += 4
	
	elif isinstance(node, Return):
		# Values are returned from functions in the %eax register.
		
		node['precolor'] = eax
	
	for child in node:
		precolor(child)
示例#4
0
def reads(node):
    if classGuard(node, Assign, Phi):
        sym = extractSymbol(node)

        if not sym.has_key('reads'):
            sym['reads'] = 0

    elif isinstance(node, Function):
        for sym in node.argSymbols:
            sym['reads'] = 0

    elif isinstance(node, Symbol):
        # This is kind of ugly, but because of Python's scoping rules we can
        # read from a variable before it is 'in scope.'

        if node.has_key('reads'):
            node['reads'] += 1
        else:
            node['reads'] = 1

    elif isinstance(node, Subscript) and isinstance(node.symbol, Symbol):
        # This little hack is here to take care of cases where subscripts are
        # applied to literal values. After the flatten transformation this
        # branch will be taken whenever we see a subscript.

        node.symbol['reads'] += 1

    for child in node:
        reads(child)
示例#5
0
def eliminateDeadStores(node, klass = 0):
	newChildren = []
	
	if isinstance(node, Class):
		klass += 1
	
	for child in node:
		newChildren.append(eliminateDeadStores(child, klass))
	
	node.setChildren(flatten(newChildren))
	
	if isinstance(node, Assign):
		sym = extractSymbol(node.var)
		
		if sym['reads'] == 0 and klass == 0:
			if classGuard(node.exp, Class, FunctionCall):
				return node
			
			else:
				return None
		
		else:
			return node
	
	elif isinstance(node, Phi) and node.target['reads'] == 0:
		return None
	
	else:
		return node
示例#6
0
def spans(node, count=0, alive=None):
    inc = 1

    if isinstance(node, Module):
        alive = {}

    # Count the spans over our children.
    for child in node:
        subInc = spans(child, count, alive)
        inc += subInc
        count += subInc

    if classGuard(node, Assign, Phi):
        # Due to SSA form we know this variable isn't already alive.
        sym = extractSymbol(node)

        sym['spans-funcall'] = False

        if sym in node['post-alive']:
            alive[sym] = count
        else:
            sym['span-start'] = sym['span-end'] = count
            sym['span-length'] = 0

    elif isinstance(node, Function):
        for sym in node.argSymbols:
            sym['spans-funcall'] = False

            if sym in node['post-alive']:
                alive[sym] = count
            else:
                sym['span-start'] = sym['span-end'] = count
                sym['span-length'] = 0

    elif isinstance(node, FunctionCall):
        #Mark functions that span this function call.
        for sym in node['pre-alive']:
            if sym in node['post-alive']:
                sym['spans-funcall'] = True

    # This is here so we don't change the alive list while we are iterating
    # through it.
    deletes = []

    # Symbols don't have any pre/post-alive information due to their Singleton
    # nature.
    if not classGuard(node, Name, String, Symbol):
        for sym in alive:
            if isinstance(node, Function) or sym not in node['post-alive']:
                sym['span-start'] = alive[sym]
                sym['span-end'] = count - 1
                sym['span-length'] = sym['span-end'] - sym['span-start']

                deletes.append(sym)

    for sym in deletes:
        del alive[sym]

    return inc
示例#7
0
def spans(node, count = 0, alive = None):
	inc = 1
	
	if isinstance(node, Module):
		alive = {}
	
	# Count the spans over our children.
	for child in node:
		subInc = spans(child, count, alive)
		inc   += subInc
		count += subInc
	
	if classGuard(node, Assign, Phi):
		# Due to SSA form we know this variable isn't already alive.
		sym = extractSymbol(node)
		
		sym['spans-funcall'] = False
		
		if sym in node['post-alive']:
			alive[sym] = count
		else:
			sym['span-start']	= sym['span-end'] = count
			sym['span-length']	= 0
	
	elif isinstance(node, Function):
		for sym in node.argSymbols:
			sym['spans-funcall'] = False
			
			if sym in node['post-alive']:
				alive[sym] = count
			else:
				sym['span-start']	= sym['span-end'] = count
				sym['span-length']	= 0
	
	elif isinstance(node, FunctionCall):
		#Mark functions that span this function call.
		for sym in node['pre-alive']:
			if sym in node['post-alive']:
				sym['spans-funcall'] = True
	
	# This is here so we don't change the alive list while we are iterating
	# through it.
	deletes = []
	
	# Symbols don't have any pre/post-alive information due to their Singleton
	# nature.
	if not classGuard(node, Name, String, Symbol):
		for sym in alive:
			if isinstance(node, Function) or sym not in node['post-alive']:
				sym['span-start']	= alive[sym]
				sym['span-end'  ]	= count - 1
				sym['span-length']	= sym['span-end'] - sym['span-start']
				
				deletes.append(sym)
	
	for sym in deletes:
		del alive[sym]
	
	return inc
示例#8
0
def liveness(node, alive=[]):
    if isinstance(node, Module):
        alive = []

    if not classGuard(node, Name, String, Symbol):
        node['pre-alive'] = set(alive)

    if isinstance(node, Function):
        for sym in node.argSymbols:
            #Functions might have arguments that are never read.
            if sym['reads'] > 0:
                sym['tmp'] = sym['reads']
                alive.append(sym)

    for child in node:
        liveness(child, alive)

    if classGuard(node, Assign, Phi):
        sym = extractSymbol(node)

        if not sym.has_key('tmp'):
            sym['tmp'] = sym['reads']
            alive.append(sym)

    elif isinstance(node, Symbol) or (isinstance(node, Subscript)
                                      and isinstance(node.symbol, Symbol)):
        sym = extractSymbol(node)

        if sym.has_key('tmp'):
            sym['tmp'] -= 1

            if sym['tmp'] == 0:
                alive.remove(sym)

        else:
            sym['tmp'] = sym['reads']
            alive.append(sym)

    if not classGuard(node, Name, String, Symbol):
        node['post-alive'] = set(alive)
示例#9
0
def weight(node, depth = 0.0):
	if isinstance(node, Assign):
		sym = extractSymbol(node)
		
		sym['weight'] = 1.0 + (10.0 ** depth)
		sym['tmp'] = sym['reads']
	
	elif isinstance(node, Symbol):
		node['weight'] += 1.0 + (10.0 ** depth)
		
		node['tmp'] -= 1
		
		if node['tmp'] == 0:
			node['weight'] = node['weight'] / float(node['span-length'])
	
	for child in node:
		if isinstance(node, BasicBlock):
			weight(child, depth + 1.0)
		
		else:
			weight(child, depth)
示例#10
0
def related(node):
	if isinstance(node, Assign):
		sym0 = extractSymbol(node.var)
		
		sym0['related']	= set()
		
		if not sym0.has_key('phi-related'):
			sym0['phi-related']	= set()
		
		if isinstance(node.exp, Symbol):
			sym1 = node.exp
			
			if not sym1 in node['post-alive']:
				sym0['related'].add(sym1)
		
		elif isinstance(node.exp, BinOp):
			if isinstance(node.exp.left, Symbol):
				# Mark the left symbol as related to the target symbol.
				sym1 = node.exp.left
				
				if sym1 not in node['post-alive']:
					sym0['related'].add(sym1)
			
			if classGuard(node.exp, Add, Mul) and isinstance(node.exp.right, Symbol):
				# Mark the right symbol as related to the target symbol if
				# this is an Add or Mul node.
				sym1 = node.exp.right
				
				if sym1 not in node['post-alive']:
					sym0['related'].add(sym1)
		
		elif isinstance(node.exp, UnaryOp) and isinstance(node.exp.operand, Symbol):
			sym1 = node.exp.operand
			
			if not sym1 in node['post-alive']:
				sym0['related'].add(sym1)
	
	elif isinstance(node, Function):
		for sym in node.argSymbols:
			sym['related']		= set()
			sym['phi-related']	= set()
	
	elif isinstance(node, Phi):
		fullSet	= set()
		syms		= set([node.target] + node.srcs)
		
		while len(syms) > 0:
			sym	 = syms.pop()
			
			if sym.has_key('phi-related'):
				syms	|= sym['phi-related'] - fullSet
			
			fullSet.add(sym)
		
		for sym in fullSet:
			if sym.has_key('phi-related'):
				sym['phi-related'] |= fullSet
			
			else:
				sym['phi-related'] = fullSet
	
	for child in node:
		related(child)