[M3devel] loophole/copysign

Jay K jay.krell at cornell.edu
Tue Jul 6 01:06:29 CEST 2010


I'm not sure we need to be too fancy: not sure we need a union.
I think merely taking the address and casting and derefing it might suffice.
For aliasing we just always return 0, so presumably..any pointers are pessimistic.


The alias information seems to be that any "decl" could be a variable, or a type..is in a "set".
Sets are integer indices into an array of sets.
Same integer => same set.


But I think that we just return 0 all the time makes these easy and adequate.
Could be better. But probably ok.


Perhaps the better way would be:
  if file uses loophole anywhere, same as today
   loophole in the front end or backend


 if file doesn't use loophole, we can probably at least put every? type in its own set?
  Er, not exactly: not subranges enums integers.
  But still probably some easy stuff?


 Anyway, just having everything in the same alias set should be ok for now.
 We're still digging out of a big hole: volatile everywhere.. no unit at a time..


 - Jay


----------------------------------------
> From: jay.krell at cornell.edu
> To: hosking at cs.purdue.edu
> CC: m3devel at elegosoft.com
> Subject: RE: [M3devel] loophole/copysign
> Date: Mon, 5 Jul 2010 22:50:38 +0000
>
>
> The C trees are much higher level.
>
> First, cm3/m3-libs/m3core/src/float/test_copysign.c which is analogous to CopySign, the C code:
>
> typedef struct {
>         unsigned rest : 31;
>         unsigned sign : 1;
> } float_t;
>
> float copy_sign_f(float from, float to)
> {
>         float res = to;
>         ((float_t*)&res)->sign = ((float_t*)&from)->sign;
>         return res;
> }
>
> is what we should somehow strive for.
>
> It yields a tree with almost everything preserved (typedefs fall out).
> gcc-4.2 -fdump-tree-all -c test_copysign.c
>
> test_copysign.c.003t.original:
>
> ;; Function copy_sign_f (copy_sign_f)
> ;; enabled by -tree-original
>
> {
>   float res = to;
>
>     float res = to;
>   ((struct float_t *) &res)->sign = ((struct float_t *) &from)->sign;
>   return res;
> }
>
> which is nothing like what we produce.
> We don't have structs/member_refs ever, I believe.
>
>
> To maybe answer your question..well..:
>
> int reinterpret(float f)
> {
>   return *(int*)&f;
> }
>
> gcc-4.2 -ftree-dump-all -c 5.c well, the tree is high super high fidelity, nearly
> indistinguishable from the input C:
>
>
> ;; Function reinterpret (reinterpret)
> ;; enabled by -tree-original
> {
>   return *(int *) &f;
> }
>
>
> I think we would produce about the same thing if we went down the non-bitfield path in load or store.
> You know ... we don't even need to do loophole, but we need to do just one load or one store, with a conversion,
> instead of storing one way and loading the other.
>
>
> You could imagine parse.c might buffer up one load or store and then if the next instruction is not store or load, just flush it,
> but if it is store or load, merge them. Well, it depends on what load or store is to of course.
>
>
>  - Jay
>
> ----------------------------------------
> > Subject: Re: [M3devel] loophole/copysign
> > From: hosking at cs.purdue.edu
> > Date: Mon, 5 Jul 2010 18:27:10 -0400
> > CC: m3devel at elegosoft.com
> > To: jay.krell at cornell.edu
> >
> > OK, so now I begin to understand. What you are saying is that gcc needs to have a union type capturing the fact that the variable is accessed using 2 different types. What happens in C code where you cast a memory location from one type to another? How does gcc cope with that? Presumably it gets some sort of type aliasing information?
> >
> > On 5 Jul 2010, at 17:42, Jay K wrote:
> >
> > >
> > > CastExpr.m3 has precious few calls to CG.Loophole, including none for this case.
> > > cm3cg -y output for m3core/LongReal.mc CopySign has no calls to loophole.
> > > We store into a local as one type and read it back as another type.
> > >
> > > - Jay
> > >
> > > ----------------------------------------
> > >> From: hosking at cs.purdue.edu
> > >> Date: Mon, 5 Jul 2010 17:33:43 -0400
> > >> To: jay.krell at cornell.edu
> > >> CC: m3devel at elegosoft.com
> > >> Subject: Re: [M3devel] loophole/copysign
> > >>
> > >> Surely we should instead give it the type conversion from what was stored to what is loaded. Can you point me at the problem code in CastExpr?
> > >>
> > >> On 5 Jul 2010, at 16:44, Jay K wrote:
> > >>
> > >>>
> > >>> I don't think a barrier worked.
> > >>> The thing is, I don't think a change in parse.c alone can work. It isn't being given enough information.
> > >>> Or, well, it does have enough information, but, like, it is information it never uses.
> > >>> It has some type information. It would have to notice that the most recent store to a variable was
> > >>> of a different type than a load.
> > >>>
> > >>> - Jay
> > >>>
> > >>>
> > >>>
> > >>> ----------------------------------------
> > >>>> Subject: Re: [M3devel] loophole/copysign
> > >>>> From: hosking at cs.purdue.edu
> > >>>> Date: Mon, 5 Jul 2010 14:24:01 -0400
> > >>>> CC: m3devel at elegosoft.com
> > >>>> To: jay.krell at cornell.edu
> > >>>>
> > >>>> We shouldn't need a barrier here. That is for memory operations, whereas these need not be. I would hate to make this change. Why can't we produce gcc trees that accomplish what we need?
> > >>>>
> > >>>> On 5 Jul 2010, at 05:24, Jay K wrote:
> > >>>>
> > >>>>>
> > >>>>> Our codegen is remarkably low level. That is, lower level earlier than C.
> > >>>>>
> > >>>>>
> > >>>>> gcc/m3cg -ftree-dump-all
> > >>>>>
> > >>>>>
> > >>>>> As early as LongFloat.mc.003t.original, the first file dumped, we have:
> > >>>>>
> > >>>>> LongFloat__CopySign (M3_CtKayy_x, M3_CtKayy_y)
> > >>>>> {
> > >>>>> xreel M3_CtKayy__result;
> > >>>>> xreel M3_CtKayy_res;
> > >>>>>
> > >>>>> xreel M3_CtKayy__result;
> > >>>>> xreel M3_CtKayy_res;
> > >>>>> M3_CtKayy_res = M3_CtKayy_x;
> > >>>>> BIT_FIELD_REF = (word_8) ((int_64)
> > >>>>> BIT_FIELD_REF & -129 | (word_64) BIT_FIELD_REF <(int_64) BIT_FIELD_REF , 1, 7> << 7 & 255);
> > >>>>> = M3_CtKayy_res;
> > >>>>> return ;
> > >>>>> }
> > >>>>>
> > >>>>> compared to C where as test_copysign.c.t69.copyrename3, the last file dumped, we have:
> > >>>>>
> > >>>>> copy_sign_f (from, to)
> > >>>>> {
> > >>>>> float res;
> > >>>>> float D.1918;
> > >>>>> D.1917;
> > >>>>> struct float_t * from.1;
> > >>>>> struct float_t * res.0;
> > >>>>>
> > >>>>> :
> > >>>>> res = to_1;
> > >>>>> res.0_4 = (struct float_t *) &res;
> > >>>>> from.1_5 = (struct float_t *) &from;
> > >>>>> D.1917_6 = from.1_5->sign;
> > >>>>> res.0_4->sign = D.1917_6;
> > >>>>> D.1918_7 = res;
> > >>>>> return D.1918_7;
> > >>>>>
> > >>>>> }
> > >>>>>
> > >>>>>
> > >>>>> See, you know, from gcc's point of view, we don't have any records/structs/unions.
> > >>>>> Just integers and offsets from them mostly.
> > >>>>>
> > >>>>>
> > >>>>> The right fix is to build up types.
> > >>>>> That way also debugging with gdb will have a chance.
> > >>>>> Perhaps not a small amount of work. But maybe not too bad.
> > >>>>>
> > >>>>>
> > >>>>> For now my inclination is in m3front to insert a barrier between the store and the load associated with loopholes.
> > >>>>> At least if one type but not the other is floating point.
> > >>>>> I don't know if that will work, but maybe.
> > >>>>>
> > >>>>> Or maybe have m3front actually call loophole for this case and again, either a barrier or make the load and/or
> > >>>>> store volatile.
> > >>>>>
> > >>>>> - Jay
> > >>>>>
> > >>>>
> > >>>
> > >>
> > >
> >
>
 		 	   		  


More information about the M3devel mailing list