21 #undef PACKAGE_BUGREPORT
24 #undef PACKAGE_TARNAME
25 #undef PACKAGE_VERSION
27 #ifndef BUILDING_GCC_VERSION
29 #define GCC_VERSION BUILDING_GCC_VERSION
31 #if (BUILDING_GCC_VERSION < 4009)
32 #include "gcc-plugin.h"
33 #include "tree-pass.h"
38 #include "gcc-plugin.h"
41 #include "coretypes.h"
44 #include "stringpool.h"
46 #include "basic-block.h"
47 #include "pointer-set.h"
48 #include "hash-table.h"
51 #include "basic-block.h"
52 #include "tree-ssa-alias.h"
53 #include "internal-fn.h"
54 #include "gimple-fold.h"
56 #include "gimple-expr.h"
59 #include "gimple-iterator.h"
61 #include "tree-pass.h"
63 #include "diagnostic.h"
73 using namespace mageec;
79 static bool mageec_featextract_gate(
void)
87 static unsigned mageec_featextract_exec(
void)
90 gimple_stmt_iterator gsi;
95 std::vector<unsigned> insn_counts;
96 unsigned bb_count = 0;
97 unsigned bb_single_successor = 0;
98 unsigned bb_two_successors = 0;
99 unsigned bb_gt2_successors = 0;
100 unsigned bb_single_predecessor = 0;
101 unsigned bb_two_predecessors = 0;
102 unsigned bb_gt2_predecessors = 0;
103 unsigned bb_1pred_1succ = 0;
104 unsigned bb_1pred_2succ = 0;
105 unsigned bb_2pred_1succ = 0;
106 unsigned bb_2pred_2succ = 0;
107 unsigned bb_gt2pred_gt2succ = 0;
108 unsigned insn_count_lt15 = 0;
109 unsigned insn_count_15_to_500 = 0;
110 unsigned insn_count_gt500 = 0;
111 unsigned edges_in_cfg = 0;
112 unsigned edges_critical = 0;
113 unsigned edges_abnormal = 0;
114 unsigned method_cond_stmt = 0;
115 unsigned call_direct = 0;
116 unsigned method_assignments = 0;
117 unsigned int_operations = 0;
118 unsigned float_operations = 0;
119 unsigned average_phi_node_head = 0;
120 unsigned average_phi_args = 0;
121 unsigned bb_phi_count_0 = 0;
122 unsigned bb_phi_count_0_to_3 = 0;
123 unsigned bb_phi_count_gt3 = 0;
124 unsigned bb_phi_args_gt5 = 0;
125 unsigned bb_phi_args_1_to_5 = 0;
126 unsigned method_switch_stmt = 0;
127 unsigned method_unary_ops = 0;
128 unsigned pointer_arith = 0;
129 unsigned call_indirect = 0;
130 unsigned call_ptr_arg = 0;
131 unsigned call_gt4_args = 0;
132 unsigned call_ret_float = 0;
133 unsigned call_ret_int = 0;
134 unsigned uncond_branches = 0;
137 unsigned stmt_count = 0;
138 unsigned phi_nodes = 0;
139 unsigned phi_args = 0;
140 bool in_phi_header =
false;
141 unsigned phi_header_nodes = 0;
142 unsigned total_phi_args = 0;
143 unsigned total_phi_nodes = 0;
145 #if (GCC_VERSION < 4009)
148 FOR_ALL_BB_FN (bb, cfun)
154 in_phi_header =
true;
158 for (gsi=gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi))
160 gimple stmt = gsi_stmt (gsi);
163 if (is_gimple_assign (stmt))
165 method_assignments++;
166 enum gimple_rhs_class grhs_class =
167 get_gimple_rhs_class (gimple_expr_code (stmt));
168 if (grhs_class == GIMPLE_UNARY_RHS)
170 if (grhs_class == GIMPLE_BINARY_RHS)
172 tree arg1 = gimple_assign_rhs1 (stmt);
173 tree arg2 = gimple_assign_rhs2 (stmt);
174 if (FLOAT_TYPE_P (TREE_TYPE (arg1)))
176 else if (INTEGRAL_TYPE_P (TREE_TYPE (arg2)))
179 if (POINTER_TYPE_P (TREE_TYPE (arg1)) ||
180 POINTER_TYPE_P (TREE_TYPE (arg2)))
186 if (gimple_code (stmt) == GIMPLE_PHI)
192 phi_args += gimple_phi_num_args (stmt);
193 total_phi_args += gimple_phi_num_args (stmt);
196 in_phi_header =
false;
197 if (gimple_code (stmt) == GIMPLE_SWITCH)
198 method_switch_stmt++;
201 if (is_gimple_call (stmt))
203 if (gimple_call_num_args (stmt) > 4)
206 bool call_has_ptr =
false;
207 for (
unsigned i = 0; i < gimple_call_num_args (stmt); i++)
209 tree arg = gimple_call_arg (stmt, i);
210 if (POINTER_TYPE_P (TREE_TYPE (arg)))
216 tree call_fn = gimple_call_fndecl (stmt);
221 tree call_ret = gimple_call_lhs (stmt);
224 if (FLOAT_TYPE_P (TREE_TYPE (call_ret)))
226 else if (INTEGRAL_TYPE_P (TREE_TYPE (call_ret)))
231 if (gimple_code (stmt) == GIMPLE_COND)
236 if (EDGE_COUNT(bb->succs) == 1)
237 bb_single_successor++;
238 else if (EDGE_COUNT(bb->succs) == 2)
240 else if (EDGE_COUNT(bb->succs) > 2)
242 if (EDGE_COUNT(bb->preds) == 1)
243 bb_single_predecessor++;
244 else if (EDGE_COUNT(bb->preds) == 2)
245 bb_two_predecessors++;
246 else if (EDGE_COUNT(bb->preds) > 2)
247 bb_gt2_predecessors++;
248 if ((EDGE_COUNT(bb->preds) == 1) && (EDGE_COUNT(bb->succs) == 1))
250 if ((EDGE_COUNT(bb->preds) == 1) && (EDGE_COUNT(bb->succs) == 2))
252 if ((EDGE_COUNT(bb->preds) == 2) && (EDGE_COUNT(bb->succs) == 1))
254 if ((EDGE_COUNT(bb->preds) == 2) && (EDGE_COUNT(bb->succs) == 2))
256 if ((EDGE_COUNT(bb->preds) > 2) && (EDGE_COUNT(bb->succs) > 2))
257 bb_gt2pred_gt2succ++;
260 FOR_EACH_EDGE (e, ei, bb->succs)
263 if (EDGE_CRITICAL_P (e))
265 if (e->flags & EDGE_ABNORMAL)
271 insn_counts.push_back(stmt_count);
274 else if (stmt_count > 500)
277 insn_count_15_to_500++;
282 bb_phi_count_0_to_3++;
287 else if ((phi_args >= 1) && (phi_args <= 5))
288 bb_phi_args_1_to_5++;
292 if (total_phi_nodes > 0)
293 average_phi_args = total_phi_args / total_phi_nodes;
295 average_phi_node_head = phi_header_nodes / bb_count;
298 std::vector<mageec::mageec_feature*> features;
299 features.push_back(
new basic_feature(
"ft1",
"Basic Block Count", bb_count));
300 features.push_back(
new basic_feature(
"ft2",
"BB with 1 successor", bb_single_successor));
301 features.push_back(
new basic_feature(
"ft3",
"BB with 2 successor", bb_two_successors));
302 features.push_back(
new basic_feature(
"ft4",
"BB with > 2 successor", bb_gt2_successors));
303 features.push_back(
new basic_feature(
"ft5",
"BB with 1 predecessor", bb_single_predecessor));
304 features.push_back(
new basic_feature(
"ft6",
"BB with 2 predecessor", bb_two_predecessors));
305 features.push_back(
new basic_feature(
"ft7",
"BB with > 2 predecesso", bb_gt2_predecessors));
306 features.push_back(
new basic_feature(
"ft8",
"BB with 1 pred 1 succ", bb_1pred_1succ));
307 features.push_back(
new basic_feature(
"ft9",
"BB with 1 pred 2 succ", bb_1pred_2succ));
308 features.push_back(
new basic_feature(
"ft10",
"BB with 2 pred 1 succ", bb_2pred_1succ));
309 features.push_back(
new basic_feature(
"ft11",
"BB with 2 pred 2 succ", bb_2pred_2succ));
310 features.push_back(
new basic_feature(
"ft12",
"BB with >2 pred >2 suc", bb_gt2pred_gt2succ));
311 features.push_back(
new basic_feature(
"ft13",
"BB with insn < 15", insn_count_lt15));
312 features.push_back(
new basic_feature(
"ft14",
"BB with insn [15, 500]", insn_count_15_to_500));
313 features.push_back(
new basic_feature(
"ft15",
"BB with insn > 500", insn_count_gt500));
314 features.push_back(
new basic_feature(
"ft16",
"Edges in CFG", edges_in_cfg));
315 features.push_back(
new basic_feature(
"ft17",
"Critical Edges in CFG", edges_critical));
316 features.push_back(
new basic_feature(
"ft18",
"Abnormal Edges in CFG", edges_abnormal));
317 features.push_back(
new basic_feature(
"ft19",
"Conditional Statements", method_cond_stmt));
318 features.push_back(
new basic_feature(
"ft20",
"Direct Calls", call_direct));
319 features.push_back(
new basic_feature(
"ft21",
"Assignments in method", method_assignments));
320 features.push_back(
new basic_feature(
"ft22",
"Integer operations", int_operations));
321 features.push_back(
new basic_feature(
"ft23",
"Floating Point Operations", float_operations));
322 features.push_back(
new basic_feature(
"ft24",
"Total Statement in BB", vector_sum(insn_counts)));
323 features.push_back(
new basic_feature(
"ft25",
"Avg Statement in BB", vector_sum(insn_counts)/bb_count));
324 features.push_back(
new basic_feature(
"ft26",
"Avg phis at top of BB", average_phi_node_head));
325 features.push_back(
new basic_feature(
"ft27",
"Average phi arg count", average_phi_args));
326 features.push_back(
new basic_feature(
"ft28",
"BB with 0 phis", bb_phi_count_0));
327 features.push_back(
new basic_feature(
"ft29",
"BB with [0, 3] phis", bb_phi_count_0_to_3));
328 features.push_back(
new basic_feature(
"ft30",
"BB with > 3 phis", bb_phi_count_gt3));
329 features.push_back(
new basic_feature(
"ft31",
"BB phis with > 5 args", bb_phi_args_gt5));
330 features.push_back(
new basic_feature(
"ft32",
"BB phis with [1,5] arg", bb_phi_args_1_to_5));
331 features.push_back(
new basic_feature(
"ft33",
"Switch stmts in method", method_switch_stmt));
332 features.push_back(
new basic_feature(
"ft34",
"Unary ops in method", method_unary_ops));
333 features.push_back(
new basic_feature(
"ft35",
"Pointer Arithmetic", pointer_arith));
334 features.push_back(
new basic_feature(
"ft39",
"Indirect Calls", call_indirect));
335 features.push_back(
new basic_feature(
"ft42",
"Calls with pointer args", call_ptr_arg));
336 features.push_back(
new basic_feature(
"ft43",
"Calls with > 4 args", call_gt4_args));
337 features.push_back(
new basic_feature(
"ft44",
"Calls that return float", call_ret_float));
338 features.push_back(
new basic_feature(
"ft45",
"Calls that return int", call_ret_int));
339 features.push_back(
new basic_feature(
"ft46",
"Unconditional branches", uncond_branches));
344 std::cerr <<
"Current Function: " << current_function_name() << std::endl;
354 #if (GCC_VERSION < 4009)
355 static struct gimple_opt_pass mageec_featextract =
361 mageec_featextract_gate,
362 mageec_featextract_exec,
377 const pass_data pass_data_mageec_featextract =
392 class mageec_featpass :
public gimple_opt_pass
395 mageec_featpass(gcc::context *ctxt)
396 : gimple_opt_pass(pass_data_mageec_featextract, ctxt)
400 bool gate () {
return mageec_featextract_gate (); }
401 unsigned int execute () {
return mageec_featextract_exec (); }
407 static gimple_opt_pass *
408 make_mageec_pass (gcc::context *ctxt)
410 return new mageec_featpass (ctxt);
420 struct register_pass_info pass;
422 #if (GCC_VERSION < 4009)
423 pass.pass = &mageec_featextract.pass;
425 pass.pass = make_mageec_pass (g);
427 pass.reference_pass_name =
"ssa";
428 pass.ref_pass_instance_number = 1;
429 pass.pos_op = PASS_POS_INSERT_AFTER;