>Пятница, 7 июня 2019, 9:50 +05:00 от Jeff Law <law@xxxxxxxxxx>: > >On 6/6/19 10:42 PM, Alex Hill via gcc-help wrote: >> >> I need to reduce amount of branches in code. There is exist benchmark called median it have some code like: >> if ( A < B ) >> return A = foo[i]; >> else >> return B = foo[i]; >> I wrote a pattern in machine description file *.md to avoid branches: >> (define_insn "smin<GPR:mode>3" >> [ >> (set >> (match_operand:GPR 0 "register_operand" "=r") >> (if_then_else:GPR >> (lt:GPR >> (match_operand:GPR 1 "register_operand" " r") >> (match_operand:GPR 2 "register_operand" " r")) >> (match_dup 1) >> (match_dup 2))) >> ] >> "" >> "min\t%0,%1,%2" >> [(set_attr "type" "move") >> (set_attr "mode" "<MODE>")]) >> It works in case of simple comparison: >> if ( A < B ) >> return A ; >> else >> return B; >> GCC emit: >> min a0,a0,a1 # 9 smindi3 [length = 4] >> ret # 21 simple_return [length = 4] >> But if i try same, but with indexed variable( array ): it won`t works: >> if ( A < B ) >> return A = foo[i]; >> else >> return B = foo[i]; >> GCC emit: >> blt a0,a1,.L5 # 11 *branch_orderdi [length = 4] >> sd a1,8(a2) # 18 *movdi_64bit/4 [length = 4] >> mv a0,a1 # 8 *movdi_64bit/1 [length = 4] >> ret # 34 simple_return [length = 4] >> .L5: >> sd a0,8(a2) # 13 *movdi_64bit/4 [length = 4] >> ret # 28 simple_return [length = 4] >> I need to GCC emit something like this: >> min a0,a0,a1 # 9 smindi3 [length = 4] >> sd a0,8(a2) # 18 *movdi_64bit/4 [length = 4] >> ret # 34 simple_return [length = 4] >> I appreciate any help, and i desperate to find a desicion, i tried to look into GIMPLE to change conditions of MIN_EXPR, but there is no(almost) any documentation, and sources are VERY puzzling(( >Rather than using a match_dup which requires the exact same register >throughout the RTL pipeline, you might consider using a matching constraint. > > (define_insn "smin<GPR:mode>3" > [ > (set > (match_operand:GPR 0 "register_operand" "=r") > (if_then_else:GPR > (lt:GPR > (match_operand:GPR 1 "register_operand" " r") > (match_operand:GPR 2 "register_operand" " r")) > (match_operand:GPR 3 "register_operand" "1") > (match_operand:GPR 4 "register_operand" "2"))) > >I would also strongly recommnend reviewing the various dump files to see >if you're getting min/max as you leave gimple and if they're carried >through the RTL pipeline. > >jeff It won`t help of course, in GIMPLE direct comparisen gets MIN_EXPR() but indexed storing gets long int _1; <bb 2> [100.00%]: if (A_3(D) < B_4(D)) goto <bb 3>; [46.00%] else goto <bb 4>; [54.00%] <bb 3> [46.00%]: MEM[(long int *)kekeke_5(D) + 8B] = A_3(D); goto <bb 5>; [100.00%] <bb 4> [54.00%]: MEM[(long int *)kekeke_5(D) + 8B] = B_4(D); <bb 5> [100.00%]: # _1 = PHI <A_3(D)(3), B_4(D)(4)> return _1; Kind regards Alex Hill.