tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Tinycc-devel] Buggy commit "Rework expr_landor"


From: Michael Matz
Subject: Re: [Tinycc-devel] Buggy commit "Rework expr_landor"
Date: Mon, 27 Jan 2020 21:32:59 +0000 (UTC)
User-agent: Alpine 2.21 (LSU 202 2017-01-01)

Hello,

On Mon, 20 Jan 2020, grischka wrote:

> > Your last commit breaks something in my bignum library used by OpenLisp.
> >
> > This library does a lot of logical and bit operations on integers.
> >
> > Only this last commit generates a core dump as tested on Linux x64 (tcc
> > compiled by gcc 9.2.1) and Windows x64 (tcc compiled by boostrapped tcc).
> >
> > It is hard to currently investigate where it exactly happens.
> 
> Hi, well, here too, exactly what Christian wrote: strange failures,
> hard to impossible to say more.

Hrmpf, I've used that patch since some weeks and never hit that problem 
:-/  Obviously not enough testing coverage.

> But I found another test that might give a hint (attached).

Indeed, and thanks for fixing it ;-)

> About the precedence parser, great to see this, how it can really work 
> and all.
> 
> Still, hope you don't mind, I'd vote against it, for plain ordinary 
> nostalgic reasons, in the first place:
> 
> Basically those small functions making the top-down parser, still
> almost unchanged from how Fabrice wrote them,  are a just wonderful
> demonstration how simple C is, at its basics.

Actually, what Fabrice originally wrote is a sort-of precedence parser 
written in the slowest imaginable way (see commit a9f08655), though I 
found out only later :-)

In principle I agree with you on the nostalgia part, though I find other 
places in TCC more warty and unelegant than the precedence expression 
parser (_actually_ I find it fairly elegant, even :) ).

My motivation for writing it in the first place were two-fold: to reduce 
recursion depth, the precedence parser simply is faster and less deep; and 
second to save code lines, I have some little code optimizer that needs 
250 lines or so, and I thought I'd trade that with lines of code I remove 
with other patches ;-)

> I figure everybody seeing this wants to start working on her own 
> compiler immediately.
> 
> We can't let that go away, can we?
> 
> About expr_landor,  I didn't feel quite happy with how it looks,
> either.

Don't tell me.  I spent literally _days_ on making expr_landor 
somewhat more "natural" and failed.  Multiple times, I went back and forth 
with the gvtst helpers, either leaving things on the stack (a label 
reference) plus a gen_op helper that would combine them, or what's there 
now.  I thought that my expr_landor variant was a bit nicer, but obviously 
it also was wronger ;)

> Why for example
> 
>          if (c < 0)
>              t = gvtst(i, t);
>          else
>              vpop();
> 
> and not just
> 
>          t = gvtst(i, t);
> 
> and let the "automatic code suppression" do it?  (Guess it was
> const expressions or something.)

This is actually because gjmp() (used by gvtst) unconditionally does a 
CODE_OFF, but gsym(t) only does a CODE_ON when if(t).  The attached 
patch (on top of mob) works, but it introduces an explicit check on 
nocode_wanted.  That could be replaced by 

  static int gjmp_acs(int t) { t = gjmp(t); if (t) CODE_OFF(); return t; }

But that doesn't catch the case when a jump chain already was established 
and we are now newly in a nocode_wanted region, that would need to check 
t_after_gjmp != t_before_gjmp, but that's exactly equivalent to a 
nocode_wanted check again.

> Obviously you tried to move these 'non-obviousnesses' to the
> gvtest_set stuff.  I'm not sure that's a good idea.  At least
> that part I was still able to understand.  Now, for example,
> what means (t = gvtest()) == NULL?
> 
>          int t = gvtst(inv, 0);
>          if (t) /* in case gvtst only needed to do a gsym */
>          ...
> 
> Before that was because of nocode_wanted.  And that was the
> reason why I did avoid to have any 'if' with it anywhere.

Yeah, so the above was not for correctness, but for generating the 100% 
same code as without the expr_landor changes, nothing directly to do with 
nocode_wanted (though the changed code happened on the border of 
nocode_wanted changes, and only with my changes to gvtst+friends).  The 
thing is, gvtst doesn't always emit a jump (when the inverse setting and 
the jtrue/jfalse entries are right it only does a gsym(foo)), but the 
unconditional vseti(VT_JMP+inv, ...) makes it look to the compiler as if a 
jump was emitted that needs to be resolved when evaluating for value.  
The individual backends could of course handle the case when .c.i is zero 
for VT_JMP[I], but I thought why bother, the generic code could just as 
well handle that :)

> Anywho, there is less stack usage indeed, from compiling tcc.
> On the other hand 6 or 7 kB (on i386) aren't that much either.
> 
> The patch to make those traces is attached too. Usage is
>     $ tcc.exe -bt1000 -d9 tcc.c -o tcc1.exe
>     $ tcc1.exe tcc.c -bench -d7 > tcc.log 2>&1

Ah, cool, thanks, I was already curious how you measured that :)


Ciao,
Michael.

Attachment: tcc-landor-bla.diff
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]