1# Copyright (C) 2003,2004,2005,2006,2007,2008, 2010 2# Free Software Foundation, Inc. 3# Contributed by Kelley Cook, June 2004. 4# Original code from Neil Booth, May 2003. 5# 6# This program is free software; you can redistribute it and/or modify it 7# under the terms of the GNU General Public License as published by the 8# Free Software Foundation; either version 3, or (at your option) any 9# later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program; see the file COPYING3. If not see 18# <http://www.gnu.org/licenses/>. 19 20# This Awk script reads in the option records generated from 21# opt-gather.awk, combines the flags of duplicate options and generates a 22# C header file. 23# 24# This program uses functions from opt-functions.awk 25# Usage: awk -f opt-functions.awk -f opth-gen.awk < inputfile > options.h 26 27BEGIN { 28 n_opts = 0 29 n_langs = 0 30 n_target_save = 0 31 n_extra_masks = 0 32 quote = "\042" 33 comma = "," 34 FS=SUBSEP 35} 36 37# Collect the text and flags of each option into an array 38 { 39 if ($1 == "Language") { 40 langs[n_langs] = $2 41 n_langs++; 42 } 43 else if ($1 == "TargetSave") { 44 # Make sure the declarations are put in source order 45 target_save_decl[n_target_save] = $2 46 n_target_save++ 47 } 48 else { 49 name = opt_args("Mask", $1) 50 if (name == "") { 51 opts[n_opts] = $1 52 flags[n_opts] = $2 53 help[n_opts] = $3 54 n_opts++; 55 } 56 else { 57 extra_masks[n_extra_masks++] = name 58 } 59 } 60 } 61 62# Dump out an enumeration into a .h file. 63# Combine the flags of duplicate options. 64END { 65print "/* This file is auto-generated by opth-gen.awk. */" 66print "" 67print "#ifndef OPTIONS_H" 68print "#define OPTIONS_H" 69print "" 70print "extern int target_flags;" 71print "extern int target_flags_explicit;" 72print "" 73 74have_save = 0; 75 76for (i = 0; i < n_opts; i++) { 77 if (flag_set_p("Save", flags[i])) 78 have_save = 1; 79 80 name = var_name(flags[i]); 81 if (name == "") 82 continue; 83 84 if (name in var_seen) 85 continue; 86 87 var_seen[name] = 1; 88 print "extern " var_type(flags[i]) name ";" 89} 90print "" 91 92# All of the optimization switches gathered together so they can be saved and restored. 93# This will allow attribute((cold)) to turn on space optimization. 94 95# Change the type of normal switches from int to unsigned char to save space. 96# Also, order the structure so that pointer fields occur first, then int 97# fields, and then char fields to provide the best packing. 98 99print "#if !defined(GCC_DRIVER) && !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS)" 100print "" 101print "/* Structure to save/restore optimization and target specific options. */"; 102print "struct GTY(()) cl_optimization"; 103print "{"; 104 105n_opt_char = 2; 106n_opt_short = 0; 107n_opt_int = 0; 108n_opt_other = 0; 109var_opt_char[0] = "unsigned char optimize"; 110var_opt_char[1] = "unsigned char optimize_size"; 111 112for (i = 0; i < n_opts; i++) { 113 if (flag_set_p("Optimization", flags[i])) { 114 name = var_name(flags[i]) 115 if(name == "") 116 continue; 117 118 if(name in var_opt_seen) 119 continue; 120 121 var_opt_seen[name]++; 122 otype = var_type_struct(flags[i]); 123 if (otype ~ "^((un)?signed +)?int *$") 124 var_opt_int[n_opt_int++] = otype name; 125 126 else if (otype ~ "^((un)?signed +)?short *$") 127 var_opt_short[n_opt_short++] = otype name; 128 129 else if (otype ~ "^((un)?signed +)?char *$") 130 var_opt_char[n_opt_char++] = otype name; 131 132 else 133 var_opt_other[n_opt_other++] = otype name; 134 } 135} 136 137for (i = 0; i < n_opt_other; i++) { 138 print " " var_opt_other[i] ";"; 139} 140 141for (i = 0; i < n_opt_int; i++) { 142 print " " var_opt_int[i] ";"; 143} 144 145for (i = 0; i < n_opt_short; i++) { 146 print " " var_opt_short[i] ";"; 147} 148 149for (i = 0; i < n_opt_char; i++) { 150 print " " var_opt_char[i] ";"; 151} 152 153print "};"; 154print ""; 155 156# Target and optimization save/restore/print functions. 157print "/* Structure to save/restore selected target specific options. */"; 158print "struct GTY(()) cl_target_option"; 159print "{"; 160 161n_target_char = 0; 162n_target_short = 0; 163n_target_int = 0; 164n_target_other = 0; 165 166for (i = 0; i < n_target_save; i++) { 167 if (target_save_decl[i] ~ "^((un)?signed +)?int +[_a-zA-Z0-9]+$") 168 var_target_int[n_target_int++] = target_save_decl[i]; 169 170 else if (target_save_decl[i] ~ "^((un)?signed +)?short +[_a-zA-Z0-9]+$") 171 var_target_short[n_target_short++] = target_save_decl[i]; 172 173 else if (target_save_decl[i] ~ "^((un)?signed +)?char +[_a-zA-Z0-9]+$") 174 var_target_char[n_target_char++] = target_save_decl[i]; 175 176 else 177 var_target_other[n_target_other++] = target_save_decl[i]; 178} 179 180if (have_save) { 181 for (i = 0; i < n_opts; i++) { 182 if (flag_set_p("Save", flags[i])) { 183 name = var_name(flags[i]) 184 if(name == "") 185 name = "target_flags"; 186 187 if(name in var_save_seen) 188 continue; 189 190 var_save_seen[name]++; 191 otype = var_type_struct(flags[i]) 192 if (otype ~ "^((un)?signed +)?int *$") 193 var_target_int[n_target_int++] = otype name; 194 195 else if (otype ~ "^((un)?signed +)?short *$") 196 var_target_short[n_target_short++] = otype name; 197 198 else if (otype ~ "^((un)?signed +)?char *$") 199 var_target_char[n_target_char++] = otype name; 200 201 else 202 var_target_other[n_target_other++] = otype name; 203 } 204 } 205} else { 206 var_target_int[n_target_int++] = "int target_flags"; 207} 208 209for (i = 0; i < n_target_other; i++) { 210 print " " var_target_other[i] ";"; 211} 212 213for (i = 0; i < n_target_int; i++) { 214 print " " var_target_int[i] ";"; 215} 216 217for (i = 0; i < n_target_short; i++) { 218 print " " var_target_short[i] ";"; 219} 220 221for (i = 0; i < n_target_char; i++) { 222 print " " var_target_char[i] ";"; 223} 224 225print "};"; 226print ""; 227print ""; 228print "/* Save optimization variables into a structure. */" 229print "extern void cl_optimization_save (struct cl_optimization *);"; 230print ""; 231print "/* Restore optimization variables from a structure. */"; 232print "extern void cl_optimization_restore (struct cl_optimization *);"; 233print ""; 234print "/* Print optimization variables from a structure. */"; 235print "extern void cl_optimization_print (FILE *, int, struct cl_optimization *);"; 236print ""; 237print "/* Save selected option variables into a structure. */" 238print "extern void cl_target_option_save (struct cl_target_option *);"; 239print ""; 240print "/* Restore selected option variables from a structure. */" 241print "extern void cl_target_option_restore (struct cl_target_option *);"; 242print ""; 243print "/* Print target option variables from a structure. */"; 244print "extern void cl_target_option_print (FILE *, int, struct cl_target_option *);"; 245print "#endif"; 246print ""; 247 248for (i = 0; i < n_opts; i++) { 249 name = opt_args("Mask", flags[i]) 250 vname = var_name(flags[i]) 251 mask = "MASK_" 252 if (vname != "") { 253 mask = "OPTION_MASK_" 254 } 255 if (name != "" && !flag_set_p("MaskExists", flags[i])) 256 print "#define " mask name " (1 << " masknum[vname]++ ")" 257} 258for (i = 0; i < n_extra_masks; i++) { 259 print "#define MASK_" extra_masks[i] " (1 << " masknum[""]++ ")" 260} 261 262for (var in masknum) { 263 if (masknum[var] > 31) { 264 if (var == "") 265 print "#error too many target masks" 266 else 267 print "#error too many masks for " var 268 } 269} 270print "" 271 272for (i = 0; i < n_opts; i++) { 273 name = opt_args("Mask", flags[i]) 274 vname = var_name(flags[i]) 275 macro = "OPTION_" 276 mask = "OPTION_MASK_" 277 if (vname == "") { 278 vname = "target_flags" 279 macro = "TARGET_" 280 mask = "MASK_" 281 } 282 if (name != "" && !flag_set_p("MaskExists", flags[i])) 283 print "#define " macro name \ 284 " ((" vname " & " mask name ") != 0)" 285} 286for (i = 0; i < n_extra_masks; i++) { 287 print "#define TARGET_" extra_masks[i] \ 288 " ((target_flags & MASK_" extra_masks[i] ") != 0)" 289} 290print "" 291 292for (i = 0; i < n_opts; i++) { 293 opt = opt_args("InverseMask", flags[i]) 294 if (opt ~ ",") { 295 vname = var_name(flags[i]) 296 macro = "OPTION_" 297 mask = "OPTION_MASK_" 298 if (vname == "") { 299 vname = "target_flags" 300 macro = "TARGET_" 301 mask = "MASK_" 302 } 303 print "#define " macro nth_arg(1, opt) \ 304 " ((" vname " & " mask nth_arg(0, opt) ") == 0)" 305 } 306} 307print "" 308 309for (i = 0; i < n_langs; i++) { 310 macros[i] = "CL_" langs[i] 311 gsub( "[^A-Za-z0-9_]", "X", macros[i] ) 312 s = substr(" ", length (macros[i])) 313 print "#define " macros[i] s " (1 << " i ")" 314 } 315print "#define CL_LANG_ALL ((1 << " n_langs ") - 1)" 316 317print "" 318print "enum opt_code" 319print "{" 320 321for (i = 0; i < n_opts; i++) 322 back_chain[i] = "N_OPTS"; 323 324for (i = 0; i < n_opts; i++) { 325 # Combine the flags of identical switches. Switches 326 # appear many times if they are handled by many front 327 # ends, for example. 328 while( i + 1 != n_opts && opts[i] == opts[i + 1] ) { 329 flags[i + 1] = flags[i] " " flags[i + 1]; 330 i++; 331 } 332 333 len = length (opts[i]); 334 enum = "OPT_" opts[i] 335 if (opts[i] == "finline-limit=" || opts[i] == "Wlarger-than=" \ 336 || opts[i] == "ftemplate-depth=") 337 enum = enum "eq" 338 if (opts[i] == "gdwarf+") 339 enum = "OPT_gdwarfplus" 340 gsub ("[^A-Za-z0-9]", "_", enum) 341 342 # If this switch takes joined arguments, back-chain all 343 # subsequent switches to it for which it is a prefix. If 344 # a later switch S is a longer prefix of a switch T, T 345 # will be back-chained to S in a later iteration of this 346 # for() loop, which is what we want. 347 if (flag_set_p("Joined.*", flags[i])) { 348 for (j = i + 1; j < n_opts; j++) { 349 if (substr (opts[j], 1, len) != opts[i]) 350 break; 351 back_chain[j] = enum; 352 } 353 } 354 355 s = substr(" ", length (enum)) 356 if (i + 1 == n_opts) 357 comma = "" 358 359 if (help[i] == "") 360 hlp = "0" 361 else 362 hlp = "N_(\"" help[i] "\")"; 363 364 print " " enum "," s "/* -" opts[i] " */" 365} 366 367print " N_OPTS" 368print "};" 369print "" 370print "#endif /* OPTIONS_H */" 371} 372