OpenADFortTk (including Open64 and OpenAnalysis references)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
config.cxx
Go to the documentation of this file.
1 
2 /*
3 
4  Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved.
5 
6  This program is free software; you can redistribute it and/or modify it
7  under the terms of version 2 of the GNU General Public License as
8  published by the Free Software Foundation.
9 
10  This program is distributed in the hope that it would be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 
14  Further, this software is distributed without any warranty that it is
15  free of the rightful claim of any third person regarding infringement
16  or the like. Any license provided herein, whether implied or
17  otherwise, applies only to this software file. Patent licenses, if
18  any, provided herein do not apply to combinations of this program with
19  other software, or any other product whatsoever.
20 
21  You should have received a copy of the GNU General Public License along
22  with this program; if not, write the Free Software Foundation, Inc., 59
23  Temple Place - Suite 330, Boston MA 02111-1307, USA.
24 
25  Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky,
26  Mountain View, CA 94043, or:
27 
28  http://www.sgi.com
29 
30  For further information regarding this notice, see:
31 
32  http://oss.sgi.com/projects/GenInfo/NoticeExplan
33 
34 */
35 
36 /* ====================================================================
37  * ====================================================================
38  *
39  *
40  * Revision history:
41  * 06-Jun-90 - Original Version (moved from cdriver.c)
42  * 01-Feb-91 - Copied for TP/Muse
43  * 15-Jun-91 - Restructured and integrated Josie
44  * 05-May-96 - Added -WOPT group.
45  *
46  * Description:
47  *
48  * Configuration data and routines to set up configuration.
49  *
50  * Refer to the discussion in config.h for the distribution of such
51  * data and processing among the various configuration files.
52  *
53  * ====================================================================
54  * ====================================================================
55  */
56 
57 #ifdef _KEEP_RCS_ID
58 /*REFERENCED*/
59 #endif /* _KEEP_RCS_ID */
60 
61 
62 #define USE_STANDARD_TYPES 1
63 #include "defs.h"
64 #undef USE_STANDARD_TYPES
65 
66 #ifdef FRONT_END /* For setting fullwarn, woff in front end */
67 # ifndef FRONT_F90
68 # ifdef EDGSRC
69 # include "basics.h"
70 # include "cmd_line.h"
71 # include "error.h"
72 # endif /* EDGSRC */
73 # endif /* ~FRONT_F90 */
74 #endif /* FRONT_END */
75 #include <ctype.h> // For isdigit
76 #include <elf.h> // Open64 version
77 
78 #include "x_string.h" // for strcasecmp()
79 #include "em_elf.h"
80 #include "config.h"
81 #include "config_platform.h"
82 #include "config_targ.h"
83 #include "erglob.h"
84 #include "flags.h"
85 #include "tracing.h"
86 #include "glob.h"
87 #include "symtab.h"
88 #include "wn.h"
89 
90 #ifndef BACK_END
91  static INT32 Ignore_Int;
92 #endif
93 
94 /* The following contains the phase-specific option groups and their
95  * associated variable definitions:
96  */
97 #include "config_targ2.cxx"
98 #include "config_debug.cxx"
99 #include "config_ipa.cxx"
100 #include "config_list.cxx"
101 #include "config_opt.cxx"
102 #include "config_wopt.cxx"
103 #include "config_vho.cxx"
104 #include "config_flist.cxx"
105 #include "config_clist.cxx"
106 #include "config_purple.cxx"
107 #include "config_promp.cxx"
108 
109 #ifdef BACK_END
110 # include "config_lno.cxx"
111 # include "instr_reader.h"
112 #endif
113 
114 /* IR builder sometimes needs to know whether we're in front end: */
115 #ifdef SINGLE_PROCESS
116 INT16 In_Front_End = TRUE; /* Start out there */
117 #endif
118 
119 /* ====================================================================
120  *
121  * Global option flags
122  *
123  * ====================================================================
124  */
125 
126 /***** General optimization control *****/
127 BOOL Enable_LOH = FALSE; /* Do loop overhead processing? */
128 BOOL Enable_LOH_overridden = FALSE; /* ... option seen? */
129 BOOL CSE_Elim_Enabled = FALSE; /* Is CSE-elim on? -- this does
130  * not control it, it just
131  * shadows the opt. level
132  */
133 
134 #ifdef BACK_END
135 # define DEF_DEBUG_LEVEL 0
136 INT8 Debug_Level = DEF_DEBUG_LEVEL; /* -gn: debug level */
137 #endif
138 
139 
140 /***** Alignment (misaligned memory reference) control *****/
141 BOOL UseAlignedCopyForStructs = FALSE; /* control aggregrate copy */
142 INT32 MinStructCopyLoopSize = 16; /* 0 = always expand */
143 INT32 MinStructCopyMemIntrSize= 0; /* generate bcopy */
144 INT32 Aggregate_Alignment = -1; /* This alignment for aggregate layout */
145 
147 
148 /***** Pointer optimizations, such as treating pointers as arrays *****/
150 
151 /***** Put all-zero initialized file-level data in the BSS section? *****/
153 
154 /* don't make strings gp-relative (to save gp space) */
156 
157 /***** IEEE 754 options *****/
158 IEEE_LEVEL IEEE_Arithmetic = IEEE_ACCURATE; /* IEEE arithmetic? */
159 BOOL IEEE_Arith_Set = FALSE; /* ... option seen? */
160 /* BOOL Force_IEEE_Comparisons = FALSE; */ /* IEEE NaN comparisons? */
161  /* Moved to ISA/config_targ.cxx */
162 
163 /***** Speculation eagerness options *****/
164 EAGER_LEVEL Eager_Level = EAGER_SAFE; /* Eagerness to use: -Xn */
165 static BOOL Eager_Level_Set = FALSE; /* ... option seen? */
166 
167 /***** Constant folding and WHIRL simplifier options *****/
168 ROUNDOFF Roundoff_Level = ROUNDOFF_NONE;/* -OPT_roundoff=n value */
169 BOOL Roundoff_Set = FALSE; /* ... option seen? */
170 BOOL Fast_Complex_Allowed = FALSE; /* Fast c_div and c_abs? */
171 BOOL Fast_Complex_Set = FALSE; /* ... option seen? */
172 BOOL Fast_Bit_Allowed = FALSE; /* Fast inlined bit intrinsics? */
173 BOOL Fast_Bit_Set = FALSE; /* ... option seen? */
174 BOOL Fast_NINT_Allowed = FALSE; /* Fast NINT and ANINT? */
175 BOOL Fast_NINT_Set = FALSE; /* ... option seen? */
176 BOOL Fast_trunc_Allowed = FALSE; /* Fast truncs for NINT/ANINT/AINT/AMOD? */
177 BOOL Fast_trunc_Set = FALSE; /* ... option seen? */
178 BOOL Inline_Intrinsics_Allowed = TRUE; /* Inline intrinsics? Or lib calls? */
179 BOOL Inline_Intrinsics_Set = FALSE; /* ... option seen? */
180 BOOL Regions_Around_Inner_Loops = FALSE;/* Put REGIONs around inner loops? */
181 BOOL Region_Boundary_Info = FALSE; /* calc boundary info for regions */
182 BOOL Simp_Multiply_To_Shift=FALSE; /* Convert multiplies to shifts */
183 BOOL Enable_NaryExpr= FALSE; /* allow nary expression in the lowerer */
184 BOOL Enable_NaryExpr_Set = FALSE; /* ... option seen? */
185 
186 /***** LANGuage group options *****/
187 static char *Language_Name = NULL; /* Source language name */
188 LANGUAGE Language = LANG_UNKNOWN; /* See language.h */
229 
242 
243 /***** INTERNAL group options *****/
244 
250 #ifdef TARG_IA64
252 #else
254 #endif
262 
267 
268 /***** F90 Heap/stack allocation threshold */
269 INT32 Heap_Allocation_Threshold=-1; /* Allocate objects > this on the heap
270  * (-1 means always use stack), 0 always use heap
271  * default is -1
272  */
273 
274 /***** Miscellaneous code generation options *****/
275 INT32 Short_Data = DEF_SDATA_ELT_SIZE; /* Objects of this size in .sdata */
276 static BOOL Short_Data_Set = FALSE; /* ... option seen? */
277 INT32 Short_Lits = DEF_SDATA_ELT_SIZE; /* Literals of this size in .litX */
278 static BOOL Short_Lits_Set = FALSE; /* ... option seen? */
280 BOOL Constant_GP = FALSE; /* gp never changes? */
281 
282 /* ====================================================================
283  *
284  * Option groups (see flags.h)
285  *
286  * When defining a new option group, remember to not only add an
287  * option descriptor list (e.g. Options_TENV), but also to add an
288  * entry describing the group in Common_Option_Groups, below.
289  *
290  * ====================================================================
291  */
292 
293 /* Temporary variables used for holding GOT size options during option
294  * processing until Guaranteed_Small_GOT can be set properly:
295  */
299 
300 /* Always force EH Region offsets to be long */
302 /* Force stack frame to use large model */
304 BOOL Force_GP_Prolog; /* force usage of gp prolog */
305 
307 
308 /* Unique ident from IPA */
310 
312 
313 /* Target environment options: */
315  { OVK_INT32, OV_VISIBLE, FALSE, "align_aggregates", "align_ag",
316  -1, 0, 16, &Aggregate_Alignment, NULL,
317  "Minimum alignment to use for aggregates (structs/arrays)" },
318  { OVK_BOOL, OV_INTERNAL, FALSE, "aligned_copy", NULL,
319  0, 0, 0, &UseAlignedCopyForStructs, NULL },
320  { OVK_BOOL, OV_SHY, FALSE, "call_mcount", NULL,
321  0, 0, 0, &Call_Mcount, NULL },
322  { OVK_BOOL, OV_SHY, FALSE, "constant_gp", NULL,
323  0, 0, 0, &Constant_GP, NULL },
324  { OVK_BOOL, OV_SHY, FALSE, "cpic", "cp",
325  0, 0, 0, &Gen_PIC_Call_Shared, NULL,
326  "Generate code for executable programs which may call DSOs" },
327  { OVK_BOOL, OV_VISIBLE, FALSE, "fixed_addresses", "fi",
328  0, 0, 0, &PIC_Fixed_Addresses, NULL },
329  { OVK_INT32, OV_SHY, FALSE, "Gspace", NULL,
331  "Maximum GP-relative space available" },
332  { OVK_UINT32, OV_INTERNAL, FALSE, "ipa_ident", NULL,
334  "Specify IPA timestamp number" },
335  { OVK_BOOL, OV_VISIBLE, FALSE, "kernel", NULL,
336  0, 0, 0, &Kernel_Code, NULL,
337  "Generate code for kernel use" },
338  { OVK_BOOL, OV_VISIBLE, FALSE, "large_GOT", "",
339  0, 0, 0, &Use_Large_GOT, NULL,
340  "Assume GOT is larger than 64K bytes" },
341  { OVK_NAME, OV_SHY, FALSE, "io_library", NULL,
342  0, 0, 0, &Library_Name, NULL },
343  { OVK_BOOL, OV_INTERNAL, FALSE, "large_stack", NULL,
344  0, 0, 0, &Force_Large_Stack_Model, NULL,
345  "Generate code assuming >32KB stack frame" },
346  { OVK_BOOL, OV_VISIBLE, FALSE, "local_names", "",
347  0, 0, 0, &PIC_Local_Names, NULL },
348  { OVK_BOOL, OV_SHY, FALSE, "long_eh_offsets", "long_eh",
349  0, 0, 0, &Force_Long_EH_Range_Offsets, NULL },
350  { OVK_BOOL, OV_INTERNAL, FALSE, "non_volatile_GOT", "non_v",
351  0, 0, 0, &Non_Volatile_GOT, NULL,
352  "Assume GOT is non-volatile" },
353  { OVK_BOOL, OV_INTERNAL, FALSE, "no_page_offset", "no_p",
354  0, 0, 0, &PIC_No_Page_Offset, NULL,
355  "Don't use GOT page/offset addressing" },
356  { OVK_BOOL, OV_SHY, FALSE, "pic2", "pi",
357  0, 0, 0, &Gen_PIC_Shared, NULL,
358  "Generate position-independent code suitable for DSOs" },
359  { OVK_BOOL, OV_SHY, FALSE, "pic1", NULL,
360  0, 0, 0, &Gen_PIC_Call_Shared, NULL,
361  "Generate code for executable programs which may call DSOs" },
362  { OVK_BOOL, OV_SHY, FALSE, "profile_call", "prof",
363  0, 0, 0, &Gen_Profile, NULL },
364  { OVK_NAME, OV_SHY, FALSE, "profile_name", "",
365  0, 0, 0, &Gen_Profile_Name, NULL },
366  { OVK_BOOL, OV_VISIBLE, FALSE, "protected_names", "",
367  0, 0, 0, &PIC_Protected_Names, NULL },
368  { OVK_INT32, OV_INTERNAL, FALSE, "short_data", "short_d",
369  0, 0, 4096, &Short_Data, &Short_Data_Set,
370  "Maximum size of data to allocate GP-relative" },
371  { OVK_INT32, OV_INTERNAL, FALSE, "short_literals", "short_l",
372  0, 0, 1024, &Short_Lits, &Short_Lits_Set,
373  "Maximum size of literals to allocate GP-relative" },
374  { OVK_BOOL, OV_VISIBLE, FALSE, "small_GOT", "sm",
375  0, 0, 0, &Use_Small_GOT, NULL,
376  "Assume GOT is smaller than 64K bytes" },
377  { OVK_INT32, OV_INTERNAL, FALSE, "struct_copy_loop_size", "struct_copy_loop",
378  -1, 0, 4096, &MinStructCopyLoopSize, NULL },
379  { OVK_INT32, OV_INTERNAL, FALSE, "struct_copy_mem_intr_size", "struct_copy_mem",
380  -1, 0, 4096, &MinStructCopyMemIntrSize, NULL },
381  { OVK_INT32, OV_VISIBLE, FALSE, "X", NULL,
382  1, 0, 4, &Eager_Level, &Eager_Level_Set,
383  "Exception-enable level" },
384  { OVK_BOOL, OV_VISIBLE, FALSE, "zeroinit_in_bss", NULL,
385  0, 0, 0, &Zeroinit_in_bss, NULL,
386  "Place zero-initialized data in .bss section" },
387  { OVK_BOOL, OV_SHY, FALSE, "strings_not_gprelative", "strings_not_gprel",
388  0, 0, 0, &Strings_Not_Gprelative, NULL,
389  "Do not put any strings in gp-relative sections" },
390  { OVK_NAME, OV_SHY, FALSE, "emit_global_data", "emit_global",
391  0, 0, 0, &Emit_Global_Data, NULL,
392  "only process the global data" },
393  { OVK_NAME, OV_SHY, FALSE, "read_global_data", "read_global",
394  0, 0, 0, &Read_Global_Data, NULL,
395  "only read the already-processed global data" },
396  { OVK_BOOL, OV_SHY, FALSE, "force_gp_prolog", "force_gp",
397  0, 0, 0, &Force_GP_Prolog, NULL,
398  "force gp_prolog to always be setup" },
399  { OVK_LIST, OV_VISIBLE, FALSE, "registers_not_allocatable", NULL,
400  0, 0, 0, &Registers_Not_Allocatable, NULL,
401  "list of registers that are reserved and not available for allocation" },
402 
403  /***** Options moved elsewhere -- retained for compatibility: *****/
404  /* See -DEBUG:div_check */
405  { OVK_INT32, OV_INTERNAL, FALSE, "check_div", "check_div",
407  /* See -DEBUG:trap_uninitialized */
408  { OVK_BOOL, OV_INTERNAL, FALSE, "trapuv", "",
410  /* See -DEBUG:trapuv_right_justify */
411  { OVK_BOOL, OV_INTERNAL, FALSE, "trapuv_right_justify", "trapuv_right",
414 
415  /***** Options moved elsewhere -- replaced: *****/
416  /* See -DEBUG:varargs_prototypes */
417  { OVK_REPLACED, OV_INTERNAL, FALSE, "varargs_prototypes", "varargs_p",
418  0, 0, 0,
419  const_cast<char*>("-DEBUG:varargs_prototypes"), NULL },
420 
421  /***** Obsolete options: *****/
422  { /* OVK_INT32, */
423  OVK_OBSOLETE, OV_INTERNAL, FALSE, "align_extern", NULL,
424  0, 0, 16, NULL, NULL,
425  "Assume this alignment for unknown objects" },
426  { /* OVK_BOOL, */
427  OVK_OBSOLETE, OV_SHY, FALSE, "aligned", NULL,
428  0, 0, 0, NULL, NULL,
429  "Assume unknown objects are properly aligned" },
430  { /* OVK_INT32, */
431  OVK_OBSOLETE, OV_INTERNAL, FALSE, "misalignment", NULL,
432  3, 0, 3, NULL, NULL },
433  { OVK_INT32, OV_INTERNAL, FALSE, "iolist_reuse", "iolist_reuse",
434  100, 1, INT32_MAX, &iolist_reuse_limit, NULL,
435  "Maximum number of iolists which will share stack space" },
436 
437  { OVK_COUNT } /* List terminator -- must be last */
438 };
439 
440 #ifdef BACK_END
441 
442 /* Phase selection options: */
444  { OVK_BOOL, OV_INTERNAL, FALSE, "lno", "l", 0, 0, 0,
445  &Run_lno, NULL},
446  { OVK_BOOL, OV_INTERNAL, FALSE, "wopt", "w", 0, 0, 0,
447  &Run_wopt, NULL},
448  { OVK_BOOL, OV_INTERNAL, FALSE, "preopt", "p", 0, 0, 0,
449  &Run_preopt, NULL},
450  { OVK_BOOL, OV_INTERNAL, FALSE, "cg", "c", 0, 0, 0,
451  &Run_cg, NULL},
452  { OVK_BOOL, OV_INTERNAL, FALSE, "clist", NULL, 0, 0, 0,
453  &Run_w2c, NULL},
454  { OVK_BOOL, OV_INTERNAL, FALSE, "flist", NULL, 0, 0, 0,
455  &Run_w2f, NULL},
456  { OVK_BOOL, OV_INTERNAL, FALSE, "mplist", NULL, 0, 0, 0,
457  &Run_w2fc_early, NULL},
458  { OVK_BOOL, OV_INTERNAL, FALSE, "purple", "", 0, 0, 0,
459  &Run_purple, NULL},
460  { OVK_BOOL, OV_INTERNAL, FALSE, "ipl", "i", 0, 0, 0,
461  &Run_ipl, NULL},
462  { OVK_BOOL, OV_INTERNAL, FALSE, "prompf", NULL, 0, 0, 0,
463  &Run_prompf, NULL},
464  { OVK_NAME, OV_INTERNAL, FALSE, "lpath", "", 0, 0, 0,
465  &LNO_Path, NULL},
466  { OVK_NAME, OV_INTERNAL, FALSE, "wpath", "", 0, 0, 0,
467  &WOPT_Path, NULL},
468  { OVK_NAME, OV_INTERNAL, FALSE, "cpath", "", 0, 0, 0,
469  &CG_Path, NULL},
470  { OVK_NAME, OV_INTERNAL, FALSE, "w2cpath", "", 0, 0, 0,
471  &W2C_Path, NULL},
472  { OVK_NAME, OV_INTERNAL, FALSE, "w2fpath", "", 0, 0, 0,
473  &W2F_Path, NULL},
474  { OVK_NAME, OV_INTERNAL, FALSE, "purpath", "", 0, 0, 0,
475  &Purple_Path, NULL},
476  { OVK_NAME, OV_INTERNAL, FALSE, "ipath", "", 0, 0, 0,
477  &Ipl_Path, NULL},
478  { OVK_NAME, OV_INTERNAL, FALSE, "tpath", "", 0, 0, 0,
479  &Targ_Path, NULL},
480  { OVK_NAME, OV_INTERNAL, FALSE, "prompf_anl_path", "", 0, 0, 0,
482  { OVK_COUNT}
483 };
484 #elif defined(QIKKI_BE)
485 static OPTION_DESC Options_PHASE[] = {
486  { OVK_NAME, OV_INTERNAL, FALSE, "tpath", "t", 0, 0, 0,
487  &Targ_Path, NULL},
488  { OVK_COUNT}
489 };
490 #endif /* BACK_END */
491 
493  { OVK_NAME, OV_INTERNAL, FALSE, "", NULL,
494  0, 0, 0, &Language_Name, NULL,
495  "Language being compiled, from front end" },
496  { OVK_BOOL, OV_VISIBLE, FALSE, "bool", "",
497  0, 0, 0, &CXX_Bool_On, &CXX_Bool_Set,
498  "C++: enable builtin type 'bool'" },
499  { OVK_BOOL, OV_VISIBLE, FALSE, "exceptions", "",
501  "C++: enable exceptions" },
502 #if 0 // remove it till we have a robust design
503  { OVK_BOOL, OV_SHY, FALSE, "alias_const", "",
504  0, 0, 0, &CXX_Alias_Const, &CXX_Alias_Const_Set },
505 #endif
506  { OVK_BOOL, OV_VISIBLE, FALSE, "recursive", "",
508  "FORTRAN: program contains recursion" },
509  { OVK_BOOL, OV_VISIBLE, FALSE, "wchar_t", "",
510  0, 0, 0, &CXX_Wchar_On, &CXX_Wchar_Set,
511  "C++: enable builtin type 'wchar_t'" },
512  { OVK_BOOL, OV_VISIBLE, FALSE, "namespaces", "namespace",
514  "C++: enable namespaces" },
515  { OVK_BOOL, OV_VISIBLE, FALSE, "ansi-for-init-scope", "",
517  { OVK_BOOL, OV_VISIBLE, FALSE, "std", "",
519  { OVK_BOOL, OV_SHY, FALSE, "restrict", "",
520  0, 0, 0, &C_Restrict_On, &C_Restrict_Set },
521  { OVK_NAME, OV_VISIBLE, FALSE, "autorestrict", NULL,
523  "Automatically set the \"restrict\" qualifier on some or all pointers" },
524  { OVK_BOOL, OV_INTERNAL, FALSE, "scalar_formal_ref", "",
525  0, 0, 0, &Scalar_Formal_Ref, NULL },
526  { OVK_BOOL, OV_INTERNAL, FALSE, "non_scalar_formal_ref", "",
527  0, 0, 0, &Non_Scalar_Formal_Ref, NULL },
528  { OVK_BOOL, OV_INTERNAL, FALSE, "short_circuit_conditionals", "",
530  { OVK_BOOL, OV_VISIBLE, FALSE, "vla", "",
531  0, 0, 0, &C_VLA_On, &C_VLA_Set,
532  "C/C++: enable variable length arrays" },
533  { OVK_BOOL, OV_VISIBLE, FALSE, "explicit", "",
534  0, 0, 0, &CXX_Explicit_On, &CXX_Explicit_Set,
535  "C++: enable explicit keyword" },
536  { OVK_BOOL, OV_VISIBLE, FALSE, "typename", "",
537  0, 0, 0, &CXX_Typename_On, &CXX_Typename_Set,
538  "C++: enable typename keyword" },
539  { OVK_BOOL, OV_VISIBLE, FALSE, "mutable", "",
540  0, 0, 0, &CXX_Mutable_On, &CXX_Mutable_Set,
541  "C++: enable mutable keyword" },
542  { OVK_BOOL, OV_VISIBLE, FALSE, "macro_expand_pragmas", "",
544  "C/C++: enable macro expansion in pragmas" },
545  { OVK_BOOL, OV_VISIBLE, FALSE, "packed", "",
546  0, 0, 0, &CXX_Packed_On, &CXX_Packed_Set,
547  "C++: enable pragma pack" },
548  { OVK_BOOL, OV_INTERNAL, FALSE, "symtab_verify", "",
550  { OVK_BOOL, OV_VISIBLE, FALSE, "pch", NULL,
551  0, 0, 0, &LANG_Pch, &LANG_Pch_Set,
552  "Create a precompiled header for this compilation unit" },
553  { OVK_NAME, OV_VISIBLE, FALSE, "create_pch", NULL,
555  "Create a precompiled header file named by this option" },
556  { OVK_NAME, OV_VISIBLE, FALSE, "use_pch", NULL,
557  0, 0, 0, &LANG_Use_Pch, &LANG_Use_Pch_Set,
558  "Use the precompiled header file named by this option" },
559  { OVK_NAME, OV_VISIBLE, FALSE, "pch_dir", NULL,
560  0, 0, 0, &LANG_Pchdir, &LANG_Pchdir_Set,
561  "Create/Use from the directory named by this option" },
562  { OVK_BOOL, OV_VISIBLE, FALSE, "ansi_setjmp", "",
564  "C/C++: enable optimization of functions with calls to setjmp" },
565  { OVK_BOOL, OV_VISIBLE, FALSE, "microsoft_extensions", "microsoft_extension",
567 
568  { OVK_INT32,OV_VISIBLE, TRUE, "heap_allocation_threshold", "heap_a",
570  "Size threshold for switching from stack to heap allocation" },
571  { OVK_NAME, OV_VISIBLE, FALSE, "cxx_dialect", NULL,
573  { OVK_BOOL, OV_VISIBLE, FALSE, "ignore_carriage_return", "",
575  "C/C++: ignore carriage returns in source" },
576 
577 
578  { OVK_COUNT } /* List terminator -- must be last */
579 };
580 
582 
583  { OVK_BOOL, OV_INTERNAL, FALSE, "comma_rcomma", "",
585  { OVK_BOOL, OV_INTERNAL, FALSE, "merge_types", "",
587  { OVK_BOOL, OV_INTERNAL, FALSE, "mtype_a", NULL,
588  0, 0, 0, &WHIRL_Mtype_A_On, NULL },
589  { OVK_BOOL, OV_INTERNAL, FALSE, "mtype_b", NULL,
590  0, 0, 0, &WHIRL_Mtype_B_On, NULL },
591  { OVK_BOOL, OV_INTERNAL, FALSE, "mtype_bs", NULL,
592  0, 0, 0, &WHIRL_Mtype_BS_On, NULL },
593  { OVK_BOOL, OV_INTERNAL, FALSE, "return_val", NULL,
594  0, 0, 0, &WHIRL_Return_Val_On, NULL },
595  { OVK_BOOL, OV_INTERNAL, FALSE, "flatten_field", NULL,
596  0, 0, 0, &WHIRL_Flatten_Field_On, NULL },
597  { OVK_BOOL, OV_INTERNAL, FALSE, "mldid_mstid", NULL,
598  0, 0, 0, &WHIRL_Mldid_Mstid_On, NULL },
599  { OVK_BOOL, OV_INTERNAL, FALSE, "vfcall", NULL,
600  0, 0, 0, &WHIRL_Vfcall_On, NULL },
601  { OVK_BOOL, OV_INTERNAL, FALSE, "addr_passed", NULL,
602  0, 0, 0, &WHIRL_Addr_Passed_On, NULL },
603  { OVK_BOOL, OV_INTERNAL, FALSE, "addr_saved_for_passed", NULL,
604  0, 0, 0, &WHIRL_Addr_Saved_For_Passed_On, NULL },
605  { OVK_BOOL, OV_INTERNAL, FALSE, "addr_saved", NULL,
606  0, 0, 0, &WHIRL_Addr_Saved_On, NULL },
607  { OVK_BOOL, OV_INTERNAL, FALSE, "keep_cvt", NULL,
608  0, 0, 0, &WHIRL_Keep_Cvt_On, NULL },
609  { OVK_BOOL, OV_INTERNAL, FALSE, "return_info", NULL,
610  0, 0, 0, &WHIRL_Return_Info_On, NULL },
611  { OVK_BOOL, OV_INTERNAL, FALSE, "global_pragmas", NULL,
612  0, 0, 0, &Global_Pragmas_In_Dummy_PU_On, NULL },
613  { OVK_BOOL, OV_INTERNAL, FALSE, "malloc_free", NULL,
614  0, 0, 0, &Malloc_Free_On, NULL },
615  { OVK_BOOL, OV_INTERNAL, FALSE, "alloca_dealloca", NULL,
616  0, 0, 0, &Alloca_Dealloca_On, NULL },
617  { OVK_BOOL, OV_INTERNAL, FALSE, "barrier_lvalues", NULL,
618  0, 0, 0, &Barrier_Lvalues_On, NULL },
619  { OVK_BOOL, OV_INTERNAL, FALSE, "mask_shift_counts", NULL,
620  0, 0, 0, &ARCH_mask_shift_counts, NULL },
621  { OVK_BOOL, OV_INTERNAL, FALSE, "generate_nor", NULL,
622  0, 0, 0, &ARCH_generate_nor, NULL },
623 
624  { OVK_COUNT } /* List terminator -- must be last */
625 };
626 
628  { "DEBUG", ':', '=', Options_DEBUG, NULL,
629  "Options to assist debugging" },
630  { "INLINE", ':', '=', Options_INLINE, NULL,
631  "Options to control subprogram inlining" },
632  { "INTERNAL", ':', '=', Options_INTERNAL, NULL,
633  "Options to control internal flags for testing" },
634  { "IPA", ':', '=', Options_IPA, NULL,
635  "Options to control interprocedural analysis and optimization" },
636  { "LANG", ':', '=', Options_LANG, NULL,
637  "Options to control source language interpretation" },
638  { "LIST", ':', '=', Options_LIST, NULL,
639  "Options to control the listing file" },
640  { "OPT", ':', '=', Options_OPT, NULL,
641  "Options to control general optimization" },
642 #ifdef BACK_END
643  { "LNO", ':', '=', Options_LNO, NULL,
644  "Options to control loop nest optimization" },
645 #endif /* BACK_END */
646 #if defined(BACK_END) || defined(QIKKI_BE)
647  { "PHASE", ':', '=', Options_PHASE, NULL,
648  "Options to control phase invocation and locations" },
649 #endif /* defined(BACK_END) || defined(QIKKI_BE) */
650  { "TARG", ':', '=', Options_TARG, NULL,
651  "Options to specify the target machine characteristics" },
652  { "TENV", ':', '=', Options_TENV, NULL,
653  "Options to set or assert target environment characteristics" },
654  { "WOPT", ':', '=', Options_WOPT, NULL,
655  "Options to control internal WHIRL optimization" },
656  { "VHO", ':', '=', Options_VHO, NULL,
657  "Options to control internal VH WHIRL optimization" },
658  { "FLIST", ':', '=', Options_FLIST, NULL,
659  "Options to control listing of transformed f77 source" },
660  { "CLIST", ':', '=', Options_CLIST, NULL,
661  "Options to control listing of transformed C source" },
662  { "PURPLE", ':', '=', Options_PURPLE, NULL,
663  "Options to control program region extraction process" },
664  { "PROMP", ':', '=', Options_PROMP, NULL,
665  "Options to control listing mp transformations" },
666  { NULL } /* List terminator -- must be last */
667 };
668 
669 /* ====================================================================
670  *
671  * Miscellaneous data declarations and initialization
672  *
673  * ====================================================================
674  */
675 
676 /* What is the model to be used for logical values in Fortran? */
678 
679 /* Is exception-handling enabled in C++? */
681 
682 /***** Compiler debug/trace options *****/
683 BOOL Tracing_Enabled = FALSE; /* Any trace options set? */
684 
685 /***** Miscellaneous optimization options *****/
686 /* Should idict commute operands in seeking match? */
688 BOOL Scalar_Formal_Ref = TRUE; /* for fortran scalar formal refs */
689 BOOL Non_Scalar_Formal_Ref = FALSE; /* for fortran non_scalar formal refs */
690 
691 BOOL CG_mem_intrinsics = TRUE; /* for memory intrinsic expansion */
692 INT32 CG_memmove_inst_count = 16; /* for intrinsic expansion of bzero etc */
694 BOOL CG_bcopy_cannot_overlap = FALSE; /* for intrinsic expansion of bcopy */
695 BOOL CG_memcpy_cannot_overlap = FALSE; /* for intrinsic expansion of memcpy */
696 BOOL CG_memmove_cannot_overlap = FALSE; /* for intrinsic expansion of memmove */
697 BOOL CG_memmove_nonconst = FALSE; /* expand mem intrinsics unknown size */
698 
699 /***** Miscellaneous GOPT options *****/
701 INT32 OPT_unroll_times = 4; /* but see Configure_Target() */
703 INT32 OPT_unroll_size = 40; /* but see Configure_CG_Options() */
708 BOOL Enable_SWP = FALSE; /* but see cgdriver.c */
710 
711 /***** What is the byte sex of the host and target? *****/
712 UINT8 Host_Byte_Sex = BIG_ENDIAN; /* Set in config_host.c */
713 UINT8 Target_Byte_Sex = BIG_ENDIAN; /* Set in config_targ.c */
714 BOOL Same_Byte_Sex = TRUE; /* Set in config_targ.c */
715 
716 /***** Miscellaneous code generation options *****/
717 BOOL Use_Base_Ptrs = TRUE; /* Explicit ptrs to .DATA./.RDATA? */
720 BOOL Gen_PIC_Calls = FALSE; /* PIC calls */
721 BOOL Guaranteed_Small_GOT = TRUE; /* GOT < 64kB? */
722 BOOL Non_Volatile_GOT = FALSE; /* GOT entries volatile? */
723 BOOL PIC_Local_Names = FALSE; /* Names local by default? */
724 BOOL PIC_Protected_Names = FALSE; /* Names protected by default? */
725 BOOL PIC_Fixed_Addresses = FALSE; /* Names fixed by default? */
726 BOOL PIC_No_Page_Offset = FALSE; /* Don't use page/offset addressing? */
727 BOOL Force_Mem_Formals = FALSE; /* Always force formals to memory? */
728 BOOL Kernel_Code = FALSE; /* Compiling OS kernel? */
729 BOOL Varargs_Prototypes = TRUE; /* Varargs have prototypes for FP? */
730 BOOL Gen_Profile = FALSE; /* Generate a profile call for each user call */
731 char *Gen_Profile_Name = "__profile_call";
732 BOOL Call_Mcount = FALSE; /* generate a call to mcount in pu entry */
733 BOOL GP_Is_Preserved = FALSE; /* GP is neither caller or callee-save */
734 
735 char *Emit_Global_Data = NULL; /* only emit global data */
736 char *Read_Global_Data = NULL; /* only read global data */
737 
738 char *Library_Name = NULL; /* -TENV:io_library=xxx */
740 
741 BOOL Meld_Schedule = FALSE; /* Attempt to meld basic blocks */
742 BOOL Gap_Schedule = FALSE; /* Attempt to perform gap scheduling */
743 BOOL Attempt_Bypass = FALSE; /* Attempt to use bypass registers */
744 BOOL Isolate_Lines = FALSE; /* Don't overlap source lines */
745 BOOL Fill_Delay_Slots = FALSE; /* Attempt to fill branch delay slots */
746 BOOL Enable_GDSE = FALSE; /* Allow global dead store elimination */
747 BOOL Enable_CG_Peephole =FALSE; /* Enable peephole optimization in cgprep */
748 
749 #ifdef BACK_END
750 /* back end phases options */
751 BOOL Run_lno = FALSE; /* run loop-nest optimizer */
752 BOOL Run_wopt = FALSE; /* run WHIRL global optimizer */
753 BOOL Run_preopt = FALSE; /* run WHIRL preopt optimizer */
754 BOOL Run_ipl = FALSE; /* run procedure summary phase */
755 BOOL Run_cg = FALSE; /* run code generator */
756 BOOL Run_w2c = FALSE; /* run whirl2c */
757 BOOL Run_w2f = FALSE; /* run whirl2f */
758 BOOL Run_w2fc_early = FALSE; /* run whirl2fc after LNO auto par*/
759 BOOL Run_purple = FALSE; /* run purple code instrumenter */
760 BOOL Run_prompf = FALSE; /* run to generate prompf analysis file */
761 char *LNO_Path = 0; /* path to lno.so */
762 char *WOPT_Path = 0; /* path to wopt.so */
763 char *CG_Path = 0; /* path to cg.so */
764 char *Ipl_Path = 0; /* path to ipl.so */
765 char *W2C_Path = 0; /* path to whirl2c.so */
766 char *W2F_Path = 0; /* path to whirl2f.so */
767 char *Purple_Path = 0; /* path to purple.so */
768 char *Prompf_Anl_Path = 0; /* path to prompf_anl.so */
770  /* Maps WN constructs to unique identifiers */
771 #endif /* BACK_END */
772 char *Inline_Path = 0; /* path to inline.so */
773 #if defined(BACK_END) || defined(QIKKI_BE)
774 char *Targ_Path = 0; /* path to targ_info .so */
775 #endif /* defined(BACK_END) || defined(QIKKI_BE) */
776 
777 /* ====================================================================
778  *
779  * Preconfigure
780  *
781  * Configure compiler options prior to flag processing.
782  *
783  * ====================================================================
784  */
785 
786 void
788 {
789  OPTION_GROUP *og;
790 
791  /* Perform host-specific and target-specific configuration: */
794 
795  /* Initialize the option groups: */
796  Initialize_Option_Groups ( Common_Option_Groups );
797 
798  og = Get_Command_Line_Group ( Common_Option_Groups, "TARG" );
799  Set_Option_Internal ( og, "fp_regs" /* don't admit to this one */ );
800  Set_Option_Internal ( og, "mips1" /* duplicates isa=mips1 */ );
801  Set_Option_Internal ( og, "mips2" /* duplicates isa=mips2 */ );
802  Set_Option_Internal ( og, "mips3" /* duplicates isa=mips3 */ );
803  Set_Option_Internal ( og, "mips4" /* duplicates isa=mips4 */ );
804  Set_Option_Internal ( og, "mips5" /* duplicates isa=mips5 */ );
805  Set_Option_Internal ( og, "mips6" /* duplicates isa=mips6 */ );
806 
807  og = Get_Command_Line_Group ( Common_Option_Groups, "TENV" );
808  Set_Option_Internal ( og, "pic1" /* same as -TENV:cpic */ );
809  Set_Option_Internal ( og, "pic2" /* same as -TENV:pic */ );
810 
811 #ifdef BACK_END
812  /* -PHASE is just for driver and internal use -- don't expose it */
813  og = Get_Command_Line_Group ( Common_Option_Groups, "PHASE" );
814  Set_Option_Internal ( og, NULL );
815 
816  /* -INLINE and -IPA aren't passed properly to back end, so don't
817  * confuse the poor users by printing the defaults (PV 645705)
818  */
819  og = Get_Command_Line_Group ( Common_Option_Groups, "INLINE" );
820  Set_Option_Internal ( og, NULL );
821  og = Get_Command_Line_Group ( Common_Option_Groups, "IPA" );
822  Set_Option_Internal ( og, NULL );
823 
824 #endif /* BACK_END */
825 }
826 
827 /* ====================================================================
828  *
829  * Configure_Platform
830  *
831  * Process a platform name, setting Platform and Processor_Name, the
832  * latter to be processed by Configure_Target. The platform name may
833  * come from either -OPT:Ofast=name or -TARG:platform=name.
834  *
835  * ====================================================================
836  */
837 
838 static void
839 Configure_Platform ( char *platform_name )
840 {
841  PLATFORM_OPTIONS *popts;
842 
843  /* If we've already set the platform, and the new name is empty,
844  * don't re-default it:
845  */
846  if ( Platform != IP0
847  && ( platform_name == NULL || *platform_name == 0 ) )
848  {
849  return;
850  }
851 
852  /* Get platform and its associated options: */
853  popts = Get_Platform_Options ( platform_name );
854  Platform = POPTS_id(popts);
855 
856  /* Set the per-IP options: */
857  if ( Processor_Name == NULL ) {
858  Processor_Name = POPTS_pname(popts);
859  }
860 }
861 
862 /* ====================================================================
863  *
864  * Configure_Ofast
865  *
866  * Configure option defaults which depend on -Ofast (the baseline SPEC
867  * optimizaiton option). These currently include:
868  *
869  * -OPT:Olimit=0 -- no limit on optimization region size.
870  * -OPT:roundoff=3 -- do any mathematically valid rearrangement.
871  * -OPT:div_split=ON -- allow splitting a/b => a*recip(b).
872  * -OPT:speculative_null_ptr_deref=ON -- allow speculation past the null
873  * ptr test. assumes page zero as
874  * readable.
875  * -OPT:alias=typed -- pointers to different types don't alias.
876  * -WOPT:copy_ops=OFF -- don't copy-propagate operations that the IVR
877  * can't handle (OFF by default now, but just in case...).
878  * -WOPT:estr_fb_injury=ON -- SSAPRE strength reduction uses
879  * feedback frequency rather than loop
880  * nesting to decide whether each IV
881  * update should be viewed as injury or
882  * kill.
883  *
884  * This must be done before abi/isa/processor configuration.
885  *
886  * ====================================================================
887  */
888 
889 static void
891 {
892  /* We assume that the driver has defaulted Opt_Level properly. */
893  /* First set the options that are common to all targets: */
894  if ( ! Olimit_Set ) {
895  Olimit = 0;
896  Olimit_Set = TRUE;
897  }
898  if ( ! Roundoff_Set ) {
900  Roundoff_Set = TRUE;
901  }
902  if ( ! Div_Split_Set ) {
905  }
906 /* #645549: There exists an OS bug which gets triggered by NULL ptr
907  speculation. Disable NULL ptr speculation for Ofast (base flags).
908  They will however continue to be turned ON for SPEC peak flags.
909 
910  if ( ! GCM_Eager_Null_Ptr_Deref_Set ) {
911  GCM_Eager_Null_Ptr_Deref = TRUE;
912  GCM_Eager_Null_Ptr_Deref_Set = TRUE;
913  }
914 */
915  if ( ! Alias_Pointer_Types_Set ) {
918  }
922  }
926  }
927 
928  /* Get platform and its associated options: */
930 }
931 
932 /* ====================================================================
933  *
934  * Configure
935  *
936  * Configure compiler options based on flag values.
937  *
938  * ====================================================================
939  */
940 
941 #ifdef KEEP_WHIRLSTATS
942 /* defined in wn.c */
943 extern void whirlstats();
944 #endif
945 
946 
947 extern BOOL IR_set_dump_order (BOOL prefix); /* in ir_reader.c */
948 
949 void
950 Configure (void)
951 {
952  static BOOL dev_warn_toggled = FALSE;
953 
954 #if !defined(SGI_FRONT_END_CPP)
955  /* See if trees should be dumped in prefix order */
958  }
959 #endif
960 
961  if ( ! dev_warn_toggled ) {
962  if ( Get_Trace( TP_MISC, 0x40 ) ) {
963  dev_warn_toggled = TRUE;
964  DevWarn_Toggle();
965  }
966  }
967 
968 #ifdef KEEP_WHIRLSTATS
969  atexit(whirlstats);
970 #endif
971 
972  /* Configure the alias options first so the list is processed and
973  * we can tell for -OPT:Ofast below what overrides have occurred:
974  */
976 
977  /* Check the -TARG:platform option (subordinate to Ofast): */
978  if ( Platform_Name != NULL && *Platform_Name != 0 ) {
980  }
981 
982  /* First, if -OPT:Ofast (a.k.a. SPEC) is set, configure defaults: */
983  if ( Ofast != NULL ) {
984  Configure_Ofast ();
985  }
986 
987 
988  /* Perform host-specific and target-specific configuration: */
989  Configure_Host ();
990  Configure_Target ();
991 
992  /* What size GOT to use? Configure_Target sets it to small for
993  * 32-bit pointers, large for 64-bit pointers. Override it here
994  * if TENV was used to specify it:
995  */
996  if ( Use_Large_GOT && Use_Small_GOT ) {
997  /* Make up your mind! */
998  ErrMsg ( EC_GOT_Size, Guaranteed_Small_GOT ? "small" : "large" );
999  } else if ( Use_Large_GOT ) {
1000  Guaranteed_Small_GOT = FALSE;
1001  } else if ( Use_Small_GOT ) {
1002  Guaranteed_Small_GOT = TRUE;
1003  }
1004 
1005  if (Emit_Global_Data && Read_Global_Data) {
1006  /* Make up your mind! */
1007  FmtAssert (FALSE, ("can't specify options to both emit and read global data"));
1008  }
1009  else if (Emit_Global_Data) Global_File_Name = Emit_Global_Data;
1010  else if (Read_Global_Data) Global_File_Name = Read_Global_Data;
1011 
1012  /* Configure the treatment of short literals and data. We give
1013  * precedence to the -TENV:short_lits=nnn:short_data=mmm options,
1014  * but -Gn can override either of them if not specified:
1015  */
1016  if ( ! Short_Lits_Set ) {
1018  }
1019  if ( ! Short_Data_Set ) {
1021  }
1022 
1023  /* Turn on -OPT:Reorg_Common by default at -O3: */
1024  if ( ! OPT_Reorg_Common_Set && Opt_Level > 2 ) {
1026  }
1027 
1029 }
1030 
1031 /* ====================================================================
1032  *
1033  * Configure_Source
1034  *
1035  * Configure compiler options for each source file.
1036  *
1037  * Note that we set the various optimization and code generation
1038  * options at this level to ultimately allow per-source respecification
1039  * with pragmas.
1040  *
1041  * ====================================================================
1042  */
1043 
1044 void
1045 Configure_Source ( char *filename )
1047 {
1048  /* Identify the source language: */
1049  if ( Language_Name != NULL ) {
1050  if ( ux_strcasecmp ( Language_Name, "KR_C" ) == 0 ) {
1051  Language = LANG_KR_C;
1052  } else if ( ux_strcasecmp ( Language_Name, "ANSI_C" ) == 0 ) {
1054  } else if ( ux_strcasecmp ( Language_Name, "CPLUS" ) == 0 ) {
1055  Language = LANG_CPLUS;
1056  } else if ( ux_strcasecmp ( Language_Name, "DELTA" ) == 0 ) {
1057  Language = LANG_DELTA;
1058  } else if ( ux_strcasecmp ( Language_Name, "F77" ) == 0 ) {
1059  Language = LANG_F77;
1060  } else if ( ux_strcasecmp ( Language_Name, "F90" ) == 0 ) {
1061  Language = LANG_F90;
1062  }
1063  }
1064 
1065  /* Configure the -DEBUG and -LIST groups: */
1066  DEBUG_Configure ();
1067  LIST_Configure ();
1068 
1069  /* Determine whether to use the CRAY or MIPS IO library */
1070  if (Library_Name != NULL) {
1071  if (ux_strcasecmp ( Library_Name,"cray") == 0 ) {
1072  target_io_library = IOLIB_CRAY;
1073  } else if (ux_strcasecmp ( Library_Name,"mips") == 0 ) {
1074  target_io_library = IOLIB_MIPS;
1075  }
1076  } else {
1077  /* For F90, use the CRAY libraries by default */
1078  if (Language == LANG_F90) {
1079  target_io_library = IOLIB_CRAY;
1080  /* For F77, use the MIPS libraries by default */
1081  } else {
1082  target_io_library = IOLIB_MIPS;
1083  }
1084  }
1085 
1086 #ifdef BACK_END
1087 
1088  /* If we're invoking CITE, turn on whirl2c/f: */
1089  if ( List_Cite ) {
1090  if ( Language == LANG_F77 || Language == LANG_F90 ) {
1091  Run_w2f = TRUE;
1092  } else if ( Language == LANG_KR_C || Language == LANG_ANSI_C
1093  || Language == LANG_CPLUS || Language == LANG_DELTA )
1094  {
1095  Run_w2c = TRUE;
1096  }
1097  }
1098 
1099  /* If we're invoking CITE, turn on whirl2c/f: */
1100  if (Run_w2fc_early) {
1101  if ( Language == LANG_F77 || Language == LANG_F90 ) {
1102  Run_w2f = TRUE;
1103  } else if ( Language == LANG_KR_C || Language == LANG_ANSI_C
1104  || Language == LANG_CPLUS || Language == LANG_DELTA )
1105  {
1106  Run_w2c = TRUE;
1107  }
1108  }
1109 #endif /* BACK_END */
1110 
1111  if ( Use_Large_GOT ) Guaranteed_Small_GOT = FALSE;
1112 
1113  /* if we get both TENV:CPIC and TENV:PIC, use only TENV:CPIC */
1114  if (Gen_PIC_Call_Shared && Gen_PIC_Shared) Gen_PIC_Shared = FALSE;
1115 
1116  /* Select optimization options: */
1117 
1118  /* Are we skipping any PUs for optimization? */
1120  /* Are we skipping any regions for optimization? */
1122 
1123  /* F90 is a recursive language, so this needs to be set */
1125  LANG_Recursive = TRUE;
1126 
1127  /* Since there seems to be little compile time reason not to be aggressive,
1128  * make the folder aggressive by default
1129  */
1130  if ( ! Cfold_Aggr_Set )
1132 
1133  if (!Enable_CVT_Opt_Set)
1134  Enable_CVT_Opt = ( Opt_Level > 0);
1135 
1136  CSE_Elim_Enabled = Opt_Level > 0;
1137 
1138  /* Perform the %call16 -> %got_disp relocation change? */
1140  Enable_GOT_Call_Conversion = Opt_Level > 2;
1141 
1142  /* Force formal parameters to memory? */
1143  Force_Mem_Formals = ( Opt_Level < 1 );
1144 
1145  /* Optimize for space */
1146  if ( OPT_Space ) {
1147 
1148  /* TODO: Other space optimizations to force? */
1149  if (!CG_memmove_inst_count_overridden)
1150  CG_memmove_inst_count = 8;
1151  if (! OPT_unroll_size_overridden)
1152  OPT_unroll_size = 20;
1153  /* reduce caller+callee "size" limit for inlining */
1154  INLINE_Max_Pu_Size=1000;
1155 #if 0 /* not ready for this yet. */
1156  /* don't inline divide expansions */
1158 #endif
1159 
1160 #ifdef BACK_END
1161  /* LNO options to be turned off for SPACE */
1162  LNO_Outer_Unroll = 1;
1164 #endif /* BACK_END */
1165  }
1166 
1167  /* symbolic debug stuff */
1169  if (Debug_Level > 0 && Debug_Level <= 2)
1171  if (Debug_Level > 0) {
1174  }
1175 
1176 
1177  /* Disabling splitting of long basic blocks: */
1178  Enable_BB_Splitting = ! Get_Trace ( TP_FLOWOPT, 0x080 );
1179 
1180  if (Opt_Level > 2 && ! Olimit_Set)
1182  if (Olimit == 0) {
1183  /* 0 Olimit means no limit or infinite limit */
1184  Olimit = MAX_OLIMIT;
1185  }
1186  else if (Olimit < 10) {
1187  /* olimit too small to work properly */
1188  DevWarn("Olimit < 10 is too small; resetting to Olimit=10");
1189  Olimit = 10;
1190  }
1191  if (Opt_Level == 0 && ! Olimit_opt_Set)
1192  Olimit_opt = FALSE;
1193 
1194 #if !defined(SGI_FRONT_END_CPP) && !defined(QIKKI_BE)
1195  /* -OPT:rail or -OPT:rbi implies -OPT:compile_by_region
1196  * unless -OPT:compile_by_region=no is specified.
1197  */
1200 #endif /* !defined(SGI_FRONT_END_CPP) && !defined(QIKKI_BE) */
1201 
1202  /* Enable IEEE_arithmetic options */
1203  if (Opt_Level > 2 && !IEEE_Arith_Set) {
1205  }
1206 
1208  /* IEEE arithmetic options: */
1209  if ( IEEE_Arithmetic > IEEE_ACCURATE ) {
1210  /* Minor roundoff differences for inexact results: */
1211  if ( ! Recip_Set )
1213  if ( ! Rsqrt_Set )
1215  /* Potential non-IEEE results for exact operations: */
1216  if ( ! Div_Split_Set )
1218  }
1219 
1220  /* Constant folding options: */
1221  if ( ! Roundoff_Set && Opt_Level > 2 ) {
1223  }
1224  if ( Roundoff_Level > ROUNDOFF_NONE ) {
1225 
1226  /* The following allow minor roundoff differences: */
1227  if ( ! Fast_Exp_Set )
1229 
1230  /* The following allows folding of intrinsics with constant arguments: */
1231  if ( ! Cfold_Intrinsics_Set )
1233 
1234  /* The following allows arbitrary reassociation: */
1235  if ( ! Cfold_Reassoc_Set )
1237 
1238  /* reassociate in the lowerer to find MADD oportunities */
1239  if ( ! Enable_NaryExpr_Set )
1241 
1242  if (!Fast_Complex_Set)
1244  if (!Fast_NINT_Set)
1246  if (!Fast_trunc_Set)
1248 
1249  if ( ! CIS_Set )
1251  }
1252 
1253 #if 0
1254  /* Set the relational operator folding in simplifier based on the optimizer
1255  setting of Allow_wrap_around_opt */
1258  }
1261  }
1262 #endif
1263  if (!Simp_Unsafe_Relops_Set && Opt_Level > 2) {
1265  }
1266 
1267  Enable_GDSE = ((Opt_Level > 1) &&
1268  (!Get_Trace(TP_GLOBOPT, 4096))
1269  );
1270  /* The lowerer will do a simple treeheight reduction for
1271  * binary commutative ops
1272  */
1274  OPT_Lower_Treeheight = (Opt_Level > 1);
1275 
1276  /* Perform host-specific and target-specific configuration: */
1277 
1280  Configure_Source_Host ( filename );
1281  Configure_Source_Target ( filename );
1282 
1283  /* Set eagerness-level-based information. This must come after the
1284  * call to Configure_Source_Target, since that routine sets the
1285  * FP exception enable masks.
1286  */
1287  if ( ! Eager_Level_Set && Opt_Level > 2 ) {
1289  }
1290  if ( Eager_Level >= EAGER_ARITH ) {
1292  }
1293  if ( Eager_Level >= EAGER_DIVIDE ) {
1295  }
1296  if ( Eager_Level >= EAGER_MEMORY ) {
1298  }
1299 
1300 #ifdef BACK_END
1301  /* Configure the -LNO group: */
1302  LNO_Configure ();
1303 #endif /* BACK_END */
1304 
1305  /* Trace options: */
1306  if ( Get_Trace ( TP_MISC, 128 ) ) {
1307  Trace_Option_Groups ( TFile, Common_Option_Groups, TRUE );
1308  } else if ( Get_Trace ( TP_MISC, 32 ) ) {
1309  Trace_Option_Groups ( TFile, Common_Option_Groups, FALSE );
1310  }
1311 }
1312 
1313 /* ====================================================================
1314  *
1315  * Configure_Alias_Options
1316  *
1317  * Configure the options related to alias analysis.
1318  *
1319  * ====================================================================
1320  */
1321 
1322 void
1324 {
1325  OPTION_LIST *ol;
1326  for (ol = olist; ol != NULL; ol = OLIST_next(ol)) {
1327  char *val = OLIST_val(ol);
1328  INT len = strlen (val);
1329  if (ux_strncasecmp( val, "any", len) == 0) {
1330  Alias_Pointer_Parms = TRUE; /* observed by Fortran programs */
1331  Alias_Pointer_Cray = FALSE; /* observed by Fortran programs */
1332  Alias_Pointer_Types = TRUE; /* observed by C and C++ programs */
1333  Alias_Not_In_Union = TRUE; /* observed by C++ programs only */
1334  Alias_Pointer_Strongly_Typed = FALSE; /* observed by C and C++ programs */
1336  Alias_Not_In_Union_Set = TRUE; /* observed by C++ programs only */
1337  Alias_Pointer_Named_Data = FALSE; /* observed by C and C++ programs */
1338  Alias_Pointer_Restricted = FALSE; /* observed by C and C++ programs */
1340  } else if (ux_strncasecmp( val, "parm", len) == 0) {
1342  } else if (ux_strncasecmp( val, "typed", len) == 0) {
1345  } else if (ux_strncasecmp( val, "unnamed", len) == 0) {
1347  } else if (ux_strncasecmp( val, "nounion",len) == 0) {
1348  Alias_Not_In_Union = TRUE; /* observed by C++ programs only */
1349  Alias_Not_In_Union_Set = TRUE; /* observed by C++ programs only */
1350  } else if (ux_strncasecmp( val, "restricted", len) == 0) {
1353  } else if (ux_strncasecmp( val, "disjoint", len) == 0) {
1357  } else if (ux_strncasecmp( val, "cray_pointer", len) == 0) {
1359  } else if (ux_strncasecmp( val, "strongly_typed", len) == 0) {
1361  } else if (ux_strncasecmp( val, "no_parm", len) == 0) {
1363  } else if (ux_strncasecmp( val, "no_typed", len) == 0) {
1366  } else if (ux_strncasecmp( val, "no_unnamed", len) == 0) {
1368  } else if (ux_strncasecmp( val, "no_restricted", len) == 0) {
1371  } else if (ux_strncasecmp( val, "no_disjoint", len) == 0) {
1374  } else if (ux_strncasecmp( val, "no_cray_pointer", len) == 0) {
1376  } else if (ux_strncasecmp( val, "no_strongly_typed", len) == 0) {
1378  } else if (ux_strncasecmp( val, "cckr_default", len) == 0) {
1380  } else if (ux_strncasecmp( val, "common_scalar", len) == 0) {
1382  } else if (ux_strncasecmp( val, "no_common_scalar", len) == 0) {
1384  } else if (ux_strncasecmp( val, "no_f90_pointer_alias", len) == 0) {
1386  } else if (ux_strncasecmp( val, "f90_pointer_alias", len) == 0) {
1388  } else {
1389  ErrMsg ( EC_Inv_OPT, "alias", val );
1390  }
1391  }
1392 
1393  /* If we didn't explicitly set alias=typed, and this is a -cckr
1394  * compilation, turn off Alias_Pointer_Types:
1395  */
1398  }
1399 }
1400 
1401 /* ====================================================================
1402  *
1403  * SKIPLIST
1404  *
1405  * Support for lists of PU numbers to skip (e.g. for optimization)
1406  * based on options in a command line group. A typedef for SKIPLIST
1407  * is defined in config.h, but the type is opaque outside; for now,
1408  * Build_Skiplist and Query_Skiplist are the only visible interface.
1409  *
1410  * This interface is sufficiently generic that it could go into flags.*
1411  * in common/util. It isn't there because that could end up breaking
1412  * the principle that flags.h should not be widely included (i.e. other
1413  * than by command line processing).
1414  *
1415  * ====================================================================
1416  */
1417 
1418 typedef enum {
1419  SK_NONE, /* End of list */
1420  SK_AFTER, /* Values after this one */
1421  SK_BEFORE, /* Values before this one */
1422  SK_EQUAL /* Just this one */
1423 } SKIPKIND;
1424 
1425 struct skiplist {
1426  mINT32 size; /* Number of elements */
1427  mINT8 *kind; /* Array of kinds */
1428  mINT32 *val; /* Array of values */
1429 };
1430 
1431 #define SKIPLIST_size(sl) ((sl)->size)
1432 #define SKIPLIST_kind_vec(sl) ((sl)->kind)
1433 #define SKIPLIST_kind(sl,i) ((SKIPKIND)((sl)->kind[i]))
1434 #define Set_SKIPLIST_kind(sl,i,v) (((sl)->kind[i]) = (mINT8)(v))
1435 #define SKIPLIST_val_vec(sl) ((sl)->val)
1436 #define SKIPLIST_val(sl,i) ((sl)->val[i])
1437 
1438 /* ====================================================================
1439  *
1440  * Print_Skiplist
1441  *
1442  * Print a skiplist.
1443  *
1444  * ====================================================================
1445  */
1446 
1447 static void
1448 Print_Skiplist ( FILE *tf, SKIPLIST *skip, char *lab )
1449 {
1450  INT32 i;
1451 
1452  if ( skip == NULL ) {
1453  fprintf ( tf, "SKIPLIST %s empty\n", lab );
1454  return;
1455  }
1456  fprintf ( tf, "SKIPLIST %s:\n", lab );
1457 
1458  for ( i = 0; SKIPLIST_kind(skip,i) != SK_NONE; i++ ) {
1459  switch ( SKIPLIST_kind(skip,i) ) {
1460  case SK_EQUAL:
1461  fprintf ( tf, " equal %d\n", SKIPLIST_val(skip,i) );
1462  break;
1463  case SK_AFTER:
1464  fprintf ( tf, " after %d\n", SKIPLIST_val(skip,i) );
1465  break;
1466  case SK_BEFORE:
1467  fprintf ( tf, " before %d\n", SKIPLIST_val(skip,i) );
1468  break;
1469  }
1470  }
1471  fprintf ( tf, "SKIPLIST %s end\n\n", lab );
1472 }
1473 
1474 /* ====================================================================
1475  *
1476  * Build_Skiplist
1477  *
1478  * Build a skiplist from a group option list. For now, we assume that
1479  * the only choices are skip_a* (after) skip_b* (before), and skip_e*
1480  * (equal). See Query_Skiplist below for the list semantics.
1481  *
1482  * Note that we interpret skip_equal=1,3-5,7-10,12,35-39 as you might
1483  * hope.
1484  *
1485  * WARNING: This routine does no error checking. This option is for
1486  * internal use, and if the syntax is wrong, strange (non-fatal) things
1487  * may happen (typically ignoring the rest of the option).
1488  *
1489  * ====================================================================
1490  */
1491 
1492 SKIPLIST *
1494 {
1495  INT32 count = 0;
1496  OPTION_LIST *ol;
1497  SKIPLIST *sl;
1498  BOOL list_found = FALSE;
1499  char *p;
1500 
1501  /* Count the elements: */
1502  if ( olist == NULL ) return NULL;
1503  for ( ol = olist; ol != NULL; ol = OLIST_next(ol) ) {
1504 
1505  /* At least one entry: */
1506  ++count;
1507 
1508  /* Check for commas and ranges: */
1509  p = OLIST_val(ol);
1510  while ( *p != ':' && *p != 0 ) {
1511  if ( *p == ',' || *p == '-' ) {
1512  ++count;
1513  list_found = TRUE;
1514  }
1515  ++p;
1516  }
1517  }
1518 
1519  /* Allocate the skiplist: */
1520  sl = (SKIPLIST *) malloc ( sizeof(SKIPLIST) );
1521  SKIPLIST_size(sl) = count+1;
1522  SKIPLIST_kind_vec(sl) = (mINT8 *) calloc ( sizeof(mINT8), count+1 );
1523  SKIPLIST_val_vec(sl) = (mINT32 *) calloc ( sizeof(mINT32), count+1 );
1524 
1525  /* Fill the skiplist: */
1526  for ( count = 0, ol = olist;
1527  ol != NULL;
1528  ++count, ol = OLIST_next(ol) )
1529  {
1530  if ( !strncmp ( "skip_a", OLIST_opt(ol), 6 ) ||
1531  !strncmp ( "region_skip_a", OLIST_opt(ol), 13 ) ) {
1532  Set_SKIPLIST_kind ( sl, count, SK_AFTER );
1533  } else if ( !strncmp ( "skip_b", OLIST_opt(ol), 6 ) ||
1534  !strncmp ( "region_skip_b", OLIST_opt(ol), 13 ) ) {
1535  Set_SKIPLIST_kind ( sl, count, SK_BEFORE );
1536  } else {
1537  Set_SKIPLIST_kind ( sl, count, SK_EQUAL );
1538  }
1539  SKIPLIST_val(sl,count) = atoi ( OLIST_val(ol) );
1540 
1541  /* If this is skip_equal, look for a list... */
1542  if ( list_found && SKIPLIST_kind(sl,count) == SK_EQUAL ) {
1543  p = OLIST_val(ol);
1544  while ( *p >= '0' && *p <= '9' ) ++p;
1545  if ( *p == '-' ) {
1546  Set_SKIPLIST_kind ( sl, count, SK_AFTER );
1547  --SKIPLIST_val(sl,count);
1548  ++p;
1549  ++count;
1550  Set_SKIPLIST_kind ( sl, count, SK_BEFORE );
1551  SKIPLIST_val(sl,count) = 1 + atoi ( p );
1552  while ( *p >= '0' && *p <= '9' ) ++p;
1553  }
1554  while ( *p++ == ',' ) {
1555  ++count;
1556  Set_SKIPLIST_kind ( sl, count, SK_EQUAL );
1557  SKIPLIST_val(sl,count) = atoi ( p );
1558  while ( *p >= '0' && *p <= '9' ) ++p;
1559  if ( *p == '-' ) {
1560  Set_SKIPLIST_kind ( sl, count, SK_AFTER );
1561  --SKIPLIST_val(sl,count);
1562  ++p;
1563  ++count;
1564  Set_SKIPLIST_kind ( sl, count, SK_BEFORE );
1565  SKIPLIST_val(sl,count) = 1 + atoi ( p );
1566  while ( *p >= '0' && *p <= '9' ) ++p;
1567  }
1568  }
1569  }
1570  }
1571  Set_SKIPLIST_kind ( sl, count, SK_NONE );
1572 
1573  if ( Get_Trace ( TP_MISC, 0x80 ) ) {
1574  Print_Skiplist ( TFile, sl, "Build_Skiplist" );
1575  }
1576 
1577  return sl;
1578 }
1579 
1580 /* ====================================================================
1581  *
1582  * Query_Skiplist
1583  *
1584  * Query a skiplist. A TRUE result means that the element passed is in
1585  * the skiplist. The semantics of the list is as follows: Return TRUE
1586  * if elmt is equal to an SK_EQUAL element of the list. Return TRUE if
1587  * elmt is greater than an SK_AFTER element AND it is less than an
1588  * immediately following SK_BEFORE element; otherwise skip over the
1589  * following SK_BEFORE element. Return TRUE if elmt is smaller than an
1590  * SK_BEFORE which does not immediately follow an SK_AFTER. If nothing
1591  * on the list produces a TRUE result, return FALSE. That is, a list
1592  * consists of SK_EQUAL elements, SK_AFTER/SK_BEFORE pairs in that
1593  * order, or SK_AFTER and SK_BEFORE elements that aren't in such pairs.
1594  * Any match of one of these tests causes a skip.
1595  *
1596  * ====================================================================
1597  */
1598 
1599 BOOL
1601 {
1602  INT32 i;
1603  BOOL ok;
1604 
1605  if ( skip == NULL ) return FALSE;
1606 
1607  for ( i = 0; SKIPLIST_kind(skip,i) != SK_NONE; i++ ) {
1608  switch ( SKIPLIST_kind(skip,i) ) {
1609  case SK_EQUAL:
1610  /* printf ( "<skip> equal %d ? %d\n", SKIPLIST_val(skip,i), elmt ); */
1611  if ( SKIPLIST_val(skip,i) == elmt ) return TRUE;
1612  break;
1613  case SK_AFTER:
1614  ok = ( SKIPLIST_val(skip,i) < elmt );
1615  /* printf ( "<skip> after %d ? %d\n", SKIPLIST_val(skip,i), elmt ); */
1616  if ( SKIPLIST_kind(skip,i+1) == SK_BEFORE
1617  && SKIPLIST_val(skip,i+1) > SKIPLIST_val(skip,i))
1618  {
1619  if ( SKIPLIST_val(skip,++i) <= elmt ) ok = FALSE;
1620  }
1621  if ( ok ) return TRUE;
1622  break;
1623  case SK_BEFORE:
1624  /* printf ( "<skip> before %d ? %d\n", SKIPLIST_val(skip,i), elmt ); */
1625  if ( SKIPLIST_val(skip,i) > elmt ) return TRUE;
1626  break;
1627  }
1628  }
1629  return FALSE;
1630 }
1631 
1632 /* ====================================================================
1633  *
1634  * Process_Trace_Option
1635  *
1636  * Given a trace option -t..., process it. The caller should already
1637  * have determined that it cannot be anything else. The option should
1638  * be the full option string, with leading -t... (for error messages).
1639  * such options may be catenated, except for those which take name
1640  * operands which can't be delimited, which must be last.
1641  *
1642  * ====================================================================
1643  */
1644 
1645 BOOL
1646 Process_Trace_Option ( char *option )
1647 {
1648  char *cp = option+1;
1649  INT32 phase;
1650 
1651  Tracing_Enabled = TRUE;
1652 
1653  while ( cp && *cp == 't' ) {
1654  cp += 2;
1655 
1656  switch ( *(cp-1) ) {
1657  case 'a':
1659  Get_Trace_Phase_Number ( &cp, option ) );
1660  break;
1661 
1662  case 'b':
1664  Get_Numeric_Flag (&cp, 0, 32767, 0, option));
1665  break;
1666 
1667  case 'c':
1669  Get_Numeric_Flag (&cp, 0, 32767, 0, option));
1670  break;
1671 
1672  case 'd':
1674  Get_Numeric_Flag (&cp, 1, 32767, 0, option));
1675  break;
1676 
1677  /* ex: -Wb,-tf0 for function 0 in the file */
1678  case 'f':
1679  if ( isdigit (*cp) ) {
1681  Get_Numeric_Flag (&cp, 0, 0x7fffffff, 0, option) );
1682  } else {
1683  Set_Trace_Pu ( cp );
1684  cp = 0; /* Done with this flag */
1685  }
1686  break;
1687 
1688  /* ex: -Wb,-tg1 for region 1 in each function (best when used with -tf) */
1689  case 'g':
1690  if ( isdigit (*cp) ) {
1692  Get_Numeric_Flag (&cp, 0, 0x7fffffff, 0, option) );
1693  } else
1694  Is_True(FALSE,("Process_Trace_Option: regions don't have names"));
1695  break;
1696 
1697  case 'i':
1699  Get_Numeric_Flag (&cp, 1, 32767, 0, option));
1700  break;
1701 
1702  case 'n':
1704  Get_Trace_Phase_Number ( &cp, option ) );
1705  break;
1706 
1707  case 'p':
1708  phase = Get_Trace_Phase_Number ( &cp, option );
1709  if ( phase != 0 && (*cp == ',' || *cp == '\0'))
1710  Set_Trace (TKIND_XPHASE, phase);
1711  break;
1712 
1713  case 'r':
1715  Get_Trace_Phase_Number ( &cp, option ) );
1716  break;
1717 
1718  case 's':
1720  Get_Trace_Phase_Number ( &cp, option ) );
1722  break;
1723 
1724  case 't':
1725  phase = Get_Trace_Phase_Number ( &cp, option );
1726  if ( *cp != ',' && *cp != ':' ) {
1727  ErrMsg ( EC_Trace_Flag, *cp, option );
1728  break;
1729  }
1730  cp++; /* skip separator */
1731  Set_Trace (phase,
1732  Get_Numeric_Flag (&cp, 1, 0xffffffff, 0,
1733  option));
1734  break;
1735 
1736 #ifdef FRONT_END
1737  case 'v':
1738  {
1739  /* Used by the EDG front ends to control tracing verbosity: */
1740  extern BOOL trace_verbose; /* Type must match a_boolean */
1741  trace_verbose = TRUE;
1742  }
1743  break;
1744 #endif
1745 
1746  case 0:
1747  ErrMsg ( EC_Trace_Flag, '?', option );
1748  return FALSE;
1749 
1750  default:
1751  --cp;
1752  ErrMsg ( EC_Trace_Flag, *cp, option );
1753  return FALSE;
1754  }
1755 
1756  }
1757 
1758  if ( cp && *cp != 0 ) {
1759  ErrMsg ( EC_Trace_Flag, '?', option );
1760  return FALSE;
1761  }
1762  return TRUE;
1763 
1764 }
1765 
1766 /* ====================================================================
1767  *
1768  * List_Compile_Options
1769  *
1770  * List options to the given file. This is primarily an interface to
1771  * the flags.c routine Print_Option_Groups, but also prints a number of
1772  * non-group options. The "internal" flag indicates whether to list
1773  * internal-only options. The "full" flag indicates whether to list
1774  * all options if "internal" is set; otherwise option group listing
1775  * is controlled by List_Options and List_All_Options.
1776  *
1777  * ====================================================================
1778  */
1779 
1780 void
1782  FILE *f,
1783  char *pfx,
1784  BOOL internal,
1785  BOOL full,
1786  BOOL update )
1787 {
1788  char *bar = SBar+12; /* Shorten it a bit */
1789 
1790  fprintf ( f, "\n%s%s%s Compiling %s (%s)\n%s%s",
1791  pfx, bar, pfx, Src_File_Name, Irb_File_Name, pfx, bar );
1792  fprintf ( f, "\n%s%s%s Options:\n%s%s", pfx, bar, pfx, pfx, bar );
1793 
1794  fprintf ( f, "%s Target:%s, ISA:%s, Pointer Size:%d\n",
1795  pfx, Targ_Name (Target), Isa_Name (Target_ISA),
1796  (Use_32_Bit_Pointers ? 32 : 64) );
1797  fprintf ( f, "%s -O%d\t(Optimization level)\n", pfx, Opt_Level );
1798  fprintf ( f, "%s -g%d\t(Debug level)\n", pfx, Debug_Level );
1799 
1801  fprintf ( f, "%s -m2\t(Report advisories)\n", pfx );
1802  else if ( Min_Error_Severity == ES_WARNING )
1803  fprintf ( f, "%s -m1\t(Report warnings)\n", pfx );
1804  else
1805  fprintf ( f, "%s -m0\t(Report errors only)\n", pfx );
1806 
1807  fprintf ( f, "%s%s\n", pfx, bar );
1808 
1809  if ( internal || List_Options ) {
1810  fprintf ( f, "%s Group options are marked with '#' if changed,\n"
1811  "%s or with '=' if explicitly set to default value.\n",
1812  pfx, pfx );
1813  Print_Option_Groups ( f, Common_Option_Groups, pfx, internal,
1814  internal ? full : List_All_Options , update );
1815  }
1816 }
1817