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