xref: /dflybsd-src/contrib/gcc-8.0/gcc/gen-pass-instances.awk (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj#  Copyright (C) 2013-2018 Free Software Foundation, Inc.
2*38fd1498Szrj#
3*38fd1498Szrj# This program is free software; you can redistribute it and/or modify it
4*38fd1498Szrj# under the terms of the GNU General Public License as published by the
5*38fd1498Szrj# Free Software Foundation; either version 3, or (at your option) any
6*38fd1498Szrj# later version.
7*38fd1498Szrj#
8*38fd1498Szrj# This program is distributed in the hope that it will be useful,
9*38fd1498Szrj# but WITHOUT ANY WARRANTY; without even the implied warranty of
10*38fd1498Szrj# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11*38fd1498Szrj# GNU General Public License for more details.
12*38fd1498Szrj#
13*38fd1498Szrj# You should have received a copy of the GNU General Public License
14*38fd1498Szrj# along with this program; see the file COPYING3.  If not see
15*38fd1498Szrj# <http://www.gnu.org/licenses/>.
16*38fd1498Szrj
17*38fd1498Szrj# This Awk script takes passes.def and writes pass-instances.def,
18*38fd1498Szrj# counting the instances of each kind of pass, adding an instance number
19*38fd1498Szrj# to everywhere that NEXT_PASS is used.
20*38fd1498Szrj# Also handle INSERT_PASS_AFTER, INSERT_PASS_BEFORE and REPLACE_PASS
21*38fd1498Szrj# directives.
22*38fd1498Szrj#
23*38fd1498Szrj# For example, the single-instanced pass:
24*38fd1498Szrj#     NEXT_PASS (pass_warn_unused_result);
25*38fd1498Szrj# becomes this in the output:
26*38fd1498Szrj#     NEXT_PASS (pass_warn_unused_result, 1);
27*38fd1498Szrj#
28*38fd1498Szrj# The various instances of
29*38fd1498Szrj#   NEXT_PASS (pass_copy_prop);
30*38fd1498Szrj# become:
31*38fd1498Szrj#   NEXT_PASS (pass_copy_prop, 1);
32*38fd1498Szrj# through:
33*38fd1498Szrj#   NEXT_PASS (pass_copy_prop, 8);
34*38fd1498Szrj# (currently there are 8 instances of that pass)
35*38fd1498Szrj#
36*38fd1498Szrj#     INSERT_PASS_AFTER (pass_copy_prop, 1, pass_stv);
37*38fd1498Szrj# will insert
38*38fd1498Szrj#     NEXT_PASS (pass_stv, 1);
39*38fd1498Szrj# immediately after the NEXT_PASS (pass_copy_prop, 1) line,
40*38fd1498Szrj# similarly INSERT_PASS_BEFORE inserts immediately before that line.
41*38fd1498Szrj#     REPLACE_PASS (pass_copy_prop, 1, pass_stv, true);
42*38fd1498Szrj# will replace NEXT_PASS (pass_copy_prop, 1) line with
43*38fd1498Szrj#     NEXT_PASS (pass_stv, 1, true);
44*38fd1498Szrj# line and renumber all higher pass_copy_prop instances if any.
45*38fd1498Szrj
46*38fd1498Szrj# Usage: awk -f gen-pass-instances.awk passes.def
47*38fd1498Szrj
48*38fd1498SzrjBEGIN {
49*38fd1498Szrj  print "/* This file is auto-generated by gen-pass-instances.awk";
50*38fd1498Szrj  print "   from passes.def.  */";
51*38fd1498Szrj  lineno = 1;
52*38fd1498Szrj}
53*38fd1498Szrj
54*38fd1498Szrjfunction parse_line(line, fnname,	len_of_call, len_of_start,
55*38fd1498Szrj					len_of_open, len_of_close,
56*38fd1498Szrj					len_of_args, args_start_at,
57*38fd1498Szrj					args_str, len_of_prefix,
58*38fd1498Szrj					call_starts_at,
59*38fd1498Szrj					postfix_starts_at)
60*38fd1498Szrj{
61*38fd1498Szrj  # Find call expression.
62*38fd1498Szrj  call_starts_at = match(line, fnname " \\(.+\\)");
63*38fd1498Szrj  if (call_starts_at == 0)
64*38fd1498Szrj    return 0;
65*38fd1498Szrj
66*38fd1498Szrj  # Length of the call expression.
67*38fd1498Szrj  len_of_call = RLENGTH;
68*38fd1498Szrj
69*38fd1498Szrj  len_of_start = length(fnname " (");
70*38fd1498Szrj  len_of_open = length("(");
71*38fd1498Szrj  len_of_close = length(")");
72*38fd1498Szrj
73*38fd1498Szrj  # Find arguments
74*38fd1498Szrj  len_of_args = len_of_call - (len_of_start + len_of_close);
75*38fd1498Szrj  args_start_at = call_starts_at + len_of_start;
76*38fd1498Szrj  args_str = substr(line, args_start_at, len_of_args);
77*38fd1498Szrj  split(args_str, args, ",");
78*38fd1498Szrj
79*38fd1498Szrj  # Find call expression prefix
80*38fd1498Szrj  len_of_prefix = call_starts_at - 1;
81*38fd1498Szrj  prefix = substr(line, 1, len_of_prefix);
82*38fd1498Szrj
83*38fd1498Szrj  # Find call expression postfix
84*38fd1498Szrj  postfix_starts_at = call_starts_at + len_of_call;
85*38fd1498Szrj  postfix = substr(line, postfix_starts_at);
86*38fd1498Szrj  return 1;
87*38fd1498Szrj}
88*38fd1498Szrj
89*38fd1498Szrjfunction adjust_linenos(above, increment,	p, i)
90*38fd1498Szrj{
91*38fd1498Szrj  for (p in pass_lines)
92*38fd1498Szrj    if (pass_lines[p] >= above)
93*38fd1498Szrj      pass_lines[p] += increment;
94*38fd1498Szrj  if (increment > 0)
95*38fd1498Szrj    for (i = lineno - 1; i >= above; i--)
96*38fd1498Szrj      lines[i + increment] = lines[i];
97*38fd1498Szrj  else
98*38fd1498Szrj    for (i = above; i < lineno; i++)
99*38fd1498Szrj      lines[i + increment] = lines[i];
100*38fd1498Szrj  lineno += increment;
101*38fd1498Szrj}
102*38fd1498Szrj
103*38fd1498Szrjfunction insert_remove_pass(line, fnname,	arg3)
104*38fd1498Szrj{
105*38fd1498Szrj  parse_line($0, fnname);
106*38fd1498Szrj  pass_name = args[1];
107*38fd1498Szrj  if (pass_name == "PASS")
108*38fd1498Szrj    return 1;
109*38fd1498Szrj  pass_num = args[2] + 0;
110*38fd1498Szrj  arg3 = args[3];
111*38fd1498Szrj  sub(/^[ \t]*/, "", arg3);
112*38fd1498Szrj  new_line = prefix "NEXT_PASS (" arg3;
113*38fd1498Szrj  if (args[4])
114*38fd1498Szrj    new_line = new_line "," args[4];
115*38fd1498Szrj  new_line = new_line ")" postfix;
116*38fd1498Szrj  if (!pass_lines[pass_name, pass_num])
117*38fd1498Szrj    {
118*38fd1498Szrj      print "ERROR: Can't locate instance of the pass mentioned in " fnname;
119*38fd1498Szrj      return 1;
120*38fd1498Szrj    }
121*38fd1498Szrj  return 0;
122*38fd1498Szrj}
123*38fd1498Szrj
124*38fd1498Szrjfunction insert_pass(line, fnname, after,		num)
125*38fd1498Szrj{
126*38fd1498Szrj  if (insert_remove_pass(line, fnname))
127*38fd1498Szrj    return;
128*38fd1498Szrj  num = pass_lines[pass_name, pass_num];
129*38fd1498Szrj  adjust_linenos(num + after, 1);
130*38fd1498Szrj  pass_name = args[3];
131*38fd1498Szrj  # Set pass_counts
132*38fd1498Szrj  if (args[3] in pass_counts)
133*38fd1498Szrj    pass_counts[pass_name]++;
134*38fd1498Szrj  else
135*38fd1498Szrj    pass_counts[pass_name] = 1;
136*38fd1498Szrj
137*38fd1498Szrj  pass_lines[pass_name, pass_counts[pass_name]] = num + after;
138*38fd1498Szrj  lines[num + after] = new_line;
139*38fd1498Szrj}
140*38fd1498Szrj
141*38fd1498Szrjfunction replace_pass(line, fnname,			num, i)
142*38fd1498Szrj{
143*38fd1498Szrj  if (insert_remove_pass(line, "REPLACE_PASS"))
144*38fd1498Szrj    return;
145*38fd1498Szrj  num = pass_lines[pass_name, pass_num];
146*38fd1498Szrj  for (i = pass_counts[pass_name]; i > pass_num; i--)
147*38fd1498Szrj    pass_lines[pass_name, i - 1] = pass_lines[pass_name, i];
148*38fd1498Szrj  delete pass_lines[pass_name, pass_counts[pass_name]];
149*38fd1498Szrj  if (pass_counts[pass_name] == 1)
150*38fd1498Szrj    delete pass_counts[pass_name];
151*38fd1498Szrj  else
152*38fd1498Szrj    pass_counts[pass_name]--;
153*38fd1498Szrj
154*38fd1498Szrj  pass_name = args[3];
155*38fd1498Szrj  # Set pass_counts
156*38fd1498Szrj  if (args[3] in pass_counts)
157*38fd1498Szrj    pass_counts[pass_name]++;
158*38fd1498Szrj  else
159*38fd1498Szrj    pass_counts[pass_name] = 1;
160*38fd1498Szrj
161*38fd1498Szrj  pass_lines[pass_name, pass_counts[pass_name]] = num;
162*38fd1498Szrj  lines[num] = new_line;
163*38fd1498Szrj}
164*38fd1498Szrj
165*38fd1498Szrj/INSERT_PASS_AFTER \(.+\)/ {
166*38fd1498Szrj  insert_pass($0, "INSERT_PASS_AFTER", 1);
167*38fd1498Szrj  next;
168*38fd1498Szrj}
169*38fd1498Szrj
170*38fd1498Szrj/INSERT_PASS_BEFORE \(.+\)/ {
171*38fd1498Szrj  insert_pass($0, "INSERT_PASS_BEFORE", 0);
172*38fd1498Szrj  next;
173*38fd1498Szrj}
174*38fd1498Szrj
175*38fd1498Szrj/REPLACE_PASS \(.+\)/ {
176*38fd1498Szrj  replace_pass($0, "REPLACE_PASS");
177*38fd1498Szrj  next;
178*38fd1498Szrj}
179*38fd1498Szrj
180*38fd1498Szrj{
181*38fd1498Szrj  ret = parse_line($0, "NEXT_PASS");
182*38fd1498Szrj  if (ret)
183*38fd1498Szrj    {
184*38fd1498Szrj      pass_name = args[1];
185*38fd1498Szrj
186*38fd1498Szrj      # Set pass_counts
187*38fd1498Szrj      if (pass_name in pass_counts)
188*38fd1498Szrj	pass_counts[pass_name]++;
189*38fd1498Szrj      else
190*38fd1498Szrj	pass_counts[pass_name] = 1;
191*38fd1498Szrj
192*38fd1498Szrj      pass_lines[pass_name, pass_counts[pass_name]] = lineno;
193*38fd1498Szrj    }
194*38fd1498Szrj  lines[lineno++] = $0;
195*38fd1498Szrj}
196*38fd1498Szrj
197*38fd1498SzrjEND {
198*38fd1498Szrj  for (i = 1; i < lineno; i++)
199*38fd1498Szrj    {
200*38fd1498Szrj      ret = parse_line(lines[i], "NEXT_PASS");
201*38fd1498Szrj      if (ret)
202*38fd1498Szrj	{
203*38fd1498Szrj	  # Set pass_name argument, an optional with_arg argument
204*38fd1498Szrj	  pass_name = args[1];
205*38fd1498Szrj	  with_arg = args[2];
206*38fd1498Szrj
207*38fd1498Szrj	  # Set pass_final_counts
208*38fd1498Szrj	  if (pass_name in pass_final_counts)
209*38fd1498Szrj	    pass_final_counts[pass_name]++;
210*38fd1498Szrj	  else
211*38fd1498Szrj	    pass_final_counts[pass_name] = 1;
212*38fd1498Szrj
213*38fd1498Szrj	  pass_num = pass_final_counts[pass_name];
214*38fd1498Szrj
215*38fd1498Szrj	  # Print call expression with extra pass_num argument
216*38fd1498Szrj	  printf "%s", prefix;
217*38fd1498Szrj	  if (with_arg)
218*38fd1498Szrj	    printf "NEXT_PASS_WITH_ARG";
219*38fd1498Szrj	  else
220*38fd1498Szrj	    printf "NEXT_PASS";
221*38fd1498Szrj	  printf " (%s, %s", pass_name, pass_num;
222*38fd1498Szrj	  if (with_arg)
223*38fd1498Szrj	    printf ",%s", with_arg;
224*38fd1498Szrj	  printf ")%s\n", postfix;
225*38fd1498Szrj	}
226*38fd1498Szrj      else
227*38fd1498Szrj	print lines[i];
228*38fd1498Szrj    }
229*38fd1498Szrj}
230*38fd1498Szrj
231*38fd1498Szrj# Local Variables:
232*38fd1498Szrj# mode:awk
233*38fd1498Szrj# c-basic-offset:8
234*38fd1498Szrj# End:
235