GCC-3.4.6源代码学习笔记(26)

3.3.3.1.2.            处理公用选项

对于公用选项及c_common_handle_option未能完成处理之选项,则需要继续调用 common_handle_option

 

655  static int

656  common_handle_option (size_t scode, const char *arg,                                  in opts.c

657                      int value ATTRIBUTE_UNUSED)

658  {

659    enum opt_code code = (enum opt_code) scode;

660 

661    switch (code)

662    {

663      default:

664        abort ();

665 

666      case OPT__help:

667        print_help ();

668        exit_after_options = true;

669        break;

670 

671      case OPT__param:

672        handle_param (arg);

673        break;

 

选项–param name=value设定某些GCC使用的内部限制,以确定优化的力度,因此调整这些变量就是调整优化。

参数调整通过handle_param来完成。

 

1529 static void

1530 handle_param (const char *carg)                                                                        in opts.c

1531 {

1532   char *equal, *arg;

1533   int value;

1534

1535   arg = xstrdup (carg);

1536   equal = strchr (arg, '=');

1537   if (!equal)

1538     error ("%s: --param arguments should be of the form NAME=VALUE", arg);

1539   else

1540   {

1541     value = integral_argument (equal + 1);

1542     if (value == -1)

1543       error ("invalid --param value `%s'", equal + 1);

1544     else

1545     {

1546       *equal = '/0';

1547       set_param_value (arg, value);

1548     }

1549   }

1550

1551   free (arg);

1552 }

 

参数必须是正整数,为了设定值,调用set_param_value

 

58    void

59    set_param_value (const char *name, int value)                                              in params.c

60    {

61      size_t i;

62   

63      /* Make sure nobody tries to set a parameter to an invalid value.  */

64      if (value == INVALID_PARAM_VAL)

65        abort ();

66   

67     /* Scan the parameter table to find a matching entry.  */

68      for (i = 0; i < num_compiler_params; ++i)

69        if (strcmp (compiler_params[i].option, name) == 0)

70        {

71          compiler_params[i].value = value;

72          return;

73        }

74   

75     /* If we didn't find this parameter, issue an error message.  */

76      error ("invalid parameter `%s'", name);

77    }

 

--param所能使用的参数是已经确定的。在general_init4264行,add_params确定了这些名字,并使用lang_independent_params初始化compiler_params

 

common_handle_option (continue)

 

675      case OPT__target_help:

676        display_target_options ();

677        exit_after_options = true;

678        break;

679 

680      case OPT__version:

681        print_version (stderr, "");

682        exit_after_options = true;

683        break;

684 

685      case OPT_G:

686        g_switch_value = value;

687        g_switch_set = true;

688        break;

689 

690      case OPT_O:

691      case OPT_Os:

692        /* Currently handled in a prescan.  */

693        break;

694 

695      case OPT_W:

696        /* For backward compatibility, -W is the same as -Wextra.  */

697        set_Wextra (value);

698        break;

699 

700      case OPT_Waggregate_return:

701        warn_aggregate_return = value;

702        break;

703 

704      case OPT_Wcast_align:

705        warn_cast_align = value;

706        break;

707 

708      case OPT_Wdeprecated_declarations:

709        warn_deprecated_decl = value;

710        break;

711 

712      case OPT_Wdisabled_optimization:

713        warn_disabled_optimization = value;

714        break;

715 

716      case OPT_Werror:

717        warnings_are_errors = value;

718        break;

719 

720      case OPT_Wextra:

721        set_Wextra (value);

722        break;

723 

724      case OPT_Winline:

725        warn_inline = value;

726        break;

727 

728      case OPT_Wlarger_than_:

729        larger_than_size = value;

730        warn_larger_than = value != -1;

731        break;

732 

733      case OPT_Wmissing_noreturn:

734        warn_missing_noreturn = value;

735        break;

736 

737      case OPT_Wpacked:

738        warn_packed = value;

739        break;

740 

741      case OPT_Wpadded:

742        warn_padded = value;

743        break;

744 

745      case OPT_Wshadow:

746        warn_shadow = value;

747        break;

748 

749      case OPT_Wstrict_aliasing:

750        warn_strict_aliasing = value;

751        break;

752 

753      case OPT_Wswitch:

754        warn_switch = value;

755        break;

756 

757      case OPT_Wswitch_default:

758        warn_switch_default = value;

759        break;

760 

761      case OPT_Wswitch_enum:

762        warn_switch_enum = value;

763        break;

764 

765      case OPT_Wsystem_headers:

766        warn_system_headers = value;

767        break;

768 

769      case OPT_Wuninitialized:

770        warn_uninitialized = value;

771        break;

772 

773      case OPT_Wunreachable_code:

774        warn_notreached = value;

775        break;

776 

777      case OPT_Wunused:

778        set_Wunused (value);

779        break;

780 

781      case OPT_Wunused_function:

782        warn_unused_function = value;

783        break;

784 

785      case OPT_Wunused_label:

786        warn_unused_label = value;

787        break;

788 

789      case OPT_Wunused_parameter:

790        warn_unused_parameter = value;

791        break;

792 

793      case OPT_Wunused_value:

794        warn_unused_value = value;

795        break;

796 

797      case OPT_Wunused_variable:

798        warn_unused_variable = value;

799        break;

 

上面,所遭遇的选项及相关的变量有:

g_switch_value-G number),将小于number字节的全局及静态对象置于小的数据或bss段,而不是普通的数据段或bss段。默认的number值是8。选项-msdata必须被设为sdata或能使得该选项起作用。所有模块必须使用同一组-msdata-G设置来编译。使用不同的number值,编译可能能正常工作,也可能不正常。如果不正常,链接器将检出错误,以避免产生错误的代码。

又在697行,选项–Wset_Wextra来处理。

 

1555 static void

1556 set_Wextra (int setting)                                                                                    in opts.c

1557 {

1558   extra_warnings = setting;

1559   warn_unused_value = setting;

1560   warn_unused_parameter = (setting && maybe_warn_unused_parameter);

1561

1562   /* We save the value of warn_uninitialized, since if they put

1563     -Wuninitialized on the command line, we need to generate a

1564     warning about not using it without also specifying -O.  */

1565   if (setting == 0)

1566     warn_uninitialized = 0;

1567   else if (warn_uninitialized != 1)

1568     warn_uninitialized = 2;

1569 }

 

-W 这个选项启动了一族警告。这些警告主要涉及可能导致问题的代码,但这些代码可能是编程者故意为之。这个选项将启动如下所有:

Comparison 如果一个无符号值测试小于0,发出警告。例如,因为无符号值不会为负数,下列测试永远为false

unsigned int x;

. . .

if(x < 0) . . .

Comparison 如果一个有符号值与无符号值比较,发出警告。当一个无符号值转换为有符号值用于比较时,可能会产生不正确的结果。这个警告可被-Wno-sign-compare压制。

Comparison 代数记符和C句法,在表示比较方面是不同的。下面的语句将触发警告:

if(a < b < c) . . .

在代数记符中,这个表达式是true仅当bac的开区间内。在C里,这个表达式与下列表达式等效,含义大不相同:

int result;

result = a < b;

if(result < b) . . .

Const return 警告函数的返回值被声明为const。在这里的const声明没有任何意义,因为函数返回值是一个右值。

Aggregate initializers 警告一个聚集类的初始化值,这个值不能涵盖聚集类的所有成员。在下面的例子中,数组和结构体均被警告:

struct {

int a;

int b;

int c;

} trmp = { 1, 2 };

int arr[10] = { 1, 2, 3, 4, 5 };

No side effect 警告一条没有副作用的语句。例如,下面加法的结果就没有被使用:

int a = 1;

int b = 2;

a + b;

Overflow Fortran中,警告浮点常量声明的溢出。

Return value 警告函数被写成可能返回或不返回值,象下例中,如果x是负数,函数不返回值:

ambigret(int x) {

if(x >= 0)

return(x);

}

Static syntax 警告关键字static不是第一个出现在声明行上。这个次序已不再被标准C要求。

Unused arguments 如果-Wall-Wunused,和-W一起使用,警告在函数体内未被使用的参数。

warn_inlineCC++ObjC-Winline)如果非0,警告函数被声明为内联但不能展开为内联。

warn_larger_thanCC++ObjC-Wlarger-than)如果非0,警告声明一个大于特定字节数的对象,及一个函数的返回值大于特定字节数。

warn_aggregate_returnCC++ObjC-Waggregate-return)如果非0,警告函数返回一个结构体,union或者数组。

warn_cast_alignCC++ObjC-Wcast-align)如果非0,警告将一指针转换为不同类型者,可能会因对齐而导致问题。例如,在一些机器上,可能只可以在24的边界上访问一个int,因此将一个char指针转换为一个int指针会导致无效的地址值。

warn_deprecated_declCC++ObjC-Wdeprecated-declaration)如果非0,警告使用了过时的特性,除非指明-Wno-deprecated-declarations

warn_disabled_optimization-Wdisabled-optimization)如果非0,警告所要求的优化被失能。这个情况的发生不是由于代码的问题,而是因为编译器本身的限制。GCC将拒绝执行太复杂及需时太多的优化。

warn_missing_noreturn,如果非0,警告函数可能是noreturn属性的候选。

warn_packed,如果非0,警告结构体所应用的packed属性是不必要及低效的。

warn_padded,如果非0,警告gcc填充结构体至对齐边界。

warn_shadow,如果非0,警告声明将屏蔽其他声明。

warn_switch_defaul,如果非0,警告switch缺少default项。

warn_switch_enum,如果非0,警告应用enumswitch语句不能覆盖所有枚举值。

warn_system_headersC, C++, ObjC, -Wsystem-headers)如果非0,对系统头文件亦发出警告信息。通常系统头文件导致的警告会被压制。要对系统头文件中的不能识别之pragmas产生警告,需指明-Wunknown-pragmas,因为使用-Wall仅检查程序中的pragmas,而忽略在系统头文件中的pragmas

warn_notreached,如果非0,警告不能到达之代码。

 

common_handle_option (continue)

 

801      case OPT_aux_info:

802      case OPT_aux_info_:

803        aux_info_file_name = arg;

804        flag_gen_aux_info = 1;

805        break;

806 

807      case OPT_auxbase:

808        aux_base_name = arg;

809        break;

810 

811      case OPT_auxbase_strip:

812      {

813        char *tmp = xstrdup (arg);

814        strip_off_ending (tmp, strlen (tmp));

815        if (tmp[0])

816          aux_base_name = tmp;

817      }

818      break;

819 

820      case OPT_d:

821        decode_d_option (arg);

822        break;

823 

824      case OPT_dumpbase:

825        dump_base_name = arg;

826        break;

827 

828      case OPT_fPIC:

829        flag_pic = value + value;

830        break;

831 

832      case OPT_fPIE:

833        flag_pie = value + value;

834        break;

835 

836      case OPT_fabi_version_:

837        flag_abi_version = value;

838        break;

839 

840      case OPT_falign_functions:

841        align_functions = !value;

842        break;

843 

844      case OPT_falign_functions_:

845        align_functions = value;

846        break;

847 

848      case OPT_falign_jumps:

849        align_jumps = !value;

850        break;

851 

852      case OPT_falign_jumps_:

853        align_jumps = value;

854        break;

855 

856      case OPT_falign_labels:

857        align_labels = !value;

858        break;

859 

860      case OPT_falign_labels_:

861        align_labels = value;

862        break;

863 

864      case OPT_falign_loops:

865        align_loops = !value;

866        break;

867 

868      case OPT_falign_loops_:

869        align_loops = value;

870        break;

871 

872      case OPT_fargument_alias:

873        flag_argument_noalias = !value;

874        break;

875 

876      case OPT_fargument_noalias:

877        flag_argument_noalias = value;

878        break;

879 

880      case OPT_fargument_noalias_global:

881        flag_argument_noalias = value + value;

882        break;

883 

884      case OPT_fasynchronous_unwind_tables:

885        flag_asynchronous_unwind_tables = value;

886        break;

887 

888      case OPT_fbounds_check:

889        flag_bounds_check = value;

890        break;

891 

892      case OPT_fbranch_count_reg:

893        flag_branch_on_count_reg = value;

894        break;

895 

896      case OPT_fbranch_probabilities:

897        flag_branch_probabilities_set = true;

898        flag_branch_probabilities = value;

899        break;

900 

901      case OPT_fbranch_target_load_optimize:

902        flag_branch_target_load_optimize = value;

903        break;

904 

905      case OPT_fbranch_target_load_optimize2:

906        flag_branch_target_load_optimize2 = value;

907        break;

 

aux_info_file_nameC-aux-info filename)输出在单一编译单元(一个C源文件及所有包含的头文件)中声明或定义的函数原型声明至命名文件。

flag_gen_aux_info,如果非0,表示将声明信息保存在一个.X后缀文件内。

aux_base_name-auxbase-auxbase-strip)指明用作辅助输出文件的不带后缀名。

flag_abi_version-fabi-version=)表示所使用的C++ ABI的版本。以下值是所允许的:

0 ABI的版本确信符合C++ ABI的规范。这个ABI可能因为bug的发现及修正而修改。因此,在不同G++版本中,表示相同的ABI0是不足够的。

1 该版本的ABI首先用于G++ 3.2

2 该版本的ABI首先用于G++ 3.4

额外的整数将被用于作为默认版本的新版本ABI

flag_argument_noalias取以下值:

0 如果指针参数可互为别名。在C中为true

1 如果指针参数不能互为别名,但可为全局变量的别名。

2 如果指针参数不能互为别名,亦不能为全局变量的别名。在fortran中为true

对于C,默认值为0。并且其值可由下列选项设定。

-fargument-alias 表明传给函数的实参可能互为别名。亦即,2个或多个参数可能访问同一内存位置。亦可能一实参是一全局值的别名。对于CC++ObjC,这是默认选项。

-fargument-noalias 表明传给函数的实参不互为别名。亦即,2个或多个参数不会访问同一内存位置。然而,有可能一实参是一全局值的别名。

-fargument-noalias-global表明传给函数的实参不互为别名。亦即,2个或多个参数不会访问同一内存位置。同时该实参亦不会是全局值的别名。

flag_bounds_check-fbounds-check)导致gcc进行数组边界检查。对于CC++ObjC,默认为关。对于Java,默认为开。对于Fortran,默认为关。

flag_branch_on_count_reg-fbranch-count-reg)如果非0,表示试图替换加-1,比较,跳转元组(tupple)为基于计数寄存器(count register)的更低代价的跳转。

flag_branch_probabilities-fbranch-probabilities)如果非0,在使用-fprofile-arcs进行编译,并运行编译所得程序,以得到包含代码每个块执行计数的文件后,使用这个选项重新编译程序,使用前生成文件中的信息,对最频繁的跳转进行优化。没有这些信息,GCC则只能猜测哪条路径最可能执取而进行优化。这些信息保存在与源文件同名具有.da后缀的文件中。

flag_branch_target_load_optimize-fbranch-target-load-optimize)如果非0,在序言/结尾线程(prologue / epilogue threading)前执行跳转目的加载优化(branch target load optimization

flag_branch_target_load_optimize2-fbranch-target-load-optimize2)如果非0,在序言/结尾线程(prologue / epilogue threading)后执行跳转目的加载优化(branch target load optimization)。

 

你可能感兴趣的:(fortran,compiler,deprecated,branch,loops,optimization)