Example #1
0
    def collectDB(self, liveCode):
        self.allReads = set()
        self.allModifies = set()

        self.opReadDB = opDataflowSchema.instance()
        self.opModifyDB = opDataflowSchema.instance()

        self.allocations = collections.defaultdict(set)

        # Copy modifies
        for code in liveCode:
            self.handleModifies(code, None, code.annotation.codeModifies)
            ops, lcls = getOps(code)
            for op in ops:
                self.handleModifies(code, op, op.annotation.opModifies)

        # Copy reads
        for code in liveCode:
            self.handleReads(code, None, code.annotation.codeReads)
            self.handleAllocates(code, None, code.annotation.codeAllocates)

            ops, lcls = getOps(code)
            for op in ops:
                self.handleReads(code, op, op.annotation.opReads)
                self.handleAllocates(code, op, op.annotation.opAllocates)
Example #2
0
    def collectDB(self, liveCode):
        self.allReads = set()
        self.allModifies = set()

        self.opReadDB = opDataflowSchema.instance()
        self.opModifyDB = opDataflowSchema.instance()

        self.allocations = collections.defaultdict(set)

        # Copy modifies
        for code in liveCode:
            self.handleModifies(code, None, code.annotation.codeModifies)
            ops, lcls = getOps(code)
            for op in ops:
                self.handleModifies(code, op, op.annotation.opModifies)

                # Copy reads
        for code in liveCode:
            self.handleReads(code, None, code.annotation.codeReads)
            self.handleAllocates(code, None, code.annotation.codeAllocates)

            ops, lcls = getOps(code)
            for op in ops:
                self.handleReads(code, op, op.annotation.opReads)
                self.handleAllocates(code, op, op.annotation.opAllocates)
Example #3
0
	def annotate(self):
		if self.clone:
			cloner = codecloner.FunctionCloner(self.codeContexts.iterkeys())

			# Translate the live code
			self.liveCode = set([cloner.code(code) for code in self.liveCode])
		else:
			cloner = codecloner.NullCloner(self.codeContexts.iterkeys())

		self.annotationCount = 0
		self.annotationCache = {}

		self.reindexAnnotations(cloner)

		self.annotateEntryPoints(cloner)

		for code, contexts in self.codeContexts.iteritems():
			if code is self.externalFunction: continue

			cloner.process(code)

			contexts = self.annotateCode(code, contexts, cloner)

			ops, lcls = getOps(code)

			self.annotateOps(code, contexts, ops, cloner)
			self.annotateLocals(code, contexts, lcls, cloner)

			self.mergeAbstractCode(code, cloner)

		self.console.output("Annotation compression %f - %d" % (float(len(self.annotationCache))/max(self.annotationCount, 1), self.annotationCount))

		del self.annotationCache
		del self.annotationCount
Example #4
0
    def process(self):
        # TODO get all fields from heap?

        # Local references
        for code in self.liveCode:
            self.liveObjs[code] = set()
            self.liveFields[code] = set()

            ops, lcls = getOps(code)
            for op in ops:

                self.liveFields[code].update(op.annotation.reads[0])
                self.liveFields[code].update(op.annotation.modifies[0])

                if not op.annotation.invokes[0]:
                    # If the op does not invoke, it does real work.
                    self.merge(op.annotation.reads[0])
                    self.merge(op.annotation.modifies[0])

                    # TODO seperate by concrete field type before merge

                for cobj in op.annotation.allocates[0]:
                    if not cobj.leaks:
                        self.liveObjs[code].add(cobj)

            for lcl in lcls:
                for ref in lcl.annotation.references[0]:
                    if not ref.leaks:
                        self.liveObjs[code].add(ref)
Example #5
0
    def children(self, node):
        code, context = node

        self.liveFunc.add(code)

        if code not in self.liveFuncContext:
            self.liveFuncContext[code] = set()
        self.liveFuncContext[code].add(context)

        if code not in self.invokes:
            self.invokes[code] = set()

        if node not in self.invokesContext:
            self.invokesContext[node] = set()

        cindex = code.annotation.contexts.index(context)

        children = []

        ops, _lcls = getOps(code)
        for op in ops:
            assert hasattr(op.annotation, "invokes"), op
            invokes = op.annotation.invokes
            if invokes is not None:
                cinvokes = invokes[1][cindex]
                for dstf, dstc in cinvokes:
                    child = (dstf, dstc)
                    self.invokes[code].add(dstf)
                    self.invokesContext[node].add(child)
                    children.append(child)
        return children
	def process(self):
		# TODO get all fields from heap?

		# Local references
		for code in self.liveCode:
			self.liveObjs[code]   = set()
			self.liveFields[code] = set()

			ops, lcls = getOps(code)
			for op in ops:

				self.liveFields[code].update(op.annotation.reads[0])
				self.liveFields[code].update(op.annotation.modifies[0])

				if not op.annotation.invokes[0]:
					# If the op does not invoke, it does real work.
					self.merge(op.annotation.reads[0])
					self.merge(op.annotation.modifies[0])

					# TODO seperate by concrete field type before merge

				for cobj in op.annotation.allocates[0]:
					if not cobj.leaks:
						self.liveObjs[code].add(cobj)

			for lcl in lcls:
				for ref in lcl.annotation.references[0]:
					if not ref.leaks:
						self.liveObjs[code].add(ref)
Example #7
0
    def children(self, node):
        code, context = node

        self.liveFunc.add(code)

        if code not in self.liveFuncContext:
            self.liveFuncContext[code] = set()
        self.liveFuncContext[code].add(context)

        if code not in self.invokes:
            self.invokes[code] = set()

        if node not in self.invokesContext:
            self.invokesContext[node] = set()

        cindex = code.annotation.contexts.index(context)

        children = []

        ops, _lcls = getOps(code)
        for op in ops:
            assert hasattr(op.annotation, 'invokes'), op
            invokes = op.annotation.invokes
            if invokes is not None:
                cinvokes = invokes[1][cindex]
                for dstf, dstc in cinvokes:
                    child = (dstf, dstc)
                    self.invokes[code].add(dstf)
                    self.invokesContext[node].add(child)
                    children.append(child)
        return children
Example #8
0
    def gatherSlots(self, liveCode, entryContexts):

        searcher = ObjectSearcher(self)

        for code in liveCode:
            callee = code.codeParameters()

            ops, lcls = getOps(code)
            for lcl in lcls:
                for ref in lcl.annotation.references[0]:
                    searcher.enqueue(ref)

                    # Mark the return parameters for external contexts as visible.
            for cindex, context in enumerate(code.annotation.contexts):
                if context in entryContexts:
                    for param in callee.returnparams:
                        self.markVisible(param, cindex)

        searcher.process()
Example #9
0
    def gatherSlots(self, liveCode, entryContexts):

        searcher = ObjectSearcher(self)

        for code in liveCode:
            callee = code.codeParameters()

            ops, lcls = getOps(code)
            for lcl in lcls:
                for ref in lcl.annotation.references[0]:
                    searcher.enqueue(ref)

            # Mark the return parameters for external contexts as visible.
            for cindex, context in enumerate(code.annotation.contexts):
                if context in entryContexts:
                    for param in callee.returnparams:
                        self.markVisible(param, cindex)

        searcher.process()
Example #10
0
	def process(self, node):
		if node not in self.processed:
			assert node.isCode(), type(node)

			self.processed.add(node)
			self.trace.add(node)
			self.modified = False
			self.code = node

			if node.isStandardCode():
				result = self(node.ast)
				if self.modified:
					node.ast = result
					# Always done immediately after inlining, so if we inline
					# this function, less needs to be processed.
					optimization.simplify.evaluateCode(self.compiler, self.prgm, node)
			else:
				ops, lcls = getOps(node)
				for op in ops:
					self.processInvocations(op)

			self.code = None
			self.trace.remove(node)
Example #11
0
    def annotate(self):
        if self.clone:
            cloner = codecloner.FunctionCloner(self.codeContexts.iterkeys())

            # Translate the live code
            self.liveCode = set([cloner.code(code) for code in self.liveCode])
        else:
            cloner = codecloner.NullCloner(self.codeContexts.iterkeys())

        self.annotationCount = 0
        self.annotationCache = {}

        self.reindexAnnotations(cloner)

        self.annotateEntryPoints(cloner)

        for code, contexts in self.codeContexts.iteritems():
            if code is self.externalFunction: continue

            cloner.process(code)

            contexts = self.annotateCode(code, contexts, cloner)

            ops, lcls = getOps(code)

            self.annotateOps(code, contexts, ops, cloner)
            self.annotateLocals(code, contexts, lcls, cloner)

            self.mergeAbstractCode(code, cloner)

        self.console.output(
            "Annotation compression %f - %d" %
            (float(len(self.annotationCache)) / max(self.annotationCount, 1),
             self.annotationCount))

        del self.annotationCache
        del self.annotationCount
Example #12
0
    def process(self, node):
        if node not in self.processed:
            assert node.isCode(), type(node)

            self.processed.add(node)
            self.trace.add(node)
            self.modified = False
            self.code = node

            if node.isStandardCode():
                result = self(node.ast)
                if self.modified:
                    node.ast = result
                    # Always done immediately after inlining, so if we inline
                    # this function, less needs to be processed.
                    optimization.simplify.evaluateCode(self.compiler,
                                                       self.prgm, node)
            else:
                ops, lcls = getOps(node)
                for op in ops:
                    self.processInvocations(op)

            self.code = None
            self.trace.remove(node)
Example #13
0
    def gatherInvokes(self, liveCode, entryContexts):
        invokesDB = invokesSchema.instance()

        self.entries = set()

        for code in liveCode:
            for context in code.annotation.contexts:
                if context in entryContexts:
                    self.entries.add((code, context))

            assert code.isCode(), type(code)
            ops, lcls = getOps(code)
            for op in ops:
                invokes = op.annotation.invokes
                if invokes is not None:
                    for cindex, context in enumerate(code.annotation.contexts):
                        opInvokes = invokes[1][cindex]

                        for dstF, dstC in opInvokes:
                            assert dstF.isCode(), type(dstF)
                            invokesDB[code][op][context].add(dstF, dstC)

            for lcl in lcls:
                refs = lcl.annotation.references
                if refs is None:
                    continue

                for cindex, context in enumerate(code.annotation.contexts):
                    for ref in refs[1][cindex]:
                        obj = self.getObjectInfo(ref)
                        obj.localReference.add(code)

                        self.codeRefersToHeap[(code, context)].add(ref)

        self.invokes = invokesDB
        self.invokeSources = invertInvokes(invokesDB)
Example #14
0
    def gatherInvokes(self, liveCode, entryContexts):
        invokesDB = invokesSchema.instance()

        self.entries = set()

        for code in liveCode:
            for context in code.annotation.contexts:
                if context in entryContexts:
                    self.entries.add((code, context))

            assert code.isCode(), type(code)
            ops, lcls = getOps(code)
            for op in ops:
                invokes = op.annotation.invokes
                if invokes is not None:
                    for cindex, context in enumerate(code.annotation.contexts):
                        opInvokes = invokes[1][cindex]

                        for dstF, dstC in opInvokes:
                            assert dstF.isCode(), type(dstF)
                            invokesDB[code][op][context].add(dstF, dstC)

            for lcl in lcls:
                refs = lcl.annotation.references
                if refs is None:
                    continue

                for cindex, context in enumerate(code.annotation.contexts):
                    for ref in refs[1][cindex]:
                        obj = self.getObjectInfo(ref)
                        obj.localReference.add(code)

                        self.codeRefersToHeap[(code, context)].add(ref)

        self.invokes = invokesDB
        self.invokeSources = invertInvokes(invokesDB)
Example #15
0
    def createDB(self, compiler, prgm):
        self.annotationCount = 0
        self.annotationCache = {}

        readDB = self.rm.opReadDB
        modifyDB = self.rm.opModifyDB
        self.allocations = self.rm.allocations

        for code in prgm.liveCode:
            # Annotate the code
            live = []
            killed = []
            for cindex, context in enumerate(code.annotation.contexts):
                key = (code, context)
                live.append(annotations.annotationSet(self.live[key]))
                killed.append(annotations.annotationSet(self.contextKilled[key]))

            code.rewriteAnnotation(
                live=annotations.makeContextualAnnotation(live), killed=annotations.makeContextualAnnotation(killed)
            )

            # Annotate the ops
            ops, lcls = getOps(code)
            for op in ops:
                # TODO is this a good HACK?
                # if not op.annotation.invokes[0]: continue

                reads = readDB[code][op]
                modifies = modifyDB[code][op]

                rout = []
                mout = []
                aout = []

                for cindex, context in enumerate(code.annotation.contexts):
                    # HACK if an operation directly reads a field, but it is never modified
                    # it still must appear in the reads annotation so cloning behaves correctly!
                    reads.merge(context, op.annotation.opReads[1][cindex])

                    creads = reads[context]
                    creads = annotations.annotationSet(creads) if creads else ()
                    rout.append(creads)

                    cmod = modifies[context]
                    cmod = annotations.annotationSet(cmod) if cmod else ()
                    mout.append(cmod)

                    kills = self.killed[(code, op, context)]

                    calloc = set()
                    for dstCode, dstContext in op.annotation.invokes[1][cindex]:
                        live = self.live[(dstCode, dstContext)]
                        killed = kills[(dstCode, dstContext)]
                        calloc.update(live - killed)

                    calloc.update(op.annotation.opAllocates[1][cindex])

                    aout.append(annotations.annotationSet(calloc))

                opReads = annotations.makeContextualAnnotation(rout)
                opModifies = annotations.makeContextualAnnotation(mout)
                opAllocates = annotations.makeContextualAnnotation(aout)

                opReads = self.annotationCache.setdefault(opReads, opReads)
                opModifies = self.annotationCache.setdefault(opModifies, opModifies)
                opAllocates = self.annotationCache.setdefault(opAllocates, opAllocates)
                self.annotationCount += 3

                op.rewriteAnnotation(reads=opReads, modifies=opModifies, allocates=opAllocates)

        compiler.console.output(
            "Annotation compression %f - %d"
            % (float(len(self.annotationCache)) / max(self.annotationCount, 1), self.annotationCount)
        )

        del self.annotationCache
        del self.annotationCount
Example #16
0
    def createDB(self, compiler, prgm):
        self.annotationCount = 0
        self.annotationCache = {}

        readDB = self.rm.opReadDB
        modifyDB = self.rm.opModifyDB
        self.allocations = self.rm.allocations

        for code in prgm.liveCode:
            # Annotate the code
            live = []
            killed = []
            for cindex, context in enumerate(code.annotation.contexts):
                key = (code, context)
                live.append(annotations.annotationSet(self.live[key]))
                killed.append(
                    annotations.annotationSet(self.contextKilled[key]))

            code.rewriteAnnotation(
                live=annotations.makeContextualAnnotation(live),
                killed=annotations.makeContextualAnnotation(killed))

            # Annotate the ops
            ops, lcls = getOps(code)
            for op in ops:
                # TODO is this a good HACK?
                # if not op.annotation.invokes[0]: continue

                reads = readDB[code][op]
                modifies = modifyDB[code][op]

                rout = []
                mout = []
                aout = []

                for cindex, context in enumerate(code.annotation.contexts):
                    # HACK if an operation directly reads a field, but it is never modified
                    # it still must appear in the reads annotation so cloning behaves correctly!
                    reads.merge(context, op.annotation.opReads[1][cindex])

                    creads = reads[context]
                    creads = annotations.annotationSet(creads) if creads else (
                    )
                    rout.append(creads)

                    cmod = modifies[context]
                    cmod = annotations.annotationSet(cmod) if cmod else ()
                    mout.append(cmod)

                    kills = self.killed[(code, op, context)]

                    calloc = set()
                    for dstCode, dstContext in op.annotation.invokes[1][
                            cindex]:
                        live = self.live[(dstCode, dstContext)]
                        killed = kills[(dstCode, dstContext)]
                        calloc.update(live - killed)

                    calloc.update(op.annotation.opAllocates[1][cindex])

                    aout.append(annotations.annotationSet(calloc))

                opReads = annotations.makeContextualAnnotation(rout)
                opModifies = annotations.makeContextualAnnotation(mout)
                opAllocates = annotations.makeContextualAnnotation(aout)

                opReads = self.annotationCache.setdefault(opReads, opReads)
                opModifies = self.annotationCache.setdefault(
                    opModifies, opModifies)
                opAllocates = self.annotationCache.setdefault(
                    opAllocates, opAllocates)
                self.annotationCount += 3

                op.rewriteAnnotation(reads=opReads,
                                     modifies=opModifies,
                                     allocates=opAllocates)

        compiler.console.output(
            "Annotation compression %f - %d" %
            (float(len(self.annotationCache)) / max(self.annotationCount, 1),
             self.annotationCount))

        del self.annotationCache
        del self.annotationCount