[M3devel] unaligned procedures closure marker check broken?

Jay K jay.krell at cornell.edu
Thu Aug 2 09:28:40 CEST 2012


Given:


MODULE RTTest; IMPORT RT0;

PROCEDURE F1 (b: RT0.Binder) = BEGIN
EVAL b(0);
END F1;

BEGIN END RTTest.


This tends to fail on Aligned_procedures := FALSE architectures.
I see this testing SPARC64_SOLARIS with gcc 4.7 backend,
when the procedure isn't 8-aligned -- alignment fault.


IL is reasonable:

...
(89)         start_call_indirect type:addr
(90)           load_integer type:int_64 0
(91)           pop_param type:int_64
(92)           load var:0x5 offset:0 src_t:addr dst_t:addr m3name:noname 
(93)           loophole type1:addr type2:int_64
(94)           load_integer type:int_64 7
(95)           and type:int_64
(96)           if_true type:int_64 label:1 frequency:0X32(50)
(97)           load var:0x5 offset:0 src_t:addr dst_t:addr m3name:noname 
(98)           load_nil
...


but the assembly is inefficient and incorrect:


RTTest__F1:
.LLFB0:
    save    %sp, -208, %sp
.LLCFI0:
    stx    %i0, [%fp+2175]
    ldx    [%fp+2175], %g1
    stx    %g1, [%fp+2039]
    ldx    [%fp+2039], %g1
    and    %g1, 7, %g1 <= correct
    and    %g1, 1, %g1  <= incorrect
    and    %g1, 0xff, %g1  <=  pointless, inefficient
    cmp    %g1, 0


current parse.c:


M3CG_HANDLER (IF_TRUE)
{
  tree cond = m3_cast (boolean_type_node, EXPR_REF (-1));
  EXPR_POP ();

  add_stmt (build3 (COND_EXPR, t_void, cond,
                    build1 (GOTO_EXPR, t_void, label),
                    NULL_TREE));
}


static tree
m3_cast (tree type, tree op0)
{
  return m3_build1 (NOP_EXPR, type, op0);
}


Thoughts?


I'm thinking, something like:


PROCEDURE If_closure (proc: Val;  true, false: Label;  freq: Frequency) =
  VAR skip := Next_label ();  nope := skip;
  BEGIN
    IF (false # No_label) THEN  nope := false; END;
    IF NOT Target.Aligned_procedures THEN
      Push (proc);
      Force ();
      cg.loophole (Type.Addr, Target.Integer.cg_type);
      Push_int (TargetMap.CG_Align_bytes[Target.Integer.cg_type] - 1);
      cg.and (Target.Integer.cg_type);
      
      == insert comparisong to 0 here ==

      cg.if_true (Target.Integer.cg_type, nope, Always - freq);
      SPop (1, "If_closure-unaligned");
    END;
    

and possibly if_true should assert that top of stack is boolean already.


I'll check that this isn't something I broke in 4.7 -- maybe boolean changed.


I was thinking this had something to do with tagged types, but no -- there is nothing
related to them in the IL. I guess function pointers can't be tagged?


 - Jay 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20120802/e570e051/attachment-0001.html>


More information about the M3devel mailing list