Esempio n. 1
0
    def make_constant_array(self, builder, typ, ary):
        """
        Create an array structure reifying the given constant array.
        A low-level contiguous array constant is created in the LLVM IR.
        """
        datatype = self.get_data_type(typ.dtype)
        # don't freeze ary of non-contig or bigger than 1MB
        size_limit = 10**6

        if (self.allow_dynamic_globals and
                (typ.layout not in 'FC' or ary.nbytes > size_limit)):
            # get pointer from the ary
            dataptr = ary.ctypes.data
            data = self.add_dynamic_addr(builder, dataptr, info=str(type(dataptr)))
            rt_addr = self.add_dynamic_addr(builder, id(ary), info=str(type(ary)))
        else:
            # Handle data: reify the flattened array in "C" or "F" order as a
            # global array of bytes.
            flat = ary.flatten(order=typ.layout)
            # Note: we use `bytearray(flat.data)` instead of `bytearray(flat)` to
            #       workaround issue #1850 which is due to numpy issue #3147
            consts = cgutils.create_constant_array(llvmir.IntType(8), bytearray(flat.data))
            data = cgutils.global_constant(builder, ".const.array.data", consts)
            # Ensure correct data alignment (issue #1933)
            data.align = self.get_abi_alignment(datatype)
            # No reference to parent ndarray
            rt_addr = None

        # Handle shape
        llintp = self.get_value_type(types.intp)
        shapevals = [self.get_constant(types.intp, s) for s in ary.shape]
        cshape = cgutils.create_constant_array(llintp, shapevals)

        # Handle strides
        stridevals = [self.get_constant(types.intp, s) for s in ary.strides]
        cstrides = cgutils.create_constant_array(llintp, stridevals)

        # Create array structure
        cary = self.make_array(typ)(self, builder)

        intp_itemsize = self.get_constant(types.intp, ary.dtype.itemsize)
        self.populate_array(cary,
                            data=builder.bitcast(data, cary.data.type),
                            shape=cshape,
                            strides=cstrides,
                            itemsize=intp_itemsize,
                            parent=rt_addr,
                            meminfo=None)

        return cary._getvalue()
Esempio n. 2
0
    def _emit_method_array(self, llvm_module):
        """
        Collect exported methods and emit a PyMethodDef array.

        :returns: a pointer to the PyMethodDef array.
        """
        method_defs = []
        for entry in self.export_entries:
            name = entry.symbol
            llvm_func_name = self._mangle_method_symbol(name)
            fnty = self.exported_function_types[entry]
            lfunc = ir.Function(llvm_module, fnty, llvm_func_name)

            method_name = self.context.insert_const_string(llvm_module, name)
            method_def_const = ir.Constant.literal_struct(
                (method_name, ir.Constant.bitcast(lfunc, lt._void_star),
                 METH_VARARGS_AND_KEYWORDS, NULL))
            method_defs.append(method_def_const)

        sentinel = ir.Constant.literal_struct([NULL, NULL, ZERO, NULL])
        method_defs.append(sentinel)
        method_array_init = create_constant_array(self.method_def_ty,
                                                  method_defs)
        method_array = cgutils.add_global_variable(llvm_module,
                                                   method_array_init.type,
                                                   '.module_methods')
        method_array.initializer = method_array_init
        method_array.linkage = 'internal'
        method_array_ptr = ir.Constant.gep(method_array, [ZERO, ZERO])
        return method_array_ptr
Esempio n. 3
0
    def _emit_envgvs_array(self, llvm_module, builder, pyapi):
        """
        Emit an array of Environment pointers that needs to be filled at
        initialization.
        """
        env_setters = []
        for entry in self.export_entries:
            envgv_name = self.environment_gvs[entry]
            gv = self.context.declare_env_global(llvm_module, envgv_name)
            envgv = gv.bitcast(lt._void_star)
            env_setters.append(envgv)

        env_setters_init = create_constant_array(lt._void_star, env_setters)
        gv = self.context.insert_unique_const(llvm_module, '.module_envgvs',
                                              env_setters_init)
        return gv.gep([ZERO, ZERO])
Esempio n. 4
0
 def _emit_environment_array(self, llvm_module, builder, pyapi):
     """
     Emit an array of env_def_t structures (see modulemixin.c)
     storing the pickled environment constants for each of the
     exported functions.
     """
     env_defs = []
     for entry in self.export_entries:
         env = self.function_environments[entry]
         # Constants may be unhashable so avoid trying to cache them
         env_def = pyapi.serialize_uncached(env.consts)
         env_defs.append(env_def)
     env_defs_init = create_constant_array(self.env_def_ty, env_defs)
     gv = self.context.insert_unique_const(llvm_module,
                                           '.module_environments',
                                           env_defs_init)
     return gv.gep([ZERO, ZERO])
Esempio n. 5
0
    """
    return builder.icmp_unsigned('!=', val, NAT)


def are_not_nat(builder, vals):
    """
    Return a predicate which is true if all of *vals* are not NaT.
    """
    assert len(vals) >= 1
    pred = is_not_nat(builder, vals[0])
    for val in vals[1:]:
        pred = builder.and_(pred, is_not_nat(builder, val))
    return pred


normal_year_months = create_constant_array(
    TIMEDELTA64, [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31])
leap_year_months = create_constant_array(
    TIMEDELTA64, [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31])
normal_year_months_acc = create_constant_array(
    TIMEDELTA64, [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334])
leap_year_months_acc = create_constant_array(
    TIMEDELTA64, [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335])


@lower_constant(types.NPDatetime)
@lower_constant(types.NPTimedelta)
def datetime_constant(context, builder, ty, pyval):
    return DATETIME64(pyval.astype(np.int64))


# Arithmetic operators on timedelta64