|
From: Julian S. <js...@ac...> - 2012-10-12 00:40:33
|
We need to be able to represent conditional loads and stores in IR. The initial motivating case is AVX's VMASKMOVP[SD], which is not implemented due to lack of them, and apparently AVX2 has others that will need them. They would also be very useful for ARM, where conditional loads and stores produce IR which is both slow and confuses Memcheck into false positives, from time to time. Being able to express them directly in IR would give much shorter and more straightforward translations. Also s390 might benefit from them, I think. This seems quite simple to me. Currently we have stores as IRStmts and loads as IRExprs. For conditional stores, we could either add a guard expression field to IRStmt_Store. Or, add a new variant, IRStmt_StoreC, identical to IRStmt_Store but with an added guard field. This would have the advantage of not having to have the vast majority of (normal) stores carry an "always-true" guard field. For conditional loads, basically what we need is a normal load with two extra fields: a guard field, and a "backup" value which is the returned value if the guard is false. At first I thought of having conditional loads as just another IRExpr member. But that gives potential complexity with register allocation if we allow arbitrary expressions for the "backup" value, since if the guard is false then we won't want any of the expression to be evaluated. But that requires doing proper control flow within superblocks in the back ends, which they, and particularly the register allocator, are not set up to do. So an alternative, more conservative proposal, is to have conditional loads be a statement kind: result_temp = Conditional_Load( guard_expr, address_expr, backup_temp ) and the trick is that the backup value is an IRTemp, not an IRExpr, which unambiguously forces us to evaluate it regardless of what 'guard_expr' evaluates to. Hence it sidesteps the regalloc problems, because a Conditional_Load can be compiled into <compute address_expr into rAddr> <move backup_temp to rDest> <compute guard_expr_into condition codes> CLOAD rDest, (rAddr) where CMOV is either a conditional load instruction (on arm) or a pseudo-insn comprising a conditional jump over an unconditional load (on all other targets). But in either case posing no problem for register allocation. Hence in summary, the proposal is to add two new IRStmt kinds: StoreC ( guard_expr, address_expr, data_expr ) result_temp = LoadC ( guard_expr, address_expr, backup_temp ) I think this should get us almost all the benefits of conditional loads/stores with only minor modification of the IR optimiser, instruction selectors, and the register allocator. J |