tcg_gen_extract.cocci (3010B)
1 // optimize TCG using extract op 2 // 3 // Copyright: (C) 2017 Philippe Mathieu-Daudé. GPLv2+. 4 // Confidence: High 5 // Options: --macro-file scripts/cocci-macro-file.h 6 // 7 // Nikunj A Dadhania optimization: 8 // http://lists.nongnu.org/archive/html/qemu-devel/2017-02/msg05211.html 9 // Aurelien Jarno optimization: 10 // http://lists.nongnu.org/archive/html/qemu-devel/2017-05/msg01466.html 11 // 12 // This script can be run either using spatch locally or via a docker image: 13 // 14 // $ spatch \ 15 // --macro-file scripts/cocci-macro-file.h \ 16 // --sp-file scripts/coccinelle/tcg_gen_extract.cocci \ 17 // --keep-comments --in-place \ 18 // --use-gitgrep --dir target 19 // 20 // $ docker run --rm -v $PWD:$PWD -w $PWD philmd/coccinelle \ 21 // --macro-file scripts/cocci-macro-file.h \ 22 // --sp-file scripts/coccinelle/tcg_gen_extract.cocci \ 23 // --keep-comments --in-place \ 24 // --use-gitgrep --dir target 25 26 @initialize:python@ 27 @@ 28 import sys 29 fd = sys.stderr 30 def debug(msg="", trailer="\n"): 31 fd.write("[DBG] " + msg + trailer) 32 def low_bits_count(value): 33 bits_count = 0 34 while (value & (1 << bits_count)): 35 bits_count += 1 36 return bits_count 37 def Mn(order): # Mersenne number 38 return (1 << order) - 1 39 40 @match@ 41 identifier ret; 42 metavariable arg; 43 constant ofs, msk; 44 position shr_p, and_p; 45 @@ 46 ( 47 tcg_gen_shri_i32@shr_p 48 | 49 tcg_gen_shri_i64@shr_p 50 | 51 tcg_gen_shri_tl@shr_p 52 )(ret, arg, ofs); 53 ... WHEN != ret 54 ( 55 tcg_gen_andi_i32@and_p 56 | 57 tcg_gen_andi_i64@and_p 58 | 59 tcg_gen_andi_tl@and_p 60 )(ret, ret, msk); 61 62 @script:python verify_len depends on match@ 63 ret_s << match.ret; 64 msk_s << match.msk; 65 shr_p << match.shr_p; 66 extract_len; 67 @@ 68 is_optimizable = False 69 debug("candidate at %s:%s" % (shr_p[0].file, shr_p[0].line)) 70 try: # only eval integer, no #define like 'SR_M' (cpp did this, else some headers are missing). 71 msk_v = long(msk_s.strip("UL"), 0) 72 msk_b = low_bits_count(msk_v) 73 if msk_b == 0: 74 debug(" value: 0x%x low_bits: %d" % (msk_v, msk_b)) 75 else: 76 debug(" value: 0x%x low_bits: %d [Mersenne number: 0x%x]" % (msk_v, msk_b, Mn(msk_b))) 77 is_optimizable = Mn(msk_b) == msk_v # check low_bits 78 coccinelle.extract_len = "%d" % msk_b 79 debug(" candidate %s optimizable" % ("IS" if is_optimizable else "is NOT")) 80 except: 81 debug(" ERROR (check included headers?)") 82 cocci.include_match(is_optimizable) 83 debug() 84 85 @replacement depends on verify_len@ 86 identifier match.ret; 87 metavariable match.arg; 88 constant match.ofs, match.msk; 89 position match.shr_p, match.and_p; 90 identifier verify_len.extract_len; 91 @@ 92 ( 93 -tcg_gen_shri_i32@shr_p(ret, arg, ofs); 94 +tcg_gen_extract_i32(ret, arg, ofs, extract_len); 95 ... WHEN != ret 96 -tcg_gen_andi_i32@and_p(ret, ret, msk); 97 | 98 -tcg_gen_shri_i64@shr_p(ret, arg, ofs); 99 +tcg_gen_extract_i64(ret, arg, ofs, extract_len); 100 ... WHEN != ret 101 -tcg_gen_andi_i64@and_p(ret, ret, msk); 102 | 103 -tcg_gen_shri_tl@shr_p(ret, arg, ofs); 104 +tcg_gen_extract_tl(ret, arg, ofs, extract_len); 105 ... WHEN != ret 106 -tcg_gen_andi_tl@and_p(ret, ret, msk); 107 )