[M3devel] unaligned procedures closure marker check broken?
Jay K
jay.krell at cornell.edu
Thu Aug 2 09:38:52 CEST 2012
okok..4.5 generates:
ldx [%fp+2039], %g1
and %g1, 7, %g1
and %g1, 0xff, %g1
cmp %g1, 0
which is good.
The and 0xff is still pointless.
This is without optimizing.
optimized it is:
andcc %i0, 7, %g0
bne,pn %xcc, .LL2
- Jay
From: jay.krell at cornell.edu
To: m3devel at elegosoft.com
Date: Thu, 2 Aug 2012 07:28:40 +0000
Subject: [M3devel] unaligned procedures closure marker check broken?
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/bf07ca1c/attachment-0002.html>
More information about the M3devel
mailing list