Hi Alfie,

before I get to the rest of the series, a question about the codegen 
strategy.  It would probably have been a better fit for the v1 
discussion but... :)

> +/* Inserts fixup block for HSSR controls.
> +
> +   This inserts the following logic:
> +
> +   <bb 0>:
> +     v1 = .MASK_FF_HSSR_LOAD (src1, 64B, loop_mask, { 0, ... });
> +     v2 = .MASK_FF_HSSR_LOAD (src2, 64B, loop_mask, { 0, ... });
> +     hssr_mask = .READ_FAULT_STATE ();
> +     if (hssr_mask == { -1, ... })
> +       goto <bb 2>; [99.95%]
> +     else
> +       goto <bb 1>; [0.05%]
> +
> +   <bb 1>:
> +     .SET_FAULT_STATE ({ -1, ... });
> +     hssr_loop_mask = loop_mask & hssr_mask;
> +      num_iters = .COUNT_ACTIVE (hssr_mask);
> +
> +   <bb 2>:
> +     # loop_mask_1 = PHI <loop_mask(0), hssr_loop_mask(1)>
> +     # num_iters_56 = PHI <POLY_INT_CST [4, 4](0), num_iters (1)>
> +
> +     ... Logic using loop_mask_1 and incrementing IV's by num_iters_56
> +    */

So from what I figure, the decision for the fixup approach is based on 
the assumption that READ_FAULT_STATE can be slow and dependencies on it 
would limit throughput?
I'm asking because for riscv, the only relevant dependency would be on 
the pointer bump and READ_FAULT_STATE isn't necessarily slow.
Therefore, for RVV, I'd favor a third approach (beside full duplication 
and fixup) that would roughly look just like

       v1 = .MASK_FF_HSSR_LOAD (src1, 64B, loop_mask, { 0, ... });
       v2 = .MASK_FF_HSSR_LOAD (src2, 64B, loop_mask, { 0, ... });
       hssr_mask = .READ_FAULT_STATE ();
       .SET_FAULT_STATE ({ -1, ... });
       hssr_loop_mask = loop_mask & hssr_mask;
       num_iters = .COUNT_ACTIVE (hssr_mask);

(only with length instead of mask of course)

Is that something that would work for aarch64 cores as well?  Or is that 
rather an optimization that you deliberately skipped for now?

-- 
Regards
 Robin

Reply via email to