[llvm-commits] [llvm] r105387 - in /llvm/trunk: lib/CodeGen/MachineSink.cpp test/CodeGen/X86/MachineSink-CritEdge.ll test/CodeGen/X86/sink-hoist.ll

Bill Wendling isanbard at gmail.com
Thu Jun 3 16:44:44 PDT 2010


On Jun 3, 2010, at 10:46 AM, Jakob Stoklund Olesen wrote:

> On Jun 3, 2010, at 12:54 AM, Bill Wendling wrote:
> 
>> Author: void
>> Date: Thu Jun  3 02:54:20 2010
>> New Revision: 105387
>> 
>> URL: http://llvm.org/viewvc/llvm-project?rev=105387&view=rev
>> Log:
>> Machine sink could potentially sink instructions into a block where the physical
>> registers it defines then interfere with an existing preg live range.
>> 
>> For instance, if we had something like these machine instructions:
>> 
>> BB#0
>> ... = imul ... EFLAGS<imp-def,dead>
>> test ..., EFLAGS<imp-def>
>> jcc BB#2 EFLAGS<imp-use>
>> 
>> BB#1
>> ... ; fallthrough to BB#2
>> 
>> BB#2
>> ... ; No code that defines EFLAGS
>> jcc ... EFLAGS<imp-use>
>> 
>> Machine sink will come along, see that imul implicitly defines EFLAGS, but
>> because it's "dead", it assumes that it can move imul into BB#2. But when it
>> does, imul's "dead" imp-def of EFLAGS is raised from the dead (a zombie) and
>> messes up the condition code for the jump (and pretty much anything else which
>> relies upon it being correct).
>> 
>> The solution is to know which pregs are live going into a basic block. However,
>> that information isn't calculated at this point. Nor does the LiveVariables pass
>> take into account non-allocatable physical registers. In lieu of this, we do a
>> *very* conservative pass through the basic block to determine if a preg is live
>> coming out of it.
> 
> Bill,
> 
> There is something hinky about this example. I thought that our livein lists were always up to date.

Unfortunately, they aren't.

> They are usually empty because there shouldn't be live physical registers across blocks this early.
> 
> Coalescing and register allocation update the livein lists. If there are other passes using physical registers across blocks, they should update the livein lists as well.
> 
This is happening before register allocation and coalescing. This is coming from a "select" statement, which gets lowered down into a diamond if-then pattern on X86. It's there that we get the live across blocks stuff.

> Maybe there is some confusion about the difference between unallocatable and reserved registers. IIRC, EFLAGS is unallocatable, but not reserved.
> 
> Do you know which pass creates the cross-block use of EFLAGS to begin with?
> 
It's that way after instruction selection. Probably from here: X86TargetLowering::EmitLoweredSelect

-bw





More information about the llvm-commits mailing list