Ejemplo n.º 1
0
    def frontend_looplift(self):
        """
        Loop lifting analysis and transformation
        """
        assert not self.lifted

        # Try loop lifting
        loop_flags = self.flags.copy()
        outer_flags = self.flags.copy()
        # Do not recursively loop lift
        outer_flags.unset('enable_looplift')
        loop_flags.unset('enable_looplift')
        if not self.flags.enable_pyobject_looplift:
            loop_flags.unset('enable_pyobject')

        def dispatcher_factory(loopbc):
            from . import dispatcher
            return dispatcher.LiftedLoop(loopbc, self.typingctx,
                                         self.targetctx,
                                         self.locals, loop_flags)

        entry, loops = looplifting.lift_loop(self.bc, dispatcher_factory)
        if loops:
            # Some loops were extracted
            if config.DEBUG_FRONTEND or config.DEBUG:
                print("Lifting loop", loops[0].get_source_location())

            cres = compile_bytecode(self.typingctx, self.targetctx, entry,
                                    self.args, self.return_type,
                                    outer_flags, self.locals,
                                    lifted=tuple(loops), lifted_from=None,
                                    func_attr=self.func_attr)
            return cres
Ejemplo n.º 2
0
    def frontend_looplift(self):
        """
        Loop lifting analysis and transformation
        """
        assert not self.lifted

        # Try loop lifting
        loop_flags = self.flags.copy()
        outer_flags = self.flags.copy()
        # Do not recursively loop lift
        outer_flags.unset('enable_looplift')
        loop_flags.unset('enable_looplift')
        if not self.flags.enable_pyobject_looplift:
            loop_flags.unset('enable_pyobject')

        def dispatcher_factory(loopbc):
            from . import dispatcher
            return dispatcher.LiftedLoop(loopbc, self.typingctx,
                                         self.targetctx,
                                         self.locals, loop_flags)

        entry, loops = looplifting.lift_loop(self.bc, dispatcher_factory)
        if loops:
            # Some loops were extracted
            if config.DEBUG_FRONTEND or config.DEBUG:
                print("Lifting loop", loops[0].get_source_location())

            cres = compile_bytecode(self.typingctx, self.targetctx, entry,
                                    self.args, self.return_type,
                                    outer_flags, self.locals,
                                    lifted=tuple(loops), lifted_from=None,
                                    func_attr=self.func_attr)
            return cres
Ejemplo n.º 3
0
def compile_bytecode(typingctx, targetctx, bc, args, return_type, flags,
                     locals, lifted=()):
    interp = translate_stage(bc)
    nargs = len(interp.argspec.args)
    if len(args) > nargs:
        raise TypeError("Too many argument types")

    status = _CompileStatus()
    status.can_fallback = flags.enable_pyobject
    status.fail_reason = None
    status.use_python_mode = flags.force_pyobject

    targetctx = targetctx.localized()

    if not status.use_python_mode:
        with _fallback_context(status):
            legalize_given_types(args, return_type)
            # Type inference
            typemap, return_type, calltypes = type_inference_stage(typingctx,
                                                                   interp,
                                                                   args,
                                                                   return_type,
                                                                   locals)

        if not status.use_python_mode:
            with _fallback_context(status):
                legalize_return_type(return_type, interp, targetctx)

    if status.use_python_mode and flags.enable_looplift:
        assert not lifted
        # Try loop lifting
        entry, loops = looplifting.lift_loop(bc)
        if not loops:
            # No extracted loops
            pass
        else:
            loopflags = flags.copy()
            # Do not recursively loop lift
            loopflags.unset('enable_looplift')
            loopdisp = looplifting.bind(loops, typingctx, targetctx, locals,
                                        loopflags)
            lifted = tuple(loopdisp)
            cres = compile_bytecode(typingctx, targetctx, entry, args,
                                    return_type, loopflags, locals,
                                    lifted=lifted)
            return cres._replace(lifted=lifted)

    if status.use_python_mode:
        # Object mode compilation
        func, fnptr, lmod, lfunc, fndesc = py_lowering_stage(targetctx, interp,
                                                             flags.no_compile)
        typemap = defaultdict(lambda: types.pyobject)
        calltypes = defaultdict(lambda: types.pyobject)

        return_type = types.pyobject

        if len(args) != nargs:
            # append missing
            args = tuple(args) + (types.pyobject,) * (nargs - len(args))
    else:
        # Native mode compilation
        func, fnptr, lmod, lfunc, fndesc = native_lowering_stage(targetctx,
                                                                 interp,
                                                                 typemap,
                                                                 return_type,
                                                                 calltypes,
                                                                 flags.no_compile)

    type_annotation = type_annotations.TypeAnnotation(interp=interp,
                                                      typemap=typemap,
                                                      calltypes=calltypes,
                                                      lifted=lifted)
    if config.ANNOTATE:
        print("ANNOTATION".center(80, '-'))
        print(type_annotation)
        print('=' * 80)

    signature = typing.signature(return_type, *args)

    assert lfunc.module is lmod
    cr = compile_result(typing_context=typingctx,
                        target_context=targetctx,
                        entry_point=func,
                        entry_point_addr=fnptr,
                        typing_error=status.fail_reason,
                        type_annotation=type_annotation,
                        llvm_func=lfunc,
                        llvm_module=lmod,
                        signature=signature,
                        objectmode=status.use_python_mode,
                        lifted=lifted,
                        fndesc=fndesc,)
    return cr
Ejemplo n.º 4
0
def _compile_core(typingctx, targetctx, bc, args, return_type, flags, locals,
                  lifted, func_attr, status):
    ### Front-end: Analyze bytecode, generate Numba IR, infer types
    interp = translate_stage(bc)
    nargs = len(interp.argspec.args)
    if len(args) > nargs:
        raise TypeError("Too many argument types")

    if not status.use_python_mode:
        with _fallback_context(status):
            legalize_given_types(args, return_type)
            # Type inference
            typemap, return_type, calltypes = type_inference_stage(
                typingctx, interp, args, return_type, locals)

        if status.fail_reason is not None:
            warnings.warn_explicit(
                'Function "%s" failed type inference: %s' %
                (func_attr.name, status.fail_reason), config.NumbaWarning,
                func_attr.filename, func_attr.lineno)

        if not status.use_python_mode:
            with _fallback_context(status):
                legalize_return_type(return_type, interp, targetctx)
            if status.fail_reason is not None:
                warnings.warn_explicit(
                    'Function "%s" has invalid return type: %s' %
                    (func_attr.name, status.fail_reason), config.NumbaWarning,
                    func_attr.filename, func_attr.lineno)

    if status.use_python_mode and flags.enable_looplift:
        assert not lifted

        # Try loop lifting
        loop_flags = flags.copy()
        outer_flags = flags.copy()
        # Do not recursively loop lift
        outer_flags.unset('enable_looplift')
        loop_flags.unset('enable_looplift')
        if not flags.enable_pyobject_looplift:
            loop_flags.unset('enable_pyobject')

        def dispatcher_factory(loopbc):
            from . import dispatcher
            return dispatcher.LiftedLoop(loopbc, typingctx, targetctx, locals,
                                         loop_flags)

        entry, loops = looplifting.lift_loop(bc, dispatcher_factory)
        if loops:
            # Some loops were extracted
            cres = compile_bytecode(typingctx,
                                    targetctx,
                                    entry,
                                    args,
                                    return_type,
                                    outer_flags,
                                    locals,
                                    lifted=tuple(loops),
                                    func_attr=func_attr)
            return cres

    if status.use_python_mode:
        # Fallback typing: everything is a python object
        typemap = defaultdict(lambda: types.pyobject)
        calltypes = defaultdict(lambda: types.pyobject)
        return_type = types.pyobject

    type_annotation = type_annotations.TypeAnnotation(interp=interp,
                                                      typemap=typemap,
                                                      calltypes=calltypes,
                                                      lifted=lifted)
    if config.ANNOTATE:
        print("ANNOTATION".center(80, '-'))
        print(type_annotation)
        print('=' * 80)

    ### Back-end: Generate LLVM IR from Numba IR, compile to machine code

    if status.use_python_mode:
        # Object mode compilation
        func, lmod, lfunc, fndesc = py_lowering_stage(targetctx, interp,
                                                      flags.no_compile)
        if len(args) != nargs:
            # append missing
            args = tuple(args) + (types.pyobject, ) * (nargs - len(args))
    else:
        # Native mode compilation
        func, lmod, lfunc, fndesc = native_lowering_stage(
            targetctx, interp, typemap, return_type, calltypes,
            flags.no_compile)

    signature = typing.signature(return_type, *args)

    assert lfunc.module is lmod
    cr = compile_result(
        typing_context=typingctx,
        target_context=targetctx,
        entry_point=func,
        typing_error=status.fail_reason,
        type_annotation=type_annotation,
        llvm_func=lfunc,
        llvm_module=lmod,
        signature=signature,
        objectmode=status.use_python_mode,
        lifted=lifted,
        fndesc=fndesc,
    )

    # Warn if compiled function in object mode and force_pyobject not set
    if status.use_python_mode and not flags.force_pyobject:
        warn_msg = ('Function "{name}" was compiled in object mode '
                    'without forceobj=True').format(name=func_attr.name)

        if len(lifted) > 0:
            warn_msg += ', but has lifted loops.'

        warnings.warn_explicit(warn_msg, config.NumbaWarning,
                               func_attr.filename, func_attr.lineno)

    return cr
Ejemplo n.º 5
0
def _compile_core(typingctx, targetctx, bc, args, return_type, flags, locals,
                  lifted, func_attr, status):
    ### Front-end: Analyze bytecode, generate Numba IR, infer types
    interp = translate_stage(bc)
    nargs = len(interp.argspec.args)
    if len(args) > nargs:
        raise TypeError("Too many argument types")

    if not status.use_python_mode:
        with _fallback_context(status):
            legalize_given_types(args, return_type)
            # Type inference
            typemap, return_type, calltypes = type_inference_stage(typingctx,
                                                                   interp,
                                                                   args,
                                                                   return_type,
                                                                   locals)

        if status.fail_reason is not None:
            warnings.warn_explicit('Function "%s" failed type inference: %s'
                          % (func_attr.name, status.fail_reason),
                          config.NumbaWarning,
                          func_attr.filename, func_attr.lineno)

        if not status.use_python_mode:
            with _fallback_context(status):
                legalize_return_type(return_type, interp, targetctx)
            if status.fail_reason is not None:
                warnings.warn_explicit('Function "%s" has invalid return type: %s'
                                       % (func_attr.name, status.fail_reason),
                                       config.NumbaWarning,
                                       func_attr.filename, func_attr.lineno)

    if status.use_python_mode and flags.enable_looplift:
        assert not lifted

        # Try loop lifting
        loop_flags = flags.copy()
        outer_flags = flags.copy()
        # Do not recursively loop lift
        outer_flags.unset('enable_looplift')
        loop_flags.unset('enable_looplift')
        if not flags.enable_pyobject_looplift:
            loop_flags.unset('enable_pyobject')

        def dispatcher_factory(loopbc):
            from . import dispatcher
            return dispatcher.LiftedLoop(loopbc, typingctx, targetctx,
                                         locals, loop_flags)

        entry, loops = looplifting.lift_loop(bc, dispatcher_factory)
        if loops:
            # Some loops were extracted
            cres = compile_bytecode(typingctx, targetctx, entry, args,
                                    return_type, outer_flags, locals,
                                    lifted=tuple(loops),
                                    func_attr=func_attr)
            return cres

    if status.use_python_mode:
        # Fallback typing: everything is a python object
        typemap = defaultdict(lambda: types.pyobject)
        calltypes = defaultdict(lambda: types.pyobject)
        return_type = types.pyobject

    type_annotation = type_annotations.TypeAnnotation(interp=interp,
                                                      typemap=typemap,
                                                      calltypes=calltypes,
                                                      lifted=lifted)
    if config.ANNOTATE:
        print("ANNOTATION".center(80, '-'))
        print(type_annotation)
        print('=' * 80)

    ### Back-end: Generate LLVM IR from Numba IR, compile to machine code

    if status.use_python_mode:
        # Object mode compilation
        func, lmod, lfunc, fndesc = py_lowering_stage(targetctx, interp,
                                                      flags.no_compile)
        if len(args) != nargs:
            # append missing
            args = tuple(args) + (types.pyobject,) * (nargs - len(args))
    else:
        # Native mode compilation
        func, lmod, lfunc, fndesc = native_lowering_stage(targetctx,
                                                          interp,
                                                          typemap,
                                                          return_type,
                                                          calltypes,
                                                          flags.no_compile)

    signature = typing.signature(return_type, *args)

    assert lfunc.module is lmod
    cr = compile_result(typing_context=typingctx,
                        target_context=targetctx,
                        entry_point=func,
                        typing_error=status.fail_reason,
                        type_annotation=type_annotation,
                        llvm_func=lfunc,
                        llvm_module=lmod,
                        signature=signature,
                        objectmode=status.use_python_mode,
                        lifted=lifted,
                        fndesc=fndesc,)

    # Warn if compiled function in object mode and force_pyobject not set
    if status.use_python_mode and not flags.force_pyobject:
        warn_msg = ('Function "{name}" was compiled in object mode '
                         'without forceobj=True').format(name=func_attr.name)

        if len(lifted) > 0:
            warn_msg += ', but has lifted loops.'

        warnings.warn_explicit(warn_msg,
                               config.NumbaWarning, func_attr.filename,
                               func_attr.lineno)

    return cr
Ejemplo n.º 6
0
def compile_bytecode(typingctx, targetctx, bc, args, return_type, flags,
                     locals, lifted=()):
    interp = translate_stage(bc)
    nargs = len(interp.argspec.args)
    if len(args) > nargs:
        raise TypeError("Too many argument types")

    status = _CompileStatus()
    status.can_fallback = flags.enable_pyobject
    status.fail_reason = None
    status.use_python_mode = flags.force_pyobject

    targetctx = targetctx.localized()
    targetctx.metadata['wraparound'] = not flags.no_wraparound

    if not status.use_python_mode:
        with _fallback_context(status):
            legalize_given_types(args, return_type)
            # Type inference
            typemap, return_type, calltypes = type_inference_stage(typingctx,
                                                                   interp,
                                                                   args,
                                                                   return_type,
                                                                   locals)

        if not status.use_python_mode:
            with _fallback_context(status):
                legalize_return_type(return_type, interp, targetctx)

    if status.use_python_mode and flags.enable_looplift:
        assert not lifted
        # Try loop lifting
        entry, loops = looplifting.lift_loop(bc)
        if not loops:
            # No extracted loops
            pass
        else:
            loopflags = flags.copy()
            # Do not recursively loop lift
            loopflags.unset('enable_looplift')
            loopdisp = looplifting.bind(loops, typingctx, targetctx, locals,
                                        loopflags)
            lifted = tuple(loopdisp)
            cres = compile_bytecode(typingctx, targetctx, entry, args,
                                    return_type, loopflags, locals,
                                    lifted=lifted)
            return cres._replace(lifted=lifted)

    if status.use_python_mode:
        # Object mode compilation
        func, fnptr, lmod, lfunc, fndesc = py_lowering_stage(targetctx, interp,
                                                             flags.no_compile)
        typemap = defaultdict(lambda: types.pyobject)
        calltypes = defaultdict(lambda: types.pyobject)

        return_type = types.pyobject

        if len(args) != nargs:
            # append missing
            args = tuple(args) + (types.pyobject,) * (nargs - len(args))
    else:
        # Native mode compilation
        func, fnptr, lmod, lfunc, fndesc = native_lowering_stage(targetctx,
                                                                 interp,
                                                                 typemap,
                                                                 return_type,
                                                                 calltypes,
                                                                 flags.no_compile)

    type_annotation = type_annotations.TypeAnnotation(interp=interp,
                                                      typemap=typemap,
                                                      calltypes=calltypes,
                                                      lifted=lifted)
    if config.ANNOTATE:
        print("ANNOTATION".center(80, '-'))
        print(type_annotation)
        print('=' * 80)

    signature = typing.signature(return_type, *args)

    assert lfunc.module is lmod
    cr = compile_result(typing_context=typingctx,
                        target_context=targetctx,
                        entry_point=func,
                        entry_point_addr=fnptr,
                        typing_error=status.fail_reason,
                        type_annotation=type_annotation,
                        llvm_func=lfunc,
                        llvm_module=lmod,
                        signature=signature,
                        objectmode=status.use_python_mode,
                        lifted=lifted,
                        fndesc=fndesc,)
    return cr