Now with *almost* working EH codegen. Does not compile Phobos yet
because we run into the "instruction does not dominate all uses"
issue when an r-value result of toElemDtor is used and we need to
run cleanups in between. Should easily be fixed by promoting those
values to allocas.
Most of the changes outside of ir/irfunction.{h, cpp} are just
because CreateCallOrInvoke moved locations. I took the
opportunity to also make use of the different arg count
overloads where possible.
Never generates any landing pads or invoke instructions right now
for simplicity. The code for emitting them will be added back in
the next step.
The "after..." blocks without any precedessors remain for now, as
we need a clean way to suppress any codegen for that block (but
not new blocks, which might resolve labels) before tackling that
one.
Builds druntime/Phobos on OS X x86_64 (albeit without EH, of course).
Specifying the basic block before which to insert the new one
is not mandatory when calling llvm::BasicBlock::Create. This
was the only use of the tracked "end" block. The concept was
phony anyway because there is no single "end" to a scope with
unwinding and so on.
For prettying up the IR, it is possible to change the order
of basic blocks using move{Before, After}().
0.15.1 used stdcall convention everywhere. But the ABI change in 0.15.2
requires use of the C calling convention for variadic calls on x86
because the stdcall convention does not support vararg functions.
Solution is to check the llvm::FunctionType if the function has varargs.
This commit also makes the C calling convention the global default
because according to the LLVM documentation the fastcc convention used
for D linkage does not support varargs.
This fixes issue #1000.
Debug information is based on static lexical blocks. Most calls to
EmitFuncEnd() are done if control flow reaches the end of the
function which is quite different.
The functions for all arrayops are compiler-generated but the functions
which are also defined in druntime are never emitted. This prevents
inlining of the function body and causes issue #938.
The fix is to emit the arrayops if inlining is enabled and otherwise
use the druntime provided implementations.
An alternative approach could be to always emit the arrayops and
never use the druntime version.
The 2.067 front-end doesn't rewrite these to void anymore, so let's
rewrite in DtoFunctionType().
This issue has surfaced in a std.conv unit test, where
std.range.primitives.front() is instantiated for const(void)[].
The template refuses void[] but accepts this const(void)[]...
Implying that when allocating storage for the D delegate argument,
we need to allocate a LL struct representing the D delegate instead
of an instance of the actually passed LL type, which may have been
rewritten.
In case of a ctor `this` is passed to the function and is also the
return value. This is the perfect case for the `Returned` attribute.
But the x86_64 ABI missed the fact that the return value was a pointer
to a struct and did a struct rewrite, resulting in an bitcast
incompatible type.
Since the change to the symbol emission strategy, a lot of the
previous attempts to derive the linkage for a symbol from its
AST node has been superfluous. This cleans up all the related
code, as it is really not doing much anymore.
The code to opportunistically internalize symbols is now gone
entirely. It was commented out anyway due to problems with
making it work reliably in the face of the not-so-stable
structure of the AST we get from the frontend (regarding the
modules certain symbols end up in). But in any case internal
linkage woudl also be troublesome for cross-module inlining,
so I gave up on making this work for the time being.
The only (minor) change in the emitted code should be in
.offTi generation, which is untested and disabled by default
anyway (GENERATE_OFFTI).
Turns out that since the change to use DMD's symbol emission
logic a few releases back we didn't actually ever emit code
for the extra modules. Thus, all the effort for the extra
semantic passes went to waste.
If we want to implement DMD-style cross-module inlining, we
need to add the extra semantic3s back in, and then iterate
over all the non-root modules with a codegen visitor that
only emits symbols as available_externally.
We probably won't need the availableExternally members if
we start with a clean design in the new symbol emission
framework. Thus, remove everything in the meantime. This
will make some release builds a bit faster, and should not
negatively affect generated code.