让我们解释一下GCC 5.1的源代码,看看O上发生了什么,因为在手册页上不清楚。

我们将得出结论:

O以上-O的任何内容与Os相同,但未来可能很容易改变,所以不要依赖它。

如果输入大于O的整数,GCC 5.1将运行未定义的行为。

参数只能有数字,或者优雅地失败。 特别是,这不包括像O这样的负整数

专注于子程序

首先要记住GCC只是O,-O,Os,collect2的前端。快速./XXX --help表示只有collect2和cc1需要-O,所以让我们关注它们。

和:

gcc -v -O100 main.c |& grep 100

得到:

COLLECT_GCC_OPTIONS='-O100' '-v' '-mtune=generic' '-march=x86-64'

/usr/local/libexec/gcc/x86_64-unknown-linux-gnu/5.1.0/cc1 [[noise]] hello_world.c -O100 -o /tmp/ccetECB5.

所以O被转发到-O和Os。

O在common.opt中

common.opt是内部文档中描述的GCC特定的CLI选项描述格式,并由opth-gen.awk和optc-gen.awk翻译为C.

它包含以下有趣的行:

O

Common JoinedOrMissing Optimization

-O Set optimization level to

Os

Common Optimization

Optimize for space rather than speed

Ofast

Common Optimization

Optimize for speed disregarding exact standards compliance

Og

Common Optimization

Optimize for debugging experience rather than speed or size

其中指定了所有O选项。 注意-O是如何与其他Os,OPT_O和O分开列入独立系列的。

当我们构建时,这会生成一个OPT_O文件,其中包含:

OPT_O = 139, /* -O */

OPT_Ofast = 140, /* -Ofast */

OPT_Og = 141, /* -Og */

OPT_Os = 142, /* -Os */

作为奖励,虽然我们在OPT_O里面的OPT_O,我们注意到这些线路:

-optimize

Common Alias(O)

它告诉我们OPT_O(双击,因为它以opts.c:default_options_table文件中的短划线O开头)是-O的无证别名,可以用作--optimize=3!

使用OPT_O的地方

现在我们grep:

git grep -E '\bOPT_O\b'

这指向我们两个文件:

opts.c

LTO-wrapper.c

我们先来追踪OPT_O

opts.c:default_options_optimization

所有OPT_O用法发生在:O。

我们回溯看看谁调用了这个函数,我们看到唯一的代码路径是:

OPT_O

OPT_O

OPT_O

OPT_O

和OPT_O是O的切入点。好!

这个功能的第一部分:

OPT_O在对应于opts.c:default_options_table的字符串上调用O来解析输入参数

将值存储在OPT_O中,其中O是opts.c:default_options_table。

struct gcc_opts

在徒劳地贪图之后,我们注意到这个OPT_O也生成于O:

struct gcc_options {

int x_optimize;

[...]

}

其中OPT_O来自以下行:

Variable

int optimize

目前在OPT_O,和O:

struct gcc_options global_options;

所以我们猜测这是包含整个配置全局状态的,OPT_O是优化值。

255是内部最大值

在OPT_O,O中应用于输入参数,因此opts.c:default_options_table是上限。 如果你把任何更大的东西,似乎GCC运行C未定义的行为。 哎哟?

OPT_O也会精简包装O,如果任何字符不是数字,则拒绝该参数。 所以负值优雅地失败了。

回到OPT_O,我们看到了这一行:

if ((unsigned int) opts->x_optimize > 255)

opts->x_optimize = 255;

所以优化级别被截断为OPT_O.在阅读O时,我遇到过:

# All of the optimization switches gathered together so they can be saved and restored.

# This will allow attribute((cold)) to turn on space optimization.

并在生成的OPT_O上:

struct GTY(()) cl_optimization

{

unsigned char x_optimize;

这解释了为什么截断:选项也必须转发到OPT_O,它使用O来节省空间。 所以255实际上是一个内部最大值。

opts.c:maybe_default_options

返回OPT_O,我们看到O,听起来很有趣。 我们输入它,然后我们到达一个大开关的opts.c:default_options_table:

switch (default_opt->levels)

{

[...]

case OPT_LEVELS_1_PLUS:

enabled = (level >= 1);

break;

[...]

case OPT_LEVELS_3_PLUS:

enabled = (level >= 3);

break;

没有OPT_O检查,这表明O是最大可能的。

在O上搜索OPT_O的定义:

enum opt_levels

{

OPT_LEVELS_NONE, /* No levels (mark end of array). */

OPT_LEVELS_ALL, /* All levels (used by targets to disable options

enabled in target-independent code). */

OPT_LEVELS_0_ONLY, /* -O0 only. */

OPT_LEVELS_1_PLUS, /* -O1 and above, including -Os and -Og. */

OPT_LEVELS_1_PLUS_SPEED_ONLY, /* -O1 and above, but not -Os or -Og. */

OPT_LEVELS_1_PLUS_NOT_DEBUG, /* -O1 and above, but not -Og. */

OPT_LEVELS_2_PLUS, /* -O2 and above, including -Os. */

OPT_LEVELS_2_PLUS_SPEED_ONLY, /* -O2 and above, but not -Os or -Og. */

OPT_LEVELS_3_PLUS, /* -O3 and above. */

OPT_LEVELS_3_PLUS_AND_SIZE, /* -O3 and above and -Os. */

OPT_LEVELS_SIZE, /* -Os only. */

OPT_LEVELS_FAST /* -Ofast only. */

};

哈! 这是一个强有力的指标,只有3个级别。

opts.c:default_options_table

OPT_O非常有趣,我们grep O,并且翻译为opts.c:default_options_table:

static const struct default_options default_options_table[] = {

/* -O1 optimizations. */

{ OPT_LEVELS_1_PLUS, OPT_fdefer_pop, NULL, 1 },

[...]

/* -O3 optimizations. */

{ OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },

[...]

}

所以这是对文档中提到的特定优化映射进行编码的OPT_O。太好了!

确保x_optimize没有更多用途

OPT_O的主要用途是设置其他特定的优化选项,如手册页中记录的O。 还有吗?

我们OPT_O,并找到更多。 数量很小,经过人工检查,我们发现每次使用最多只能进行O,所以我们的结论是成立的。

LTO-wrapper.c

现在我们去第二次出现OPT_O,这是在O。

LTO意味着链接时间优化,顾名思义它将需要OPT_O选项,并且将链接到O(基本上是链接器)。

事实上,第一行OPT_O说:

/* Wrapper to call lto. Used by collect2 and the linker plugin.

在这个文件中,OPT_O的出现似乎只是将O的值标准化为向前传递,所以我们应该没问题。

优化级别linux gcc,c - 有多少GCC优化级别?相关推荐

  1. linux异常级别,linux性能异常定位之进程级别

    [前言] 本文和大家分享:linux系统下常见得性能异常,怎样定位到进程级别.说简单点,就是:linux性能出问题了,我们需要确定哪些进程影响了linux的性能. 本文主要涉及的linux的常见的性能 ...

  2. Linux【基础篇】—— linux操作系统目录结构、运行级别介绍

    目录 一.Linux 系统目录结构介绍 二.Linux 操作系统运行级别 1. 级别切换 2. 指定运行级别 一.Linux 系统目录结构介绍 Linux 的文件系统是采用层级形式的树状目录结构,最上 ...

  3. GCC编译器选项及优化提示

    很多弟兄可能都很关心如何优化编译自己的程序,虽然本人不赞成"骨灰"玩法,却也不得不承认这是掌握gcc的绝佳途径: 因此献上此帖,以供各位玩家参考,绝对原创噢 =========== ...

  4. GCC中常用的优化的参数

    -pipe 的作用: 使用管道代替编译中临时文件, -pipe 加速编译 gcc -pipe foo.c -o foo 加速 在将源代码变成可执行文件的过程中,需要经过许多中间步骤,包含预处理.编译. ...

  5. gcc/g++编译器的优化

    gcc/g++编译器的优化 gcc提供了从O0-O3以及Os这几种不同的优化级别供大家选择 O0是编译器默认的设置 (1).-O1:它主要对代码的分支,常量以及表达式等进行优化 (2).-O2:尝试更 ...

  6. 嵌入式linux内存使用和性能优化

    这本书有两个关切点:系统内存(用户层)和性能优化. 这本书和Brendan Gregg的<Systems Performance>相比,无论是技术层次还是更高的理论都有较大差距.但是这不影 ...

  7. 【CentOS Linux 7】【gcc编译器】

    Linux系统及应用---调研报告 [CentOS Linux 7]实验1[VMware安装.新建虚拟机:63个基础命令运行结果图] [CentOS Linux 7]实验2[Shell编程及应用] [ ...

  8. Linux装c编译器gcc,c编译器进阶之路,linux下的gcc c编译器使用教程

    c编译器的重要性不言而喻,从往期c编译器文章中,如c编译器优化.选定c编译器等,想必大家对c编译器均已有所了解.往期文章中,小编主要从宏观方面为大家讲解c编译器,此外对于gcc c编译器的讲解也大多基 ...

  9. Linux | 编译原理、gcc的命令参数、自动化构建工具 make/Makefile

    文章目录 编译原理 预处理 编译 汇编 链接 gcc的常用命令参数 make 和 Makefile 的概念 make的运行 通配符 自动化变量 伪目标.PHONE:[命令] 编译原理 在解释 make ...

最新文章

  1. Matlab与数据结构 -- 对矩阵的排序
  2. 修改android4.0的鼠标箭头图标(方法)
  3. 到底应该加几个卷积核?
  4. 纯jsp实现评论功能_基于云开发的小程序版本更新、评论功能改进、后台管理的实现...
  5. 使用squid在阿里云服务器(centos7)上搭建自己的代理服务器
  6. JavaScript学习-1
  7. Feign深入学习(一)
  8. OutOfMemoryException异常解析
  9. php代理m3u8,PHP实现m3u8并发下载
  10. linux5.5 里dns,linux red hat 5.5 dns 问题求解
  11. 交换机IP-MAC地址绑定
  12. 基于人脸识别的课堂签到管理系统(五)---启动/结束签到,以及在百度智能云创建用户组
  13. 云上持续交付实践系列1 --- java 篇
  14. Spring深入学习之IOC与AOP
  15. html + CSS
  16. android instance区别,Android singleTask 和singleInstance的区别
  17. IOS开发之——音乐播放器-概述(01)
  18. mongo connect error no reachable servers
  19. 一文看懂π型滤波电路原理
  20. python 已知三角形的三条边,通过反三角函数计算出三角形的三个角;其中用到math的引用;

热门文章

  1. JavaScript进阶部分笔记
  2. Python colormap库的安装和使用
  3. Django自带的用户验证与事务管理的基本概念理解
  4. Pytorch《DCGAN模型》
  5. 漫步线性代数五——三角分解和行交换
  6. leetcode二分查找
  7. HTTP状态码及含义
  8. 多元正态分布的后验采样(包含程序)
  9. TensorFlow 第二步 小试牛刀:一个神经元
  10. OpenCV--读取图像中任意点的像素值,并显示坐标