This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

CFG and libcall conflict for java


The ia64-java compiler is not working because of a conflict between the
relatively new CFG code, and the LIBCALL/RETVAL support that we have had
for a while.  We get a segfault in flow for some testcases.

The problem arises because java uses -fnon-call-exceptions.  IA-64 does
not have a divide instruction, so divides are implemented as libcall
sequences.  A divide traps, so these libcall sequences can throw.  A call
that can throw ends a basic block.  We thus get libcall sequences that span
a basic block boundary in the CFG.

The CFG based optimizations are not aware of the libcall sequences, so
eventually we get basic blocks reordered such that the libcall sequence
is no longer contiguous.  The first half is in one basic block, and the
last half is in a different block reachable only via a branch.  Then
when we try to handle REG_LIBCALL/REG_RETVAL notes, the compiler segfaults,
because it can't find the the instruction with the REG_RETVAL note
corresponding to the REG_LIBCALL note.

I only have a java testcase for this at the moment.  Compile at -O2
with an ia64-java compiler and you get a segfault in flow.

public class divtest {
    private long min_transaction_count = Long.MAX_VALUE;
    private long max_transaction_count = Long.MIN_VALUE;
    public void set(long z) { min_transaction_count = z; }
    public synchronized void displayThreadResults()
    {

        // long diff = max_transaction_count - min_transaction_count; 
	float diff_pct = (float)max_transaction_count / (float)min_transaction_count;

    }
}

Removing the REG_LIBCALL/REG_RETVAL notes for trapping libcalls when
-fnon-call-exceptions makes the problem go away, but then we can no longer
optimize away dead divide libcall sequences.  So we have a performance
regression if we do this.

If we had a high level IL, then the problem would go away.  In the high
level IL we would just have a divide operation, and it would be trivial
to optimize away unused divides.  Then when we lower the IL we emit the
libcall sequence, and we don't need the REG_LIBCALL/REG_RETVAL notes anymore.
The REG_LIBCALL/REG_RETVAL notes are only needed for optimizing operations
implemented via libcalls, and if we have already optimized them at the high
level we don't need to worry about optimizing them at the low level.  This
however is more work than I can do for a simple bug report.  Perhaps
the ast-optimizer-branch will help?

I am not very familiar with the new CFG support.  However, my suspicion
that the only good way to solve the problem (without a higher IL) is
to make the CFG code aware that edges inside libcalls are special.
Perhaps a new EDGE_ABNORMAL_LIBCALL flag bit for CFG edges.  Then
every optimization pass that makes use of the CFG needs to be modified
to be aware of these EDGE_ABNORMAL_LIBCALL edges, and handle them
specially.  I do not know if this is feasible, or how much work it would
be if it was feasible.  Additionally, code that knows how to optimize
away libcall sequences may need to be aware of the CFG, since deleting a
libcall may modify the CFG.  I think this part would not be too hard.

Comments anyone?  The ia64 java compiler is broken, so we do need some kind
of fix.  At the moment, the only working fix I have is one that disables
REG_LIBCALL/REG_RETVAL notes when they cause trouble, and this is undesirable
because it causes a performance regression.  But if we can't easily fix the
CFG code, then I may have to go with this patch to get the java compiler
working again.

Jim


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]