【问题标题】:How to know what code has been optimized out?如何知道哪些代码已经优化出来了?
【发布时间】:2016-10-12 00:28:45
【问题描述】:

有没有办法在编译期间或编译后获取有关代码的哪些部分已优化的信息,但无需查看程序集或执行代码。

如果一个大的代码块被优化掉,马上知道会很好。

【问题讨论】:

  • 为什么会很高兴知道?这是优化器的工作,优化大块代码。它删除了复杂的抽象、辅助方法以及人类编写的各种东西,以使代码更易于阅读和推理。为什么你觉得你需要对优化器进行二次猜测?你有真正的问题吗?
  • @Cody Gray 它可能会暴露我正在编译的代码(甚至是编译器)中的错误,它会满足我的好奇心 :)

标签: gcc optimization clang compiler-optimization static-analysis


【解决方案1】:
gcc -S

将输出本应传递给汇编器的汇编代码(并最终链接到可执行文件中)。如果你眯着眼睛的方式正确(并且有耐心),你可以从那个角度向后工作,以确认给定的代码位是否实际包含在可执行文件中,或者被优化掉了。

显然你不会做某事,除非你怀疑事情正在发生,考虑到所需的时间和精力......

【讨论】:

  • 我知道-S,但希望有更直接的解决方案。
【解决方案2】:

抱歉,您的期望与编译器的实际操作不符。无论您是要查找死代码还是查找导致应该运行的代码被跳过的错误,编译器都无法以易于阅读的形式提供信息。

使用将每一行源代码转换为一系列机器指令的编译器,编译器可以很容易地告诉您它没有包含与特定行相对应的任何内容。当然它不能告诉你一行是否被翻译成机器指令,但这些机器指令实际上永远不会被执行——代码可达性是undecidable——但我不认为这就是你想要的。

问题在于现代优化编译器比这复杂得多。在不同的假设(专业化、部分评估、循环展开……)下,一段代码经常被复制和编译多次。或者,相反,可以将代码片段合并在一起(函数内联,......)。源代码和机器代码之间没有简单的对应关系。 (这就是为什么调试器有时无法报告二进制指令的确切源代码位置的原因。)

如果一大块代码被优化掉了,那可能只是因为它是许多专门化副本之一,而特定的专门化永远不会发生(例如,x==0x!=0 有单独的代码,y==0 有单独的代码和y!=0xy 永远不会一起为0,因此x==0 && y==0 分支最终被删除)。它可能是编译时条件指令生成的东西,例如编译器优化的 C 宏;这种情况在 C 代码中经常发生,如果编译器报告所有此类实例,则会产生大量误报。

获取可能未使用的代码或可能表明存在错误的可疑程序代码的有用报告需要一种与编译器完全不同的静态分析。有一些工具可以做到这一点,但它们通常与将源代码转换为优化的机器代码的工具不同。制作静态分析工具,既能经常检测潜在问题,又能发挥作用,又不会产生太多误报,以至于实际上无法使用,这并不容易。

【讨论】:

    猜你喜欢
    • 2015-02-10
    • 1970-01-01
    • 1970-01-01
    • 2011-03-14
    • 2018-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多