Android/ARM: fixing exception-handling
Joakim via digitalmars-d-ldc
digitalmars-d-ldc at puremagic.com
Sat Jul 25 10:09:26 PDT 2015
On Wednesday, 8 July 2015 at 16:14:43 UTC, Joakim wrote:
> I spent some time looking into the ARM EH issues and it appears
> that disabling inlining fixes a lot of it:
>
> --- a/gen/optimizer.cpp
> +++ b/gen/optimizer.cpp
> @@ -163,8 +163,8 @@ static unsigned sizeLevel() {
>
> // Determines whether or not to run the normal, full inlining
> pass.
> bool willInline() {
> - return enableInlining == cl::BOU_TRUE ||
> - (enableInlining == cl::BOU_UNSET && optLevel() > 1);
> + return enableInlining == cl::BOU_TRUE;// ||
> + //(enableInlining == cl::BOU_UNSET && optLevel() > 1);
> }
>
> bool isOptimizationEnabled() {
>
> I also get proper backtraces in gdb much more often after
> turning off inlining, not to mention actual error output on the
> command-line as opposed to segfaults. I'm guessing something
> is screwed up in the generation or handling of DWARF exception
> data by function inlining. Almost all of druntime now passes
> tests on Android/ARM, with the exception of some codegen issues
> in core.time.
>
> For a comparison, running the phobos tests with logging turned
> on in the ldc/eh.d code showed that only about 67 exceptions
> were thrown with -O2/-O3 -release and inlining turned on. With
> inlining turned off, it jumps up to 658 exceptions, an order of
> magnitude more, because many more tests are run once EH starts
> working. A couple exceptions might still be uncaught and need
> to be fixed, but it appears that EH is not the bottleneck
> anymore, it's codegen and other ARM issues.
>
> David, Kai, or whoever else runs tests on linux/Android/ARM,
> can you turn inlining off and verify the same results on your
> ARM hardware?
I spent some more time looking into this and it appears that an
ARM optimization pass in llvm is the real issue, not inlining.
It turns out that enabling the EH_personality debug output in
ldc.eh and turning off inlining happened to generate ARM code
that worked earlier, but I can get it to work without those two
hacks by turning off one call to an ARM optimization pass in llvm
instead. Specifically, if I disable this second call to
createARMLoadStoreOptimizationPass() and then compile only
ldc/eh.d with the resulting ldc2, ARM EH will work, because the
second "while" loop in eh_personality_common doesn't segfault
anymore:
https://github.com/llvm-mirror/llvm/blob/release_36/lib/Target/ARM/ARMTargetMachine.cpp#L312
Otherwise, it will often, though not always, fail at a ldmib
instruction, similar to the other codegen issue I brought up in
another thread, which Dan provided a workaround for. With this
second pass turned off, that ldmib instruction isn't there and EH
starts working. I haven't looked further into exactly what that
ARM optimization pass is screwing up, but this is probably an
llvm codegen issue.
More information about the digitalmars-d-ldc
mailing list