Skip to content
  • Kenneth Graunke's avatar
    i965: Add src/dst interference for certain instructions with hazards. · 83dedb63
    Kenneth Graunke authored
    
    
    When working on tessellation shaders, I created some vec4 virtual
    opcodes for creating message headers through a sequence like:
    
       mov(8) g7<1>UD      0x00000000UD    { align1 WE_all 1Q compacted };
       mov(1) g7.5<1>UD    0x00000100UD    { align1 WE_all };
       mov(1) g7<1>UD      g0<0,1,0>UD     { align1 WE_all compacted };
       mov(1) g7.3<1>UD    g8<0,1,0>UD     { align1 WE_all };
    
    This is done in the generator since the vec4 backend can't handle align1
    regioning.  From the visitor's point of view, this is a single opcode:
    
       hs_set_output_urb_offsets vgrf7.0:UD, 1U, vgrf8.xxxx:UD
    
    Normally, there's no hazard between sources and destinations - an
    instruction (naturally) reads its sources, then writes the result to the
    destination.  However, when the virtual instruction generates multiple
    hardware instructions, we can get into trouble.
    
    In the above example, if the register allocator assigned vgrf7 and vgrf8
    to the same hardware register, then we'd clobber the source with 0 in
    the first instruction, and read back the wrong value in the last one.
    
    It occured to me that this is exactly the same problem we have with
    SIMD16 instructions that use W/UW or B/UB types with 0 stride.  The
    hardware implicitly decodes them as two SIMD8 instructions, and with
    the overlapping regions, the first would clobber the second.
    
    Previously, we handled that by incrementing the live range end IP by 1,
    which works, but is excessive: the next instruction doesn't actually
    care about that.  It might also be the end of control flow.  This might
    keep values alive too long.  What we really want is to say "my source
    and destinations interfere".
    
    This patch creates new infrastructure for doing just that, and teaches
    the register allocator to add interference when there's a hazard.  For
    my vec4 case, we can determine this by switching on opcodes.  For the
    SIMD16 case, we just move the existing code there.
    
    I audited our existing virtual opcodes that generate multiple
    instructions; I believe FS_OPCODE_PACK_HALF_2x16_SPLIT needs this
    treatment as well, but no others.
    
    v2: Rebased by mattst88.
    
    Signed-off-by: Kenneth Graunke's avatarKenneth Graunke <kenneth@whitecape.org>
    Reviewed-by: default avatarMatt Turner <mattst88@gmail.com>
    83dedb63