如何查看编译器应用于Swift代码的优化?

时间:2022-01-09 08:19:02

Specifically, I have some Swift 3.0 logging functions that wrap all of their statements in an if that only executes when an operation on two static const values bridged in from ObjC has a nonzero result.

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

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

Variables a and b are declared in my bridging header like this:

变量a和b在我的桥接头中声明如下:

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

Will the compiler elide the entire call to logStuff() when the result of a & b is zero and whole module optimization is enabled?

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

A specific answer to this question would be appreciated, but a way to easily see what optimizations are actually applied by LLVM in any situation would be ideal.

可以理解这个问题的具体答案,但是在任何情况下轻松查看LLVM实际应用的优化方法都是理想的。

1 个解决方案

#1


0  

If you build your own Swift compiler using your own LLVM compiled with instrumentation, you should be able to dump that info as described in the LLVM documentation Writing an LLVM Pass.

如果使用自己使用检测编译的LLVM构建自己的Swift编译器,则应该能够按照LLVM文档编写LLVM Pass中的描述转储该信息。

But optimization passes interact, can be run several times, and might not always do what you expect them to do. So you'd do better to check the specific cases you're concerned about experimentally and then inspecting the resulting binary.

但是优化传递交互,可以运行多次,并且可能并不总是按照您期望的方式执行。因此,您最好通过实验检查您关注的具体案例,然后检查生成的二进制文件。

Since it's a logging function and probably can be readily triggered dynamically, a (probably simpler) alternative to static inspection of the compiler output would be to run the executable under a debugger, set breakpoint on the function that you expect should not be called, and then carry out an action in the executable that would trigger a call if the call had not been optimized out.

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

Then, repeat the verification throughout the lifetime of the app, because the compiler and the source code continue to change. (Or decide that it's not a significant concern worth that degree of diligence.)

然后,在应用程序的整个生命周期内重复验证,因为编译器和源代码会继续更改。 (或者认为这不是值得那么勤奋的重要问题。)

#1


0  

If you build your own Swift compiler using your own LLVM compiled with instrumentation, you should be able to dump that info as described in the LLVM documentation Writing an LLVM Pass.

如果使用自己使用检测编译的LLVM构建自己的Swift编译器,则应该能够按照LLVM文档编写LLVM Pass中的描述转储该信息。

But optimization passes interact, can be run several times, and might not always do what you expect them to do. So you'd do better to check the specific cases you're concerned about experimentally and then inspecting the resulting binary.

但是优化传递交互,可以运行多次,并且可能并不总是按照您期望的方式执行。因此,您最好通过实验检查您关注的具体案例,然后检查生成的二进制文件。

Since it's a logging function and probably can be readily triggered dynamically, a (probably simpler) alternative to static inspection of the compiler output would be to run the executable under a debugger, set breakpoint on the function that you expect should not be called, and then carry out an action in the executable that would trigger a call if the call had not been optimized out.

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

Then, repeat the verification throughout the lifetime of the app, because the compiler and the source code continue to change. (Or decide that it's not a significant concern worth that degree of diligence.)

然后,在应用程序的整个生命周期内重复验证,因为编译器和源代码会继续更改。 (或者认为这不是值得那么勤奋的重要问题。)