99
98
| c :: (Times (a, b)) :: d ->
100
99
maybep ^ (op "FMA" a b c) ^ (unparse_plus yes d)
101
100
| (Uminus a :: b) ->
102
maybem ^ (parenthesize a) ^ (unparse_plus yes b)
101
" - " ^ (parenthesize a) ^ (unparse_plus yes b)
104
103
maybep ^ (parenthesize a) ^ (unparse_plus yes b)
105
104
and parenthesize x = match x with
106
| (Load _) -> unparse_expr x
107
| (Num _) -> unparse_expr x
108
| _ -> "(" ^ (unparse_expr x) ^ ")"
105
| (Load _) -> unparse_expr_c x
106
| (Num _) -> unparse_expr_c x
107
| _ -> "(" ^ (unparse_expr_c x) ^ ")"
109
108
and op nam a b c =
110
nam ^ "(" ^ (unparse_expr a) ^ ", " ^ (unparse_expr b) ^ ", " ^
111
(unparse_expr c) ^ ")"
109
nam ^ "(" ^ (unparse_expr_c a) ^ ", " ^ (unparse_expr_c b) ^ ", " ^
110
(unparse_expr_c c) ^ ")"
114
113
| Load v -> Variable.unparse v
115
114
| Num n -> Number.to_konst n
116
115
| Plus [] -> "0.0 /* bug */"
117
| Plus [a] -> " /* bug */ " ^ (unparse_expr a)
116
| Plus [a] -> " /* bug */ " ^ (unparse_expr_c a)
118
117
| Plus a -> (unparse_plus no a)
119
118
| Times (a, b) -> (parenthesize a) ^ " * " ^ (parenthesize b)
119
| Uminus (Plus [a; Uminus b]) -> unparse_plus no [b; Uminus a]
120
120
| Uminus a -> "- " ^ (parenthesize a)
121
| _ -> failwith "unparse_expr_c"
123
and unparse_expr_generic =
124
let rec u x = unparse_expr_generic x
125
and unary op a = Printf.sprintf "%s(%s)" op (u a)
126
and binary op a b = Printf.sprintf "%s(%s, %s)" op (u a) (u b)
127
and ternary op a b c = Printf.sprintf "%s(%s, %s, %s)" op (u a) (u b) (u c)
128
and quaternary op a b c d =
129
Printf.sprintf "%s(%s, %s, %s, %s)" op (u a) (u b) (u c) (u d)
130
and unparse_plus = function
131
| [(Uminus (Times (a, b))); Times (c, d)] -> quaternary "FNMMS" a b c d
132
| [Times (c, d); (Uminus (Times (a, b)))] -> quaternary "FNMMS" a b c d
133
| [Times (c, d); (Times (a, b))] -> quaternary "FMMA" a b c d
134
| [(Uminus (Times (a, b))); c] -> ternary "FNMS" a b c
135
| [c; (Uminus (Times (a, b)))] -> ternary "FNMS" a b c
136
| [c; (Times (a, b))] -> ternary "FMA" a b c
137
| [(Times (a, b)); c] -> ternary "FMA" a b c
138
| [a; Uminus b] -> binary "SUB" a b
139
| [a; b] -> binary "ADD" a b
140
| a :: b :: c -> binary "ADD" a (Plus (b :: c))
141
| _ -> failwith "unparse_plus"
143
| Load v -> Variable.unparse v
144
| Num n -> Number.to_konst n
145
| Plus a -> unparse_plus a
146
| Times (a, b) -> binary "MUL" a b
147
| Uminus a -> unary "NEG" a
121
148
| _ -> failwith "unparse_expr"
151
if !Magic.generic_arith then
152
unparse_expr_generic x
123
156
and unparse_assignment (Assign (v, x)) =
124
157
(Variable.unparse v) ^ " = " ^ (unparse_expr x) ^ ";\n"
193
225
| Comma (a, b) -> (unparse_ast a) ^ ", " ^ (unparse_ast b)
194
226
| Integer i -> string_of_int i
228
| CCall (s, x) -> s ^ "(" ^ (unparse_ast x) ^ ")"
196
229
| CPlus [] -> "0 /* bug */"
197
230
| CPlus [a] -> " /* bug */ " ^ (unparse_ast a)
198
231
| CPlus (a::b) -> (parenthesize a) ^ (unparse_plus b)
199
| CTimes (a, b) -> (parenthesize a) ^ " * " ^ (parenthesize b)
232
| ITimes (a, b) -> (parenthesize a) ^ " * " ^ (parenthesize b)
200
233
| CUminus a -> "- " ^ (parenthesize a)
202
235
and unparse_function = function
241
274
let extract_constants f =
242
275
let constlist = flatten (map expr_to_constants (ast_to_expr_list f))
243
in let u = unique_constants constlist
244
in let use_const () =
247
Idecl (("const " ^ extended_realtype), (Number.to_konst n),
248
"K(" ^ (Number.to_string n) ^ ")"))
254
("DK(" ^ (Number.to_konst n) ^ ", " ^ (Number.to_string n) ^ ")"))
257
if !Magic.compact then
279
("DK(" ^ (Number.to_konst n) ^ ", " ^ (Number.to_string n) ^
281
(unique_constants constlist)
262
283
(******************************
263
284
Extracting operation counts
264
285
******************************)
315
336
let rec count_flops_expr_func (adds, mults, fmas) = function
316
337
| Plus [] -> (adds, mults, fmas)
317
| Plus ([_; _] as a) -> (match build_fma a with
319
let (newadds, newmults, newfmas) =
320
fold_left count_flops_expr_func (adds, mults, fmas) a
321
in (newadds + (length a) - 1, newmults, newfmas)
323
let (newadds, newmults, newfmas) =
324
fold_left count_flops_expr_func (adds, mults, fmas) [a; b; c]
325
in (newadds, newmults, newfmas + 1))
338
| Plus ([_; _] as a) ->
340
match build_fma a with
342
fold_left count_flops_expr_func
343
(adds + (length a) - 1, mults, fmas) a
345
fold_left count_flops_expr_func (adds, mults, fmas+1) [a; b; c]
326
347
| Plus (a :: b) ->
327
348
count_flops_expr_func (adds, mults, fmas) (Plus [a; Plus b])
328
| Times (NaN _,b) -> count_flops_expr_func (adds, mults, fmas) b
329
| Times (Num _, b) ->
330
let (newadds, newmults, newfmas) =
331
count_flops_expr_func (adds, mults, fmas) b
332
in (newadds, newmults + 1, newfmas)
334
let (newadds, newmults, newfmas) =
335
fold_left count_flops_expr_func (adds, mults, fmas) [a; b]
336
in if !Simdmagic.simd_mode then
337
(* complex multiplication *)
338
(newadds + 1, newmults + 2, newfmas)
340
(newadds, newmults + 1, newfmas)
349
| Times (NaN MULTI_A,_) -> (adds, mults, fmas)
350
| Times (NaN MULTI_B,_) -> (adds, mults, fmas)
351
| Times (NaN I,b) -> count_flops_expr_func (adds, mults, fmas) b
352
| Times (a,b) -> fold_left count_flops_expr_func (adds, mults+1, fmas) [a; b]
354
fold_left count_flops_expr_func (adds+1, mults+2, fmas) [a; b]
356
fold_left count_flops_expr_func (adds+1, mults+2, fmas) [a; b]
341
357
| Uminus a -> count_flops_expr_func (adds, mults, fmas) a
342
358
| _ -> (adds, mults, fmas)