【问题标题】:How can I see the optimizations that the compiler applies to my Swift code?如何查看编译器对我的 Swift 代码应用的优化?
【发布时间】:2017-03-17 07:25:08
【问题描述】:

具体来说,我有一些 Swift 3.0 日志记录函数,它们将所有语句包装在 if 中,仅当对从 ObjC 桥接的两个 static const 值的操作具有非零结果时才会执行。

func logStuff(_ message: @autoclosure () -> String) {
    if a & b != 0 {
        // log stuff here...
    }
}

变量ab 在我的桥接头中声明如下:

static const NSUInteger a = <some literal>;
static const NSUInteger b = <some literal>;

a &amp; b 的结果为零并且启用了整个模块优化时,编译器是否会忽略对logStuff() 的整个调用?

对此问题的具体答案将不胜感激,但理想的方法是轻松查看 LLVM 在任何情况下实际应用了哪些优化。

【问题讨论】:

  • 您可以完全绕过这个问题:为什么不直接使用已建立的日志框架?
  • 已经在使用 CocoaLumberjack。尝试为 ObjC 复制 here 中描述的“细粒度日志记录”,而不会对生产环境造成性能影响。
  • 编译器有一些开关可以在不同阶段后为您提供结果,例如-emit-assembly.

标签: swift compilation swift3 llvm


【解决方案1】:

如果您使用自己的通过仪器编译的 LLVM 构建自己的 Swift 编译器,您应该能够按照 LLVM 文档Writing an LLVM Pass 中的描述转储该信息。

但优化过程会相互影响,可以运行多次,并且可能并不总是按照您的预期进行。因此,您最好通过实验检查您关注的特定情况,然后检查生成的二进制文件。

由于它是一个日志记录功能并且可能很容易被动态触发,一个(可能更简单的)编译器输出静态检查的替代方法是在调试器下运行可执行文件,在您期望的函数上设置断点不应该是调用,然后在可执行文件中执行一个动作,如果调用没有被优化,就会触发调用。

然后,在应用的整个生命周期内重复验证,因为编译器和源代码会不断变化。 (或者认为这不是一个值得如此努力的重大问题。)

【讨论】:

    猜你喜欢
    • 2011-05-26
    • 2017-07-28
    • 2011-10-27
    • 1970-01-01
    • 2016-02-14
    • 1970-01-01
    • 1970-01-01
    • 2011-03-26
    • 2010-12-02
    相关资源
    最近更新 更多