Commit Graph

2 Commits

Author SHA1 Message Date
Alexander Udalov a7fef487c1 JVM IR: fix support of cyclic module dependencies
Previous episode was at 987a3460 (KT-45915).

Apparently, it's not enough to run psi2ir for all modules, and then
backend for all modules. If there are several modules in the chunk, IR
in any one of them can reference IR of any other one after psi2ir.

So we would end up in a situation where we're running codegen for the
first module, but the second module is completely unlowered. This would
break some assumptions in the codegen, for example in KT-49575, codegen
would see a reference to a top-level function from another module, and
would fail because the function has no containing class (since file
facades have not been generated yet!), and thus must be an intrinsic,
yet no such intrinsic is known to the codegen.

The solution is to run lowerings first on all modules, and then run
codegen on all modules. The kind of error explained above shouldn't be
possible anymore, because lowerings have to deal both with lowered and
unlowered code from other files all the time, so lowerings can't assume
that reference from other module is lowered either (or unlowered).

The code is not very nice, but hopefully it can be improved as soon as
we get rid of the old JVM backend (and maybe later with the migration to
FIR too).

 #KT-49575 Fixed
2021-11-16 20:20:20 +01:00
Alexander Udalov 987a346015 JVM IR: support cyclic module dependencies
The only way to make the compiler compile several modules with a
dependency loop is via the "build file", given by -Xbuild-file and used
in the JPS (IntelliJ built-in build system) plugin.

For the old frontend/backend it works like this: we _analyze_ sources of
all modules once, as if it's one big module, and then for each module,
we _generate_ (invoke backend) only sources of that module. Backend
needs to be invoked separately per-module because every module has its
own destination directory specified in the build file.

For JVM IR, this separation into just two steps, analyze and generate,
was problematic because there's psi2ir, which works like frontend, in
that it needs the global analysis result to be able to create and link
IR correctly. So, in case of JVM IR, we need to run psi2ir on the whole
module after analysis and before generation.

In this change, psi2ir is run on the whole module via
`CodegenFactory.convertToIr` (which does nothing in the old backend),
and then parts of the resulting IR module are extracted according to the
original separation of the combined module into individual modules via
`getModuleChunkBackendInput` by matching IrFile against KtFile. And
then, backend is run for each such module.

 #KT-45915 Fixed
 #KT-48668 Fixed
2021-09-17 17:39:49 +02:00