Re: [Tinycc-devel] Generating better i386 code
On Fri, Sep 27, 2013 at 11:21:19AM +1000, Jason Hood wrote: On 26/09/2013 16:30, Daniel Glöckner wrote: On Thu, Sep 26, 2013 at 03:39:45PM +1000, Jason Hood wrote: * 4- 8-byte structs copy as int/long long (all targets); did you check if the structure is aligned to a multiple of 4 bytes? Otherwise it will crash on ARM. No, as I thought structures of these sizes would already be aligned (as if they were int or long long). Is that not necessarily the case? No, struct { char x[4]; } has an alignment of 1 byte. Daniel ___ Tinycc-devel mailing list Tinycc-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/tinycc-devel
Re: [Tinycc-devel] inline assembly and optimization passes
Date: Thu, 26 Sep 2013 11:33:38 +0200 From: Sylvain BERTRAND sylw...@legeek.net To: tinycc-devel@nongnu.org Subject: Re: [Tinycc-devel] inline assembly and optimization passes Message-ID: 20130926093338.GA500@freedom Content-Type: text/plain; charset=us-ascii If I was doing that then I'd be looking at an application language that would easily integrate with a systems language, hence high-end features along with C compatibility. If I was going for a new systems language then I'd just take C, modify the syntax for pointers declarations, and maybe modify the standard library. Presumably a smaller job than a from-scratch language. I do not agree. I would go C- for system and application. I don't like my software stack to depend on tons of different languages (because at the end, it's what we get). A purpose for everything, and for everything a purpose. C is a difficult language to write big programs in, most of all because you have to do all memory management yourself (non-cyclic dependencies make this easy, cyclic dependencies make this hard, data outside of basic foundations such as trees usually involves cyclic dependencies... and unlike those you can introduce to basic data structures, these dependencies are not simple to manage). It's also an awkward language due to it's lack of higher-end constructs such as classes, closures (well, lambda functions, really), casting operators, and language-enforced RAII. The applications language would be C-based, a closure would look something like the following: _int( _int ) _closure abs = @ _int ( _int arg ) { _return( arg = 0 ? arg : -arg ); }; Basically, a rationalized form of C (e.g., pointers are now part of the TYPE portion of the declaration, NOT the VARIABLE part; a keyword is used instead of a re-purposed operator; and the pointer operators have their own character sequences instead of reusing other's), and THEN adapted to the application-programming realm. Part of the idea is that while C has the right basic syntax, when you get out of the bare-metal realm you want some richer (and, more importantly, more convenient) features to use. Thus, a language that takes the most of the good from C, tries to fix the bad (declaration and pointer syntax goofs, namespace collisions, multiple types in a single declaration), and adds some general convenience features, such as GC (because doing it correctly is hard), and some things that GC suddenly makes practical (like closures). The output of the compiler would be C, intended to be linked with a provided runtime library (it wouldn't be that big, as the standard library would be something separate: the runtime provides the bits inherently required by the language, the standard library provides the stuff you normally use, and thus can be replaced with what the programmer wants). This would certainly be made easier by the firm resemblance to C (everything will either be lifted from C, implemented with a C library, or built on top of such capabilities). Frankly, if I were running a software company, I would keep most of my employees away from languages like C-- while on company time. The moment you get into memory management, everything becomes more complex, and the simple reference counting scheme that seems to commonly be used isn't up to the job of correctly managing reference-loops. It's a task best left to a dedicated library. I don't think the designers of C-- would suggest it for applications programming, or at least some systems programming, either. C-- (unless you're talking about the Sphinx one, which I don't remember anything about) was designed as a language for COMPILERS to target. And indeed, you could design a fairly good compiler target language if you lifted syntax from C. Unfortunately, C-- is (at least to the best of my knowledge) tied rather directly to the x86 architecture. Furthermore, as I best recall the only real advantage that it had was a swap operator, and some more-efficient versions of e.g. if. This is not really what you want in a compiler-target language. What you really want to a way to describe functions and data structures in such a way that you both convey the details that you require, and allow the C-- compiler to reinterpret your information into an improved form. Annotations are certainly useful for this, but you're probably not quite looking at C, because I'm pretty certain that you would really want compile-time code to be run during that phase, which C in no way provides for. So you want to hook into the TCC parser itself? I said, if this has no obvious blockers, we could use fake targets that would be optimization passes. They would output C code. Yeah, I mostly paid attention to the fake-target bit, since outputting IL/IC from that seemed like the easiest way into the standard route. I don't know what this standard route is, all I know is ouputing C code with fake targets to handle some optimization passes seems to be a good tradeoff to
Re: [Tinycc-devel] Generating better i386 code
On 27/09/2013 16:54, Daniel Glöckner wrote: No, struct { char x[4]; } has an alignment of 1 byte. Right, well I think that's simple enough: --- tccgen~.c 2013-09-25 19:24:46 +1000 +++ tccgen.c2013-09-27 19:33:08 +1000 @@ -2405,12 +2405,18 @@ if (!nocode_wanted) { size = type_size(vtop-type, align); +#ifdef TCC_TARGET_ARM +if (!(align 3)) { +#endif if (size == 4) goto small_struct; if (size == 8) { ft = VT_LLONG; goto small_struct; } +#ifdef TCC_TARGET_ARM +} +#endif /* destination */ vswap(); -- Jason. ___ Tinycc-devel mailing list Tinycc-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/tinycc-devel
Re: [Tinycc-devel] inline assembly and optimization passes
A purpose for everything, and for everything a purpose. C is a difficult language to write big programs in, most of all because you have to do all memory management yourself (non-cyclic dependencies make this easy, cyclic dependencies make this hard, data outside of basic foundations such as trees usually involves cyclic dependencies... and unlike those you can introduce to basic data structures, these dependencies are not simple to manage). It's also an awkward language due to it's lack of higher-end constructs such as classes, closures (well, lambda functions, really), casting operators, and language-enforced RAII. The applications language would be C-based, a closure would look something like the following: _int( _int ) _closure abs = @ _int ( _int arg ) { _return( arg = 0 ? arg : -arg ); }; Basically, a rationalized form of C (e.g., pointers are now part of the TYPE portion of the declaration, NOT the VARIABLE part; a keyword is used instead of a re-purposed operator; and the pointer operators have their own character sequences instead of reusing other's), and THEN adapted to the application-programming realm. Part of the idea is that while C has the right basic syntax, when you get out of the bare-metal realm you want some richer (and, more importantly, more convenient) features to use. Thus, a language that takes the most of the good from C, tries to fix the bad (declaration and pointer syntax goofs, namespace collisions, multiple types in a single declaration), and adds some general convenience features, such as GC (because doing it correctly is hard), and some things that GC suddenly makes practical (like closures). The output of the compiler would be C, intended to be linked with a provided runtime library (it wouldn't be that big, as the standard library would be something separate: the runtime provides the bits inherently required by the language, the standard library provides the stuff you normally use, and thus can be replaced with what the programmer wants). This would certainly be made easier by the firm resemblance to C (everything will either be lifted from C, implemented with a C library, or built on top of such capabilities). Frankly, if I were running a software company, I would keep most of my employees away from languages like C-- while on company time. The moment you get into memory management, everything becomes more complex, and the simple reference counting scheme that seems to commonly be used isn't up to the job of correctly managing reference-loops. It's a task best left to a dedicated library. I don't think the designers of C-- would suggest it for applications programming, or at least some systems programming, either. C-- (unless you're talking about the Sphinx one, which I don't remember anything about) was designed as a language for COMPILERS to target. And indeed, you could design a fairly good compiler target language if you lifted syntax from C. Unfortunately, C-- is (at least to the best of my knowledge) tied rather directly to the x86 architecture. Furthermore, as I best recall the only real advantage that it had was a swap operator, and some more-efficient versions of e.g. if. This is not really what you want in a compiler-target language. What you really want to a way to describe functions and data structures in such a way that you both convey the details that you require, and allow the C-- compiler to reinterpret your information into an improved form. Annotations are certainly useful for this, but you're probably not quite looking at C, because I'm pretty certain that you would really want compile-time code to be run during that phase, which C in no way provides for. Again, I mostly do not agree and you really keep missing my point: a C- compiler would be easier to code than a C compiler (C-- is a project already taken by some evil people and is not interesting). And I would use it for system and application programming. I'm going the other way, I certainly do *not* want a language which has a richer syntax, with a special attention *not* to have more complex data structures (class...), because it makes the syntax exponentially more complex (one of the worst being c++). The comfort provided by a higher level language is never worth its technical cost. That's my final opinion based on my ground experience. Moreover, as I said, you end up in facts with tons of high level languages, which make the software stack insanely costly. Sure if C- happens one day, pointer syntax and implicit casts will need some cleanup, and I'm thinking about friendlyness with formal proof. The standard route to optimizations is that your C parse outputs something that represents the C input, but in a more convenient form, which is then read in by your optimizer and assembler. As I understand it, this is normally some version of Polish notation (either normal, or reverse) due to the greater ease in parsing it.