comparison gcc/genpeep.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
children 84e7813d76e9
comparison
equal deleted inserted replaced
68:561a7518be6b 111:04ced10e8804
1 /* Generate code from machine description to perform peephole optimizations. 1 /* Generate code from machine description to perform peephole optimizations.
2 Copyright (C) 1987, 1989, 1992, 1997, 1998, 1999, 2000, 2003, 2004, 2 Copyright (C) 1987-2017 Free Software Foundation, Inc.
3 2007, 2010 Free Software Foundation, Inc.
4 3
5 This file is part of GCC. 4 This file is part of GCC.
6 5
7 GCC is free software; you can redistribute it and/or modify it under 6 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free 7 the terms of the GNU General Public License as published by the Free
45 44
46 /* Number of operands used in current peephole definition. */ 45 /* Number of operands used in current peephole definition. */
47 46
48 static int n_operands; 47 static int n_operands;
49 48
50 /* Peephole optimizations get insn codes just like insn patterns.
51 Count them so we know the code of the define_peephole we are handling. */
52
53 static int insn_code_number = 0;
54
55 static void gen_peephole (rtx);
56 static void match_rtx (rtx, struct link *, int); 49 static void match_rtx (rtx, struct link *, int);
57 static void print_path (struct link *); 50 static void print_path (struct link *);
58 static void print_code (RTX_CODE); 51 static void print_code (RTX_CODE);
59 52
60 static void 53 static void
61 gen_peephole (rtx peep) 54 gen_peephole (md_rtx_info *info)
62 { 55 {
56 rtx peep = info->def;
63 int ninsns = XVECLEN (peep, 0); 57 int ninsns = XVECLEN (peep, 0);
64 int i; 58 int i;
65 59
66 n_operands = 0; 60 n_operands = 0;
67 61
70 for (i = 0; i < ninsns; i++) 64 for (i = 0; i < ninsns; i++)
71 { 65 {
72 if (i > 0) 66 if (i > 0)
73 { 67 {
74 printf (" do { insn = NEXT_INSN (insn);\n"); 68 printf (" do { insn = NEXT_INSN (insn);\n");
75 printf (" if (insn == 0) goto L%d; }\n", 69 printf (" if (insn == 0) goto L%d; }\n", info->index);
76 insn_code_number);
77 printf (" while (NOTE_P (insn)\n"); 70 printf (" while (NOTE_P (insn)\n");
78 printf ("\t || (NONJUMP_INSN_P (insn)\n"); 71 printf ("\t || (NONJUMP_INSN_P (insn)\n");
79 printf ("\t && (GET_CODE (PATTERN (insn)) == USE\n"); 72 printf ("\t && (GET_CODE (PATTERN (insn)) == USE\n");
80 printf ("\t\t || GET_CODE (PATTERN (insn)) == CLOBBER)));\n"); 73 printf ("\t\t || GET_CODE (PATTERN (insn)) == CLOBBER)));\n");
81 74
82 printf (" if (LABEL_P (insn)\n\ 75 printf (" if (LABEL_P (insn)\n\
83 || BARRIER_P (insn))\n goto L%d;\n", 76 || BARRIER_P (insn))\n goto L%d;\n", info->index);
84 insn_code_number);
85 } 77 }
86 78
87 printf (" pat = PATTERN (insn);\n"); 79 printf (" pat = PATTERN (insn);\n");
88 80
89 /* Walk the insn's pattern, remembering at all times the path 81 /* Walk the insn's pattern, remembering at all times the path
90 down to the walking point. */ 82 down to the walking point. */
91 83
92 match_rtx (XVECEXP (peep, 0, i), NULL, insn_code_number); 84 match_rtx (XVECEXP (peep, 0, i), NULL, info->index);
93 } 85 }
94 86
95 /* We get this far if the pattern matches. 87 /* We get this far if the pattern matches.
96 Now test the extra condition. */ 88 Now test the extra condition. */
97 89
98 if (XSTR (peep, 1) && XSTR (peep, 1)[0]) 90 if (XSTR (peep, 1) && XSTR (peep, 1)[0])
99 printf (" if (! (%s)) goto L%d;\n", 91 printf (" if (! (%s)) goto L%d;\n",
100 XSTR (peep, 1), insn_code_number); 92 XSTR (peep, 1), info->index);
101 93
102 /* If that matches, construct new pattern and put it in the first insn. 94 /* If that matches, construct new pattern and put it in the first insn.
103 This new pattern will never be matched. 95 This new pattern will never be matched.
104 It exists only so that insn-extract can get the operands back. 96 It exists only so that insn-extract can get the operands back.
105 So use a simple regular form: a PARALLEL containing a vector 97 So use a simple regular form: a PARALLEL containing a vector
107 99
108 printf (" PATTERN (ins1) = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (%d, operands));\n", n_operands); 100 printf (" PATTERN (ins1) = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (%d, operands));\n", n_operands);
109 101
110 /* Record this define_peephole's insn code in the insn, 102 /* Record this define_peephole's insn code in the insn,
111 as if it had been recognized to match this. */ 103 as if it had been recognized to match this. */
112 printf (" INSN_CODE (ins1) = %d;\n", 104 printf (" INSN_CODE (ins1) = %d;\n", info->index);
113 insn_code_number);
114 105
115 /* Delete the remaining insns. */ 106 /* Delete the remaining insns. */
116 if (ninsns > 1) 107 if (ninsns > 1)
117 printf (" delete_for_peephole (NEXT_INSN (ins1), insn);\n"); 108 printf (" delete_for_peephole (NEXT_INSN (ins1), insn);\n");
118 109
119 /* See reload1.c for insertion of NOTE which guarantees that this 110 /* See reload1.c for insertion of NOTE which guarantees that this
120 cannot be zero. */ 111 cannot be zero. */
121 printf (" return NEXT_INSN (insn);\n"); 112 printf (" return NEXT_INSN (insn);\n");
122 113
123 printf (" L%d:\n\n", insn_code_number); 114 printf (" L%d:\n\n", info->index);
124 } 115 }
125 116
126 static void 117 static void
127 match_rtx (rtx x, struct link *path, int fail_label) 118 match_rtx (rtx x, struct link *path, int fail_label)
128 { 119 {
229 link.vecelt = i; 220 link.vecelt = i;
230 match_rtx (XVECEXP (x, 2, i), &link, fail_label); 221 match_rtx (XVECEXP (x, 2, i), &link, fail_label);
231 } 222 }
232 return; 223 return;
233 224
234 case ADDRESS:
235 match_rtx (XEXP (x, 0), path, fail_label);
236 return;
237
238 default: 225 default:
239 break; 226 break;
240 } 227 }
241 228
242 printf (" x = "); 229 printf (" x = ");
284 } 271 }
285 272
286 printf (" if (XINT (x, %d) != %d) goto L%d;\n", 273 printf (" if (XINT (x, %d) != %d) goto L%d;\n",
287 i, XINT (x, i), fail_label); 274 i, XINT (x, i), fail_label);
288 } 275 }
276 else if (fmt[i] == 'r')
277 {
278 gcc_assert (i == 0);
279 printf (" if (REGNO (x) != %d) goto L%d;\n",
280 REGNO (x), fail_label);
281 }
289 else if (fmt[i] == 'w') 282 else if (fmt[i] == 'w')
290 { 283 {
291 /* Make sure that at run time `x' is the RTX we want to test. */ 284 /* Make sure that at run time `x' is the RTX we want to test. */
292 if (i != 0) 285 if (i != 0)
293 { 286 {
342 static void 335 static void
343 print_code (RTX_CODE code) 336 print_code (RTX_CODE code)
344 { 337 {
345 const char *p1; 338 const char *p1;
346 for (p1 = GET_RTX_NAME (code); *p1; p1++) 339 for (p1 = GET_RTX_NAME (code); *p1; p1++)
347 putchar (TOUPPER(*p1)); 340 putchar (TOUPPER (*p1));
348 } 341 }
349 342
350 extern int main (int, char **); 343 extern int main (int, const char **);
351 344
352 int 345 int
353 main (int argc, char **argv) 346 main (int argc, const char **argv)
354 { 347 {
355 rtx desc;
356
357 max_opno = -1; 348 max_opno = -1;
358 349
359 progname = "genpeep"; 350 progname = "genpeep";
360 351
361 if (!init_rtx_reader_args (argc, argv)) 352 if (!init_rtx_reader_args (argc, argv))
365 from the machine description file `md'. */\n\n"); 356 from the machine description file `md'. */\n\n");
366 357
367 printf ("#include \"config.h\"\n"); 358 printf ("#include \"config.h\"\n");
368 printf ("#include \"system.h\"\n"); 359 printf ("#include \"system.h\"\n");
369 printf ("#include \"coretypes.h\"\n"); 360 printf ("#include \"coretypes.h\"\n");
370 printf ("#include \"tm.h\"\n"); 361 printf ("#include \"backend.h\"\n");
362 printf ("#include \"tree.h\"\n");
363 printf ("#include \"rtl.h\"\n");
371 printf ("#include \"insn-config.h\"\n"); 364 printf ("#include \"insn-config.h\"\n");
372 printf ("#include \"rtl.h\"\n"); 365 printf ("#include \"alias.h\"\n");
366 printf ("#include \"varasm.h\"\n");
367 printf ("#include \"stor-layout.h\"\n");
368 printf ("#include \"calls.h\"\n");
369 printf ("#include \"memmodel.h\"\n");
373 printf ("#include \"tm_p.h\"\n"); 370 printf ("#include \"tm_p.h\"\n");
374 printf ("#include \"regs.h\"\n"); 371 printf ("#include \"regs.h\"\n");
375 printf ("#include \"output.h\"\n"); 372 printf ("#include \"output.h\"\n");
376 printf ("#include \"recog.h\"\n"); 373 printf ("#include \"recog.h\"\n");
377 printf ("#include \"except.h\"\n"); 374 printf ("#include \"except.h\"\n");
378 printf ("#include \"function.h\"\n");
379 printf ("#include \"diagnostic-core.h\"\n"); 375 printf ("#include \"diagnostic-core.h\"\n");
380 printf ("#include \"flags.h\"\n"); 376 printf ("#include \"flags.h\"\n");
381 printf ("#include \"tm-constrs.h\"\n\n"); 377 printf ("#include \"tm-constrs.h\"\n\n");
382 378
383 printf ("#ifdef HAVE_peephole\n");
384 printf ("extern rtx peep_operand[];\n\n"); 379 printf ("extern rtx peep_operand[];\n\n");
385 printf ("#define operands peep_operand\n\n"); 380 printf ("#define operands peep_operand\n\n");
386 381
387 printf ("rtx\npeephole (rtx ins1)\n{\n"); 382 printf ("rtx_insn *\npeephole (rtx_insn *ins1)\n{\n");
388 printf (" rtx insn ATTRIBUTE_UNUSED, x ATTRIBUTE_UNUSED, pat ATTRIBUTE_UNUSED;\n\n"); 383 printf (" rtx_insn *insn ATTRIBUTE_UNUSED;\n");
384 printf (" rtx x ATTRIBUTE_UNUSED, pat ATTRIBUTE_UNUSED;\n\n");
389 385
390 /* Early out: no peepholes for insns followed by barriers. */ 386 /* Early out: no peepholes for insns followed by barriers. */
391 printf (" if (NEXT_INSN (ins1)\n"); 387 printf (" if (NEXT_INSN (ins1)\n");
392 printf (" && BARRIER_P (NEXT_INSN (ins1)))\n"); 388 printf (" && BARRIER_P (NEXT_INSN (ins1)))\n");
393 printf (" return 0;\n\n"); 389 printf (" return 0;\n\n");
394 390
395 /* Read the machine description. */ 391 /* Read the machine description. */
396 392
397 while (1) 393 md_rtx_info info;
398 { 394 while (read_md_rtx (&info))
399 int line_no, rtx_number = 0; 395 switch (GET_CODE (info.def))
400 396 {
401 desc = read_md_rtx (&line_no, &rtx_number); 397 case DEFINE_PEEPHOLE:
402 if (desc == NULL) 398 gen_peephole (&info);
403 break; 399 break;
404 400
405 if (GET_CODE (desc) == DEFINE_PEEPHOLE) 401 default:
406 { 402 break;
407 gen_peephole (desc); 403 }
408 insn_code_number++;
409 }
410 if (GET_CODE (desc) == DEFINE_INSN
411 || GET_CODE (desc) == DEFINE_EXPAND
412 || GET_CODE (desc) == DEFINE_SPLIT
413 || GET_CODE (desc) == DEFINE_PEEPHOLE2)
414 {
415 insn_code_number++;
416 }
417 }
418 404
419 printf (" return 0;\n}\n\n"); 405 printf (" return 0;\n}\n\n");
420 406
421 if (max_opno == -1) 407 if (max_opno == -1)
422 max_opno = 1; 408 max_opno = 1;
423 409
424 printf ("rtx peep_operand[%d];\n", max_opno + 1); 410 printf ("rtx peep_operand[%d];\n", max_opno + 1);
425 printf ("#endif\n");
426 411
427 fflush (stdout); 412 fflush (stdout);
428 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); 413 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
429 } 414 }