def op_bit_sizes(op):
    sizes = None
    if not type_has_size(op.output_type):
        sizes = set(type_sizes(op.output_type))

    for input_type in op.input_types:
        if not type_has_size(input_type):
            if sizes is None:
                sizes = set(type_sizes(input_type))
            else:
                sizes = sizes.intersection(set(type_sizes(input_type)))

    return sorted(list(sizes)) if sizes is not None else None
def op_bit_sizes(op):
    sizes = None
    if not type_has_size(op.output_type):
        sizes = set(type_sizes(op.output_type))

    for input_type in op.input_types:
        if not type_has_size(input_type):
            if sizes is None:
                sizes = set(type_sizes(input_type))
            else:
                sizes = sizes.intersection(set(type_sizes(input_type)))

    return sorted(list(sizes)) if sizes is not None else None
Exemple #3
0
   def __init__(self, val, name, varset):
      Value.__init__(self, val, name, "variable")

      m = _var_name_re.match(val)
      assert m and m.group('name') is not None

      self.var_name = m.group('name')

      # Prevent common cases where someone puts quotes around a literal
      # constant.  If we want to support names that have numeric or
      # punctuation characters, we can me the first assertion more flexible.
      assert self.var_name.isalpha()
      assert self.var_name is not 'True'
      assert self.var_name is not 'False'

      self.is_constant = m.group('const') is not None
      self.cond = m.group('cond')
      self.required_type = m.group('type')
      self._bit_size = int(m.group('bits')) if m.group('bits') else None

      if self.required_type == 'bool':
         if self._bit_size is not None:
            assert self._bit_size in type_sizes(self.required_type)
         else:
            self._bit_size = 1

      if self.required_type is not None:
         assert self.required_type in ('float', 'bool', 'int', 'uint')

      self.index = varset[self.var_name]
Exemple #4
0
   def __init__(self, pass_name, transforms):
      self.xforms = []
      self.opcode_xforms = defaultdict(lambda : [])
      self.pass_name = pass_name

      error = False

      for xform in transforms:
         if not isinstance(xform, SearchAndReplace):
            try:
               xform = SearchAndReplace(xform)
            except:
               print("Failed to parse transformation:", file=sys.stderr)
               print("  " + str(xform), file=sys.stderr)
               traceback.print_exc(file=sys.stderr)
               print('', file=sys.stderr)
               error = True
               continue

         self.xforms.append(xform)
         if xform.search.opcode in conv_opcode_types:
            dst_type = conv_opcode_types[xform.search.opcode]
            for size in type_sizes(dst_type):
               sized_opcode = xform.search.opcode + str(size)
               self.opcode_xforms[sized_opcode].append(xform)
         else:
            self.opcode_xforms[xform.search.opcode].append(xform)

      self.automaton = TreeAutomaton(self.xforms)

      if error:
         sys.exit(1)
Exemple #5
0
   def __init__(self, pass_name, transforms):
      self.xforms = []
      self.opcode_xforms = defaultdict(lambda : [])
      self.pass_name = pass_name

      error = False

      for xform in transforms:
         if not isinstance(xform, SearchAndReplace):
            try:
               xform = SearchAndReplace(xform)
            except:
               print("Failed to parse transformation:", file=sys.stderr)
               print("  " + str(xform), file=sys.stderr)
               traceback.print_exc(file=sys.stderr)
               print('', file=sys.stderr)
               error = True
               continue

         self.xforms.append(xform)
         if xform.search.opcode in conv_opcode_types:
            dst_type = conv_opcode_types[xform.search.opcode]
            for size in type_sizes(dst_type):
               sized_opcode = xform.search.opcode + str(size)
               self.opcode_xforms[sized_opcode].append(xform)
         else:
            self.opcode_xforms[xform.search.opcode].append(xform)

         # Check to make sure the search pattern does not unexpectedly contain
         # more commutative expressions than match_expression (nir_search.c)
         # can handle.
         comm_exprs = xform.search.comm_exprs

         if xform.search.many_commutative_expressions:
            if comm_exprs <= nir_search_max_comm_ops:
               print("Transform expected to have too many commutative " \
                     "expression but did not " \
                     "({} <= {}).".format(comm_exprs, nir_search_max_comm_op),
                     file=sys.stderr)
               print("  " + str(xform), file=sys.stderr)
               traceback.print_exc(file=sys.stderr)
               print('', file=sys.stderr)
               error = True
         else:
            if comm_exprs > nir_search_max_comm_ops:
               print("Transformation with too many commutative expressions " \
                     "({} > {}).  Modify pattern or annotate with " \
                     "\"many-comm-expr\".".format(comm_exprs,
                                                  nir_search_max_comm_ops),
                     file=sys.stderr)
               print("  " + str(xform.search), file=sys.stderr)
               print("{}".format(xform.search.cond), file=sys.stderr)
               error = True

      self.automaton = TreeAutomaton(self.xforms)

      if error:
         sys.exit(1)
Exemple #6
0
                                                            ('extract_i8', 'v', 2),
                                                            ('extract_i8', 'v', 3))),
                                           127.0))),
     'options->lower_unpack_snorm_4x8'),
]

invert = OrderedDict([('feq', 'fne'), ('fne', 'feq'), ('fge', 'flt'), ('flt', 'fge')])

for left, right in itertools.combinations_with_replacement(invert.keys(), 2):
   optimizations.append((('inot', ('ior(is_used_once)', (left, a, b), (right, c, d))),
                         ('iand', (invert[left], a, b), (invert[right], c, d))))
   optimizations.append((('inot', ('iand(is_used_once)', (left, a, b), (right, c, d))),
                         ('ior', (invert[left], a, b), (invert[right], c, d))))

# Optimize x2bN(b2x(x)) -> x
for size in type_sizes('bool'):
    aN = 'a@' + str(size)
    f2bN = 'f2b' + str(size)
    i2bN = 'i2b' + str(size)
    optimizations.append(((f2bN, ('b2f', aN)), a))
    optimizations.append(((i2bN, ('b2i', aN)), a))

# Optimize x2yN(b2x(x)) -> b2y
for x, y in itertools.product(['f', 'u', 'i'], ['f', 'u', 'i']):
   if x != 'f' and y != 'f' and x != y:
      continue

   b2x = 'b2f' if x == 'f' else 'b2i'
   b2y = 'b2f' if y == 'f' else 'b2i'
   x2yN = '{}2{}'.format(x, y)
   optimizations.append(((x2yN, (b2x, a)), (b2y, a)))