www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.ldc - iphone + LDC, a new ARM adventure

reply Dan Olson <zans.is.for.cans yahoo.com> writes:
Compiling LDC for iphone ARM. Running into expected problems, but
thought I'd post status so I am not working in a vacuum. I am new to
building LLVM as of this week so more likely to miss configuration
options.

During the LDC build, druntime and phobos run into a few problems (3
types of error), which don't suprise me because I don't think many have
tried this combo yet (arm-apple-darwin). However, I can compile a simple
standalone .d file to .o and link it into an xcode iphone arm project
and run it on hardware.

First class of error I run into is exception based. Any code that needs
to handle exceptions gets this:

Assertion failed: (getOperand(0)->getType() ==
cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr must be a
pointer to Val type!"), function AssertOK, file
/Users/dan/projects/ldc/llvm-3.3.src/lib/IR/Instructions.cpp, line 1084.
... snip
0.	Running pass 'SJLJ Exception Handling preparation' on function
' _D4core8demangle8Demangle9parseTypeMFAaZAa'
/bin/sh: line 1: 53946 Illegal instruction: 4 
/Users/dan/projects/ldc/buildldc-3.3-hacked-armv7/bin/ldc2 --output-o -c
-I/Users/dan/projects/ldc/ldc-0.12.1-src/runtime/druntime/src
-I/Users/dan/projects/ldc/ldc-0.12.1-src/runtime/druntime/src/gc
/Users/dan/projects/ldc/ldc-0.12.1-src/runtime/druntime/src/core/demangle.d
-of/Users/dan/projects/ldc/buildldc-3.3-hacked-armv7/runtime
src/core/demangle.o -w -d -march=thumb -relocation-model=static -O3 -release
-disable-invariants

Any thoughts?

Dan

----

Build machine is Lion using clang x86_64-apple-darwin12.5.0

I tried various LLVM --target configurations (arm, armv7,
x86-apple-darwin), but they do not seem to make a difference in the
resulting ldc2. LLVM 3.3 yields fewer errors when build druntime than
3.2.  Both give me the same exception error above.

I am using -march=thumb -relocation-model=static as I seem to encounter
fewer llvm failures with these flags. I updated
ldc-0.12.1-src/runtime/CMakeLists.txt and changed D_FLAGS to include
these.

The compiler reports this:

/Users/dan/projects/ldc/buildldc-3.3-hacked-armv7/bin/ldmd2 -help
LDC - the LLVM D compiler (0.12.0):
  based on DMD v2.063.2 and LLVM 3.3
  Default target: armv7-apple-darwin12.5.0
  Host CPU: corei7-avx
  http://dlang.org - http://wiki.dlang.org/LDC

  Registered Targets:
    aarch64  - AArch64
    arm      - ARM
    cpp      - C++ backend
    hexagon  - Hexagon
    mblaze   - MBlaze
    mips     - Mips
    mips64   - Mips64 [experimental]
    mips64el - Mips64el [experimental]
    mipsel   - Mipsel
    msp430   - MSP430 [experimental]
    nvptx    - NVIDIA PTX 32-bit
    nvptx64  - NVIDIA PTX 64-bit
    ppc32    - PowerPC 32
    ppc64    - PowerPC 64
    sparc    - Sparc
    sparcv9  - Sparc V9
    systemz  - SystemZ
    thumb    - Thumb
    x86      - 32-bit X86: Pentium-Pro and above
    x86-64   - 64-bit X86: EM64T and AMD64
    xcore    - XCore


Background:

About a year ago, I worked and gave up on making gdc build druntime and
phobos for iphone (ios arm). I could get a simple standalone D function
to run on an iphone but no further.

http://www.digitalmars.com/d/archives/D/gnu/iphone_D_getting_closer_4788.html

The problem was that gcc-4.8 had no support for iphone and the latest
sources that apple released were for gcc-4.2. I tried in vain to merge
the iphone changes into 4.8, but it was a losing battle.

I have always wanted to continue this adventure, trying LDC. Apple is
all clang/LLVM now and seems to be pushing out some of their LLVM
updates.  So seems LDC is way to go!
Jan 04 2014
parent reply David Nadlinger <code klickverbot.at> writes:
Hi Dan,

On Sat, Jan 4, 2014 at 10:56 PM, Dan Olson <zans.is.for.cans yahoo.com> wrote:
 First class of error I run into is exception based. Any code that needs
 to handle exceptions gets this:

 Assertion failed: (getOperand(0)->getType() ==
cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr must be a
pointer to Val type!"), function AssertOK, file
/Users/dan/projects/ldc/llvm-3.3.src/lib/IR/Instructions.cpp, line 1084.
The issue is most likely that ARM/iOS uses setjmp/longjmp-based exception handling, whereas all the other target platforms use DWARF-based EH (or a similar concept on Win64). I don't see any fundamental issue with using SLJL for D/LDC (besides performance and the other generic SLJL downsides), but you'd have to adapt druntime and also some parts of the relevant parts of the LDC glue code (e.g. to avoid the above error).
 I have always wanted to continue this adventure, trying LDC. Apple is
 all clang/LLVM now and seems to be pushing out some of their LLVM
 updates.  So seems LDC is way to go!
If you have the time and inclination to work on iOS support for ARM, it would be awesome if you could try to get things running. In any case, please do feel free to ask around for help with LDC development. Best, David
Jan 04 2014
parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
David Nadlinger <code klickverbot.at> writes:

 The issue is most likely that ARM/iOS uses setjmp/longjmp-based
 exception handling, whereas all the other target platforms use
 DWARF-based EH (or a similar concept on Win64).

 I don't see any fundamental issue with using SLJL for D/LDC (besides
 performance and the other generic SLJL downsides), but you'd have to
 adapt druntime and also some parts of the relevant parts of the LDC
 glue code (e.g. to avoid the above error).
Thanks David for the reply. Ah, I didn't connect SLJL with setjmp/longjmp. Good clue. Yes, it appears arm-apple-darwin exceptions are setjmp based (confirmed by compiling a c++ function with clang). Ok, I will dig in some more, see where it leads me.
 I have always wanted to continue this adventure, trying LDC. Apple is
 all clang/LLVM now and seems to be pushing out some of their LLVM
 updates.  So seems LDC is way to go!
If you have the time and inclination to work on iOS support for ARM, it would be awesome if you could try to get things running. In any case, please do feel free to ask around for help with LDC development. Best, David
Yes, just a hobby, but would very much like to make D on ios. So far, llvm looks easier to understand than gcc codebase, and toolchain builds are much faster. Better for trial and error.
Jan 04 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-01-05 08:34, Dan Olson wrote:

 Ah, I didn't connect SLJL with setjmp/longjmp. Good clue. Yes, it
 appears arm-apple-darwin exceptions are setjmp based (confirmed by
 compiling a c++ function with clang). Ok, I will dig in some more, see
 where it leads me.
Hmm, I would have thought iOS used DWARF-based exception handling. -- /Jacob Carlborg
Jan 05 2014
next sibling parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
Jacob Carlborg <doob me.com> writes:

 On 2014-01-05 08:34, Dan Olson wrote:

 Ah, I didn't connect SLJL with setjmp/longjmp. Good clue. Yes, it
 appears arm-apple-darwin exceptions are setjmp based (confirmed by
 compiling a c++ function with clang). Ok, I will dig in some more, see
 where it leads me.
Hmm, I would have thought iOS used DWARF-based exception handling.
Hi Jacob. Yeah, I probably have called it wrong as I am just learning about exception handling implementations. clangc c++ exception handling for C++ armv7-apple-darwin is emitting __gxx_personality_sj0 and plugs in _Unwind_SjLj_Register/_Unwind_SjLj_Unregister. Perhaps those are just for catching C code longjmps? For example, this C++ code: try { death(); } catch (...) { puts("got it"); } produced (edited): _main: .cfi_startproc .cfi_personality 155, L___gxx_personality_sj0$non_lazy_ptr Leh_func_begin0: .cfi_lsda 16, Lexception0 push {r4, r5, r6, r7, lr} --- snip --- LPC0_1: add r1, pc blx __Unwind_SjLj_Register Ltmp0: blx __Z5deathv Ltmp1: LBB0_1: %try.cont blx __Unwind_SjLj_Unregister --- snip function prologue --- LBB0_5: %invoke.cont2 Ltmp2: blx ___cxa_begin_catch movw r0, :lower16:(L_.str-(LPC0_3+4)) movt r0, :upper16:(L_.str-(LPC0_3+4)) LPC0_3: add r0, pc blx _puts blx ___cxa_end_catch b LBB0_1 And I do see an exception table. .section __TEXT,__gcc_except_tab .align 2 GCC_except_table0: Lexception0: L_LSDA_0: .byte 255 LPStart Encoding = omit .byte 155 TType Encoding = indirect pcrel sdata4 .asciz "\212\200\200" TType base offset .byte 3 Call site Encoding = udata4 .byte 2 Call site table length .byte 0 >> Call Site 0 << On exception at call site 0 .byte 1 Action: 1 .byte 1 >> Action Record 1 << Catch TypeInfo 1 .byte 0 No further actions >> Catch TypeInfos << .long 0 TypeInfo 1 .align 2 I read llvm source code for a while yesterday and really haven't wrapped by brain around it yet. Dan
Jan 05 2014
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2014-01-05 18:28, Dan Olson wrote:
 Jacob Carlborg <doob me.com> writes:

 On 2014-01-05 08:34, Dan Olson wrote:

 Ah, I didn't connect SLJL with setjmp/longjmp. Good clue. Yes, it
 appears arm-apple-darwin exceptions are setjmp based (confirmed by
 compiling a c++ function with clang). Ok, I will dig in some more, see
 where it leads me.
Hmm, I would have thought iOS used DWARF-based exception handling.
Hi Jacob. Yeah, I probably have called it wrong as I am just learning about exception handling implementations. clangc c++ exception handling for C++ armv7-apple-darwin is emitting __gxx_personality_sj0 and plugs in _Unwind_SjLj_Register/_Unwind_SjLj_Unregister. Perhaps those are just for catching C code longjmps? For example, this C++ code: try { death(); } catch (...) { puts("got it"); } produced (edited): _main: .cfi_startproc .cfi_personality 155, L___gxx_personality_sj0$non_lazy_ptr Leh_func_begin0: .cfi_lsda 16, Lexception0 push {r4, r5, r6, r7, lr} --- snip --- LPC0_1: add r1, pc blx __Unwind_SjLj_Register Ltmp0: blx __Z5deathv Ltmp1: LBB0_1: %try.cont blx __Unwind_SjLj_Unregister --- snip function prologue --- LBB0_5: %invoke.cont2 Ltmp2: blx ___cxa_begin_catch movw r0, :lower16:(L_.str-(LPC0_3+4)) movt r0, :upper16:(L_.str-(LPC0_3+4)) LPC0_3: add r0, pc blx _puts blx ___cxa_end_catch b LBB0_1 And I do see an exception table. .section __TEXT,__gcc_except_tab .align 2 GCC_except_table0: Lexception0: L_LSDA_0: .byte 255 LPStart Encoding = omit .byte 155 TType Encoding = indirect pcrel sdata4 .asciz "\212\200\200" TType base offset .byte 3 Call site Encoding = udata4 .byte 2 Call site table length .byte 0 >> Call Site 0 << On exception at call site 0 .byte 1 Action: 1 .byte 1 >> Action Record 1 << Catch TypeInfo 1 .byte 0 No further actions >> Catch TypeInfos << .long 0 TypeInfo 1 .align 2 I read llvm source code for a while yesterday and really haven't wrapped by brain around it yet.
You could try and compare it with x86 64bit code. C++ code on x86 64bit is using DWARF-based exception handling. You can see if that code contains anything related to SLJL. Also Objective-C on x86 32bit uses SLJL but on 64bit is uses DWARF. -- /Jacob Carlborg
Jan 06 2014
parent Dan Olson <zans.is.for.cans yahoo.com> writes:
Jacob Carlborg <doob me.com> writes:

 You could try and compare it with x86 64bit code. C++ code on x86
 64bit is using DWARF-based exception handling. You can see if that
 code contains anything related to SLJL.

 Also Objective-C on x86 32bit uses SLJL but on 64bit is uses DWARF.
Yes, I've been studing the assembly from various working triples. I like that LLVM can have all the targets built in so it can be as simple as just changing a -target on clang.
Jan 06 2014
prev sibling next sibling parent reply David Nadlinger <code klickverbot.at> writes:
Hi Dan, Hi Jacob,

On Sun, Jan 5, 2014 at 6:28 PM, Dan Olson <zans.is.for.cans yahoo.com> wrote:
 Jacob Carlborg <doob me.com> writes:
 Hmm, I would have thought iOS used DWARF-based exception handling.
Hi Jacob. Yeah, I probably have called it wrong as I am just learning about exception handling implementations.
No, even though I'm no expert for iOS development, from reading through the related LLVM code when implementing LDC/MinGW exception handling I'm fairly sure that SJLJ-style exception handling is used there. At least, the extra function calls emitted in the fast (non-EH) path are a sure sign that it is not the standard DWARF scheme. Why would you think otherwise, Jacob? Including more context with your messages would make a fair amount of them infinitely more useful…
 clangc c++ exception handling for
 C++ armv7-apple-darwin is emitting __gxx_personality_sj0 and plugs in
 _Unwind_SjLj_Register/_Unwind_SjLj_Unregister.  Perhaps those are just
 for catching C code longjmps?
They are for (un)registering the exception handling context with the global table of active handlers. The parameter to _Unwind_SjLj_Register is constructed by the setjmp() part of SJLJ (it's in fact an optimized, inlined version instead of an actual function call). When an exception is raised, this global linked list is walked, calling the personality functions for the respective entries to determine whether to longjmp to them.
 I read llvm source code for a while yesterday and really haven't wrapped
 by brain around it yet.
I'd start out by getting a feel for the LLVM IR we need to generate. For this, you can have a look at the respective Clang output (-S -emit-llvm). The LLVM docs also have a page on the subject, but unfortunately, it is rather sparse: http://llvm.org/docs/ExceptionHandling.html#setjmp-longjmp-exception-handling The more involved part will likely be to get the personality function right. Fortunately, at least the related parts of libunwind are open source: http://www.opensource.apple.com/source/libunwind/libunwind-35.3/src/Unwind-sjlj.c. The source for the GCC/Clang personality function (__gxx_personality_sj0) is probably available somewhere as well, but I don't know where to look right now (libc++, probably). David
Jan 06 2014
next sibling parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
David Nadlinger <code klickverbot.at> writes:

 They are for (un)registering the exception handling context with the
 global table of active handlers. The parameter to
 _Unwind_SjLj_Register is constructed by the setjmp() part of SJLJ
 (it's in fact an optimized, inlined version instead of an actual
 function call).  When an exception is raised, this global linked list
 is walked, calling the personality functions for the respective
 entries to determine whether to longjmp to them.

 I read llvm source code for a while yesterday and really haven't wrapped
 by brain around it yet.
I'd start out by getting a feel for the LLVM IR we need to generate. For this, you can have a look at the respective Clang output (-S -emit-llvm). The LLVM docs also have a page on the subject, but unfortunately, it is rather sparse: http://llvm.org/docs/ExceptionHandling.html#setjmp-longjmp-exception-handling The more involved part will likely be to get the personality function right. Fortunately, at least the related parts of libunwind are open source: http://www.opensource.apple.com/source/libunwind/libunwind-35.3/src/Unwind-sjlj.c. The source for the GCC/Clang personality function (__gxx_personality_sj0) is probably available somewhere as well, but I don't know where to look right now (libc++, probably). David
I decided it was time to carefully study what clang is doing. A grep of SjLj in the llvm source and build trees hopefully is showing where I should pay attention to the design. In ToolChains.cpp I see how sjlj is enabled. bool Darwin::UseSjLjExceptions() const { // Darwin uses SjLj exceptions on ARM. return (getTriple().getArch() == llvm::Triple::arm || getTriple().getArch() == llvm::Triple::thumb); } And then in CodeGen/Passes.cpp I see that SjLj has to work with dwarf eh. It is in the SjLjEHPrepare class code that something goes wrong with ldc2. switch (TM->getMCAsmInfo()->getExceptionHandlingType()) { case ExceptionHandling::SjLj: // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both // Dwarf EH prepare needs to be run after SjLj prepare. Otherwise, // catch info can get misplaced when a selector ends up more than one block // removed from the parent invoke(s). This could happen when a landing // pad is shared by multiple invokes and is also a target of a normal // edge from elsewhere. addPass(createSjLjEHPreparePass(TM->getTargetLowering())); // FALLTHROUGH case ExceptionHandling::DwarfCFI: case ExceptionHandling::ARM: case ExceptionHandling::Win64: addPass(createDwarfEHPass(TM)); break; I'll spend some more time over the next few days and see what clang does to make the sjlj pass happy. Thanks for all the help so far, Dan
Jan 06 2014
parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
Dan Olson <zans.is.for.cans yahoo.com> writes:

 I'll spend some more time over the next few days and see what clang
 does to make the sjlj pass happy.

 Thanks for all the help so far,
I looked at what clang does different on i686-apple-darwin and arm-apple-darwin and one thing that changed when targeting ios is a bitcast on the personality function. So I edited the results of ldc2 -output-l: From: %landing_pad = landingpad { i8*, i32 } personality i32 (i32, i32, i64, i8*, i8*)* _d_eh_personality To: %landing_pad = landingpad { i8*, i32 } personality i8* bitcast (i32 (i32, i32, i64, i8*, i8*)* _d_eh_personality to i8*) Then ran llc on the modified file. No assertion and I get arm assemble code! And it looks reasonable to my untrained eye. By the way, llc is very cool. As I said, I am totally new to llvm internals, so am having fun learning what it has in its magic bag of tricks. So far I cannot find where clang adds the bitcast thing for sjlj eh personality. I will keep hunting. Any ideas where I would do this in ldc? When it comes to updating the _d_eh_personality for sjlj, I noticed a very small difference in the c++ versions ( _gxx_personality_v0 and _gxx_personality_sj0). It is actually one funtion body in gcc-4.8-20121028/libstdc++-v3/libsupc++/eh_personality.cc with a little extra code in an ifdef _GLIBCXX_SJLJ_EXCEPTIONS conditional. Dan
Jan 08 2014
next sibling parent reply "Kai Nacke" <kai redstar.de> writes:
On Wednesday, 8 January 2014 at 17:39:19 UTC, Dan Olson wrote:
 Dan Olson <zans.is.for.cans yahoo.com> writes:

 I'll spend some more time over the next few days and see what 
 clang
 does to make the sjlj pass happy.

 Thanks for all the help so far,
I looked at what clang does different on i686-apple-darwin and arm-apple-darwin and one thing that changed when targeting ios is a bitcast on the personality function. So I edited the results of ldc2 -output-l: From: %landing_pad = landingpad { i8*, i32 } personality i32 (i32, i32, i64, i8*, i8*)* _d_eh_personality To: %landing_pad = landingpad { i8*, i32 } personality i8* bitcast (i32 (i32, i32, i64, i8*, i8*)* _d_eh_personality to i8*) Then ran llc on the modified file. No assertion and I get arm assemble code! And it looks reasonable to my untrained eye.
Did you get an assertion without the bitcast? This should work, too. If not then it is an LLVM bug.
 By the way, llc is very cool.  As I said, I am totally new to 
 llvm
 internals, so am having fun learning what it has in its magic 
 bag of
 tricks.
:-)
 So far I cannot find where clang adds the bitcast thing for 
 sjlj eh
 personality.  I will keep hunting.  Any ideas where I would do 
 this in
 ldc?

 When it comes to updating the _d_eh_personality for sjlj, I 
 noticed a
 very small difference in the c++ versions ( _gxx_personality_v0 
 and
 _gxx_personality_sj0).  It is actually one funtion body in

 gcc-4.8-20121028/libstdc++-v3/libsupc++/eh_personality.cc

 with a little extra code in an ifdef _GLIBCXX_SJLJ_EXCEPTIONS
 conditional.

 Dan
Regards, Kai
Jan 08 2014
parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
"Kai Nacke" <kai redstar.de> writes:

 On Wednesday, 8 January 2014 at 17:39:19 UTC, Dan Olson wrote:
 I looked at what clang does different on i686-apple-darwin and
 arm-apple-darwin and one thing that changed when targeting ios is a
 bitcast on the personality function.  So I edited the results of
 ldc2
 -output-l:

 From:
   %landing_pad = landingpad { i8*, i32 } personality i32 (i32, i32,
 i64, i8*, i8*)*  _d_eh_personality

 To:
   %landing_pad = landingpad { i8*, i32 } personality i8* bitcast
 (i32 (i32, i32, i64, i8*, i8*)*  _d_eh_personality to i8*)

 Then ran llc on the modified file.  No assertion and I get arm
 assemble
 code!  And it looks reasonable to my untrained eye.
Did you get an assertion without the bitcast? This should work, too. If not then it is an LLVM bug.
Yes. It is this one. Assertion failed: (getOperand(0)->getType() == cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr must be a pointer to Val type!"), function AssertOK, file /Users/dan/projects/ldc/llvm-3.3.src/lib/IR/Instructions.cpp, line 1084.
Jan 09 2014
parent reply "Kai Nacke" <kai redstar.de> writes:
On Thursday, 9 January 2014 at 08:39:26 UTC, Dan Olson wrote:
 Yes.  It is this one.

 Assertion failed: (getOperand(0)->getType() == 
 cast<PointerType>(getOperand(1)->getType())->getElementType() 
 && "Ptr must be a pointer to Val type!"), function AssertOK, 
 file 
 /Users/dan/projects/ldc/llvm-3.3.src/lib/IR/Instructions.cpp, 
 line 1084.
Hm. Please, could you try it with LLVM 3.4? I am not sure if my fix made it into LLVM 3.3. Thanks for working on this!!! Regards, Kai
Jan 09 2014
parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
"Kai Nacke" <kai redstar.de> writes:

 On Thursday, 9 January 2014 at 08:39:26 UTC, Dan Olson wrote:
 Yes.  It is this one.

 Assertion failed: (getOperand(0)->getType() ==
 cast<PointerType>(getOperand(1)->getType())->getElementType() &&
 "Ptr must be a pointer to Val type!"), function AssertOK, file
 /Users/dan/projects/ldc/llvm-3.3.src/lib/IR/Instructions.cpp, line
 1084.
Hm. Please, could you try it with LLVM 3.4? I am not sure if my fix made it into LLVM 3.3. Thanks for working on this!!! Regards, Kai
I am grabbing 3.4 now...
Jan 09 2014
parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
Dan Olson <zans.is.for.cans yahoo.com> writes:

 "Kai Nacke" <kai redstar.de> writes:

 On Thursday, 9 January 2014 at 08:39:26 UTC, Dan Olson wrote:
 Yes.  It is this one.

 Assertion failed: (getOperand(0)->getType() ==
 cast<PointerType>(getOperand(1)->getType())->getElementType() &&
 "Ptr must be a pointer to Val type!"), function AssertOK, file
 /Users/dan/projects/ldc/llvm-3.3.src/lib/IR/Instructions.cpp, line
 1084.
Hm. Please, could you try it with LLVM 3.4? I am not sure if my fix made it into LLVM 3.3. Thanks for working on this!!! Regards, Kai
I am grabbing 3.4 now...
and assertion passes! Much more of runtime .d files are turning into .o's. Not sure how good they are yet, but getting further. Now I am on to the next assertion that fails. I know the state of TLS is not good, but I'll toss this out for comment before I dig in again tonight. Assertion failed: (Subtarget->isTargetELF() && "TLS not implemented for non-ELF targets"), function LowerGlobalTLSAddress, file /Users/dan/projects/ldc/llvm-3.4/lib/Target/ARM/ARMISelLowering.cpp, line 2475. ... /bin/sh: line 1: 41428 Illegal instruction: 4 /Users/dan/projects/ldc/buildldc-3.4-hacked-armv7/bin/ldc2 --output-o -c -I/Users/dan/projects/ldc/ldc-0.12.1-src/runtime/druntime/src -I/Users/dan/projects/ldc/ldc-0.12.1-src/runtime/druntime/src/gc /Users/dan/projects/ldc/ldc-0.12.1-src/runtime/druntime/src/rt/lifetime.d -of/Users/dan/projects/ldc/buildldc-3.4-hacked-armv7/runtime/src/rt/lifetime.o -w -d -march=thumb -relocation-model=static -O3 -release Note that I am still working from the ldc-0.12.1-src tar, not git. Only change I've made so far is in adding flags -march=thumb -relocation-model=static because without them, things blow up fast.
Jan 10 2014
parent reply David Nadlinger <code klickverbot.at> writes:
On Fri, Jan 10, 2014 at 5:14 PM, Dan Olson <zans.is.for.cans yahoo.com> wrote:
 Now I am on to the next assertion that fails.  I know the state of TLS
 is not good, but I'll toss this out for comment before I dig in again
 tonight.

 Assertion failed: (Subtarget->isTargetELF() && "TLS not implemented for
non-ELF targets"), function LowerGlobalTLSAddress, file
/Users/dan/projects/ldc/llvm-3.4/lib/Target/ARM/ARMISelLowering.cpp, line 2475.
D (also the runtime) relies fairly heavily on thread-local storage support. LLVM provides an easy way of creating TLS variables via the thread_local attribute, but support for that is not available on all target platforms – and it seems that Darwin/ARM is one of them (they work on Linux resp. glibc). I'm not sure what the best way of going forward with this would be. One option might be to just hack LDC to emit all TLS globals as normal globals. This would obviously break threading support, but might be interesting for getting first Hello-World-style programs to run. The other option, and what we might end up with in the long run, would be to implement a TLS emulation scheme in either LDC or, better, LLVM itself. pthread_{get,set}specific seem to be supported on iOS, which would make an implementation similar to DMD already does on OS X possible (see src/rt/sections_osx.d in the upstream druntime repository). It might be possible to transfer this approach to LDC without touching LLVM, even though implementing it on the LLVM side would certainly be cleaner. Let us know if you want to pursue this direction so we can discuss possible designs. Best, David
Jan 10 2014
parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
David Nadlinger <code klickverbot.at> writes:

 I'm not sure what the best way of going forward with this would be.
 One option might be to just hack LDC to emit all TLS globals as normal
 globals. This would obviously break threading support, but might be
 interesting for getting first Hello-World-style programs to run.
I think this is the best option for now. I want to see how viable D is on iOS and seeing most of the runtime and phobos running on an iPhone would be cool. Then begin work on the slow, detailed work of TLS, exceptions, and all the other gottchas that pop up when I have a way of running the unittests.
 The other option, and what we might end up with in the long run, would
 be to implement a TLS emulation scheme in either LDC or, better, LLVM
 itself. pthread_{get,set}specific seem to be supported on iOS, which
 would make an implementation similar to DMD already does on OS X
 possible (see src/rt/sections_osx.d in the upstream druntime
 repository). It might be possible to transfer this approach to LDC
 without touching LLVM, even though implementing it on the LLVM side
 would certainly be cleaner. Let us know if you want to pursue this
 direction so we can discuss possible designs.

 Best,
 David
Thanks much!
Jan 12 2014
parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
I finally stubbed and hacked enough places (mostly thread and exception
handling) to build druntime and phobos.  The only LDC hack was to
disable use of TLS.

I am building everthing with -march thumb.  

I linked the resulting druntime into an xcode project to try some
things out on an iphone.  

However, this call sequence appears often (D caling D).

	mov	lr, pc
	bx	r7

When the function called returns, exectution is no longer in thumb mode
because of the way the link register was loaded.  I think it is
generated by an llvm fastcc call, but haven't narrowed it down yet.  I
will try to create a simple D function to be sure.

I am thinking it should just be a blx r7 call.

I am referring to:

http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042e/IHI0042E_aapcs.pdf

Thoughts of where to look for the culprit?

note: I am have been using thumb because -march arm fails an assertion
in llvm.

Dan
Jan 15 2014
parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
Dan Olson <zans.is.for.cans yahoo.com> writes:

 However, this call sequence appears often (D caling D).

 	mov	lr, pc
 	bx	r7

 When the function called returns, exectution is no longer in thumb mode
 because of the way the link register was loaded.  I think it is
 generated by an llvm fastcc call, but haven't narrowed it down yet.  I
 will try to create a simple D function to be sure.

 I am thinking it should just be a blx r7 call.
Nevermind, adding -mcpu cortex-a8 gives me the right blx call. I found the clue: http://llvm.org/bugs/show_bug.cgi?id=16572 I would have though configuring with --target=armv7-apple-darwin would have defaulted the cpu to armv7, but apparently it is defaulting to something else.
Jan 15 2014
parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
Well, I am kind of stuck and am going to have to start learning LLVM
internals to go further.

I can build entire druntime and phobos for iOS if I target thumb 16-bit
with llvm-3.4.  However, every function that must handle exceptions ends
up with a bad prologue/epilogue.  I get the same problem with clang++,
so it is not an ldc issue.  I am pretty sure it is related to sjlj eh.

For example, a c++ function that has a try/catch (-mtriple=thumbv6-darwin):

	.thumb_func	__Z3barv
__Z3barv:
	.cfi_startproc
	.cfi_personality 155, L___gxx_personality_sj0$non_lazy_ptr
Leh_func_begin0:
	.cfi_lsda 16, Lexception0

	push	{d8, d9, d10, d11, d12, d13, d14, d15, r8, r10, r11, r4, r5, r6, r7, lr}

        ...
	pop	{d8, d9, d10, d11, d12, d13, d14, d15, r8, r10, r11, r4, r5, r6, r7, pc}

The pop and push are incorrect and using otool to disassemble shows what
really ends up in the .o, which is a proper instruction, but will not work.

__Z3barv:
00000000	    b420	push	{r5}

...
00000050	    bc20	pop	{r5}

I think it should be more like:
	push	{r4, r5, r6, r7, lr}
	pop  	{r4, r5, r6, r7, pc}

Perhaps I need to go back to working on targeting armv7 or thumb2.  Its
assembly looks better for exception handling, but I get assertion failures from
llvm-3.4 on several files in druntime.  Maybe llvm trunk will be better?

Dan
Jan 18 2014
parent reply "Kai Nacke" <kai redstar.de> writes:
Hi Dan!

On Sunday, 19 January 2014 at 00:48:47 UTC, Dan Olson wrote:
 Well, I am kind of stuck and am going to have to start learning 
 LLVM
 internals to go further.

 I can build entire druntime and phobos for iOS if I target 
 thumb 16-bit
 with llvm-3.4.  However, every function that must handle 
 exceptions ends
 up with a bad prologue/epilogue.  I get the same problem with 
 clang++,
 so it is not an ldc issue.  I am pretty sure it is related to 
 sjlj eh.

 For example, a c++ function that has a try/catch 
 (-mtriple=thumbv6-darwin):

 	.thumb_func	__Z3barv
 __Z3barv:
 	.cfi_startproc
 	.cfi_personality 155, L___gxx_personality_sj0$non_lazy_ptr
 Leh_func_begin0:
 	.cfi_lsda 16, Lexception0

 	push	{d8, d9, d10, d11, d12, d13, d14, d15, r8, r10, r11, r4, 
 r5, r6, r7, lr}

         ...
 	pop	{d8, d9, d10, d11, d12, d13, d14, d15, r8, r10, r11, r4, 
 r5, r6, r7, pc}

 The pop and push are incorrect and using otool to disassemble 
 shows what
 really ends up in the .o, which is a proper instruction, but 
 will not work.

 __Z3barv:
 00000000	    b420	push	{r5}

 ...
 00000050	    bc20	pop	{r5}

 I think it should be more like:
 	push	{r4, r5, r6, r7, lr}
 	pop  	{r4, r5, r6, r7, pc}

 Perhaps I need to go back to working on targeting armv7 or 
 thumb2.  Its
 assembly looks better for exception handling, but I get 
 assertion failures from
 llvm-3.4 on several files in druntime.  Maybe llvm trunk will 
 be better?

 Dan
I think using trunk is always the best option if you port ldc to a new platform. I try to keep ldc in sync with LLVM trunk therefore you should have no problems with using trunk. If the bug is also present in trunk then you should enter a bug report at http://llvm.org/bugs. It sounds pretty bad. Could you please post which triple you are suing and on which druntime files you get assertion errors? An assertion in LLVM may also be triggered by bad IR. I like to have a look at it. Regards, Kai
Jan 19 2014
parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
"Kai Nacke" <kai redstar.de> writes:

 Hi Dan!

 I think using trunk is always the best option if you port ldc to a new
 platform. I try to keep ldc in sync with LLVM trunk therefore you
 should have no problems with using trunk.

 If the bug is also present in trunk then you should enter a bug report
 at http://llvm.org/bugs. It sounds pretty bad.

 Could you please post which triple you are suing and on which druntime
 files you get assertion errors? An assertion in LLVM may also be
 triggered by bad IR. I like to have a look at it.

 Regards,
 Kai
Hi Kai, I updated to llvm trunk and ldc git HEAD. Again, I am working on OSX Lion. I built llvm with: $ CC=/opt/local/bin/gcc-mp-4.8 CXX=/opt/local/bin/c++-mp-4.8 ../llvm-svn/configure --target=armv7-apple-darwin $ make I am building ldc with something like: CC=/opt/local/bin/gcc-mp-4.8 CXX=/opt/local/bin/c++-mp-4.8 cmake -DLLVM_ROOT_DIR=/Users/dan/projects/ldc/build-svn/Debug+Asserts/ -DD_FLAGS='-w;-d;-mtriple=armv7-apple-darwin' ../ldc-git Earlier I hacked around around TLS and eh/threading in druntime but have not applied those changes to ldc-git. So you can ignore theTLS assertion and some D compile errors, if you get that far. I am seeing many assertions and segvs. The four triples I am working with are: armv7-apple-darwin, thumbv7-, armv6-, and thumbv6-. ** thumbv6-apple-darwin causes no assertion problems, it just generates the funky eh function prolog I reported earlier: push {d8, d9, d10, d11, d12, d13, d14, d15, r8, r10, r11,r4, r5, r6, r7, lr} pop {d8, d9, d10, d11, d12, d13, d14, d15, r8, r10, r11,r4, r5, r6, r7, pc} Both armv7-apple-darwin and armv6-apple-darwin result in segv on many files. Examples: ** armv7-apple-darwin src/core/demangle.o is first, but many files 0 ldc2 0x00000001078fa585 llvm::sys::PrintStackTrace(__sFILE*) + 38 1 ldc2 0x00000001078fa802 PrintStackTraceSignalHandler(void*) + 30 2 ldc2 0x00000001078fa264 SignalHandler(int) + 268 3 libsystem_c.dylib 0x00007fff87bbf90a _sigtramp + 26 4 libsystem_c.dylib 0x00007fe60208ab10 _sigtramp + 2051846688 5 ldc2 0x0000000106ac8374 llvm::ARMAsmPrinter::EmitInstruction(llvm::MachineInstr const*) + 274 6 ldc2 0x000000010709dfce llvm::AsmPrinter::EmitFunctionBody() + 1418 7 ldc2 0x0000000106acc977 llvm::AsmPrinter::runOnMachineFunction(llvm::MachineFunction&) + 59 8 ldc2 0x0000000106ac1ea5 llvm::ARMAsmPrinter::runOnMachineFunction(llvm::MachineFunction&) + 81 9 ldc2 0x00000001071ccc53 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 95 10 ldc2 0x000000010775fd84 llvm::FPPassManager::runOnFunction(llvm::Function&) + 290 11 ldc2 0x000000010775fb2a llvm::legacy::FunctionPassManagerImpl::run(llvm::Function&) + 84 12 ldc2 0x000000010775f70a llvm::legacy::FunctionPassManager::run(llvm::Function&) + 180 13 ldc2 0x00000001064dcb31 codegenModule(llvm::TargetMachine&, llvm::Module&, llvm::raw_fd_ostream&, llvm::TargetMachine::CodeGenFileType) + 473 14 ldc2 0x00000001064dd6f8 writeModule(llvm::Module*, std::string) + 1851 15 ldc2 0x00000001064e6175 main + 5362 16 libdyld.dylib 0x00007fff91a6c7e1 start + 0 17 libdyld.dylib 0x000000000000000d start + 1851340844 /bin/sh: line 1: 59338 Segmentation fault: 11 /Users/dan/projects/ldc/buildldc-svn/bin/ldc2 --output-o -c -I/Users/dan/projects/ldc/ldc-git/runtime/druntime/src -I/Users/dan/projects/ldc/ldc-git/runtime/druntime/src/gc /Users/dan/projects/ldc/ldc-git/runtime/druntime/src/core/demangle.d -of/Users/dan/projects/ldc/buildldc-svn/runtime/src/core/demangle.o -w -d -mtriple=armv7-apple-darwin -O3 -release -disable-invariants ** armv6-apple-darwin src/core/cpuid.o is first 0 ldc2 0x0000000103110585 llvm::sys::PrintStackTrace(__sFILE*) + 38 1 ldc2 0x0000000103110802 PrintStackTraceSignalHandler(void*) + 30 2 ldc2 0x0000000103110264 SignalHandler(int) + 268 3 libsystem_c.dylib 0x00007fff87bbf90a _sigtramp + 26 4 libsystem_c.dylib 0x00007fbd32051a10 _sigtramp + 2856919328 5 ldc2 0x00000001022de374 llvm::ARMAsmPrinter::EmitInstruction(llvm::MachineInstr const*) + 274 6 ldc2 0x00000001028b3fce llvm::AsmPrinter::EmitFunctionBody() + 1418 7 ldc2 0x00000001022e2977 llvm::AsmPrinter::runOnMachineFunction(llvm::MachineFunction&) + 59 8 ldc2 0x00000001022d7ea5 llvm::ARMAsmPrinter::runOnMachineFunction(llvm::MachineFunction&) + 81 9 ldc2 0x00000001029e2c53 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 95 10 ldc2 0x0000000102f75d84 llvm::FPPassManager::runOnFunction(llvm::Function&) + 290 11 ldc2 0x0000000102f75b2a llvm::legacy::FunctionPassManagerImpl::run(llvm::Function&) + 84 12 ldc2 0x0000000102f7570a llvm::legacy::FunctionPassManager::run(llvm::Function&) + 180 13 ldc2 0x0000000101cf2b31 codegenModule(llvm::TargetMachine&, llvm::Module&, llvm::raw_fd_ostream&, llvm::TargetMachine::CodeGenFileType) + 473 14 ldc2 0x0000000101cf36f8 writeModule(llvm::Module*, std::string) + 1851 15 ldc2 0x0000000101cfc175 main + 5362 16 libdyld.dylib 0x00007fff91a6c7e1 start + 0 /bin/sh: line 1: 61457 Segmentation fault: 11 /Users/dan/projects/ldc/buildldc-svn/bin/ldc2 --output-o -c -I/Users/dan/projects/ldc/ldc-git/runtime/druntime/src -I/Users/dan/projects/ldc/ldc-git/runtime/druntime/src/gc /Users/dan/projects/ldc/ldc-git/runtime/druntime/src/core/cpuid.d -of/Users/dan/projects/ldc/buildldc-svn/runtime/src/core/cpuid.o -w -d -mtriple=armv6-apple-darwin -O3 -release -disable-invariants ** thumbv7-apple-darwin No segvs but various assertion failures. Files src/core/demangle.o src/core/runtime.o src/rt/cover.o src/rt/util/utf.o Assertion failed: ((TLI.getTypeAction(*DAG.getContext(), Node->getOperand(i).getValueType()) == TargetLowering::TypeLegal || Node->getOperand(i).getOpcode() == ISD::TargetConstant) && "Unexpected illegal type!"), function LegalizeOp, file /Users/dan/projects/ldc/llvm-svn/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp, line 1165. Files: src/core/sync/rwmutex.o src/gc/gc.o src/core/sync/config-debug.o src/core/sync/rwmutex-debug.o src/gc/gcx-debug.o src/rt/minfo-debug.o src/rt/tlsgc-debug.o Assertion failed: (MemVT.getScalarType().bitsLT(VT.getScalarType()) && "Should only be an extending load, not truncating!"), function getLoad, file /Users/dan/projects/ldc/llvm-svn/lib/CodeGen/SelectionDAG/SelectionDAG.cpp, line 4543. Files: src/core/sys/posix/sys/select.o src/object_.o src/gc/gcx.o src/rt/aaA.o src/rt/adi.o src/rt/sections_ldc.o src/rt/cover-debug.o 0x7fa1f2052910 [ID=0] Do not know how to soften this operator's operand! UNREACHABLE executed at /Users/dan/projects/ldc/llvm-svn/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp:622! -- Dan
Jan 21 2014
parent reply "Kai Nacke" <kai redstar.de> writes:
Hi Dan!

On Tuesday, 21 January 2014 at 09:09:37 UTC, Dan Olson wrote:
 [...]
 I am seeing many assertions and segvs.  The four triples I am 
 working
 with are: armv7-apple-darwin, thumbv7-, armv6-, and thumbv6-.
 [...]
Thanks for the examples. I'll have a look at it this evening. Maybe I can create reduced test cases. Regards, Kai
Jan 21 2014
parent reply "Kai Nacke" <kai redstar.de> writes:
On Tuesday, 21 January 2014 at 11:50:59 UTC, Kai Nacke wrote:
 Hi Dan!

 On Tuesday, 21 January 2014 at 09:09:37 UTC, Dan Olson wrote:
 [...]
 I am seeing many assertions and segvs.  The four triples I am 
 working
 with are: armv7-apple-darwin, thumbv7-, armv6-, and thumbv6-.
 [...]
Thanks for the examples. I'll have a look at it this evening. Maybe I can create reduced test cases. Regards, Kai
This code import ldc.intrinsics; real cos(real x) safe pure nothrow { return llvm_cos(x); } crashes ldc if compiled with -c -mtriple=armv7-apple-darwin. Regards, Kai
Jan 21 2014
parent reply "Kai Nacke" <kai redstar.de> writes:
On Tuesday, 21 January 2014 at 19:02:56 UTC, Kai Nacke wrote:
 This code

 import ldc.intrinsics;

 real cos(real x)  safe pure nothrow { return llvm_cos(x); }

 crashes ldc if compiled with -c -mtriple=armv7-apple-darwin.
My first impression was that it has something to do with the real data type. But it turns out to be a problem with writing the object file. There seems to be no problem if you specify -output-s or -output-ll, too. Regards, Kai
Jan 21 2014
next sibling parent reply "Szymon Gatner" <noemail gmail.com> writes:
On Wednesday, 22 January 2014 at 06:15:11 UTC, Kai Nacke wrote:
 On Tuesday, 21 January 2014 at 19:02:56 UTC, Kai Nacke wrote:
 This code

 import ldc.intrinsics;

 real cos(real x)  safe pure nothrow { return llvm_cos(x); }

 crashes ldc if compiled with -c -mtriple=armv7-apple-darwin.
My first impression was that it has something to do with the real data type. But it turns out to be a problem with writing the object file. There seems to be no problem if you specify -output-s or -output-ll, too. Regards, Kai
Slightly OT but I am just really curious: how long do you think it will take to make D work on iOS? 3 months? 6? By the end of the year? Asking because it is a major argument when convincing my managers to switch from C++. I am sooo rooting for you guys!
Jan 22 2014
next sibling parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
"Szymon Gatner" <noemail gmail.com> writes:
 Slightly OT but I am just really curious: how long do you think it
 will take to make D work on iOS? 3 months? 6? By the end of the year?
 Asking because it is a major argument when convincing my managers to
 switch from C++. I am sooo rooting for you guys!
Hi Szymon, I don't know if anybody else is working on it and for me it is just a hobby/fun puzzle to use D in iOS. I do not write iOS apps for a living and am not sure where Apple would stand on getting a D-based app through the App Store review. It is too early to consider D as a viable iOS compiler chain. Right now we are stuck on proper code gen. Then there will be implementation of proper thread support, exception handling, thread local vars, and passing the D runtime/phobos unittests. And much more. -- Dan
Jan 22 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-01-23 06:34, Dan Olson wrote:

 Hi Szymon,

 I don't know if anybody else is working on it and for me it is just a
 hobby/fun puzzle to use D in iOS.  I do not write iOS apps for a living
 and am not sure where Apple would stand on getting a D-based app through
 the App Store review.  It is too early to consider D as a viable iOS
 compiler chain.
I don't know why the wouldn't accept D since they accept applications -- /Jacob Carlborg
Jan 23 2014
next sibling parent "Szymon Gatner" <noemail gmail.com> writes:
On Thursday, 23 January 2014 at 08:02:39 UTC, Jacob Carlborg 
wrote:
 On 2014-01-23 06:34, Dan Olson wrote:

 Hi Szymon,

 I don't know if anybody else is working on it and for me it is 
 just a
 hobby/fun puzzle to use D in iOS.  I do not write iOS apps for 
 a living
 and am not sure where Apple would stand on getting a D-based 
 app through
 the App Store review.  It is too early to consider D as a 
 viable iOS
 compiler chain.
Thanks, for info. Sounds like a lot of work :( Thanks for doing this!
 I don't know why the wouldn't accept D since they accept 

Exactly, I think there should be no problem here either. They
Jan 23 2014
prev sibling parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
Jacob Carlborg <doob me.com> writes:

 On 2014-01-23 06:34, Dan Olson wrote:

 I don't know why the wouldn't accept D since they accept applications

Once we get something simple with most of D runtime working, should submit and see what they think.
Jan 23 2014
parent Jacob Carlborg <doob me.com> writes:
On 2014-01-23 09:11, Dan Olson wrote:

 Once we get something simple with most of D runtime working, should
 submit and see what they think.
It would probably be easier to send something to the Mac App Store. I'm wondering how similar the rules are. -- /Jacob Carlborg
Jan 23 2014
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2014-01-22 17:40, Szymon Gatner wrote:

 Slightly OT but I am just really curious: how long do you think it will
 take to make D work on iOS? 3 months? 6? By the end of the year? Asking
 because it is a major argument when convincing my managers to switch
 from C++. I am sooo rooting for you guys!
If you don't want to use the Objective-C runtime API to interface with the Objective-C frameworks you need D to be ABI compatible with Objective-C as well, something like this: http://michelf.ca/projects/d-objc/syntax/ https://github.com/jacob-carlborg/dmd/tree/d-objc -- /Jacob Carlborg
Jan 23 2014
prev sibling parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
A small step, but over a big hurdle.  Ran D code + druntime on an
iPhone.  Nothing fancy, but initialized runtime with rt_init() and did
some dynamic array operations.  I include a snippet of silly D program I
ran at end of post.

The big hurdle has been ldc assertion failures in backend/codegen phase.
I have been studying llvm/clang code, but that takes time.  So I tried
an experiment.

If ldc2 skips the backend phase, it can generate IR (option -output-ll)
just fine for iOS target -mtriple=thumbv7-darwin.  Then question is, can
we use llc to do the backend codegen?  Like this:

  ldc2 -output-ll   [target and compile options]
  llc -filetype=obj [similar target and compile options]

It works!  Could I compile all of druntime this way? Yes!  Will it
run on an iPhone?  Yes again.

Still need to figure out the assertions but now have a work around so I
can move on with getting more D stuff (classes, exceptions, threads,
etc) working on iOS.

I also discovered that clang does a bunch of target munging, so -target
armv7-apple-darwin becomes:

  clang -cc1 -triple thumbv7-apple-ios5.0.0 -target-cpu cortex-a8

in the compile phase.  What is good for clang must be good for ldc.  It
does affect the register usage and probably the calling convention.

So when I edited druntime makefiles and used the two step build
(ldc2/llc), I used options:

ldc2 -mtriple=thumbv7-apple-ios5.0.0 -mcpu=cortex-a8 -disable-fp-elim
-float-abi=soft
llc -mtriple=thumbv7-apple-ios5.0.0 -float-abi=soft -mcpu=cortex-a8
-disable-fp-elim -O3 -filetype=obj

Note: this is with llvm-svn trunk and ldc git HEAD with a small number
of hacks in ldc tree just to get things going.

Following is some code I ran.  It is kicked off by calling dfun() from
the iOS app's main() C functions.

extern (C) int dfun()
{
    puts("Hello from dfun");
    foo("foo");
    return 2014;
}

struct Foo {
    this(int x, int y) {
        this.x = x;
        this.y = y;
        printf("Foo(%d, %d)\n", x, y);
    }
    ~this() {
        puts("~Foo");
    }
    int x, y;
}

void foo(string p)
{
    string s = "I am a D function: " ~ p;
    puts(s.ptr);

    auto f = Foo(1,42);

    printf("%d\n", f.x + f.y);

    int[] ar = [42];
    scope(exit) puts("done");

    foreach (i; 0..11) {
        printf("hello %d\n", i);
        ar ~= i;
    }

    foreach (i; ar) {
        printf("ar %d\n", i);
    }
}
Jan 30 2014
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2014-01-30 17:56, Dan Olson wrote:
 A small step, but over a big hurdle.  Ran D code + druntime on an
 iPhone.  Nothing fancy, but initialized runtime with rt_init() and did
 some dynamic array operations.  I include a snippet of silly D program I
 ran at end of post.
This is awesome. Have you tried any non C features, like classes yet? Keep up to good work :) -- /Jacob Carlborg
Jan 31 2014
parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
Jacob Carlborg <doob me.com> writes:

 On 2014-01-30 17:56, Dan Olson wrote:
 A small step, but over a big hurdle.  Ran D code + druntime on an
 iPhone.  Nothing fancy, but initialized runtime with rt_init() and did
 some dynamic array operations.  I include a snippet of silly D program I
 ran at end of post.
This is awesome. Have you tried any non C features, like classes yet? Keep up to good work :)
Hi Jacob, Yes, classes work. So far everthing I have tried works except exceptions and threads which have some stubbed out support in druntime. And TLS is disabled too. I am just stepping through druntime features. It may be time to figure out how to run the runtime unittests on iOS. Or maybe the next step is to rebuild phobos using the ldc/llc two phase approach. Earlier I had thought classes were a problem because when I added one to my test code, I was hitting illegal instructions in places that used to work. I thought there was some sort of codegen alignment problem. I now think it was because I had breakpoints on assembly instructions and I can't leave them in after rebuilding my test app. -- Dan
Jan 31 2014
parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
 Or maybe the next step is to rebuild phobos using the ldc/llc two phase
 approach.
Success building phobos this way and was able to writeln() to the Xcode console from iPhone 4. Again, druntime rt_init() and D functions are called by the iOS app's C main (not using dmain2 main). In the process, I discovered that std.stdio was uninitialized because module constructors are not being called by rt_init(). Something in the runtime sections OSX code that does not work for iOS. Oh, well, add to the todo list. However, found I could manually initialize std.stdio with std_stdio_static_this(). --- dfun.d --- import std.stdio; extern(C) void std_stdio_static_this(); extern(C) int dfun() { // static this in std.stdiobase isn't it called automatically? Need to // figure it out. In meantime, just do it! std_stdio_static_this(); writeln("Hello phobos"); return 2014; } All the LEGO blocks are there in ldc to build a D toolchain for iOS. Over the next few weeks I will put up stuff on github along with a todo list. I am not very good with Xcode so any thoughts on how to integrate would be nice. The tolist will look something like: - fix module ctors/dtors - version info for iOS (now using OSX && ARM, but not sure that makes sense? Use darwin && ARM?, or create new IOS version?) - exception support - thread support - tls support - run (and pass) unittests - figure out ldc codegen assertion errors for armv7/thumbv7 so can ditch the ldc/llc 2-phase approach. that is enough for now. -- Dan
Feb 04 2014
next sibling parent reply "Szymon Gatner" <noemail gmail.com> writes:
On Wednesday, 5 February 2014 at 07:32:05 UTC, Dan Olson wrote:
 Or maybe the next step is to rebuild phobos using the ldc/llc 
 two phase
 approach.
Success building phobos this way and was able to writeln() to the Xcode console from iPhone 4. Again, druntime rt_init() and D functions are called by the iOS app's C main (not using dmain2 main). In the process, I discovered that std.stdio was uninitialized because module constructors are not being called by rt_init(). Something in the runtime sections OSX code that does not work for iOS. Oh, well, add to the todo list. However, found I could manually initialize std.stdio with std_stdio_static_this(). --- dfun.d --- import std.stdio; extern(C) void std_stdio_static_this(); extern(C) int dfun() { // static this in std.stdiobase isn't it called automatically? Need to // figure it out. In meantime, just do it! std_stdio_static_this(); writeln("Hello phobos"); return 2014; } All the LEGO blocks are there in ldc to build a D toolchain for iOS. Over the next few weeks I will put up stuff on github along with a todo list. I am not very good with Xcode so any thoughts on how to integrate would be nice. The tolist will look something like: - fix module ctors/dtors - version info for iOS (now using OSX && ARM, but not sure that makes sense? Use darwin && ARM?, or create new IOS version?) - exception support - thread support - tls support - run (and pass) unittests - figure out ldc codegen assertion errors for armv7/thumbv7 so can ditch the ldc/llc 2-phase approach. that is enough for now.
Great to see such progress!
Feb 05 2014
parent Dan Olson <zans.is.for.cans yahoo.com> writes:
"Szymon Gatner" <noemail gmail.com> writes:

 Great to see such progress!
Yes, it is good when stuff just starts to work. Only problem is when it cuts into sleep... :-)
Feb 05 2014
prev sibling next sibling parent reply "Kai Nacke" <kai redstar.de> writes:
Hi Dan!

On Wednesday, 5 February 2014 at 07:32:05 UTC, Dan Olson wrote:
 The tolist will look something like:
 - fix module ctors/dtors
 - version info for iOS (now using OSX && ARM, but not sure that 
 makes
    sense?  Use darwin && ARM?, or create new IOS version?)
 - exception support
 - thread support
 - tls support
 - run (and pass) unittests
 - figure out ldc codegen assertion errors for armv7/thumbv7 so 
 can ditch
    the ldc/llc 2-phase approach.

 that is enough for now.
This really great work!!!! I think the that modules ctors/dtors are not calles may be a side effect of not having the right version identifier. As soon as you know what version identifier you need, please let me know. I'll add it asap. And if you still encounter ldc crashes, please report them. Even if I can't help on iOS right know I still can make sure that you have a stable environment. Again, thanks for doing this! Regards, Kai
Feb 05 2014
next sibling parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
"Kai Nacke" <kai redstar.de> writes:

 I think the that modules ctors/dtors are not calles may be a side
 effect of not having the right version identifier. As soon as you know
 what version identifier you need, please let me know. I'll add it
 asap.
Currently the verison(OSX) works in most places for iOS, or at least it compiles. Where I know there is a difference, I used nested version blocks by ARM. In the sections code, the existing version OSX code is being compiled without error, but does not work. I need to study it. I am not sure on the proper version handling yet. Most versioned code will be identical for OSX and IOS, so maybe most places in druntime should use version(darwin), then nested OSX/IOS when there is a difference? Does that make sense?
 And if you still encounter ldc crashes, please report them. Even if I
 can't help on iOS right know I still can make sure that you have a
 stable environment.
Yeah, there are 3 flavors of assertion failures which I can write as issues. -- Dan
Feb 05 2014
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2014-02-05 18:31, Dan Olson wrote:

 I am not sure on the proper version handling yet. Most versioned code
 will be identical for OSX and IOS, so maybe most places in druntime
 should use version(darwin), then nested OSX/IOS when there is a
 difference? Does that make sense?
Funny thing. When DMD was ported to OS X, "OSX" was added as a version identifier and "darwin" as a deprecated version identifier. "darwin" was already used by GDC, which was ported to OS X long before DMD. -- /Jacob Carlborg
Feb 05 2014
prev sibling parent "Joakim" <joakim airpost.net> writes:
On Wednesday, 5 February 2014 at 17:31:23 UTC, Dan Olson wrote:
 "Kai Nacke" <kai redstar.de> writes:

 I think the that modules ctors/dtors are not calles may be a 
 side
 effect of not having the right version identifier. As soon as 
 you know
 what version identifier you need, please let me know. I'll add 
 it
 asap.
Currently the verison(OSX) works in most places for iOS, or at least it compiles. Where I know there is a difference, I used nested version blocks by ARM. In the sections code, the existing version OSX code is being compiled without error, but does not work. I need to study it. I am not sure on the proper version handling yet. Most versioned code will be identical for OSX and IOS, so maybe most places in druntime should use version(darwin), then nested OSX/IOS when there is a difference? Does that make sense?
That sounds like a reasonable approach. Alternately, you could use X86/ARM, since OS X only runs on x86 now and iOS on ARM, which would be easier since those architecture keywords already exist, but perhaps not future-proof if Apple ever releases that ARM-based OS X laptop. ;) Darwin and iOS aren't in the predefined global versions in dmd's cond.c, so you might want to add them if you use those.
Feb 06 2014
prev sibling next sibling parent Dan Olson <zans.is.for.cans yahoo.com> writes:
"Kai Nacke" <kai redstar.de> writes:

 Hi Dan!

 On Wednesday, 5 February 2014 at 07:32:05 UTC, Dan Olson wrote:
 The to *do* list will look something like:
 - fix module ctors/dtors
I think the that modules ctors/dtors are not calles may be a side effect of not having the right version identifier. As soon as you know what version identifier you need, please let me know. I'll add it asap.
I figured out why static this() wasn't working. I was calling rt_init() in a __attribute__((constructor)) function. But then I noticed that LDC builds the ModuleReference list with global ctors too. So odds were I was calling rt_init() before all D modules were in the list. Calling rt_init() from C main solved it.
Feb 09 2014
prev sibling parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
"Kai Nacke" <kai redstar.de> writes:

 Hi Dan!

 On Wednesday, 5 February 2014 at 07:32:05 UTC, Dan Olson wrote:
 The todo list will look something like:
 - figure out ldc codegen assertion errors for armv7/thumbv7 so can
 ditch
    the ldc/llc 2-phase approach.
And if you still encounter ldc crashes, please report them. Even if I can't help on iOS right know I still can make sure that you have a stable environment.
I discovered the ldc (llvm codegen assertion failures) happen when float abi is soft for triples armv7-apple-darwin or thumbv7-apple-darwin. Thumb defaults to soft, and iOS likes thumb, so by overriding with -float-abi=softfp, I am avoiding the ldc -> IR -> llc -> obj 2-phase approach and using ldc all the way to build phobos. Works ../buildldc/bin/ldc2 -c ../ldc-git/runtime/druntime/src/core/demangle.d -mtriple=thumbv7-apple-darwin -float-abi=softfp -O Fails ../buildldc/bin/ldc2 -c ../ldc-git/runtime/druntime/src/core/demangle.d -mtriple=thumbv7-apple-darwin -O Assertion failed: ((TLI.getTypeAction(*DAG.getContext(), Node->getOperand(i).getValueType()) == TargetLowering::TypeLegal || Node->getOperand(i).getOpcode() == ISD::TargetConstant) && "Unexpected illegal type!"), function LegalizeOp, file /Users/dan/projects/ldc/llvm-svn/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp, line 1165. These fail in same way: -mtriple=armv7-apple-darwin -float-abi=soft -mtriple=armv7-unknown-linux-gnueabi -float-abi=soft -mtriple=thumbv7-unknown-linux-gnueabi It has something to do with TargetOptions UseSoftFloat = 1. I can file an issue if you like. Perhaps it is an llvm bug though. -- Dan
Feb 10 2014
parent reply David Nadlinger <code klickverbot.at> writes:
On Mon, Feb 10, 2014 at 5:39 PM, Dan Olson
<zans.is.for.cans yahoo.com> wrote> Works
 ../buildldc/bin/ldc2 -c ../ldc-git/runtime/druntime/src/core/demangle.d
-mtriple=thumbv7-apple-darwin -float-abi=softfp -O

 Fails
 ../buildldc/bin/ldc2 -c ../ldc-git/runtime/druntime/src/core/demangle.d
-mtriple=thumbv7-apple-darwin -O

 […]

 It has something to do with TargetOptions UseSoftFloat = 1.

 I can file an issue if you like.  Perhaps it is an llvm bug though.
Ah, yes, that's not really surprising. Unimplemented floating point lowerings tend to be responsible for a good share of strange error messages when targeting non-x86 platforms with LLVM, in my experience. The decision whether to use "soft", "softfp" or "hard" by default is (unfortunately) made in the LDC driver code, based on the target triple: https://github.com/ldc-developers/ldc/blob/master/driver/targetmachine.cpp. The logic is supposed to mirror what Clang does, but maybe I missed something. I'd definitely double-check the behavior against Clang, although this should really be moved into an LLVM support library – every flexible ARM compiler is going to need something similar. Another potential cause is that "thumbv7-apple-darwin" might not be the right target triple for iOS (thus leading to hardware floating point support being incorrectly disabled), but I'd have to reboot into OS X to check right now. Best, David
Feb 11 2014
parent Dan Olson <zans.is.for.cans yahoo.com> writes:
David Nadlinger <code klickverbot.at> writes:

 On Mon, Feb 10, 2014 at 5:39 PM, Dan Olson
 <zans.is.for.cans yahoo.com> wrote> Works
 ../buildldc/bin/ldc2 -c ../ldc-git/runtime/druntime/src/core/demangle.d
-mtriple=thumbv7-apple-darwin -float-abi=softfp -O

 Fails
 ../buildldc/bin/ldc2 -c ../ldc-git/runtime/druntime/src/core/demangle.d
-mtriple=thumbv7-apple-darwin -O

 […]

 It has something to do with TargetOptions UseSoftFloat = 1.

 I can file an issue if you like.  Perhaps it is an llvm bug though.
Ah, yes, that's not really surprising. Unimplemented floating point lowerings tend to be responsible for a good share of strange error messages when targeting non-x86 platforms with LLVM, in my experience. The decision whether to use "soft", "softfp" or "hard" by default is (unfortunately) made in the LDC driver code, based on the target triple: https://github.com/ldc-developers/ldc/blob/master/driver/targetmachine.cpp. The logic is supposed to mirror what Clang does, but maybe I missed something. I'd definitely double-check the behavior against Clang, although this should really be moved into an LLVM support library – every flexible ARM compiler is going to need something similar. Another potential cause is that "thumbv7-apple-darwin" might not be the right target triple for iOS (thus leading to hardware floating point support being incorrectly disabled), but I'd have to reboot into OS X to check right now.
Hi David, Clang does a bunch of munging of the -target it is handed. It seems very extensive for darwin targets with many special cases. I discovered a couple weeks ago that clang converts -target armv7-apple-darwin into -triple thumbv7-apple-ios5.0.0. I later found in an article that iOS prefers thumb2 to minimize code size. So that is why I suppose armv7 is converted to thumbv7. Anyway, I was curious just now so looked through clang/lib/Driver/ToolChains.pp and found Darwin::ComputeEffectiveClangTriple() is where the conversion is. and ToolChain::ComputeLLVMTriple() ... // Thumb2 is the default for V7 on Darwin. elsewhere tools::arm::getARMFloatABI() ... // Darwin defaults to "softfp" for v6 and v7. For now I am just fine with having to tell ldc2 to use -mtriple=thumbv7-apple-ios5.0.0 -float-abi=softfp It works. I am hoping to get changes up to an ldc github fork soon along with build instructions and some sample apps. Being new to git/github, there is a bit for me to learn about best practices for forks and submodules. For example, my instinct would be to put any example apps, scripts, and notes in the forked repo, but looking at others forked repos, it seems like they don't do that. P.S. I did have to add llvm::Triple::IOS to ldc main.cpp in the switch that sets D versions. So far very few changes to ldc to get D breathing on iOS. -- Dan
Feb 11 2014
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2014-02-05 08:32, Dan Olson wrote:

 Success building phobos this way and was able to writeln() to the Xcode
 console from iPhone 4.
That's great to hear :)
 Again, druntime rt_init() and D functions are called by the iOS app's C main
(not using dmain2 main).

 In the process, I discovered that std.stdio was uninitialized because
 module constructors are not being called by rt_init().  Something in the
 runtime sections OSX code that does not work for iOS.  Oh, well, add to
 the todo list.  However, found I could manually initialize std.stdio
 with std_stdio_static_this().
To have to module constructors run you need to implement rt.sections correctly for iOS. You could most likely use rt.sections_osx for iOS.
 I am not very good with Xcode so any thoughts on how to integrate
 would be nice.
To integrate Xcode with LDC you would need to create a plugin for Xcode, which is not officially supported. This has already been done by Michel Fortin[1], but that was for Xcode 3. There are a couple of plugins for Xcode 4 out there to look at. [1] http://michelf.ca/projects/d-for-xcode/ -- /Jacob Carlborg
Feb 05 2014
parent Dan Olson <zans.is.for.cans yahoo.com> writes:
Jacob Carlborg <doob me.com> writes:

 To integrate Xcode with LDC you would need to create a plugin for
 Xcode, which is not officially supported. This has already been done
 by Michel Fortin[1], but that was for Xcode 3. There are a couple of
 plugins for Xcode 4 out there to look at.

 [1] http://michelf.ca/projects/d-for-xcode/
Ok, good reference. It would also be nice to eventually try some Michel's and your D compiler modifications to directly interface with objc. I have read about them elsewhere in the D newsgroups. Thanks, Dan
Feb 05 2014
prev sibling next sibling parent Xavier Bigand <flamaros.xavier gmail.com> writes:
Le 05/02/2014 08:32, Dan Olson a écrit :
 Or maybe the next step is to rebuild phobos using the ldc/llc two phase
 approach.
Success building phobos this way and was able to writeln() to the Xcode console from iPhone 4. Again, druntime rt_init() and D functions are called by the iOS app's C main (not using dmain2 main). In the process, I discovered that std.stdio was uninitialized because module constructors are not being called by rt_init(). Something in the runtime sections OSX code that does not work for iOS. Oh, well, add to the todo list. However, found I could manually initialize std.stdio with std_stdio_static_this(). --- dfun.d --- import std.stdio; extern(C) void std_stdio_static_this(); extern(C) int dfun() { // static this in std.stdiobase isn't it called automatically? Need to // figure it out. In meantime, just do it! std_stdio_static_this(); writeln("Hello phobos"); return 2014; } All the LEGO blocks are there in ldc to build a D toolchain for iOS. Over the next few weeks I will put up stuff on github along with a todo list. I am not very good with Xcode so any thoughts on how to integrate would be nice. The tolist will look something like: - fix module ctors/dtors - version info for iOS (now using OSX && ARM, but not sure that makes sense? Use darwin && ARM?, or create new IOS version?) - exception support - thread support - tls support - run (and pass) unittests - figure out ldc codegen assertion errors for armv7/thumbv7 so can ditch the ldc/llc 2-phase approach. that is enough for now.
Really great news... Thx for all your efforts.
Feb 05 2014
prev sibling parent "David Nadlinger" <code klickverbot.at> writes:
On 5 Feb 2014, at 8:32, Dan Olson wrote:
 Success building phobos this way and was able to writeln() to the 
 Xcode
 console from iPhone 4.  Again, druntime rt_init() and D functions are
 called by the iOS app's C main (not using dmain2 main).
Coming back after a while and reading about that kind of progress while going through the mail inbox backlog is awesome! Regarding the assertion failures when emitting object code from within LDC, I'd use a debug build and GDB to figure out to try and figure out what could be the cause of the problem, and then compare the pass list (-debug-pass=…) and TargetOptions between llc and LDC (assuming that you already checked the obvious things, such as the target CPUs selected being the same, …). David
Feb 10 2014
prev sibling parent reply "Kai Nacke" <kai redstar.de> writes:
Hi Dan!

On Thursday, 30 January 2014 at 16:56:05 UTC, Dan Olson wrote:
 If ldc2 skips the backend phase, it can generate IR (option 
 -output-ll)
 just fine for iOS target -mtriple=thumbv7-darwin.  Then 
 question is, can
 we use llc to do the backend codegen?  Like this:

   ldc2 -output-ll   [target and compile options]
   llc -filetype=obj [similar target and compile options]

 It works!  Could I compile all of druntime this way? Yes!  Will 
 it
 run on an iPhone?  Yes again.
This sounds like a great step forward! Congratulations! I think I found the root cause why ldc crashes. I fixed it in the merge-2.064 branch. If you like to try it... Regards, Kai
Feb 01 2014
parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
"Kai Nacke" <kai redstar.de> writes:

 I think I found the root cause why ldc crashes. I fixed it in the
 merge-2.064 branch. If you like to try it...

 Regards,
 Kai
Yes - I am would like to try it out this evening.
Feb 01 2014
parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
Dan Olson <zans.is.for.cans yahoo.com> writes:

 "Kai Nacke" <kai redstar.de> writes:

 I think I found the root cause why ldc crashes. I fixed it in the
 merge-2.064 branch. If you like to try it...

 Regards,
 Kai
Yes - I am would like to try it out this evening.
Tried it and no more crashing (segv) :-) Should I be using merge-2.064 branch instead of master for my iOS porting fun? -- Dan
Feb 02 2014
parent "Kai Nacke" <kai redstar.de> writes:
On Sunday, 2 February 2014 at 09:31:24 UTC, Dan Olson wrote:
 Dan Olson <zans.is.for.cans yahoo.com> writes:

 "Kai Nacke" <kai redstar.de> writes:

 I think I found the root cause why ldc crashes. I fixed it in 
 the
 merge-2.064 branch. If you like to try it...

 Regards,
 Kai
Yes - I am would like to try it out this evening.
Tried it and no more crashing (segv) :-) Should I be using merge-2.064 branch instead of master for my iOS porting fun?
Great. Yes, please do. I hope I can fix the last few bugs in this branch soon. Regards, Kai
Feb 03 2014
prev sibling parent reply "David Nadlinger" <code klickverbot.at> writes:
Hi Dan,

On 8 Jan 2014, at 18:39, Dan Olson wrote:
 By the way, llc is very cool.  As I said, I am totally new to llvm
 internals, so am having fun learning what it has in its magic bag of
 tricks.
Glad to hear you are having fun. ;) By the way, are you aware of the dump() functions that LLVM offers on many of its objects (llvm::Type, llvm::Value, …)? They are very useful when debugging inside gdb, as they let you print out the contents of an object in a human-readable form (usually LLVM IR). For example, to track down what exactly causes the assertion failure you were seeing, you could simply run LDC (linked against a debug build of LLVM) in GDB, go up a few levels in the call stack, and then dump the various parameters to see where exactly the bitcast goes wrong. You can even dump entire LLVM functions/modules (e.g. try "p gIR->module->dump()" when debugging LDC), which is sometimes useful to orient oneself when debugging a complex code generation problem.
 So far I cannot find where clang adds the bitcast thing for sjlj eh
 personality.  I will keep hunting.  Any ideas where I would do this in
 ldc?
As Kai mentioned, this is/should really be fixed in LLVM, but in case you are curious: The landing pad instructions are created in createLandingPadInst() (ir/irlandingpad.cpp), I'd just insert a bitcast (e.g. using the DtoBitCast helper) there. You can use gTargetMachine->getMCAsmInfo()->getExceptionHandlingType() to determine which EH style LLVM will lower the instructions too. Generally, I'd really recommend working with the latest LLVM version when tackling a new port, though. Especially for some of the non-x86 targets, there is usually quite a bit of progress behind the releases, and if you need to patch LLVM at some point, it will take less effort to upstream your changes.
 When it comes to updating the _d_eh_personality for sjlj, I noticed a
 very small difference in the c++ versions ( _gxx_personality_v0 and
 _gxx_personality_sj0).  It is actually one funtion body in

 gcc-4.8-20121028/libstdc++-v3/libsupc++/eh_personality.cc

 with a little extra code in an ifdef _GLIBCXX_SJLJ_EXCEPTIONS
 conditional.
Yep, I also noticed that when working on ARM EABI EH support a few days back. Let's hope for the best – although the ARM EABI unwinder changes were only a few lines too, but took quite a bit of effort to reverse-engineer. Best, David
Jan 09 2014
parent Dan Olson <zans.is.for.cans yahoo.com> writes:
"David Nadlinger" <code klickverbot.at> writes:

 Glad to hear you are having fun. ;) By the way, are you aware of the
 dump() functions that LLVM offers on many of its objects (llvm::Type,
 llvm::Value, …)? They are very useful when debugging inside gdb, as
 they let you print out the contents of an object in a human-readable
 form (usually LLVM IR). For example, to track down what exactly causes
 the assertion failure you were seeing, you could simply run LDC
 (linked against a debug build of LLVM) in GDB, go up a few levels in
 the call stack, and then dump the various parameters to see where
 exactly the bitcast goes wrong. You can even dump entire LLVM
 functions/modules (e.g. try "p gIR->module->dump()" when debugging
 LDC), which is sometimes useful to orient oneself when debugging a
 complex code generation problem.
Sounds cool. I have not tried any of that yet.
 So far I cannot find where clang adds the bitcast thing for sjlj eh
 personality.  I will keep hunting.  Any ideas where I would do this in
 ldc?
As Kai mentioned, this is/should really be fixed in LLVM, but in case you are curious: The landing pad instructions are created in createLandingPadInst() (ir/irlandingpad.cpp), I'd just insert a bitcast (e.g. using the DtoBitCast helper) there. You can use gTargetMachine->getMCAsmInfo()->getExceptionHandlingType() to determine which EH style LLVM will lower the instructions too. Generally, I'd really recommend working with the latest LLVM version when tackling a new port, though. Especially for some of the non-x86 targets, there is usually quite a bit of progress behind the releases, and if you need to patch LLVM at some point, it will take less effort to upstream your changes.
Getting 3.4 now and will see what happens.
 When it comes to updating the _d_eh_personality for sjlj, I noticed a
 very small difference in the c++ versions ( _gxx_personality_v0 and
 _gxx_personality_sj0).  It is actually one funtion body in

 gcc-4.8-20121028/libstdc++-v3/libsupc++/eh_personality.cc

 with a little extra code in an ifdef _GLIBCXX_SJLJ_EXCEPTIONS
 conditional.
Yep, I also noticed that when working on ARM EABI EH support a few days back. Let's hope for the best – although the ARM EABI unwinder changes were only a few lines too, but took quite a bit of effort to reverse-engineer.
Yeah, low level code code can take sometime to get right. But it can be a master piece that you proudly look at and say, "it all fit in 256 bytes". Embedded assembly is my favorite. Now I need to get familiar with ARM assembly.
Jan 09 2014
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2014-01-06 14:06, David Nadlinger wrote:

 Why would you think otherwise, Jacob? Including more context with your
 messages would make a fair amount of them infinitely more useful…
I was basing that on that the Objective-C modern runtime uses DWARF EH [1] and iOS uses the modern runtime [2]. It seems that's only the case on Mac OS X and not iOS. I found this [3] post on stackoverflow saying Apple chose SJLJ on iOS due to reduce binary size. So it seems you were right. [1] The bottom of: https://developer.apple.com/library/mac/releasenotes/Cocoa/RN-ObjectiveC/#//apple_ref/doc/uid/TP40004309-CH1-DontLinkElementID_11 [2] https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtVersionsPlatforms.html [3] http://stackoverflow.com/questions/3683439/what-is-the-cost-of-using-exceptions-in-objective-c -- /Jacob Carlborg
Jan 06 2014
parent David Nadlinger <code klickverbot.at> writes:
On Mon, Jan 6, 2014 at 9:11 PM, Jacob Carlborg <doob me.com> wrote:
 I was basing that on that the Objective-C modern runtime uses DWARF EH [1]
 and iOS uses the modern runtime [2]. It seems that's only the case on Mac OS
 X and not iOS. I found this [3] post on stackoverflow saying Apple chose
 SJLJ on iOS due to reduce binary size. So it seems you were right.
Thanks, that's good to know! David
Jan 06 2014
prev sibling next sibling parent reply David Nadlinger <code klickverbot.at> writes:
On Mon, Jan 6, 2014 at 2:06 PM, David Nadlinger <code klickverbot.at> wrote:
 The source for the GCC/Clang personality function
 (__gxx_personality_sj0) is probably available somewhere as well, but I
 don't know where to look right now (libc++, probably).
Okay, I just had another short look, and libc++abi seems promising: https://github.com/llvm-mirror/libcxxabi/tree/master/src (inofficial GitHub mirror) Note in particular cxa_personality.cpp and Unwind/Unwind-sljl.c. David
Jan 06 2014
parent reply "Kai Nacke" <kai redstar.de> writes:
On Monday, 6 January 2014 at 13:15:45 UTC, David Nadlinger wrote:
 On Mon, Jan 6, 2014 at 2:06 PM, David Nadlinger 
 <code klickverbot.at> wrote:
 The source for the GCC/Clang personality function
 (__gxx_personality_sj0) is probably available somewhere as 
 well, but I
 don't know where to look right now (libc++, probably).
Okay, I just had another short look, and libc++abi seems promising: https://github.com/llvm-mirror/libcxxabi/tree/master/src (inofficial GitHub mirror) Note in particular cxa_personality.cpp and Unwind/Unwind-sljl.c. David
Source for __gxx_personality_sj0 is part of gcc. Just download latest gcc source and search for the symbol. Regards, Kai
Jan 06 2014
parent reply David Nadlinger <code klickverbot.at> writes:
On Mon, Jan 6, 2014 at 3:04 PM, Kai Nacke <kai redstar.de> wrote:
 Source for __gxx_personality_sj0 is part of gcc. Just download latest gcc
 source and search for the symbol.
Yes, it's certainly there, although I don't know how recent it is, given that Apple has been trying to get away from GCC for quite some time now. I don't think it's likely that there are a lot of incompatible changes, but to be sure… David
Jan 06 2014
parent Dan Olson <zans.is.for.cans yahoo.com> writes:
David Nadlinger <code klickverbot.at> writes:

 On Mon, Jan 6, 2014 at 3:04 PM, Kai Nacke <kai redstar.de> wrote:
 Source for __gxx_personality_sj0 is part of gcc. Just download latest gcc
 source and search for the symbol.
Yes, it's certainly there, although I don't know how recent it is, given that Apple has been trying to get away from GCC for quite some time now. I don't think it's likely that there are a lot of incompatible changes, but to be sure… David
I had some old gcc-4.8 source. I found it in: libstdc++-v3/libsupc++/eh_personality.cc
Jan 06 2014
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2014-01-05 18:28, Dan Olson wrote:

 Hi Jacob.

 Yeah, I probably have called it wrong as I am just learning about
 exception handling implementations.  clangc c++ exception handling for
 C++ armv7-apple-darwin is emitting __gxx_personality_sj0 and plugs in
 _Unwind_SjLj_Register/_Unwind_SjLj_Unregister.  Perhaps those are just
 for catching C code longjmps?
I had a look the code for libc++abi. It seems that on ARM it uses SjLj but with the same API as dwarf based exceptions, that is __cxa_begin_catch, __cxa_end_catch and so on. I didn't expect that. -- /Jacob Carlborg
Jan 19 2014
prev sibling parent "Kai Nacke" <kai redstar.de> writes:
On Sunday, 5 January 2014 at 09:36:52 UTC, Jacob Carlborg wrote:
 Hmm, I would have thought iOS used DWARF-based exception 
 handling.
LLVM generates SJLJ exceptions if you use -march=arm -mtriple=arm-darwin. I know this because there was once an ICE in LDC using the options because of a bug in LLVM. I fixed this in r181802 (http://article.gmane.org/gmane.comp.compilers.llvm.cvs/145269). Regards, Kai
Jan 06 2014