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.
This finally fixes the performance regression due to missing
inlining after the switch to the DMD-style symbol emission
logic (what later became FuncDeclaration::needsCodegen).
In my tests, this slightly increased compile times in release
mode (~7% for a set of small-ish programs) due to the extra
codegen. The impact is that small because we were doing all the
extra semantic{2, 3}s anyway (only to throw their results away)
and still get to avoid the LLVM backend. The performance gains
are, depending on the benchmark, spectacular, as this was
responsible for things like std.array.front not getting inlined.