Re: [Tinycc-devel] Generating better i386 code

2013-09-27 Thread Daniel Glöckner
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

2013-09-27 Thread Jared Maddox
 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

2013-09-27 Thread Jason Hood
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

2013-09-27 Thread Sylvain BERTRAND
 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.