Beispiel #1
0
 def tag_com_overhead_instr(self, instr):
     tag_instr(instr, "communication overhead")
Beispiel #2
0
	def process_window(self, trace_fragment):
		''' Process a trace fragment. '''
		# stupid hack to convert between register objects and register strings
		special_regs = [trace_fragment.code.north, trace_fragment.code.east,\
						trace_fragment.code.south, trace_fragment.code.west, trace_fragment.code.out]
		name2reg = dict((str(x), x) for x in trace_fragment.code.regs + special_regs)

		# reinsert immediates that were cached in previous fragment
		# to their original register, all the cached registers that were not
		# overwritten yet can be found in old_register_rewrite.keys()
		old_targets = dict((v, k) for k, v in self.old_register_rewrite.iteritems())
		immediates_to_restore = [(r, v) for v, r in self.old_cached_coeffs.iteritems() if r in old_targets]
		for reg, value in immediates_to_restore:
			orig_reg = old_targets[reg]
			trace_fragment.insert_instr_before(Imm(orig_reg, value))

		# add the loading of the cached values
		trace_fragment.set_ptr(0)

		frequent_imm  = self._get_frequent_immediates(trace_fragment)
		nr_free_regs = trace_fragment.nr_free_regs()

		nr_cached_imm = min(len(frequent_imm), nr_free_regs)
		cached_coeffs = dict((frequent_imm[i][1], None) for i in xrange(nr_cached_imm))
		# mapping from original imm destination regs to new reg in cached_coeffs
		register_rewrite = {}

		while trace_fragment.ptr < len(trace_fragment):
			instr = trace_fragment.current_instr()
			def_, _ = VariableManager.get_def_use(instr_compact_repr(instr))
			if def_:	# handle None values
				def_ = name2reg[def_] # convert to register object
			if instr.opcode() == 'imm' and not instr.cond():
				value = instr.value
				if value in cached_coeffs:
					if not cached_coeffs[value]:
						# XXX could be improved by first finding the first and last usage
						# and finding the register with the tightest free range fit for this interval
						reg = trace_fragment.alloc_local_reg()
						# update book keeping
						cached_coeffs[value] = reg
						register_rewrite[instr.dest] = reg

						# assign new reg
						# XXX the old register usage could be freed!!!
						instr.dest = reg
					else:
						# update rewrite mapping
						register_rewrite[instr.dest] = cached_coeffs[value]
						trace_fragment.remove_current_instr()
						trace_fragment.dec_ptr() # make sure that next op isn't skipped
				else:
					if def_ in register_rewrite:
						# new definition of register, value of immediate is gone
						# so mapping is not needed anymore
						del register_rewrite[def_]
			else:
				if def_ in register_rewrite:
					# new definition of register, value of immediate is gone
					# so mapping is not needed anymore
					del register_rewrite[def_]
				for reg, replacement in register_rewrite.iteritems():
					replaced = self._replace_source_reg(instr, reg, replacement)
					if replaced:
						value = [k for k, v in cached_coeffs.iteritems() if v == replacement][0]
						tag_instr(instr, 'cache_use_imm:%s'%str(value))
			trace_fragment.inc_ptr()

		# now determine the release time of all cached variables
		# note that a second run is needed to get the these line nrs
		last_cached_usage = dict((k, -1) for k, v in cached_coeffs.iteritems())
		for i, instr in enumerate(trace_fragment.trace):
			cache_use = None
			if hasattr(instr, 'tag'):
				try:
					cache_use = [x.split(':')[1] for x in instr.tag if 'cache_use_imm' in x][0]
				except (IndexError): pass
			if cache_use:
				value = float(cache_use)
				if value in last_cached_usage:
					last_cached_usage[value] = i

		# finally release the variables at the appropriate moment
		for value, line in last_cached_usage.iteritems():
			trace_fragment.set_ptr(line)
			trace_fragment.release_local_reg(cached_coeffs[value])

		self.old_register_rewrite = register_rewrite
		self.old_cached_coeffs = cached_coeffs
		return trace_fragment