[GCC学习]get the optimized function call graph

2023-11-08

当GCC以优化方式编译代码的时候,它会执行Dead Code Elimiation(DCE), 就是把那些源代码中定义但是却从未调用到的函数从中间目标文件中去掉.(.o文件)

例如下面这段代码:

#include <stdio.h>

static void test() {

printf ("this code is never called.");

}

int main() {

printf("this is main function.");

return 0;

}

这里我们定义了一个static函数和一个main函数.按照C语言的约定,static 函数是只在当前模块可见, 非static函数则可被其它模块所包含. 

然后我们通过检查使用和不使用DCE时,GCC的汇编输出来观察DCE的作用.

不使用DCE:

gcc -S -fno-builtin -fdump-ipa-cgraph test.c  -o test.S

这里生成汇编结果说明了DCE的过程是在编译阶段已经完成, 命令中

-fdump-ipa-cgraph, 这是个调试输出选项,会生成一个.cgraph文件,我们后面会进一步查看这个文件.

查看test.S可以发现_test这个函数的定义出现在汇编代码中, 

ContractedBlock.gif ExpandedBlockStart.gif test.S
 1     .cstring
 2 LC0:
 3     .ascii "Hello World\12\0"
 4     .text
 5 _test:
 6     pushl   %ebp
 7     movl    %esp, %ebp
 8     subl    $24, %esp
 9     call    L3
10 "L00000000001$pb":
11 L3:
12     popl    %ecx
13     leal    LC0-"L00000000001$pb"(%ecx), %eax
14     movl    %eax, -16(%ebp)
15     leave
16     ret
17 .globl _main
18 _main:
19     pushl   %ebp
20     movl    %esp, %ebp
21     pushl   %ebx
22     subl    $20, %esp
23     call    L6
24 "L00000000002$pb":
25 L6:
26     popl    %ebx
27     leal    LC0-"L00000000002$pb"(%ebx), %eax
28     movl    %eax, (%esp)
29     call    L_printf$stub
30     movl    $0, %eax
31     addl    $20, %esp
32     popl    %ebx
33     leave
34     ret
35     .section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
36 L_printf$stub:
37     .indirect_symbol _printf
38     hlt ; hlt ; hlt ; hlt ; hlt
39     .subsections_via_symbols
40 
41 

 

如果编译生成.o文件的话,使用nm工具可以看到中间目标文件中的符号定义中也存在test这个函数.

nm  test .o

00000017  T _main
              U _printf
00000000  t _test

 

接下来打开DCE开关看看:

gcc -O -S -fno-builtin -fdump-ipa-cgraph test.c -o test.S

ContractedBlock.gif ExpandedBlockStart.gif test.S
 1     .cstring
 2 LC0:
 3     .ascii "Hello World\12\0"
 4     .text
 5 .globl _main
 6 _main:
 7     pushl   %ebp
 8     movl    %esp, %ebp
 9     pushl   %ebx
10     subl    $20, %esp
11     call    L3
12 "L00000000001$pb":
13 L3:
14     popl    %ebx
15     leal    LC0-"L00000000001$pb"(%ebx), %eax
16     movl    %eax, (%esp)
17     call    L_printf$stub
18     movl    $0, %eax
19     addl    $20, %esp
20     popl    %ebx
21     leave
22     ret
23     .section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
24 L_printf$stub:
25     .indirect_symbol _printf
26     hlt ; hlt ; hlt ; hlt ; hlt
27     .subsections_via_symbols
28 
29 

 

 

 可以看到,test函数已经不在了.nm中也不见了_test符号.

00000000  T _main
              U _printf

 

随汇编过程,GCC还会生成一个.cgraph的文件,这里面记录了gcc移除函数过程.

ContractedBlock.gif ExpandedBlockStart.gif cgraph
 1 Initial entry points: main
 2 Unit entry points: main
 3 
 4 Initial callgraph:
 5 
 6 main/416 insns needed tree inlinable
 7   called by:
 8   calls: printf/3
 9 printf/3:
10   called by: main/4
11   calls:
12 test/2: tree
13   called by:
14   calls:
15 __sputc/1: tree
16   called by:
17   calls:
18 __swbuf/0:
19   called by:
20   calls:
21 
22 Reclaiming functions: test __sputc
23 
24 Reclaimed callgraph:
25 
26 main/416 insns needed tree inlinable
27   called by:
28   calls: printf/3
29 printf/3:
30   called by: main/4
31   calls:
32 __swbuf/0:
33   called by:
34   calls:
35 
36 Marking local functions:
37 
38 Marked callgraph:
39 
40 main/416 insns needed tree inlinable
41   called by:
42   calls: printf/3
43 printf/3:
44   called by: main/4
45   calls:
46 __swbuf/0:
47   called by:
48   calls:
49 
50 Deciding on inlining.  Starting with 16 insns.
51 
52 Inlining always_inline functions:
53 
54 Deciding on smaller functions:
55 
56 Deciding on functions called once:
57 
58 Reclaiming functions: __swbuf
59 Reclaimed 0 insns
60 Inlined 0 calls, eliminated 0 functions, 16 insns turned to 16 insns.
61 
62 Optimized callgraph:
63 
64 main/416 insns needed tree inlinable
65   called by:
66   calls: printf/3
67 printf/3:
68   called by: main/4
69   calls:
70 
71 Final callgraph:
72 
73 main/416 insns needed inlinable asm_written
74   called by:
75   calls:
76 printf/3:
77   called by:
78   calls: 

 

 

转载于:https://www.cnblogs.com/jonnyyu/archive/2009/05/20/1473549.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[GCC学习]get the optimized function call graph 的相关文章

  • windows虚拟机安装Mac OS系统(操作图解)

    背景 因为工作需要学习ios开发 但是苹果电脑申请了还没审批下来所以想着先搭建一个虚拟机来熟悉开发环境 安装环境 windows vmware 16 Pro 一 准备工作 1 vmware 16 Pro 下载 2 unlocker 下载地址
  • 隐藏WiFi信号的小技巧

    隐藏WiFi信号方法 首先用手机或电脑连上路由器的WiFi网络 在浏览器地址栏输入路由器登陆地址并打开 地址一般在路由器的底部都有标注的 输入用户名与密码 很多路由器默认的账号 密码都是admin 进入路由器管理界面找到无线设置 然后找到
  • java版本微信机器人使用教程V1.0

    大家好 我是雄雄 欢迎关注微信公众号雄雄的小课堂 现在是 2023年5月10日17 57 02 免费的云桌面 每个人都能领三个月 用来跑机器人还是很不错的 领取连接 前言 历经好多天 java版本的微信机器人终于写完了初版了 接下来开放注册
  • 面向对象课程学习

    设计一般流程 黑盒 1用例分析 白盒 2 识别类 分析阶段只identify 问题领域的类 设计阶段可能添加软件世界特有的类 或者 3 识别类之间的关系 关联 泛化 聚合 组合 依赖 4 画顺序图 结合用例图 完善类图 类图是结构设计 顺序
  • 工具使用:ImageTools图片处理 (ImageMagick)

    需要注意的是 在mac和linux上不要添加imageMagickPath 和设置 convert setSearchPath imageMagickPath public class ImageTools ImageMagick的路径 p
  • python实验1

    在pycharm中编写一个Python程序 导入数学模块math 从键盘输入一个整数 然后调用Math中的数学函数sqrt 计算该数的平方根 输出结果 第一种 a float input 请输入一个整数 x a 0 5 print x 运行
  • Vulkan是什么?和我一起完成一个简单的Vulkan应用程序

    Vulkan是什么 和我一起完成一个简单的Vulkan应用程序 在本章 你将学到 Vulkan以及它背后的基本原理 如何创建一个最简单的Vulkan应用程序 在本书其余部分将使用到的术语和概念 本章将介绍并解释Vulkan是什么 我们会介绍
  • 敲七游戏-java

    题目描述 写程序无聊 玩个游戏 从1开始喊数 数到含7或者是7的倍数的要拍键盘 那么问题来了 请你 输出7和7的倍数 还有包含7的数字例如 17 27 37 70 71 72 73 输入 一个整数N N不大于30000 输出 统计出不大于N
  • 蓝库云|一文搞懂什么是MES(制造执行系统),制造业该如何选择

    MES Manufacturing Execution System 是一种将制造过程可视化并为工人提供指导和支持的系统 它的优势在于可以优化人员 机器和设备等资源 消除制造对个人技能的依赖 在本文中 蓝库云将以通俗易懂的方式说明MES的概
  • 【CV】扩散模型(Diffusion Models)

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • Apple(苹果)忘记安全问题答案怎么办?

    方法一 通过 救援电子邮件 找回 其实 针对 忘记Apple ID安全提示问题的答案 这个问题 苹果官方有一个专门的指导页面 http support apple com kb HT6170 viewlocale zh CN 里面有非常详细
  • buuctf-misc(部分)

    爱因斯坦 附件下载下来是一张图片 先用winhex看下 典型的压缩文件形式 binwalk 分离前先把上次的output文件夹删除 老一套 加密的文件 但这次题目没有给我们具体的提示 先猜测一手题目名爱因斯坦是4位 先尝试一下4位数纯数字密
  • java基础01:==与equals

    Java数据类型在执行过程中存储在两种不同形式的内存中 栈和堆 它们通常由运行Java虚拟机 JVM 的底层平台维护 基础类型是直接在栈中分配的 引用类型是引用了堆中的内存地址 对比的是栈中的值 基本数据类型是变量值 引用类型是堆中内存对象
  • @ControllerAdvice注解的使用

    系列文章目录 SpringBoot框架实现邮件发送 上 SpringBoot框架实现邮件发送 下 Java中获取控制台输出的数据 Spring Cache的详细使用 Redis 文章目录 系列文章目录 前言 一 ControllerAdvi
  • Idea|Failed to configure a DataSource: ‘url‘ attribute is not specified and no embedded datasource c

    问题排查 1 问题背景 2 问题截图 3 问题分析 4 问题解决 号外 后续补充的解决办法 5 一句话复盘 1 问题背景 从仓库拉去代码以后 通过idea进行import 往事俱备 启动服务 然后 出现了一个错误提示信息 Descripti
  • 2017 Uri Shalit & Fredrik D. Johansson:Jobs

    1986年 Lalonde公开的一个数据集 被因果推理社区作为了基准数据集 在该数据集中 干预 即Treatment 为是否接受就业培训 结果 Outcomes 是收入和就业状况 2005年 Smith Todd结合了国家对工作工程统计的观
  • javaweb设计简易计算器

    javaweb设计简易计算器
  • 3、常用关键字,变量赋值,多个变量赋值,标准数据类型,数字,字符串,列表,元组,字典,数据类型转换

    3Python变量类型 3 1常用关键字 系统中有一些常用关键字不可以用来当做标识符 and lambda except while del return import or class try if assert yield as in
  • 【MySQL】 MySQL 隐式转换的坑,差点把数据库搞挂了

    MySQL 隐式转换的坑 差点把数据库搞挂了 同事接到这个任务 于是开始在测试环境拼装这条 SQL 刚过了几分钟 同事已经自信的写好了这条SQL 于是拿给DBA 到线上跑一下 用客户端工具导出Excel 就好了 毕竟是临时方案嘛 就在SQL
  • 函数图像与MatLab实现(1)

    当函数图像与代码相遇 Mablat学过数学或者接触过计算机的同学可能都已经非常熟悉 我也是刚刚才学习了有关matlab的一些编程 有感而发 写下第一篇博客 简介一下matlab matlab简介 MATLAB和Mathematica Map

随机推荐