1 /* file "estimate.cc" */
3 /* Copyright (c) 1994 Stanford University
7 This software is provided under the terms described in
8 the "suif_copyright.h" include file. */
10 #include <suif_copyright.h>
13 * This is the implementation of the rough execution time estimating
14 * routines for the SUIF ``useful'' library of miscellaneous useful
18 #define _MODULE_ "libuseful.a"
20 #pragma implementation "basic.h"
22 #define RCS_BASE_FILE estimate_cc
24 #include "useful_internal.h"
27 "$Id: estimate.cc,v 1.1.1.1 1998/06/16 15:15:27 brm Exp $")
29 /*----------------------------------------------------------------------*
31 *----------------------------------------------------------------------*
36 This file is a place to put general estimation routines for
40 *----------------------------------------------------------------------*
42 *----------------------------------------------------------------------*/
44 #define LOAD_TIME_ESTIMATE 2.0
45 #define STORE_TIME_ESTIMATE 2.0
46 #define BRANCH_TIME_ESTIMATE 2.0
47 #define INT_ALU_ESTIMATE 1.0
48 #define FP_ADD_ESTIMATE 2.0
49 #define FP_DIV_ESTIMATE 8.0
51 #define FUNC_CALL_ESTIMATE 1000.0
52 #define INTRINSIC_CALL_ESTIMATE 50.0
53 #define GENERIC_ESTIMATE 100.0
55 #define LOOP_ITERATIONS_ESTIMATE 100
57 extern double rough_time_estimate(tree_node_list
*the_list
)
60 tree_node_list_iter
the_iter(the_list
);
61 while (!the_iter
.is_empty())
63 tree_node
*this_node
= the_iter
.step();
64 cost
+= rough_time_estimate(this_node
);
69 extern double rough_time_estimate(tree_node
*the_node
)
71 switch (the_node
->kind())
75 tree_instr
*the_tree_instr
= (tree_instr
*)the_node
;
76 return rough_time_estimate_instr_tree(the_tree_instr
->instr());
80 tree_loop
*the_loop
= (tree_loop
*)the_node
;
81 double body_estimate
= rough_time_estimate(the_loop
->body());
82 double test_estimate
= rough_time_estimate(the_loop
->test());
83 return ((double) LOOP_ITERATIONS_ESTIMATE
) *
84 (body_estimate
+ test_estimate
);
88 tree_for
*the_for
= (tree_for
*)the_node
;
89 double landing_pad_est
=
90 rough_time_estimate(the_for
->landing_pad());
91 double body_estimate
= rough_time_estimate(the_for
->body());
92 double init_estimate
= rough_time_estimate(the_for
->lb_op());
93 init_estimate
+= rough_time_estimate(the_for
->ub_op());
94 init_estimate
+= rough_time_estimate(the_for
->step_op());
96 int lb_int
, ub_int
, step_int
;
97 boolean lb_is_int
, ub_is_int
, step_is_int
;
98 lb_is_int
= operand_is_int_const(the_for
->lb_op(), &lb_int
);
99 ub_is_int
= operand_is_int_const(the_for
->ub_op(), &ub_int
);
100 step_is_int
= operand_is_int_const(the_for
->step_op(), &step_int
);
101 int factor
= LOOP_ITERATIONS_ESTIMATE
;
102 if (lb_is_int
&& ub_is_int
&& step_is_int
&& (step_int
!= 0))
104 factor
= (ub_int
- lb_int
) / step_int
;
108 double cost
= landing_pad_est
+ init_estimate
+
109 (body_estimate
* (double) factor
);
114 tree_if
*the_if
= (tree_if
*)the_node
;
115 double header_estimate
= rough_time_estimate(the_if
->header());
116 double then_estimate
= rough_time_estimate(the_if
->then_part());
117 double else_estimate
= rough_time_estimate(the_if
->else_part());
118 return header_estimate
+ ((then_estimate
+ else_estimate
) / 2.0);
122 tree_block
*the_block
= (tree_block
*)the_node
;
123 return rough_time_estimate(the_block
->body());
131 extern double rough_time_estimate(operand the_operand
)
133 if (the_operand
.is_expr())
134 return rough_time_estimate_instr_tree(the_operand
.instr());
139 extern double rough_time_estimate_instr_tree(instruction
*the_instr
)
143 unsigned num_srcs
= the_instr
->num_srcs();
144 for (unsigned src_num
= 0; src_num
< num_srcs
; ++src_num
)
145 cost
+= rough_time_estimate(the_instr
->src_op(src_num
));
146 return cost
+ rough_time_estimate_one_instr(the_instr
);
149 extern double rough_time_estimate_one_instr(instruction
*the_instr
)
151 switch (the_instr
->opcode())
154 return LOAD_TIME_ESTIMATE
;
156 return STORE_TIME_ESTIMATE
;
162 in_rrr
*the_rrr
= (in_rrr
*)the_instr
;
163 if (the_rrr
->src1_op().type()->unqual()->op() == TYPE_FLOAT
)
164 return FP_ADD_ESTIMATE
;
166 return INT_ALU_ESTIMATE
;
172 return BRANCH_TIME_ESTIMATE
;
178 if (the_instr
->result_type()->unqual()->op() == TYPE_FLOAT
)
179 return FP_DIV_ESTIMATE
;
181 return INT_ALU_ESTIMATE
;
187 return BRANCH_TIME_ESTIMATE
+ INT_ALU_ESTIMATE
;
190 in_cal
*the_call
= (in_cal
*)the_instr
;
191 proc_sym
*the_proc
= proc_for_call(the_call
);
192 if ((the_proc
!= NULL
) &&
193 (the_proc
->annotes()->peek_annote(k_fortran_intrinsic
) !=
196 return INTRINSIC_CALL_ESTIMATE
;
198 return FUNC_CALL_ESTIMATE
;
201 return GENERIC_ESTIMATE
;
204 in_array
*the_array
= (in_array
*)the_instr
;
205 if (the_instr
->result_type()->unqual()->op() == TYPE_FLOAT
)
206 return ((double) the_array
->dims()) * FP_ADD_ESTIMATE
* 2.0;
208 return ((double) the_array
->dims()) * INT_ALU_ESTIMATE
* 2.0;
211 return LOAD_TIME_ESTIMATE
+ STORE_TIME_ESTIMATE
;
213 if (the_instr
->result_type()->unqual()->op() == TYPE_FLOAT
)
214 return FP_ADD_ESTIMATE
;
216 return INT_ALU_ESTIMATE
;