[MLton] Shortening dependency chains in the x86 codegen
    Vesa Karvonen 
    vesa.karvonen at cs.helsinki.fi
       
    Sun Jan  7 08:57:30 PST 2007
    
    
  
Take a look at the following code for 32-bit endianness swapping generated
by MLton on x86:
                                 ;; cc W->R comment
        movl %edx,%esi           ;; 1       Copy (edx->esi)
        andl $0xFFFF,%esi        ;; 2  esi  Modify (esi)
        movl %esi,%edi           ;; 3  esi  Copy (esi->edi)
        xorl %edx,%edi           ;; 4  edi  Modify (edi)
        shll $0x10,%esi          ;; 4
        shrl $0x10,%edi          ;; 5  edi
        xorl %edi,%esi           ;; 6  edi
        movl %esi,%edi           ;; 7  esi  Copy (esi->edi)
        andl $0xFF00FF,%edi      ;; 8  edi  Modify (edi)
        xorl %edi,%esi           ;; 9  edi
        shll $0x8,%edi           ;; 9
        shrl $0x8,%esi           ;; 10 esi
        xorl %edi,%esi           ;; 11 esi
The pattern pointed out by the comments is
 First  movl regA,regB
 then   op   ????,regB
 and continue to use both regA and regB.
This is problematic, because there is a "dependency chain" on regB.  Copying
regA to regB must be executed before the operation on regB and the subsequent
operations reading regB are also delayed.
It would be better to transform the pattern to
 First  movl regA,regB
 then   op   ????,regA
 and continue to use both regA and regB, where the roles of regA and regB
 have been swapped.
IOW, the idea is to systematically, after a register-to-register copy,
swap the roles of the registers, so that the target of the copy isn't the
target (or source) of the subsequent op.
The previous code would be transformed to
                                 ;; cc W->R
        movl %edx,%esi           ;; 1
        andl $0xFFFF,%edx        ;; 1
        movl %edx,%edi           ;; 2  edx
        xorl %esi,%edx           ;; 2
        shll $0x10,%edi          ;; 3  edi
        shrl $0x10,%edx          ;; 3
        xorl %edx,%edi           ;; 4  edx
        movl %edi,%edx           ;; 5  edi
        andl $0xFF00FF,%edi      ;; 5
        xorl %edi,%edx           ;; 6  edi
        shll $0x8,%edi           ;; 6
        shrl $0x8,%edx           ;; 7  edx
        xorl %edi,%edx           ;; 8  edx
The dependency chains of the transformed code are now shorter than of the
original code, which means that it is easier for a CPU to execute the
intructions in parallel.  The numbers in the comments indicate the clock
cycle at which the instruction completes on an idealized processor where
consecutive instructions without W->R dependencies can be executed in
parallel and every instruction takes just one cycle.
Any estimate on how difficult something like this would be to implement?
-Vesa Karvonen
    
    
More information about the MLton
mailing list