def opThatInvokes(func): # Find the single op in the function that invokes. invokeOp = None for op in tools.codeOps(func): invokes = op.annotation.invokes if invokes is not None and invokes[0]: assert invokeOp is None invokeOp = op assert invokeOp return invokeOp
def __init__(self, liveCode): self.invokeDestination = collections.defaultdict(set) self.invokeSource = collections.defaultdict(set) self.funcReads = collections.defaultdict(lambda: collections.defaultdict(set)) self.funcModifies = collections.defaultdict(lambda: collections.defaultdict(set)) for code in liveCode: self.handleReads(code, code.annotation.codeReads) self.handleModifies(code, code.annotation.codeModifies) ops = tools.codeOps(code) for op in ops: self.handleOpInvokes(code, op) self.handleOpReads(code, op) self.handleOpModifies(code, op)
def __init__(self, liveCode): self.invokeDestination = collections.defaultdict(set) self.invokeSource = collections.defaultdict(set) self.funcReads = collections.defaultdict( lambda: collections.defaultdict(set)) self.funcModifies = collections.defaultdict( lambda: collections.defaultdict(set)) for code in liveCode: self.handleReads(code, code.annotation.codeReads) self.handleModifies(code, code.annotation.codeModifies) ops = tools.codeOps(code) for op in ops: self.handleOpInvokes(code, op) self.handleOpReads(code, op) self.handleOpModifies(code, op)
def evaluate(compiler, prgm, simplify=False): with compiler.console.scope('dead store elimination'): live = set() stores = collections.defaultdict(list) # Analysis pass for code in prgm.liveCode: live.update(code.annotation.codeReads[0]) for op in codeOps(code): live.update(op.annotation.reads[0]) if isinstance(op, ast.Store): stores[code].append(op) # Transform pass totalEliminated = 0 for code in prgm.liveCode: if not code.isStandardCode() or code.annotation.descriptive: continue replace = {} eliminated = 0 # Look for dead stores for store in stores[code]: for modify in store.annotation.modifies[0]: if modify in live: break if modify.object.leaks: break else: replace[store] = [] eliminated += 1 # Rewrite the code without the dead stores if replace: compiler.console.output('%r %d' % (code, eliminated)) if simplify: rewrite.rewriteAndSimplify(compiler, prgm, code, replace) else: rewrite.rewrite(compiler, code, replace) totalEliminated += eliminated return totalEliminated > 0
def contextsThatOnlyInvoke(funcs, invocations): output = set() # HACK There's only one op in the object getter that will invoke? for func in funcs: for op in tools.codeOps(func): invokes = op.annotation.invokes if invokes is not None: for cindex, context in enumerate(func.annotation.contexts): cinvokes = invokes[1][cindex] invokesSet = set(cinvokes) match = invokesSet.intersection(invocations) # There must be invocations, and they must all be to fget. if match and match == invokesSet: output.add((func, context)) return output
def __init__(self, liveContexts): self.liveFunctions = set(liveContexts.iterkeys()) self.liveContexts = liveContexts self.liveOps = {} for code in self.liveFunctions: self.liveOps[code] = tools.codeOps(code) # func -> context -> context set self.different = collections.defaultdict( lambda: collections.defaultdict(set)) # HACK, ensure the keys exist for func in self.liveFunctions: different = self.different[func] for context in self.liveContexts[func]: different[context] self.unifier = GroupUnifier() self.indirectGroup = {}
def __init__(self, liveContexts): self.liveFunctions = set(liveContexts.iterkeys()) self.liveContexts = liveContexts self.liveOps = {} for code in self.liveFunctions: self.liveOps[code] = tools.codeOps(code) # func -> context -> context set self.different = collections.defaultdict(lambda: collections.defaultdict(set)) # HACK, ensure the keys exist for func in self.liveFunctions: different = self.different[func] for context in self.liveContexts[func]: different[context] self.unifier = GroupUnifier() self.indirectGroup = {}