annotate src/fftw-3.3.8/genfft/c.ml @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents d0c2a83c1364
children
rev   line source
Chris@82 1 (*
Chris@82 2 * Copyright (c) 1997-1999 Massachusetts Institute of Technology
Chris@82 3 * Copyright (c) 2003, 2007-14 Matteo Frigo
Chris@82 4 * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
Chris@82 5 *
Chris@82 6 * This program is free software; you can redistribute it and/or modify
Chris@82 7 * it under the terms of the GNU General Public License as published by
Chris@82 8 * the Free Software Foundation; either version 2 of the License, or
Chris@82 9 * (at your option) any later version.
Chris@82 10 *
Chris@82 11 * This program is distributed in the hope that it will be useful,
Chris@82 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@82 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@82 14 * GNU General Public License for more details.
Chris@82 15 *
Chris@82 16 * You should have received a copy of the GNU General Public License
Chris@82 17 * along with this program; if not, write to the Free Software
Chris@82 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Chris@82 19 *
Chris@82 20 *)
Chris@82 21
Chris@82 22 (*
Chris@82 23 * This module contains the definition of a C-like abstract
Chris@82 24 * syntax tree, and functions to convert ML values into C
Chris@82 25 * programs
Chris@82 26 *)
Chris@82 27
Chris@82 28 open Expr
Chris@82 29 open Annotate
Chris@82 30 open List
Chris@82 31
Chris@82 32 let realtype = "R"
Chris@82 33 let realtypep = realtype ^ " *"
Chris@82 34 let extended_realtype = "E"
Chris@82 35 let constrealtype = "const " ^ realtype
Chris@82 36 let constrealtypep = constrealtype ^ " *"
Chris@82 37
Chris@82 38 let stridetype = "stride"
Chris@82 39
Chris@82 40 (***********************************
Chris@82 41 * C program structure
Chris@82 42 ***********************************)
Chris@82 43 type c_decl =
Chris@82 44 | Decl of string * string
Chris@82 45 | Tdecl of string (* arbitrary text declaration *)
Chris@82 46
Chris@82 47 and c_ast =
Chris@82 48 | Asch of annotated_schedule
Chris@82 49 | Simd_leavefun
Chris@82 50 | Return of c_ast
Chris@82 51 | For of c_ast * c_ast * c_ast * c_ast
Chris@82 52 | If of c_ast * c_ast
Chris@82 53 | Block of (c_decl list) * (c_ast list)
Chris@82 54 | Binop of string * c_ast * c_ast
Chris@82 55 | Expr_assign of c_ast * c_ast
Chris@82 56 | Stmt_assign of c_ast * c_ast
Chris@82 57 | Comma of c_ast * c_ast
Chris@82 58 | Integer of int
Chris@82 59 | CVar of string
Chris@82 60 | CCall of string * c_ast
Chris@82 61 | CPlus of c_ast list
Chris@82 62 | ITimes of c_ast * c_ast
Chris@82 63 | CUminus of c_ast
Chris@82 64 and c_fcn = Fcn of string * string * (c_decl list) * c_ast
Chris@82 65
Chris@82 66
Chris@82 67 let ctimes = function
Chris@82 68 | (Integer 1), a -> a
Chris@82 69 | a, (Integer 1) -> a
Chris@82 70 | a, b -> ITimes (a, b)
Chris@82 71
Chris@82 72 (*
Chris@82 73 * C AST unparser
Chris@82 74 *)
Chris@82 75 let foldr_string_concat l = fold_right (^) l ""
Chris@82 76
Chris@82 77 let rec unparse_expr_c =
Chris@82 78 let yes x = x and no x = "" in
Chris@82 79
Chris@82 80 let rec unparse_plus maybe =
Chris@82 81 let maybep = maybe " + " in
Chris@82 82 function
Chris@82 83 | [] -> ""
Chris@82 84 | (Uminus (Times (a, b))) :: (Uminus c) :: d ->
Chris@82 85 maybep ^ (op "FNMA" a b c) ^ (unparse_plus yes d)
Chris@82 86 | (Uminus c) :: (Uminus (Times (a, b))) :: d ->
Chris@82 87 maybep ^ (op "FNMA" a b c) ^ (unparse_plus yes d)
Chris@82 88 | (Uminus (Times (a, b))) :: c :: d ->
Chris@82 89 maybep ^ (op "FNMS" a b c) ^ (unparse_plus yes d)
Chris@82 90 | c :: (Uminus (Times (a, b))) :: d ->
Chris@82 91 maybep ^ (op "FNMS" a b c) ^ (unparse_plus yes d)
Chris@82 92 | (Times (a, b)) :: (Uminus c) :: d ->
Chris@82 93 maybep ^ (op "FMS" a b c) ^ (unparse_plus yes d)
Chris@82 94 | (Uminus c) :: (Times (a, b)) :: d ->
Chris@82 95 maybep ^ (op "FMS" a b c) ^ (unparse_plus yes d)
Chris@82 96 | (Times (a, b)) :: c :: d ->
Chris@82 97 maybep ^ (op "FMA" a b c) ^ (unparse_plus yes d)
Chris@82 98 | c :: (Times (a, b)) :: d ->
Chris@82 99 maybep ^ (op "FMA" a b c) ^ (unparse_plus yes d)
Chris@82 100 | (Uminus a :: b) ->
Chris@82 101 " - " ^ (parenthesize a) ^ (unparse_plus yes b)
Chris@82 102 | (a :: b) ->
Chris@82 103 maybep ^ (parenthesize a) ^ (unparse_plus yes b)
Chris@82 104 and parenthesize x = match x with
Chris@82 105 | (Load _) -> unparse_expr_c x
Chris@82 106 | (Num _) -> unparse_expr_c x
Chris@82 107 | _ -> "(" ^ (unparse_expr_c x) ^ ")"
Chris@82 108 and op nam a b c =
Chris@82 109 nam ^ "(" ^ (unparse_expr_c a) ^ ", " ^ (unparse_expr_c b) ^ ", " ^
Chris@82 110 (unparse_expr_c c) ^ ")"
Chris@82 111
Chris@82 112 in function
Chris@82 113 | Load v -> Variable.unparse v
Chris@82 114 | Num n -> Number.to_konst n
Chris@82 115 | Plus [] -> "0.0 /* bug */"
Chris@82 116 | Plus [a] -> " /* bug */ " ^ (unparse_expr_c a)
Chris@82 117 | Plus a -> (unparse_plus no a)
Chris@82 118 | Times (a, b) -> (parenthesize a) ^ " * " ^ (parenthesize b)
Chris@82 119 | Uminus (Plus [a; Uminus b]) -> unparse_plus no [b; Uminus a]
Chris@82 120 | Uminus a -> "- " ^ (parenthesize a)
Chris@82 121 | _ -> failwith "unparse_expr_c"
Chris@82 122
Chris@82 123 and unparse_expr_generic =
Chris@82 124 let rec u x = unparse_expr_generic x
Chris@82 125 and unary op a = Printf.sprintf "%s(%s)" op (u a)
Chris@82 126 and binary op a b = Printf.sprintf "%s(%s, %s)" op (u a) (u b)
Chris@82 127 and ternary op a b c = Printf.sprintf "%s(%s, %s, %s)" op (u a) (u b) (u c)
Chris@82 128 and quaternary op a b c d =
Chris@82 129 Printf.sprintf "%s(%s, %s, %s, %s)" op (u a) (u b) (u c) (u d)
Chris@82 130 and unparse_plus = function
Chris@82 131 | [(Uminus (Times (a, b))); Times (c, d)] -> quaternary "FNMMS" a b c d
Chris@82 132 | [Times (c, d); (Uminus (Times (a, b)))] -> quaternary "FNMMS" a b c d
Chris@82 133 | [Times (c, d); (Times (a, b))] -> quaternary "FMMA" a b c d
Chris@82 134 | [(Uminus (Times (a, b))); c] -> ternary "FNMS" a b c
Chris@82 135 | [c; (Uminus (Times (a, b)))] -> ternary "FNMS" a b c
Chris@82 136 | [(Uminus c); (Times (a, b))] -> ternary "FMS" a b c
Chris@82 137 | [(Times (a, b)); (Uminus c)] -> ternary "FMS" a b c
Chris@82 138 | [c; (Times (a, b))] -> ternary "FMA" a b c
Chris@82 139 | [(Times (a, b)); c] -> ternary "FMA" a b c
Chris@82 140 | [a; Uminus b] -> binary "SUB" a b
Chris@82 141 | [a; b] -> binary "ADD" a b
Chris@82 142 | a :: b :: c -> binary "ADD" a (Plus (b :: c))
Chris@82 143 | _ -> failwith "unparse_plus"
Chris@82 144 in function
Chris@82 145 | Load v -> Variable.unparse v
Chris@82 146 | Num n -> Number.to_konst n
Chris@82 147 | Plus a -> unparse_plus a
Chris@82 148 | Times (a, b) -> binary "MUL" a b
Chris@82 149 | Uminus a -> unary "NEG" a
Chris@82 150 | _ -> failwith "unparse_expr"
Chris@82 151
Chris@82 152 and unparse_expr x =
Chris@82 153 if !Magic.generic_arith then
Chris@82 154 unparse_expr_generic x
Chris@82 155 else
Chris@82 156 unparse_expr_c x
Chris@82 157
Chris@82 158 and unparse_assignment (Assign (v, x)) =
Chris@82 159 (Variable.unparse v) ^ " = " ^ (unparse_expr x) ^ ";\n"
Chris@82 160
Chris@82 161 and unparse_annotated force_bracket =
Chris@82 162 let rec unparse_code = function
Chris@82 163 ADone -> ""
Chris@82 164 | AInstr i -> unparse_assignment i
Chris@82 165 | ASeq (a, b) ->
Chris@82 166 (unparse_annotated false a) ^ (unparse_annotated false b)
Chris@82 167 and declare_variables l =
Chris@82 168 let rec uvar = function
Chris@82 169 [] -> failwith "uvar"
Chris@82 170 | [v] -> (Variable.unparse v) ^ ";\n"
Chris@82 171 | a :: b -> (Variable.unparse a) ^ ", " ^ (uvar b)
Chris@82 172 in let rec vvar l =
Chris@82 173 let s = if !Magic.compact then 15 else 1 in
Chris@82 174 if (List.length l <= s) then
Chris@82 175 match l with
Chris@82 176 [] -> ""
Chris@82 177 | _ -> extended_realtype ^ " " ^ (uvar l)
Chris@82 178 else
Chris@82 179 (vvar (Util.take s l)) ^ (vvar (Util.drop s l))
Chris@82 180 in vvar (List.filter Variable.is_temporary l)
Chris@82 181 in function
Chris@82 182 Annotate (_, _, decl, _, code) ->
Chris@82 183 if (not force_bracket) && (Util.null decl) then
Chris@82 184 unparse_code code
Chris@82 185 else "{\n" ^
Chris@82 186 (declare_variables decl) ^
Chris@82 187 (unparse_code code) ^
Chris@82 188 "}\n"
Chris@82 189
Chris@82 190 and unparse_decl = function
Chris@82 191 | Decl (a, b) -> a ^ " " ^ b ^ ";\n"
Chris@82 192 | Tdecl x -> x
Chris@82 193
Chris@82 194 and unparse_ast =
Chris@82 195 let rec unparse_plus = function
Chris@82 196 | [] -> ""
Chris@82 197 | (CUminus a :: b) -> " - " ^ (parenthesize a) ^ (unparse_plus b)
Chris@82 198 | (a :: b) -> " + " ^ (parenthesize a) ^ (unparse_plus b)
Chris@82 199 and parenthesize x = match x with
Chris@82 200 | (CVar _) -> unparse_ast x
Chris@82 201 | (CCall _) -> unparse_ast x
Chris@82 202 | (Integer _) -> unparse_ast x
Chris@82 203 | _ -> "(" ^ (unparse_ast x) ^ ")"
Chris@82 204
Chris@82 205 in
Chris@82 206 function
Chris@82 207 | Asch a -> (unparse_annotated true a)
Chris@82 208 | Simd_leavefun -> "" (* used only in SIMD code *)
Chris@82 209 | Return x -> "return " ^ unparse_ast x ^ ";"
Chris@82 210 | For (a, b, c, d) ->
Chris@82 211 "for (" ^
Chris@82 212 unparse_ast a ^ "; " ^ unparse_ast b ^ "; " ^ unparse_ast c
Chris@82 213 ^ ")" ^ unparse_ast d
Chris@82 214 | If (a, d) ->
Chris@82 215 "if (" ^
Chris@82 216 unparse_ast a
Chris@82 217 ^ ")" ^ unparse_ast d
Chris@82 218 | Block (d, s) ->
Chris@82 219 if (s == []) then ""
Chris@82 220 else
Chris@82 221 "{\n" ^
Chris@82 222 foldr_string_concat (map unparse_decl d) ^
Chris@82 223 foldr_string_concat (map unparse_ast s) ^
Chris@82 224 "}\n"
Chris@82 225 | Binop (op, a, b) -> (unparse_ast a) ^ op ^ (unparse_ast b)
Chris@82 226 | Expr_assign (a, b) -> (unparse_ast a) ^ " = " ^ (unparse_ast b)
Chris@82 227 | Stmt_assign (a, b) -> (unparse_ast a) ^ " = " ^ (unparse_ast b) ^ ";\n"
Chris@82 228 | Comma (a, b) -> (unparse_ast a) ^ ", " ^ (unparse_ast b)
Chris@82 229 | Integer i -> string_of_int i
Chris@82 230 | CVar s -> s
Chris@82 231 | CCall (s, x) -> s ^ "(" ^ (unparse_ast x) ^ ")"
Chris@82 232 | CPlus [] -> "0 /* bug */"
Chris@82 233 | CPlus [a] -> " /* bug */ " ^ (unparse_ast a)
Chris@82 234 | CPlus (a::b) -> (parenthesize a) ^ (unparse_plus b)
Chris@82 235 | ITimes (a, b) -> (parenthesize a) ^ " * " ^ (parenthesize b)
Chris@82 236 | CUminus a -> "- " ^ (parenthesize a)
Chris@82 237
Chris@82 238 and unparse_function = function
Chris@82 239 Fcn (typ, name, args, body) ->
Chris@82 240 let rec unparse_args = function
Chris@82 241 [Decl (a, b)] -> a ^ " " ^ b
Chris@82 242 | (Decl (a, b)) :: s -> a ^ " " ^ b ^ ", "
Chris@82 243 ^ unparse_args s
Chris@82 244 | [] -> ""
Chris@82 245 | _ -> failwith "unparse_function"
Chris@82 246 in
Chris@82 247 (typ ^ " " ^ name ^ "(" ^ unparse_args args ^ ")\n" ^
Chris@82 248 unparse_ast body)
Chris@82 249
Chris@82 250
Chris@82 251 (*************************************************************
Chris@82 252 * traverse a a function and return a list of all expressions,
Chris@82 253 * in the execution order
Chris@82 254 **************************************************************)
Chris@82 255 let rec fcn_to_expr_list = fun (Fcn (_, _, _, body)) -> ast_to_expr_list body
Chris@82 256 and acode_to_expr_list = function
Chris@82 257 AInstr (Assign (_, x)) -> [x]
Chris@82 258 | ASeq (a, b) ->
Chris@82 259 (asched_to_expr_list a) @ (asched_to_expr_list b)
Chris@82 260 | _ -> []
Chris@82 261 and asched_to_expr_list (Annotate (_, _, _, _, code)) =
Chris@82 262 acode_to_expr_list code
Chris@82 263 and ast_to_expr_list = function
Chris@82 264 Asch a -> asched_to_expr_list a
Chris@82 265 | Block (_, a) -> flatten (map ast_to_expr_list a)
Chris@82 266 | For (_, _, _, body) -> ast_to_expr_list body
Chris@82 267 | If (_, body) -> ast_to_expr_list body
Chris@82 268 | _ -> []
Chris@82 269
Chris@82 270 (***********************
Chris@82 271 * Extracting Constants
Chris@82 272 ***********************)
Chris@82 273
Chris@82 274 (* add a new key & value to a list of (key,value) pairs, where
Chris@82 275 the keys are floats and each key is unique up to almost_equal *)
Chris@82 276
Chris@82 277 let extract_constants f =
Chris@82 278 let constlist = flatten (map expr_to_constants (ast_to_expr_list f))
Chris@82 279 in map
Chris@82 280 (fun n ->
Chris@82 281 Tdecl
Chris@82 282 ("DK(" ^ (Number.to_konst n) ^ ", " ^ (Number.to_string n) ^
Chris@82 283 ");\n"))
Chris@82 284 (unique_constants constlist)
Chris@82 285
Chris@82 286 (******************************
Chris@82 287 Extracting operation counts
Chris@82 288 ******************************)
Chris@82 289
Chris@82 290 let count_stack_vars =
Chris@82 291 let rec count_acode = function
Chris@82 292 | ASeq (a, b) -> max (count_asched a) (count_asched b)
Chris@82 293 | _ -> 0
Chris@82 294 and count_asched (Annotate (_, _, decl, _, code)) =
Chris@82 295 (length decl) + (count_acode code)
Chris@82 296 and count_ast = function
Chris@82 297 | Asch a -> count_asched a
Chris@82 298 | Block (d, a) -> (length d) + (Util.max_list (map count_ast a))
Chris@82 299 | For (_, _, _, body) -> count_ast body
Chris@82 300 | If (_, body) -> count_ast body
Chris@82 301 | _ -> 0
Chris@82 302 in function (Fcn (_, _, _, body)) -> count_ast body
Chris@82 303
Chris@82 304 let count_memory_acc f =
Chris@82 305 let rec count_var v =
Chris@82 306 if (Variable.is_locative v) then 1 else 0
Chris@82 307 and count_acode = function
Chris@82 308 | AInstr (Assign (v, _)) -> count_var v
Chris@82 309 | ASeq (a, b) -> (count_asched a) + (count_asched b)
Chris@82 310 | _ -> 0
Chris@82 311 and count_asched = function
Chris@82 312 Annotate (_, _, _, _, code) -> count_acode code
Chris@82 313 and count_ast = function
Chris@82 314 | Asch a -> count_asched a
Chris@82 315 | Block (_, a) -> (Util.sum_list (map count_ast a))
Chris@82 316 | Comma (a, b) -> (count_ast a) + (count_ast b)
Chris@82 317 | For (_, _, _, body) -> count_ast body
Chris@82 318 | If (_, body) -> count_ast body
Chris@82 319 | _ -> 0
Chris@82 320 and count_acc_expr_func acc = function
Chris@82 321 | Load v -> acc + (count_var v)
Chris@82 322 | Plus a -> fold_left count_acc_expr_func acc a
Chris@82 323 | Times (a, b) -> fold_left count_acc_expr_func acc [a; b]
Chris@82 324 | Uminus a -> count_acc_expr_func acc a
Chris@82 325 | _ -> acc
Chris@82 326 in let (Fcn (typ, name, args, body)) = f
Chris@82 327 in (count_ast body) +
Chris@82 328 fold_left count_acc_expr_func 0 (fcn_to_expr_list f)
Chris@82 329
Chris@82 330 let good_for_fma = To_alist.good_for_fma
Chris@82 331
Chris@82 332 let build_fma = function
Chris@82 333 | [a; Times (b, c)] when good_for_fma (b, c) -> Some (a, b, c)
Chris@82 334 | [Times (b, c); a] when good_for_fma (b, c) -> Some (a, b, c)
Chris@82 335 | [a; Uminus (Times (b, c))] when good_for_fma (b, c) -> Some (a, b, c)
Chris@82 336 | [Uminus (Times (b, c)); a] when good_for_fma (b, c) -> Some (a, b, c)
Chris@82 337 | _ -> None
Chris@82 338
Chris@82 339 let rec count_flops_expr_func (adds, mults, fmas) = function
Chris@82 340 | Plus [] -> (adds, mults, fmas)
Chris@82 341 | Plus ([_; _] as a) ->
Chris@82 342 begin
Chris@82 343 match build_fma a with
Chris@82 344 | None ->
Chris@82 345 fold_left count_flops_expr_func
Chris@82 346 (adds + (length a) - 1, mults, fmas) a
Chris@82 347 | Some (a, b, c) ->
Chris@82 348 fold_left count_flops_expr_func (adds, mults, fmas+1) [a; b; c]
Chris@82 349 end
Chris@82 350 | Plus (a :: b) ->
Chris@82 351 count_flops_expr_func (adds, mults, fmas) (Plus [a; Plus b])
Chris@82 352 | Times (NaN MULTI_A,_) -> (adds, mults, fmas)
Chris@82 353 | Times (NaN MULTI_B,_) -> (adds, mults, fmas)
Chris@82 354 | Times (NaN I,b) -> count_flops_expr_func (adds, mults, fmas) b
Chris@82 355 | Times (NaN CONJ,b) -> count_flops_expr_func (adds, mults, fmas) b
Chris@82 356 | Times (a,b) -> fold_left count_flops_expr_func (adds, mults+1, fmas) [a; b]
Chris@82 357 | CTimes (a,b) ->
Chris@82 358 fold_left count_flops_expr_func (adds+1, mults+2, fmas) [a; b]
Chris@82 359 | CTimesJ (a,b) ->
Chris@82 360 fold_left count_flops_expr_func (adds+1, mults+2, fmas) [a; b]
Chris@82 361 | Uminus a -> count_flops_expr_func (adds, mults, fmas) a
Chris@82 362 | _ -> (adds, mults, fmas)
Chris@82 363
Chris@82 364 let count_flops f =
Chris@82 365 fold_left count_flops_expr_func (0, 0, 0) (fcn_to_expr_list f)
Chris@82 366
Chris@82 367 let count_constants f =
Chris@82 368 length (unique_constants (flatten (map expr_to_constants (fcn_to_expr_list f))))
Chris@82 369
Chris@82 370 let arith_complexity f =
Chris@82 371 let (a, m, fmas) = count_flops f
Chris@82 372 and v = count_stack_vars f
Chris@82 373 and c = count_constants f
Chris@82 374 and mem = count_memory_acc f
Chris@82 375 in (a, m, fmas, v, c, mem)
Chris@82 376
Chris@82 377 (* print the operation costs *)
Chris@82 378 let print_cost f =
Chris@82 379 let Fcn (_, _, _, _) = f
Chris@82 380 and (a, m, fmas, v, c, mem) = arith_complexity f
Chris@82 381 in
Chris@82 382 "/*\n"^
Chris@82 383 " * This function contains " ^
Chris@82 384 (string_of_int (a + fmas)) ^ " FP additions, " ^
Chris@82 385 (string_of_int (m + fmas)) ^ " FP multiplications,\n" ^
Chris@82 386 " * (or, " ^
Chris@82 387 (string_of_int a) ^ " additions, " ^
Chris@82 388 (string_of_int m) ^ " multiplications, " ^
Chris@82 389 (string_of_int fmas) ^ " fused multiply/add),\n" ^
Chris@82 390 " * " ^ (string_of_int v) ^ " stack variables, " ^
Chris@82 391 (string_of_int c) ^ " constants, and " ^
Chris@82 392 (string_of_int mem) ^ " memory accesses\n" ^
Chris@82 393 " */\n"
Chris@82 394
Chris@82 395 (*****************************************
Chris@82 396 * functions that create C arrays
Chris@82 397 *****************************************)
Chris@82 398 type stride =
Chris@82 399 | SVar of string
Chris@82 400 | SConst of string
Chris@82 401 | SInteger of int
Chris@82 402 | SNeg of stride
Chris@82 403
Chris@82 404 type sstride =
Chris@82 405 | Simple of int
Chris@82 406 | Constant of (string * int)
Chris@82 407 | Composite of (string * int)
Chris@82 408 | Negative of sstride
Chris@82 409
Chris@82 410 let rec simplify_stride stride i =
Chris@82 411 match (stride, i) with
Chris@82 412 (_, 0) -> Simple 0
Chris@82 413 | (SInteger n, i) -> Simple (n * i)
Chris@82 414 | (SConst s, i) -> Constant (s, i)
Chris@82 415 | (SVar s, i) -> Composite (s, i)
Chris@82 416 | (SNeg x, i) ->
Chris@82 417 match (simplify_stride x i) with
Chris@82 418 | Negative y -> y
Chris@82 419 | y -> Negative y
Chris@82 420
Chris@82 421 let rec cstride_to_string = function
Chris@82 422 | Simple i -> string_of_int i
Chris@82 423 | Constant (s, i) ->
Chris@82 424 if !Magic.lisp_syntax then
Chris@82 425 "(* " ^ s ^ " " ^ (string_of_int i) ^ ")"
Chris@82 426 else
Chris@82 427 s ^ " * " ^ (string_of_int i)
Chris@82 428 | Composite (s, i) ->
Chris@82 429 if !Magic.lisp_syntax then
Chris@82 430 "(* " ^ s ^ " " ^ (string_of_int i) ^ ")"
Chris@82 431 else
Chris@82 432 "WS(" ^ s ^ ", " ^ (string_of_int i) ^ ")"
Chris@82 433 | Negative x -> "-" ^ cstride_to_string x
Chris@82 434
Chris@82 435 let aref name index =
Chris@82 436 if !Magic.lisp_syntax then
Chris@82 437 Printf.sprintf "(aref %s %s)" name index
Chris@82 438 else
Chris@82 439 Printf.sprintf "%s[%s]" name index
Chris@82 440
Chris@82 441 let array_subscript name stride k =
Chris@82 442 aref name (cstride_to_string (simplify_stride stride k))
Chris@82 443
Chris@82 444 let varray_subscript name vstride stride v i =
Chris@82 445 let vindex = simplify_stride vstride v
Chris@82 446 and iindex = simplify_stride stride i
Chris@82 447 in
Chris@82 448 let index =
Chris@82 449 match (vindex, iindex) with
Chris@82 450 (Simple vi, Simple ii) -> string_of_int (vi + ii)
Chris@82 451 | (Simple 0, x) -> cstride_to_string x
Chris@82 452 | (x, Simple 0) -> cstride_to_string x
Chris@82 453 | _ -> (cstride_to_string vindex) ^ " + " ^ (cstride_to_string iindex)
Chris@82 454 in aref name index
Chris@82 455
Chris@82 456 let real_of s = "c_re(" ^ s ^ ")"
Chris@82 457 let imag_of s = "c_im(" ^ s ^ ")"
Chris@82 458
Chris@82 459 let flops_of f =
Chris@82 460 let (add, mul, fma) = count_flops f in
Chris@82 461 Printf.sprintf "{ %d, %d, %d, 0 }" add mul fma