This is the mail archive of the 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]

Re: CFG and libcall conflict for java

On Monday, September 24, 2001, at 08:18  PM, Jim Wilson wrote:

> 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.
This is not legal, if i remember what rth told me.
I ran into a problem with the new register allocator, store motion, and 
Because of some of the store motion, the scheduler would decide to 
speculatively move libcall argument sets out of the block in which the 
libcall existed.  This caused propagate_one_insn to fail miserably, 
because it assumes that this doesn't happen.
I produced a patch to make it handle this,but rth said the scheduler was 
at fault because libcall sequences are required to be entirely in one 
basic block, and it shouldn't have speculatively moved the argument set 
into a different basic blocks.
Of course, this isn't documented.
So unless i'm misremembering, you can't do what you want with libcalls.
Not that you shouldn't be able to.
In fact, what i'd rather see is a new RTX for calls with arguments, so 
there would be no problem moving them around in optimization passes.  
You could mark them as "libcalls" with a flag on the RTL.
We can't do this with parallels, at least, if the RTL docs aren't lying 
(since we can't expect the results of a given set to be available for 
the next one in the parallel).
Otherwise, you end up fixing up all the optimization passes that can 
move libcall sequences across blocks, to handle a special case where a 
reg note attached to a set happens to really mean we can't move it 
across blocks.

> 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]