From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7280 invoked by alias); 23 May 2011 11:27:02 -0000 Received: (qmail 7247 invoked by uid 22791); 23 May 2011 11:26:59 -0000 X-SWARE-Spam-Status: No, hits=-0.9 required=5.0 tests=AWL,BAYES_50,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,RFC_ABUSE_POST,TW_CF,TW_TM X-Spam-Check-By: sourceware.org Received: from mail-wy0-f175.google.com (HELO mail-wy0-f175.google.com) (74.125.82.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 23 May 2011 11:26:43 +0000 Received: by wye20 with SMTP id 20so4979865wye.20 for ; Mon, 23 May 2011 04:26:42 -0700 (PDT) MIME-Version: 1.0 Received: by 10.227.174.79 with SMTP id s15mr2147737wbz.76.1306150002323; Mon, 23 May 2011 04:26:42 -0700 (PDT) Received: by 10.227.38.129 with HTTP; Mon, 23 May 2011 04:26:42 -0700 (PDT) In-Reply-To: <1305813841.29239.3.camel@gnopaine> References: <1305813841.29239.3.camel@gnopaine> Date: Mon, 23 May 2011 14:05:00 -0000 Message-ID: Subject: Re: [PATCH] Add powi-to-multiply expansion to cse_sincos pass From: Richard Guenther To: "William J. Schmidt" Cc: gcc-patches@gcc.gnu.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-05/txt/msg01620.txt.bz2 On Thu, May 19, 2011 at 4:04 PM, William J. Schmidt wrote: > As Richard Guenther suggested, I'm submitting a separate patch to add > powi expansion to multiplies during the cse_sincos pass. =A0This was > originally submitted as part of a larger patch to fix PR46728. > > Richard noted that tree_expand_builtin_powi, powi_as_mults, and > powi_as_mults_1 more properly belong in tree-ssa-math-opts.c. =A0I've > moved those here. =A0These were originally in builtins.c because they > require some #defines, a static table of values, and a couple of static > functions in builtins.c. =A0Those items will also belong in > tree-ssa-math-opts.c once the similar RTL logic is removed. > > I chose to duplicate the required items into tree-ssa-math-opts.c for > now. =A0They will be removed from builtins.c in a future patch. =A0This > seemed more reasonable than exposing everything in a .h temporarily, and > then removing the .h code later. =A0But I can change to go that route if > you prefer. > > Bootstrap/regtest complete on powerpc target. > > Seeking approval for mainline -- thanks! > > Bill > > > 2011-05-19 =A0Bill Schmidt =A0 > > =A0 =A0 =A0 =A0* tree-ssa-math-opts.c (POWI_MAX_MULTS): Copied from built= ins.c; > =A0 =A0 =A0 =A0will be deleted from builtins.c in a later patch. No need to mention this. > =A0 =A0 =A0 =A0(POWI_TABLE_SIZE): Likewise. > =A0 =A0 =A0 =A0(POWI_WINDOW_SIZE): Likewise. > =A0 =A0 =A0 =A0(powi_table): Likewise. > =A0 =A0 =A0 =A0(powi_lookup_cost): Likewise. > =A0 =A0 =A0 =A0(powi_cost): Likewise. > =A0 =A0 =A0 =A0(powi_as_mults_1): New. > =A0 =A0 =A0 =A0(powi_as_mults): New. > =A0 =A0 =A0 =A0(tree_expand_builtin_powi): New. > =A0 =A0 =A0 =A0(execute_cse_sincos): Add switch case for BUILT_IN_POWI. > =A0 =A0 =A0 =A0(gate_cse_sincos): Remove sincos/cexp restriction. > > > Index: gcc/tree-ssa-math-opts.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- gcc/tree-ssa-math-opts.c =A0 =A0(revision 173908) > +++ gcc/tree-ssa-math-opts.c =A0 =A0(working copy) > @@ -795,8 +795,239 @@ execute_cse_sincos_1 (tree name) > =A0 return cfg_changed; > =A0} > > +/* To evaluate powi(x,n), the floating point value x raised to the > + =A0 constant integer exponent n, we use a hybrid algorithm that > + =A0 combines the "window method" with look-up tables. =A0For an > + =A0 introduction to exponentiation algorithms and "addition chains", > + =A0 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth, > + =A0 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programmin= g", > + =A0 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponent= iation > + =A0 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. =A0*/ > + > +/* Provide a default value for POWI_MAX_MULTS, the maximum number of > + =A0 multiplications to inline before calling the system library's pow > + =A0 function. =A0powi(x,n) requires at worst 2*bits(n)-2 multiplication= s, > + =A0 so this default never requires calling pow, powf or powl. =A0*/ > + > +#ifndef POWI_MAX_MULTS > +#define POWI_MAX_MULTS =A0(2*HOST_BITS_PER_WIDE_INT-2) > +#endif > + > +/* The size of the "optimal power tree" lookup table. =A0All > + =A0 exponents less than this value are simply looked up in the > + =A0 powi_table below. =A0This threshold is also used to size the > + =A0 cache of pseudo registers that hold intermediate results. =A0*/ > +#define POWI_TABLE_SIZE 256 > + > +/* The size, in bits of the window, used in the "window method" > + =A0 exponentiation algorithm. =A0This is equivalent to a radix of > + =A0 (1< +#define POWI_WINDOW_SIZE 3 > + > +/* The following table is an efficient representation of an > + =A0 "optimal power tree". =A0For each value, i, the corresponding > + =A0 value, j, in the table states than an optimal evaluation > + =A0 sequence for calculating pow(x,i) can be found by evaluating > + =A0 pow(x,j)*pow(x,i-j). =A0An optimal power tree for the first > + =A0 100 integers is given in Knuth's "Seminumerical algorithms". =A0*/ > + > +static const unsigned char powi_table[POWI_TABLE_SIZE] =3D > + =A0{ > + =A0 =A0 =A00, =A0 1, =A0 1, =A0 2, =A0 2, =A0 3, =A0 3, =A0 4, =A0/* = =A0 0 - =A0 7 */ > + =A0 =A0 =A04, =A0 6, =A0 5, =A0 6, =A0 6, =A010, =A0 7, =A0 9, =A0/* = =A0 8 - =A015 */ > + =A0 =A0 =A08, =A016, =A0 9, =A016, =A010, =A012, =A011, =A013, =A0/* = =A016 - =A023 */ > + =A0 =A0 12, =A017, =A013, =A018, =A014, =A024, =A015, =A026, =A0/* =A02= 4 - =A031 */ > + =A0 =A0 16, =A017, =A017, =A019, =A018, =A033, =A019, =A026, =A0/* =A03= 2 - =A039 */ > + =A0 =A0 20, =A025, =A021, =A040, =A022, =A027, =A023, =A044, =A0/* =A04= 0 - =A047 */ > + =A0 =A0 24, =A032, =A025, =A034, =A026, =A029, =A027, =A044, =A0/* =A04= 8 - =A055 */ > + =A0 =A0 28, =A031, =A029, =A034, =A030, =A060, =A031, =A036, =A0/* =A05= 6 - =A063 */ > + =A0 =A0 32, =A064, =A033, =A034, =A034, =A046, =A035, =A037, =A0/* =A06= 4 - =A071 */ > + =A0 =A0 36, =A065, =A037, =A050, =A038, =A048, =A039, =A069, =A0/* =A07= 2 - =A079 */ > + =A0 =A0 40, =A049, =A041, =A043, =A042, =A051, =A043, =A058, =A0/* =A08= 0 - =A087 */ > + =A0 =A0 44, =A064, =A045, =A047, =A046, =A059, =A047, =A076, =A0/* =A08= 8 - =A095 */ > + =A0 =A0 48, =A065, =A049, =A066, =A050, =A067, =A051, =A066, =A0/* =A09= 6 - 103 */ > + =A0 =A0 52, =A070, =A053, =A074, =A054, 104, =A055, =A074, =A0/* 104 - = 111 */ > + =A0 =A0 56, =A064, =A057, =A069, =A058, =A078, =A059, =A068, =A0/* 112 = - 119 */ > + =A0 =A0 60, =A061, =A061, =A080, =A062, =A075, =A063, =A068, =A0/* 120 = - 127 */ > + =A0 =A0 64, =A065, =A065, 128, =A066, 129, =A067, =A090, =A0/* 128 - 13= 5 */ > + =A0 =A0 68, =A073, =A069, 131, =A070, =A094, =A071, =A088, =A0/* 136 - = 143 */ > + =A0 =A0 72, 128, =A073, =A098, =A074, 132, =A075, 121, =A0/* 144 - 151 = */ > + =A0 =A0 76, 102, =A077, 124, =A078, 132, =A079, 106, =A0/* 152 - 159 */ > + =A0 =A0 80, =A097, =A081, 160, =A082, =A099, =A083, 134, =A0/* 160 - 16= 7 */ > + =A0 =A0 84, =A086, =A085, =A095, =A086, 160, =A087, 100, =A0/* 168 - 17= 5 */ > + =A0 =A0 88, 113, =A089, =A098, =A090, 107, =A091, 122, =A0/* 176 - 183 = */ > + =A0 =A0 92, 111, =A093, 102, =A094, 126, =A095, 150, =A0/* 184 - 191 */ > + =A0 =A0 96, 128, =A097, 130, =A098, 133, =A099, 195, =A0/* 192 - 199 */ > + =A0 =A0100, 128, 101, 123, 102, 164, 103, 138, =A0/* 200 - 207 */ > + =A0 =A0104, 145, 105, 146, 106, 109, 107, 149, =A0/* 208 - 215 */ > + =A0 =A0108, 200, 109, 146, 110, 170, 111, 157, =A0/* 216 - 223 */ > + =A0 =A0112, 128, 113, 130, 114, 182, 115, 132, =A0/* 224 - 231 */ > + =A0 =A0116, 200, 117, 132, 118, 158, 119, 206, =A0/* 232 - 239 */ > + =A0 =A0120, 240, 121, 162, 122, 147, 123, 152, =A0/* 240 - 247 */ > + =A0 =A0124, 166, 125, 214, 126, 138, 127, 153, =A0/* 248 - 255 */ > + =A0}; > + > + > +/* Return the number of multiplications required to calculate > + =A0 powi(x,n) where n is less than POWI_TABLE_SIZE. =A0This is a > + =A0 subroutine of powi_cost. =A0CACHE is an array indicating > + =A0 which exponents have already been calculated. =A0*/ > + > +static int > +powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache) > +{ > + =A0/* If we've already calculated this exponent, then this evaluation > + =A0 =A0 doesn't require any additional multiplications. =A0*/ > + =A0if (cache[n]) > + =A0 =A0return 0; > + > + =A0cache[n] =3D true; > + =A0return powi_lookup_cost (n - powi_table[n], cache) > + =A0 =A0 =A0 =A0+ powi_lookup_cost (powi_table[n], cache) + 1; > +} > + > +/* Return the number of multiplications required to calculate > + =A0 powi(x,n) for an arbitrary x, given the exponent N. =A0This > + =A0 function needs to be kept in sync with expand_powi below. =A0*/ Please double-check the function comments if they still refer to the correct functions. > +static int > +powi_cost (HOST_WIDE_INT n) > +{ > + =A0bool cache[POWI_TABLE_SIZE]; > + =A0unsigned HOST_WIDE_INT digit; > + =A0unsigned HOST_WIDE_INT val; > + =A0int result; > + > + =A0if (n =3D=3D 0) > + =A0 =A0return 0; > + > + =A0/* Ignore the reciprocal when calculating the cost. =A0*/ > + =A0val =3D (n < 0) ? -n : n; > + > + =A0/* Initialize the exponent cache. =A0*/ > + =A0memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool)); > + =A0cache[1] =3D true; > + > + =A0result =3D 0; > + > + =A0while (val >=3D POWI_TABLE_SIZE) > + =A0 =A0{ > + =A0 =A0 =A0if (val & 1) > + =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 digit =3D val & ((1 << POWI_WINDOW_SIZE) - 1); > + =A0 =A0 =A0 =A0 result +=3D powi_lookup_cost (digit, cache) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 + POWI_WINDOW_SIZE + 1; > + =A0 =A0 =A0 =A0 val >>=3D POWI_WINDOW_SIZE; > + =A0 =A0 =A0 } > + =A0 =A0 =A0else > + =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 val >>=3D 1; > + =A0 =A0 =A0 =A0 result++; > + =A0 =A0 =A0 } > + =A0 =A0} > + > + =A0return result + powi_lookup_cost (val, cache); > +} > + > +/* Recursive subroutine of powi_as_mults. =A0This function takes the > + =A0 array, CACHE, of already calculated exponents and an exponent N and > + =A0 returns a tree that corresponds to CACHE[1]**N, with type TYPE. =A0= */ > + > +static tree > +powi_as_mults_1 (gimple_stmt_iterator *gsi, location_t loc, tree type, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0HOST_WIDE_INT n, tree *cache) > +{ > + =A0tree op0, op1, target; > + =A0unsigned HOST_WIDE_INT digit; > + =A0gimple mult_stmt; > + > + =A0if (n < POWI_TABLE_SIZE) > + =A0 =A0{ > + =A0 =A0 =A0if (cache[n]) > + =A0 =A0 =A0 return cache[n]; > + > + =A0 =A0 =A0target =3D create_tmp_var (type, "powmult"); > + =A0 =A0 =A0add_referenced_var (target); Avoid creating multiple variables, just re-use a single temporary (just pass it along here as an additional argument). > + =A0 =A0 =A0target =3D make_ssa_name (target, NULL); > + =A0 =A0 =A0cache[n] =3D target; > + > + =A0 =A0 =A0op0 =3D powi_as_mults_1 (gsi, loc, type, n - powi_table[n], = cache); > + =A0 =A0 =A0op1 =3D powi_as_mults_1 (gsi, loc, type, powi_table[n], cach= e); > + =A0 =A0} > + =A0else if (n & 1) > + =A0 =A0{ > + =A0 =A0 =A0target =3D create_tmp_var (type, "powmult"); > + =A0 =A0 =A0add_referenced_var (target); Likewise. > + =A0 =A0 =A0target =3D make_ssa_name (target, NULL); > + =A0 =A0 =A0digit =3D n & ((1 << POWI_WINDOW_SIZE) - 1); > + =A0 =A0 =A0op0 =3D powi_as_mults_1 (gsi, loc, type, n - digit, cache); > + =A0 =A0 =A0op1 =3D powi_as_mults_1 (gsi, loc, type, digit, cache); > + =A0 =A0} > + =A0else > + =A0 =A0{ > + =A0 =A0 =A0target =3D create_tmp_var (type, "powmult"); > + =A0 =A0 =A0add_referenced_var (target); Likewise. > + =A0 =A0 =A0target =3D make_ssa_name (target, NULL); > + =A0 =A0 =A0op0 =3D powi_as_mults_1 (gsi, loc, type, n >> 1, cache); > + =A0 =A0 =A0op1 =3D op0; > + =A0 =A0} > + > + =A0mult_stmt =3D gimple_build_assign_with_ops (MULT_EXPR, target, op0, = op1); > + =A0SSA_NAME_DEF_STMT (target) =3D mult_stmt; I think setting SSA_NAME_DEF_STMT is already done by gimple_build_assign_with_ops. > + =A0gsi_insert_before (gsi, mult_stmt, GSI_SAME_STMT); > + > + =A0return target; > +} > + > +/* Convert ARG0**N to a tree of multiplications of ARG0 with itself. > + =A0 This function needs to be kept in sync with powi_cost in builtins.c= . =A0*/ > + > +static tree > +powi_as_mults (gimple_stmt_iterator *gsi, location_t loc, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0tree arg0, HOST_WIDE_INT n) > +{ > + =A0tree cache[POWI_TABLE_SIZE], result, type =3D TREE_TYPE (arg0); > + > + =A0if (n =3D=3D 0) > + =A0 =A0return omit_one_operand_loc (loc, type, build_real (type, dconst= 1), arg0); No need for omit_one_operand - simply return build_real (type, dconst1). > + =A0memset (cache, 0, =A0sizeof (cache)); > + =A0cache[1] =3D arg0; Allocate the temporary var here > + =A0result =3D powi_as_mults_1 (gsi, loc, type, (n < 0) ? -n : n, cache); > + > + =A0/* If the original exponent was negative, reciprocate the result. = =A0*/ > + =A0if (n < 0) > + =A0 =A0result =3D build2_loc (loc, RDIV_EXPR, type, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0build_real (type, dconst= 1), result); Please build a final division statement and assign it to a new SSA name which you return. > + =A0return result; > +} > + > +/* ARGS are the two arguments to a powi builtin in GSI with location info > + =A0 LOC. =A0If the arguments are appropriate, create an equivalent set = of > + =A0 statements prior to GSI using an optimal number of multiplications, > + =A0 and return an expession holding the result. =A0*/ > + > +static tree > +tree_expand_builtin_powi (gimple_stmt_iterator *gsi, location_t loc, tre= e *args) A better name would be gimple_expand_builtin_powi now. > +{ > + =A0HOST_WIDE_INT n =3D TREE_INT_CST_LOW (args[1]); > + =A0HOST_WIDE_INT n_hi =3D TREE_INT_CST_HIGH (args[1]); > + > + =A0if ((n_hi =3D=3D 0 || n_hi =3D=3D -1) > + =A0 =A0 =A0/* Avoid largest negative number. =A0*/ > + =A0 =A0 =A0&& (n !=3D -n) > + =A0 =A0 =A0&& ((n >=3D -1 && n <=3D 2) > + =A0 =A0 =A0 =A0 || (optimize_function_for_speed_p (cfun) > + =A0 =A0 =A0 =A0 =A0 =A0 && powi_cost (n) <=3D POWI_MAX_MULTS))) > + =A0 =A0return powi_as_mults (gsi, loc, args[0], n); > + > + =A0return NULL_TREE; > +} > + > =A0/* Go through all calls to sin, cos and cexpi and call execute_cse_sin= cos_1 > - =A0 on the SSA_NAME argument of each of them. =A0*/ > + =A0 on the SSA_NAME argument of each of them. =A0Also expand powi(x,n) = into > + =A0 an optimal number of multiplies, when n is a constant. =A0*/ > > =A0static unsigned int > =A0execute_cse_sincos (void) > @@ -821,7 +1052,7 @@ execute_cse_sincos (void) > =A0 =A0 =A0 =A0 =A0 =A0 =A0&& (fndecl =3D gimple_call_fndecl (stmt)) > =A0 =A0 =A0 =A0 =A0 =A0 =A0&& DECL_BUILT_IN_CLASS (fndecl) =3D=3D BUILT_I= N_NORMAL) > =A0 =A0 =A0 =A0 =A0 =A0{ > - =A0 =A0 =A0 =A0 =A0 =A0 tree arg; > + =A0 =A0 =A0 =A0 =A0 =A0 tree arg, *args; > > =A0 =A0 =A0 =A0 =A0 =A0 =A0switch (DECL_FUNCTION_CODE (fndecl)) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > @@ -833,6 +1064,23 @@ execute_cse_sincos (void) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0cfg_changed |=3D execute_cse_sinco= s_1 (arg); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 CASE_FLT_FN (BUILT_IN_POWI): > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 args =3D gimple_call_arg_ptr (stmt, 0); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (host_integerp (args[1], 0) && !TREE= _OVERFLOW (args[1])) Please access arguments via gimple_call_arg (stmt, N), simply assign both to tempoaries and pass them down separately to tree_expand_builtin_pow, the exponent as HOST_WIDE_INT instead of as tree. We also do not care for TREE_OVERFLOW (I realize this is pre-existing code). > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 tree result =3D NULL_TREE; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 location_t loc =3D gimple_locat= ion (stmt); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 result =3D tree_expand_builtin_= powi (&gsi, loc, args); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (result) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 tree lhs =3D gimple_get= _lhs (stmt); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 gimple new_stmt =3D gim= ple_build_assign (lhs, result); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 gimple_set_location (ne= w_stmt, loc); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 gsi_replace (&gsi, new_= stmt, true); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 break; > + > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0default:; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} > =A0 =A0 =A0 =A0 =A0 =A0} > @@ -849,10 +1097,9 @@ execute_cse_sincos (void) > =A0static bool > =A0gate_cse_sincos (void) > =A0{ > - =A0/* Make sure we have either sincos or cexp. =A0*/ > - =A0return (TARGET_HAS_SINCOS > - =A0 =A0 =A0 =A0 || TARGET_C99_FUNCTIONS) > - =A0 =A0 =A0 =A0&& optimize; > + =A0/* We no longer require either sincos or cexp, since powi expansion > + =A0 =A0 piggybacks on this pass. =A0*/ > + =A0return optimize; > =A0} Otherwise this patch looks good to me. Please re-post it with the suggested adjustments. The next patch to attack would be to make sure integer valued exponent pows are folded to powi for -funsafe-math-optimizations. Thanks, Richard. > =A0struct gimple_opt_pass pass_cse_sincos =3D > > >