lain Buctaw Oibuclaw DConf 2013 □ 3 Q History of Porting D Front End (DFE) □ 3 Q History of Porting D Front End (DFE) GDC Current Stat us □ 3 Q History of Porting D Front End (DFE) GDC Current Stat us Q The Anatomy of a GCC Front End □ 3 Q History of Porting D Front End (DFE) GDC Current Stat us Q The Anatomy of a GCC Front End Q GDC Extensions □ 3 Q History of Porting D Front End (DFE) GDC Current Stat us Q The Anatomy of a GCC Front End Q GDC Extensions O Future Pla ns □ 3 What is GCC? a Developed to be 100% free software. □ 3 What is GCC? • Developed to be 100% free software. Solid support for multiple language. □ 3 What is GCC? • Developed to be 100% free software. Solid support for multiple language. • Ported to almost all architectures. □ 3 That and because the Clang/LLVM compiler was not to appear for another 5 years. . . A Short History of Porting the D Front End. History January/2002: Early discussions of wanting to port D to Linux began. □ 3 History January/2002: April/2002: Early discussions of wanting to port D to Linux began. Walter Bright releases D Front End sources. □ 3 History January/2002: April/2002: Early discussions of wanting to port D to Linux began. Walter Bright releases D Front End sources. May/2002: Birth of D.gnu Mailing List and BrightD Compiler Project. □ 3 History January/2002: April/2002: Early discussions of wanting to port D to Linux began. Walter Bright releases D Front End sources. May/2002: Birth of D.gnu Mailing List and BrightD Compiler Project. June/2002: OpenD Compiler Project announced. □ 3 History August/2002: D Linux (DLI) released. □ 3 History August/2002: D Linux (DLI) released. May/2003: Walter Ports DMD to Linux. □ g History August/2002: D Linux (DLI) released. May/2003: Walter Ports DMD to Linux. February/2004: GDMD Compiler Released. □ g History August/2002: D Linux (DLI) released. May/2003: Walter Ports DMD to Linux. February/2004: GDMD Compiler Released. March/2004: DGCC Compiler Released. □ g History September/2007: New Development of an LLVM D Compiler. □ g History September/2007: New Development of an LLVM D Compiler. June/2008: DGCC Development Abandoned. □ g History September/2007: New Development of an LLVM D Compiler. June/2008: DGCC Development Abandoned. September/2009: GDC Revival Project Kicks Off. □ g History September/2007: New Development of an LLVM D Compiler. June/2008: DGCC Development Abandoned. September/2009: GDC Revival Project Kicks Off. December/2009: Enter Your Humble Speaker. □ g End of Life for Dl? November/2011: LDC D2 Compiler becomes default version that is built. □ g End of Life for Dl? November/2011: LDC D2 Compiler becomes default version that is built. December/2011: Dl discontinued support starting from 2013. □ g End of Life for Dl? November/2011: LDC D2 Compiler becomes default version that is built. December/2011: Dl discontinued support starting from 2013. January/2012: GDC drops Dl Front End from development. □ g Current State of D2 Compiler • Three main compilers based off the D2 Front End. nasas: Current State of D2 Compiler • Three main compilers based off the D2 Front End. • Platform support for Linux, FreeBSD, OSX, Solaris, and Windows. nasas: Current State of D2 Compiler • Three main compilers based off the D2 Front End. • Platform support for Linux, FreeBSD, OSX, Solaris, and Windows. • Target support for ARM, PowerPC, x86, x86_64. nasas: Current State of D2 Compiler • Three main compilers based off the D2 Front End. • Platform support for Linux, FreeBSD, OSX, Solaris, and Windows. • Target support for ARM, PowerPC, x86, x86_64. • D Runtime gaining support for more targets. nasas: Current State of D2 Compiler • Three main compilers based off the D2 Front End. • Platform support for Linux, FreeBSD, OSX, Solaris, and Windows. • Target support for ARM, PowerPC, x86, x86_64. • D Runtime gaining support for more targets. • Phobos becoming platform agnostic. a^oni Current GDC Support Status. nffiCTni GDC: Language Support • D Front End 2.062. • Passes 95% on D2 Testsuite. • Work being done on passing D Runtime/Phobos Unittests. affiCTGI GDC: Target Support • x86/x86_64: Solid support. • ARM: Partial support. • MIPS: Partial support. • Others: Untested / No runtime support. affiCTGI GDC: Platform Support • GNU/Linux: Main support platform. • FreeBSD/OpenBSD: Support should be there. • OSX: Lacks TLS Support. • Windows/MinGW: Alpha quality release available. a^oni GDC: To Hell With DMD Compatibility. • GDC follows the D calling convention as per the spec. BffiCTni GDC: To Hell With DMD Compatibility. • GDC follows the D calling convention as per the spec. » Except for Win32, which defines the D calling convention. a^oni GDC: To Hell With DMD Compatibility. • GDC follows the D calling convention as per the spec. a Except for Win32, which defines the D calling convention. » Uses thiscall convention for methods. a^oni GDC: To Hell With DMD Compatibility. • GDC follows the D calling convention as per the spec. a Except for Win32, which defines the D calling convention. » Uses thiscall convention for methods. No D Inline Assembly implemented. a^oni GDC: To Hell With DMD Compatibility. • GDC follows the D calling convention as per the spec. a Except for Win32, which defines the D calling convention. » Uses thiscall convention for methods. • No D Inline Assembly implemented. No naked function support. a^oni GDC: To Hell With DMD Compatibility. • GDC follows the D calling convention as per the spec. a Except for Win32, which defines the D calling convention. » Uses thiscall convention for methods. • No D Inline Assembly implemented. • No naked function support. • Type va list matches C ABI. a^oni GDC: To Hell With DMD Compatibility. • No simd support. a^oni GDC: To Hell With DMD Compatibility. • No simd support. » Allow vector sizes of 8, 16 or 32 bytes. a^oni GDC: To Hell With DMD Compatibility. No simd support. » Allow vector sizes of 8, 16 or 32 bytes. a No current restrictions on what targets can use vector. a^oni GDC: To Hell With DMD Compatibility. No simd support. » Allow vector sizes of 8, 16 or 32 bytes. a No current restrictions on what targets can use vector. » gcov and gprof replace -cov and -profile. a^oni □ g ^ ► « = ^ -o cvo GDC: To Hell With DMD Compatibility. No simd support. » Allow vector sizes of 8, 16 or 32 bytes. a No current restrictions on what targets can use vector. » gcov and gprof replace -cov and -profile. gdmd script maintained separately. BffiCTni □ g ^ ► « = ^ -o cvo GDC: To Hell With DMD Compatibility. • No simd support. » Allow vector sizes of 8, 16 or 32 bytes. a No current restrictions on what targets can use vector. » gcov and gprof replace -cov and -profile. gdmd script maintained separately. • No support for D DWARF extensions. a^oni □ g ^ ► « = ^ -o cvo The Anatomy of a GCC Front End. nffiCTni Why GCC? • The entry barrier to GCC development has gotten considerably lower during the last few years. • With work on documentation and separation of internal modules, writing your own front end for GCC has become accessible to a wider community of developers. nasas: Introduction to GCC • Able to translate from a variety of source languages to assembly. affiCTGI Introduction to GCC • Able to translate from a variety of source languages to assembly. • Encapsulated into one command. affiCTGI Introduction to GCC » Able to translate from a variety of source languages to assembly. • Encapsulated into one command. • Front end is made up of two main components. nasas: Compilation Driver • User interfacing application. affiCTGI Compilation Driver • User interfacing application. • Knows about all supported languages. affiCTGI □ g ^ ► « = s -o cvo Compilation Driver • User interfacing application. • Knows about all supported languages. • Able to determine source language. affiCTGI □ g ^ ► « = s -o cvo Compilation Driver • User interfacing application. • Knows about all supported languages. • Able to determine source language. • Passes output between compiler and assembler. a^oni Compiler Proper One compiler proper for each language. □ 3 nffiCTni Compiler Proper » One compiler proper for each language. • Composed from three components. affiCTGI □ g ^ ► « = ^ -o cvo Front End, Middle End and Back End • The Front End contains all the language processing logic. BffiCTni Front End, Middle End and Back End a The Front End contains all the language processing logic. • The Middle End is the platform independent part of the compiler. a^oni Front End, Middle End and Back End • The Front End contains all the language processing logic. • The Middle End is the platform independent part of the compiler. • The Back End is then the platform dependent part. a^oni GENERIC • GENERIC is a tree language. nasaa GENERIC • GENERIC is a tree language. • Mechanism to define own node types. nasaa GENERIC • GENERIC is a tree language. » Mechanism to define own node types. • Supports everything there is to represent in a typical C function. nasas: □ g ^ ► « = s -o cvo GENERIC • GENERIC is a tree language. » Mechanism to define own node types. • Supports everything there is to represent in a typical C function. • During the course of compilation, it is lowered into an intermediate code called GIMPLE. nasas: □ g ^ ► « = ^ -o cvo » GIMPLE is a subset of GENERIC. nasas: • GIMPLE is a subset of GENERIC. • Breaks down all expressions, using temporaries to store intermediate results. nasas: • GIMPLE is a subset of GENERIC. • Breaks down all expressions, using temporaries to store intermediate results. • Further transforms all blocks into gotos and labels. nasas: • GIMPLE is a subset of GENERIC. • Breaks down all expressions, using temporaries to store intermediate results. • Further transforms all blocks into gotos and labels. • Lowered down to RTL, or Register Transfer Language. a^oni Interfacing with D Front-End • GDC initialises the D Front-End, sets up all global parameters. a^oni Interfacing with D Front-End • GDC initialises the D Front-End, sets up all global parameters. • D Front-End parses and runs semantic on the code. a^oni □ g ^ ► « = s -o cvo Interfacing with D Front-End • GDC initialises the D Front-End, sets up all global parameters. • D Front-End parses and runs semantic on the code. • GDC generates GENERIC to be sent to backend. a^oni □ g ^ ► « = s -o cvo Interfacing with D Front-End • GDC initialises the D Front-End, sets up all global parameters. • D Front-End parses and runs semantic on the code. • GDC generates GENERIC to be sent to backend. • GCC backend compiles down to RTL. a^oni □ g ^ ► « = s -o cvo A Simple D Program module demo; int add ( int a , int b) { return a + b; } 1*™**™ □ 3 Code Generated in GENERIC demo .add (int a, int b) { return = a + b; > demo. add (int a, : .nt b) bind_expr ( return_expr ( init_expr ) ) (, plus _expr (a, b)) □ g «™***™ Representation after Gimplification demo. add (int a, int b) { int vartmpO ; vartmpO = a + b; return vartmpO ; } demo. add (int a, int b) gimple_bind ( int vartmpO ; gimple_assign (plus_expr, vartmpO, gimple_return (vartmpO) ) b) «™*"*™ A More Interesting D Program module demo; long fib (uint m) { return (m < 2) ? m : fib (m - 1) + fib (m - 2); } □ 3 nffiCTni Code Generated in GENERIC demo.f ib(uint m) { return = m <= 1 ? (long) m : demo. fib (m - 1) + demo. fib (m - 2) ; } demo.f ib(uint m) bind_expr ( return_expr ( init_expr ( , cond_expr (le_expr, m, 1, nop_expr (m) , plus_expr (call_expr (demo. fib, minus_expr (m, D). call_expr (demo . f ib , ) ) ) ) minus_expr (m, 2))) a^oni Representation after Gimplification demo. fib (uint m) { long vartmpO; long iftmpO; uint vartmpl; long vartmp2; uint vartmp3 ; long vartmp4; if (m <= 1) goto LI; else goto L2; LI: iftmpO = (long) m; goto L3; L2: vartmpl = m + 4294967295; vartmp2 = demo. fib (vartmpl); vartmp3 = m + 4294967294; vartmp4 = demo. fib (vartmp3) ; iftmpO = vartmp2 + vartmp4 ; L3: vartmpO = iftmpO; return vartmpO; } nffiCTGi Notation Representation demo. fib (uint m) gimple_bind ( long vartmpO; uint vartmpl ; long vartmp2; uint vartmp3 ; long vartmp4; long iftmpO; gimple_cond (le_expr, m, 1, (LI), (L2)) gimple_label (LI) gimple_assign (nop_expr, iftmpO, m) gimple_goto (L3) gimple_label (L2) gimple_assign (plus_expr, vartmpl, m, 4294967295) gimple_call (demo. fib, vartmp2, vartmpl) gimple_assign (plus_expr, vartmp3, m, 4294967294) gimple_call (demo. fib, vartmp4, vartmp3) gimple_assign (plus_expr, iftmpO, vartmp2, vartmp4) gimple_label (L3) gimple_assign (var_decl, vartmpO, iftmpO) gimple_return (vartmpO) ) «™***™ GDC Extensions nffiCTni Custom Static Chains • Generated for all nested functions • Generated for toplevel functions with nested references. int delegateO foo() { int x = 7; int barO { int bazO { return x + 3; return bazO ; } return &bar; nasas: Generated GENERIC Code closure. f oo. bar. baz (void *this) { return = ( (CLOSURE. closure. foo *) this)->x + 3; } closure. foo. bar (void *this) { return = closure. f oo.bar .baz ((CLOSURE. closure. foo *) this); } closure. foo (void *this) { int x [value-expr: ( closptr)->x] ; struct CLOSURE. closure. foo * closptr; closptr = (CLOSURE. closure. foo *) _d_allocmemory (8); closptr-> chain = OB; closptr->x = 7; return = {.object= closptr, . func=closure.f oo.bar}; □ g a^oni Function Frames • Where a closure is not required, a frame is instead generated. void barO { int add = 2; } scope dg = (int assert (dg(5) == a) ) => a + add; a^oni Generated GENERIC Code frame. bar. lambdal (void *this) { return = a + ((FRAME. frame. bar *) this)->add; } frame. bar () { struct dg; int add [value-expr: (& frame) ->add] ; struct FRAME. frame. bar frame; frame. chain = OB; (& frame) ->add = 2; dg = {.object=& frame, . func=frame.bar . lambdal}; if (dg.func (dg. object, 5) == 7) { } else { _d_assert ({.length=6, .ptr="test .d"}, 7); } a^oni GCC Built-in Functions and Types • gcc.builtins gives access to built-ins provided by the GCC backend. import gc c .built ins; vo: -r d test o real r = 0.5 « built in_sqrtl(real. min_ .normal) ; } if (_ _builtin _builtin _expect _printf ( cast (long) r = Hello World !\n = "); true)) «™***™ Generated GENERIC Code • Allows many C library calls to be optimised in certain cases. builtins.test () { real r; r = 9 . 16801933777423582810706196024241582978182485679283618642e-2467; { if ( builtin_expect ((long) r == 0, 1) != 0) { builtin_puts ("Hello World!"); } } □ g «™*"*™ Built-in Types Defines aliases to internal types. builtin_va_list ; // Target C va_list type. built in_clong; // Target C long int type. built in_culong; // Target C long unsigned int type. builtin_machine_byte ; // Signed type whose size is equal to sizeof (unit) . builtin_machine_ubyte ; // Unsigned variant. builtin_machine_int ; // Signed type whose size is equal to sizeof (word) . built in_machine_uint ; // Unsigned variant. builtin_pointer_int ; // Signed type whose size is equal to sizeof (pointer) . builtin_pointer_uint ; // Unsigned variant. builtin_unwind_int ; // Target C _Unwind_Sword type, for EH. builtin_unwind_uint ; // Target C _Unwind_Word type, for EH. nasas: Implementing D Intrinsics • DMD has several intrinsics to the compiler. import core.bitop; import core. math; void mainO { long 1; 1 = rndtol (4.5); size_t[2] a = [2, 256] ; btc(a.ptr, 35); □ g a^oni Generated GENERIC Code • core. math intrinsics are mapped to GCC builtin-ins. » core.bitop instrinsics are expanded with inlined generated code. int D main() { int D.2001; ulong a [2] ; long 1; 1 = 0; 1 = (long) builtin_llroundl (4.5e+0); a[0] = 2; a[l] = 256; D.2001 = (* (ulong *) &a & 34359738368) != ? -1 : 0; *(ulong *) &a = *(ulong *) &a " 34359738368; return = 0; nffiCTni Extending D Intrinsics o Many functions defined in core.stdc are mapped to GCC built-ins. Functions recognised as a GCC built-in can be optimised. • Can be turned off with -fno-builtin switch. a^oni import core . stdc . stdio; import core. stdc. math; void testO { real r = powl(3, 3); if (r == 27.0) printf ( "Match !\n") ; intrinsic .test () { real r; r = 2.7e+l; { if (r == 2.7e+l) { builtin_puts ("Match!"); } } a^oEi Variadic Functions a The va list type has an exclusive meaning in the compiler. • Matches the C ABI, type is not a void* • Defined in gcc.builtins, then an alias to the type in core.stdc.stdarg. • Special va functions expanded at compile-time. a^oni □ g ^ ► « = ^ -o cvo Variadic Functions import core stdc.stdarg; void v< { auto iriadic( ..) al = va. .arg (int) (_argptr) ; auto a2 = va. .arg (double) (. .argptr) ; auto a3 = va. .arg (int[2])( .argptr) ; auto a4 = va. .arg (string) ( .argptr) ; } 1*™**™ Generated GENERIC Code valist . variadic (struct Typelnf o_Tuple ft _arguments_typeinf o) { struct _argptr[l]; struct a4 ; int a3 [2] ; double a2; int al ; struct _arguments; builtin_va_start (&_argptr, _arguments_typeinf o) ; try { _arguments = _arguments_typeinf o->elements; al = VA_ARG_EXPR <_argptr>; a2 = VA_ARG_EXPR <_argptr>; a3 = VA_ARG_EXPR <_argptr>; a4 = VA_ARG_EXPR <_argptr>; } finally { builtin_va_end (&_argptr) ; a^oni GCC Attributes • Used to be accessible via pragmas in the language. • Now uses UDA syntax that gets handled by gcc. attributes. import gcc. attributes; import gcc.builtins; ©attribute ( "noreturn" ) void dieO { builtin_unreachable() ; «™*"*™ GCC Type Attributes • Attributes can also be applied to types. import gcc. attributes; @attribute( "aligned") struct A { char c; int i; } ©attribute ("unused") int unused_var; • As of writing, none of these attributes are implemented in GDC. a^oni □ g ^ ► « = ^ -o cvo GCC Extended Assembly • GDC implements a variant of GCC Extended Assembly. • Extended assembly allows you to optionally specify the operands. asm { "rdtsc" : /* outpu t operands */ : /* input operands */ : /* list of clobbered regis ters */■ } nasas: Benefits of Extended Assembly • It is available on nearly all targets. • Instruction templates can be generated through CTFE string constants. • Does not prevent a function from being inlined. • Can have some common optimisations applied to them, such as DCE. nasas: □ g ^ ► « = ^ -o cvo Future Plans nffiCTni Compiler: Short Term • Removing last of DMD-backend facing code from DFE. affiCTGI Compiler: Short Term • Removing last of DMD-backend facing code from DFE. • Find a workable solution for TLS support. affiCTGI □ g ^ ► « = ^ -o cvo Compiler: Short Term • Removing last of DMD-backend facing code from DFE. • Find a workable solution for TLS support. Better support for LTO. affiCTGI □ g ^ ► « = ^ -o cvo Compiler: Long Term Kickstart testing of more targets with D2. affiCTGI Compiler: Long Term Kickstart testing of more targets with D2. • Implement missing optimisation features of D. affiCTGI Compiler: Long Term • Kickstart testing of more targets with D2. • Implement missing optimisation features of D. » Named return value optimisation. □ 3 a^oni Compiler: Long Term Kickstart testing of more targets with D2. • Implement missing optimisation features of D. a Named return value optimisation, a POD struct types. a^oni Compiler: Long Term Kickstart testing of more targets with D2. • Implement missing optimisation features of D. a Named return value optimisation. » POD struct types. • Integration of DFE into GCC garbage collector. a^oni Compiler: Wishlist • Add support for label operands in Extended Assembly. int frob(int x) { int y; asm { "frob y.'/„r5, 7.1; j c '/,1 [Lerror] ; mov C/,2) , °///,r5" "r"(x), "r"(&y) "r5", "memory" Lerror; } return y; Lerror : return -1; nffiCTGi • Implement Exception Chaining. affiCTGI □ g ^ ► « = ^ -o cvo • Implement Exception Chaining. • Conversion of D IASM to Extended Assembly. nasas: □ g ^ ► « = ^ -o cvo • Implement Exception Chaining. • Conversion of D IASM to Extended Assembly. • Finish off port of ARM. nasas: □ g ^ ► « = ^ -o cvo • Implement Exception Chaining. • Conversion of D IASM to Extended Assembly. • Finish off port of ARM. • Fix D GC runtime for TLS support. a^oni □ g ^ ► « = ^ -o cvo It is vital that we begin testing on, and gain support for more target architectures and platforms. affiCTGI http://gdcproject.org http://gdcproject.org/wiki http://bugzilla.gdcproject.org ibuclaw@gdcproject.org i*™**™ □ g ^ ► « = ^ -o cvo Questions? «™*"*™