def __init__(self, parent, op, lhs, rhs, name='', flags=[]): if op not in self.VALID_OP: raise ValueError("invalid comparison %r for %s" % (op, self.OPNAME)) for flag in flags: if flag not in self.VALID_FLAG: raise ValueError("invalid flag %r for %s" % (flag, self.OPNAME)) opname = self.OPNAME if isinstance(lhs.type, types.VectorType): typ = types.VectorType(types.IntType(1), lhs.type.count) else: typ = types.IntType(1) super(CompareInstr, self).__init__(parent, typ, opname, [lhs, rhs], flags=flags, name=name) self.op = op
def __init__(self, module): self.module = module self.bits = 64 self.llvm_type = types.IntType(self.bits) self.signed = False self.type_id = "type" self._default = 0
def __init__(self, parent, ptr, cmp, val, ordering, failordering, name): outtype = types.LiteralStructType([val.type, types.IntType(1)]) super(CmpXchg, self).__init__( parent, outtype, "cmpxchg", (ptr, cmp, val), name=name ) self.ordering = ordering self.failordering = failordering
def set_weights(self, weights): operands = [MetaDataString(self.module, "branch_weights")] for w in weights: if w < 0: raise ValueError("branch weight must be a positive integer") operands.append(Constant(types.IntType(32), w)) md = self.module.add_metadata(operands) self.set_metadata("prof", md)
def declare_intrinsic(self, intrinsic, tys=(), fnty=None): def _error(): raise NotImplementedError("unknown intrinsic %r with %d types" % (intrinsic, len(tys))) if intrinsic in {'llvm.cttz', 'llvm.ctlz', 'llvm.fma'}: suffixes = [tys[0].intrinsic_name] else: suffixes = [t.intrinsic_name for t in tys] name = '.'.join([intrinsic] + suffixes) if name in self.globals: return self.globals[name] if fnty is not None: # General case: function type is given pass # Compute function type if omitted for common cases elif len(tys) == 0 and intrinsic == 'llvm.assume': fnty = types.FunctionType(types.VoidType(), [types.IntType(1)]) elif len(tys) == 1: if intrinsic == 'llvm.powi': fnty = types.FunctionType(tys[0], [tys[0], types.IntType(32)]) elif intrinsic == 'llvm.pow': fnty = types.FunctionType(tys[0], tys * 2) elif intrinsic == 'llvm.convert.from.fp16': fnty = types.FunctionType(tys[0], [types.IntType(16)]) elif intrinsic == 'llvm.convert.to.fp16': fnty = types.FunctionType(types.IntType(16), tys) else: fnty = types.FunctionType(tys[0], tys) elif len(tys) == 2: if intrinsic == 'llvm.memset': tys = [tys[0], types.IntType(8), tys[1], types.IntType(1)] fnty = types.FunctionType(types.VoidType(), tys) elif intrinsic in {'llvm.cttz', 'llvm.ctlz'}: tys = [tys[0], types.IntType(1)] fnty = types.FunctionType(tys[0], tys) else: _error() elif len(tys) == 3: if intrinsic in ('llvm.memcpy', 'llvm.memmove'): tys = tys + [types.IntType(1)] fnty = types.FunctionType(types.VoidType(), tys) elif intrinsic == 'llvm.fma': tys = [tys[0]] * 3 fnty = types.FunctionType(tys[0], tys) else: _error() else: _error() return values.Function(self, fnty, name=name)
def alloca(self, typ, size=None, name=""): """ Stack-allocate a slot for *size* elements of the given type. (default one element) """ if size is None: pass elif isinstance(size, (values.Value, values.Constant)): assert isinstance(size.type, types.IntType) else: # If it is not a Value instance, # assume to be a Python integer. size = values.Constant(types.IntType(32), size) al = instructions.AllocaInstr(self.block, typ, size, name) self._insert(al) return al
def wrapped(self, lhs, rhs, name=""): if lhs.type != rhs.type: raise ValueError( "Operands must be the same type, got (%s, %s)" % (lhs.type, rhs.type)) ty = lhs.type if not isinstance(ty, types.IntType): raise TypeError("expected an integer type, got %s" % (ty, )) bool_ty = types.IntType(1) mod = self.module fnty = types.FunctionType(types.LiteralStructType([ty, bool_ty]), [ty, ty]) fn = mod.declare_intrinsic("llvm.%s.with.overflow" % (opname, ), [ty], fnty) ret = self.call(fn, [lhs, rhs], name=name) return ret
def _cmp(self, prefix, sign, cmpop, other): ins = prefix + 'cmp' try: op = _CMP_MAP[cmpop] except KeyError: raise ValueError("invalid comparison %r for %s" % (cmpop, ins)) if not (prefix == 'i' and cmpop in ('==', '!=')): op = sign + op if self.type != other.type: raise ValueError("Operands must be the same type, got (%s, %s)" % (self.type, other.type)) fmt = "{0} {1} ({2} {3}, {4} {5})".format(ins, op, self.type, self.get_reference(), other.type, other.get_reference()) return FormattedConstant(types.IntType(1), fmt)
def __init__(self, function, basic_block): assert isinstance(function, Function) assert isinstance(basic_block, Block) self.type = types.IntType(8).as_pointer() self.function = function self.basic_block = basic_block
def __init__(self): self.bits = 1 self.llvm_type = types.IntType(1) self.signed = False self.type_id = "bool"
def __init__(self, bits, signed): self.bits = bits self.llvm_type = types.IntType(bits) self.signed = signed self.type_id = f'{"i" if signed else "u"}{bits}'