# Buggy code
def run(self):
    """Finds all calls to StencilFuncs in the IR and converts them to parfor."""
    from numba.stencil import StencilFunc

    # Get all the calls in the function IR.
    call_table, _ = get_call_table(self.func_ir.blocks)
    stencil_calls = []
    stencil_dict = {}
    for call_varname, call_list in call_table.items():
        if len(call_list) == 1 and isinstance(call_list[0], StencilFunc):
            # Remember all calls to StencilFuncs.
            stencil_calls.append(call_varname)
            stencil_dict[call_varname] = call_list[0]
    if not stencil_calls:
        return  # return early if no stencil calls found

    # find and transform stencil calls
    for label, block in self.func_ir.blocks.items():
        for i, stmt in reversed(list(enumerate(block.body))):
            # Found a call to a StencilFunc.
            if (
                isinstance(stmt, ir.Assign)
                and isinstance(stmt.value, ir.Expr)
                and stmt.value.op == "call"
                and stmt.value.func.name in stencil_calls
            ):
                kws = dict(stmt.value.kws)
                # Create dictionary of input argument number to
                # the argument itself.
                input_dict = {
                    i: stmt.value.args[i] for i in range(len(stmt.value.args))
                }
                in_args = stmt.value.args
                arg_typemap = tuple(self.typemap[i.name] for i in in_args)
                for arg_type in arg_typemap:
                    if isinstance(arg_type, types.BaseTuple):
                        raise ValueError(
                            "Tuple parameters not supported "
                            "for stencil kernels in parallel=True mode."
                        )

                out_arr = kws.get("out")

                # Get the StencilFunc object corresponding to this call.
                sf = stencil_dict[stmt.value.func.name]
                stencil_ir, rt, arg_to_arr_dict = get_stencil_ir(
                    sf,
                    self.typingctx,
                    arg_typemap,
                    block.scope,
                    block.loc,
                    input_dict,
                    self.typemap,
                    self.calltypes,
                )
                index_offsets = sf.options.get("index_offsets", None)
                gen_nodes = self._mk_stencil_parfor(
                    label,
                    in_args,
                    out_arr,
                    stencil_ir,
                    index_offsets,
                    stmt.target,
                    rt,
                    sf,
                    arg_to_arr_dict,
                )
                block.body = block.body[:i] + gen_nodes + block.body[i + 1 :]
            # Found a call to a stencil via numba.stencil().
            elif (
                isinstance(stmt, ir.Assign)
                and isinstance(stmt.value, ir.Expr)
                and stmt.value.op == "call"
                and guard(find_callname, self.func_ir, stmt.value)
                == ("stencil", "numba")
            ):
                # remove dummy stencil() call
                stmt.value = ir.Const(0, stmt.loc)


# Traceback (ValueError)
## run this:
```python
@njit(parallel=True)
def stencil_test2(A):
    @stencil
    def fun (a):
        c = 2
        return 0.3 * (a[-c+1] + a[0] + a[c-1])
    B = fun(A)
    return B
stencil_test2(np.arange(10))
```

## see this:
```python
/Users/bennettd/miniconda3/lib/python3.7/site-packages/numba/compiler.py:602: NumbaPerformanceWarning: 
The keyword argument 'parallel=True' was specified but no transformation for parallel execution was possible.

To find out why, try turning on parallel diagnostics, see http://numba.pydata.org/numba-doc/latest/user/parallel.html#diagnostics for help.

File "<ipython-input-575-2412dcac74fb>", line 2:
@njit(parallel=True)
def stencil_test2(A):
^

  self.func_ir.loc))

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
~/miniconda3/lib/python3.7/site-packages/numba/errors.py in new_error_context(fmt_, *args, **kwargs)
    661     try:
--> 662         yield
    663     except NumbaError as e:

~/miniconda3/lib/python3.7/site-packages/numba/lowering.py in lower_block(self, block)
    257                                    loc=self.loc, errcls_=defaulterrcls):
--> 258                 self.lower_inst(inst)
    259 

~/miniconda3/lib/python3.7/site-packages/numba/lowering.py in lower_inst(self, inst)
    300             ty = self.typeof(inst.target.name)
--> 301             val = self.lower_assign(ty, inst)
    302             self.storevar(val, inst.target.name)

~/miniconda3/lib/python3.7/site-packages/numba/lowering.py in lower_assign(self, ty, inst)
    458         elif isinstance(value, ir.Expr):
--> 459             return self.lower_expr(ty, value)
    460 

~/miniconda3/lib/python3.7/site-packages/numba/lowering.py in lower_expr(self, resty, expr)
    918         elif expr.op == 'call':
--> 919             res = self.lower_call(resty, expr)
    920             return res

~/miniconda3/lib/python3.7/site-packages/numba/lowering.py in lower_call(self, resty, expr)
    710         else:
--> 711             res = self._lower_call_normal(fnty, expr, signature)
    712 

~/miniconda3/lib/python3.7/site-packages/numba/lowering.py in _lower_call_normal(self, fnty, expr, signature)
    889 
--> 890         res = impl(self.builder, argvals, self.loc)
    891         return res

~/miniconda3/lib/python3.7/site-packages/numba/targets/base.py in __call__(self, builder, args, loc)
   1131     def __call__(self, builder, args, loc=None):
-> 1132         res = self._imp(self._context, builder, self._sig, args, loc=loc)
   1133         self._context.add_linking_libs(getattr(self, 'libs', ()))

~/miniconda3/lib/python3.7/site-packages/numba/targets/base.py in wrapper(*args, **kwargs)
   1156             kwargs.pop('loc')     # drop unused loc
-> 1157             return fn(*args, **kwargs)
   1158 

~/miniconda3/lib/python3.7/site-packages/numba/stencil.py in __call__(self, context, builder, sig, args)
     30         cres = self.stencilFunc.compile_for_argtys(sig.args, {},
---> 31                     sig.return_type, None)
     32         res = context.call_internal(builder, cres.fndesc, sig, args)

~/miniconda3/lib/python3.7/site-packages/numba/stencil.py in compile_for_argtys(self, argtys, kwtys, return_type, sigret)
    362         new_func = self._stencil_wrapper(result, sigret, return_type,
--> 363                                          typemap, calltypes, *argtys)
    364         return new_func

~/miniconda3/lib/python3.7/site-packages/numba/stencil.py in _stencil_wrapper(self, result, sigret, return_type, typemap, calltypes, *args)
    522                 kernel_copy, index_vars, the_array.ndim,
--> 523                 self.neighborhood, standard_indexed, typemap, copy_calltypes)
    524         if self.neighborhood is None:

~/miniconda3/lib/python3.7/site-packages/numba/stencil.py in add_indices_to_kernel(self, kernel, index_names, ndim, neighborhood, standard_indexed, typemap, calltypes)
    194                         else:
--> 195                             raise ValueError("stencil kernel index is not "
    196                                 "constant, 'neighborhood' option required")

ValueError: stencil kernel index is not constant, 'neighborhood' option required

During handling of the above exception, another exception occurred:

LoweringError                             Traceback (most recent call last)
<ipython-input-575-2412dcac74fb> in <module>
      7     B = fun(A)
      8     return B
----> 9 stencil_test2(np.arange(10))

~/miniconda3/lib/python3.7/site-packages/numba/dispatcher.py in _compile_for_args(self, *args, **kws)
    393                     e.patch_message(''.join(e.args) + help_msg)
    394             # ignore the FULL_TRACEBACKS config, this needs reporting!
--> 395             raise e
    396 
    397     def inspect_llvm(self, signature=None):

~/miniconda3/lib/python3.7/site-packages/numba/dispatcher.py in _compile_for_args(self, *args, **kws)
    350                 argtypes.append(self.typeof_pyval(a))
    351         try:
--> 352             return self.compile(tuple(argtypes))
    353         except errors.TypingError as e:
    354             # Intercept typing error that may be due to an argument

~/miniconda3/lib/python3.7/site-packages/numba/compiler_lock.py in _acquire_compile_lock(*args, **kwargs)
     30         def _acquire_compile_lock(*args, **kwargs):
     31             with self:
---> 32                 return func(*args, **kwargs)
     33         return _acquire_compile_lock
     34 

~/miniconda3/lib/python3.7/site-packages/numba/dispatcher.py in compile(self, sig)
    691 
    692             self._cache_misses[sig] += 1
--> 693             cres = self._compiler.compile(args, return_type)
    694             self.add_overload(cres)
    695             self._cache.save_overload(sig, cres)

~/miniconda3/lib/python3.7/site-packages/numba/dispatcher.py in compile(self, args, return_type)
     74 
     75     def compile(self, args, return_type):
---> 76         status, retval = self._compile_cached(args, return_type)
     77         if status:
     78             return retval

~/miniconda3/lib/python3.7/site-packages/numba/dispatcher.py in _compile_cached(self, args, return_type)
     88 
     89         try:
---> 90             retval = self._compile_core(args, return_type)
     91         except errors.TypingError as e:
     92             self._failed_cache[key] = e

~/miniconda3/lib/python3.7/site-packages/numba/dispatcher.py in _compile_core(self, args, return_type)
    106                                       args=args, return_type=return_type,
    107                                       flags=flags, locals=self.locals,
--> 108                                       pipeline_class=self.pipeline_class)
    109         # Check typing error if object mode is used
    110         if cres.typing_error is not None and not flags.enable_pyobject:

~/miniconda3/lib/python3.7/site-packages/numba/compiler.py in compile_extra(typingctx, targetctx, func, args, return_type, flags, locals, library, pipeline_class)
    970     pipeline = pipeline_class(typingctx, targetctx, library,
    971                               args, return_type, flags, locals)
--> 972     return pipeline.compile_extra(func)
    973 
    974 

~/miniconda3/lib/python3.7/site-packages/numba/compiler.py in compile_extra(self, func)
    388         self.lifted = ()
    389         self.lifted_from = None
--> 390         return self._compile_bytecode()
    391 
    392     def compile_ir(self, func_ir, lifted=(), lifted_from=None):

~/miniconda3/lib/python3.7/site-packages/numba/compiler.py in _compile_bytecode(self)
    901         """
    902         assert self.func_ir is None
--> 903         return self._compile_core()
    904 
    905     def _compile_ir(self):

~/miniconda3/lib/python3.7/site-packages/numba/compiler.py in _compile_core(self)
    888         self.define_pipelines(pm)
    889         pm.finalize()
--> 890         res = pm.run(self.status)
    891         if res is not None:
    892             # Early pipeline completion

~/miniconda3/lib/python3.7/site-packages/numba/compiler_lock.py in _acquire_compile_lock(*args, **kwargs)
     30         def _acquire_compile_lock(*args, **kwargs):
     31             with self:
---> 32                 return func(*args, **kwargs)
     33         return _acquire_compile_lock
     34 

~/miniconda3/lib/python3.7/site-packages/numba/compiler.py in run(self, status)
    264                     # No more fallback pipelines?
    265                     if is_final_pipeline:
--> 266                         raise patched_exception
    267                     # Go to next fallback pipeline
    268                     else:

~/miniconda3/lib/python3.7/site-packages/numba/compiler.py in run(self, status)
    255                 try:
    256                     event("-- %s" % stage_name)
--> 257                     stage()
    258                 except _EarlyPipelineCompletion as e:
    259                     return e.result

~/miniconda3/lib/python3.7/site-packages/numba/compiler.py in stage_nopython_backend(self)
    762         """
    763         lowerfn = self.backend_nopython_mode
--> 764         self._backend(lowerfn, objectmode=False)
    765 
    766     def stage_compile_interp_mode(self):

~/miniconda3/lib/python3.7/site-packages/numba/compiler.py in _backend(self, lowerfn, objectmode)
    701             self.library.enable_object_caching()
    702 
--> 703         lowered = lowerfn()
    704         signature = typing.signature(self.return_type, *self.args)
    705         self.cr = compile_result(

~/miniconda3/lib/python3.7/site-packages/numba/compiler.py in backend_nopython_mode(self)
    688                 self.calltypes,
    689                 self.flags,
--> 690                 self.metadata)
    691 
    692     def _backend(self, lowerfn, objectmode):

~/miniconda3/lib/python3.7/site-packages/numba/compiler.py in native_lowering_stage(targetctx, library, interp, typemap, restype, calltypes, flags, metadata)
   1141         lower = lowering.Lower(targetctx, library, fndesc, interp,
   1142                                metadata=metadata)
-> 1143         lower.lower()
   1144         if not flags.no_cpython_wrapper:
   1145             lower.create_cpython_wrapper(flags.release_gil)

~/miniconda3/lib/python3.7/site-packages/numba/lowering.py in lower(self)
    175         if self.generator_info is None:
    176             self.genlower = None
--> 177             self.lower_normal_function(self.fndesc)
    178         else:
    179             self.genlower = self.GeneratorLower(self)

~/miniconda3/lib/python3.7/site-packages/numba/lowering.py in lower_normal_function(self, fndesc)
    216         # Init argument values
    217         self.extract_function_arguments()
--> 218         entry_block_tail = self.lower_function_body()
    219 
    220         # Close tail of entry block

~/miniconda3/lib/python3.7/site-packages/numba/lowering.py in lower_function_body(self)
    241             bb = self.blkmap[offset]
    242             self.builder.position_at_end(bb)
--> 243             self.lower_block(block)
    244 
    245         self.post_lower()

~/miniconda3/lib/python3.7/site-packages/numba/lowering.py in lower_block(self, block)
    256             with new_error_context('lowering "{inst}" at {loc}', inst=inst,
    257                                    loc=self.loc, errcls_=defaulterrcls):
--> 258                 self.lower_inst(inst)
    259 
    260     def create_cpython_wrapper(self, release_gil=False):

~/miniconda3/lib/python3.7/contextlib.py in __exit__(self, type, value, traceback)
    128                 value = type()
    129             try:
--> 130                 self.gen.throw(type, value, traceback)
    131             except StopIteration as exc:
    132                 # Suppress StopIteration *unless* it's the same exception that

~/miniconda3/lib/python3.7/site-packages/numba/errors.py in new_error_context(fmt_, *args, **kwargs)
    668         from numba import config
    669         tb = sys.exc_info()[2] if config.FULL_TRACEBACKS else None
--> 670         six.reraise(type(newerr), newerr, tb)
    671 
    672 

~/miniconda3/lib/python3.7/site-packages/numba/six.py in reraise(tp, value, tb)
    657         if value.__traceback__ is not tb:
    658             raise value.with_traceback(tb)
--> 659         raise value
    660 
    661 else:

LoweringError: Failed in nopython mode pipeline (step: nopython mode backend)
stencil kernel index is not constant, 'neighborhood' option required

File "<ipython-input-575-2412dcac74fb>", line 7:
    def fun (a):
        <source elided>
        return 0.3 * (a[-c+1] + a[0] + a[c-1])
    B = fun(A)
    ^

[1] During: lowering "$B.9417 = call $fun.9416(A, func=$fun.9416, args=[Var(A, <ipython-input-575-2412dcac74fb> (3))], kws=(), vararg=None)" at <ipython-input-575-2412dcac74fb> (7)
-------------------------------------------------------------------------------
This should not have happened, a problem has occurred in Numba's internals.
You are currently using Numba version 0.45.1.

Please report the error message and traceback, along with a minimal reproducer
at: https://github.com/numba/numba/issues/new

If more help is needed please feel free to speak to the Numba core developers
directly at: https://gitter.im/numba/numba

Thanks in advance for your help in improving Numba!
```


# Fixed code
def run(self):
    """Finds all calls to StencilFuncs in the IR and converts them to parfor."""
    from numba.stencil import StencilFunc

    # Get all the calls in the function IR.
    call_table, _ = get_call_table(self.func_ir.blocks)
    stencil_calls = []
    stencil_dict = {}
    for call_varname, call_list in call_table.items():
        for one_call in call_list:
            if isinstance(one_call, StencilFunc):
                # Remember all calls to StencilFuncs.
                stencil_calls.append(call_varname)
                stencil_dict[call_varname] = one_call
    if not stencil_calls:
        return  # return early if no stencil calls found

    # find and transform stencil calls
    for label, block in self.func_ir.blocks.items():
        for i, stmt in reversed(list(enumerate(block.body))):
            # Found a call to a StencilFunc.
            if (
                isinstance(stmt, ir.Assign)
                and isinstance(stmt.value, ir.Expr)
                and stmt.value.op == "call"
                and stmt.value.func.name in stencil_calls
            ):
                kws = dict(stmt.value.kws)
                # Create dictionary of input argument number to
                # the argument itself.
                input_dict = {
                    i: stmt.value.args[i] for i in range(len(stmt.value.args))
                }
                in_args = stmt.value.args
                arg_typemap = tuple(self.typemap[i.name] for i in in_args)
                for arg_type in arg_typemap:
                    if isinstance(arg_type, types.BaseTuple):
                        raise ValueError(
                            "Tuple parameters not supported "
                            "for stencil kernels in parallel=True mode."
                        )

                out_arr = kws.get("out")

                # Get the StencilFunc object corresponding to this call.
                sf = stencil_dict[stmt.value.func.name]
                stencil_ir, rt, arg_to_arr_dict = get_stencil_ir(
                    sf,
                    self.typingctx,
                    arg_typemap,
                    block.scope,
                    block.loc,
                    input_dict,
                    self.typemap,
                    self.calltypes,
                )
                index_offsets = sf.options.get("index_offsets", None)
                gen_nodes = self._mk_stencil_parfor(
                    label,
                    in_args,
                    out_arr,
                    stencil_ir,
                    index_offsets,
                    stmt.target,
                    rt,
                    sf,
                    arg_to_arr_dict,
                )
                block.body = block.body[:i] + gen_nodes + block.body[i + 1 :]
            # Found a call to a stencil via numba.stencil().
            elif (
                isinstance(stmt, ir.Assign)
                and isinstance(stmt.value, ir.Expr)
                and stmt.value.op == "call"
                and guard(find_callname, self.func_ir, stmt.value)
                == ("stencil", "numba")
            ):
                # remove dummy stencil() call
                stmt.value = ir.Const(0, stmt.loc)