Sun Studio 12:C 用户指南

B.2.93 -xipo[= a]

(SPARC) 用 012 替换 a。不带任何参数的 -xipo-xipo=1 等效。-xipo=0 是缺省设置,并会关闭 -xipo。在 -xipo=1 时,编译器会跨所有源文件执行内联。

-xipo=2 时,编译器执行过程间调用别名分析同时优化内存分配和布局,以提高缓存的性能。

编译器可通过调用过程间分析组件执行部分程序优化。不同于 -xcrossfile-xipo 在链接步骤中跨所有目标文件执行优化,并且不限于编译命令的源文件。但是,正如 -xcrossfile 一样,使用 -xipo 执行的整个程序优化不包括汇编 (.s) 源文件。

编译时和链接时都必须指定 -xipo。有关在编译时和链接时都必须指定的所有编译器选项的完整列表,请参见表 A–2

由于跨文件执行优化时需要附加信息,因此 -xipo 选项会生成更大的目标文件。不过,该附加信息不会成为最后可执行的二进制文件的一部分。可执行程序大小的增加都是由于执行的附加优化导致的。在编译步骤中创建的目标文件具有在这些文件内编译的附加分析信息,这样就可以在链接步骤中执行跨文件优化。

在编译和链接大型多文件应用程序时,-xipo 特别有用。使用此标志编译的目标文件具有在其内部编译的分析信息,这样就可以跨源文件和预编译的程序文件进行过程间分析。

不过,分析和优化只限于用 -xipo 编译的目标文件,而不扩展到库或目标文件。

-xipo 是多阶段的,因此如果要在单独的步骤中进行编译和链接,需要为每一步指定 -xipo

关于 -xipo 的其他重要信息:

B.2.93.1 示例

在此例中,编译和链接在单独的步骤中进行:


cc -xipo -xO4 -o prog part1.c part2.c part3.c

优化器在三个源文件之间执行交叉文件内联。这是在最终链接步骤中完成的,因此源文件的编译不必全部在单个编译中进行,可以通过多个单独的编译来进行,且每个编译都要指定 -xipo

在此例中,编译和链接在单独的步骤中进行:


cc -xipo -xO4 -c part1.c part2.c
cc -xipo -xO4 -c part3.c
cc -xipo -xO4 -o prog part1.o part2.o part3.o

即使用 -xipo 编译,仍存在库不参与交叉文件过程间分析的约束,如下例所示:


cc -xipo -xO4 one.c two.c three.c
ar -r mylib.a one.o two.o three.o
...
cc -xipo -xO4 -o myprog main.c four.c mylib.a

在此例中,过程间调用优化是在以下例程之间执行的:one.ctwo.cthree.c 之间,main.c four.c 之间,但不在 main.cfour.cmylib.a 上的例程之间执行。(第一次编译可能产生未定义符号警告,但是由于它是编译与链接步骤,所以会执行过程间调用优化。)

B.2.93.2 何时不使用 -xipo=2 过程间分析

在链接步骤中使用目标文件集合时,编译器试图执行整个程序分析和优化。对于该目标文件集合中定义的任何函数或子例程 foo(),编译器做出以下两个假定:

如果假定 2 不成立,则既不要使用 -xipo=1 也不要使用 -xipo=2 编译。

例如,考虑使用您自己的版本干预函数 malloc() 并使用 -xipo=2 编译。因此,任何库中引用与您的代码链接的 malloc() 的所有函数也必须使用 -xipo=2 编译,并且它们的目标文件需要参与链接步骤。由于这对于系统库不大可能,因此不要使用 -xipo=2 编译您的 malloc 版本。

另举一例,假设您使用位于两个不同源文件中的两个外部调用 foo() 和 bar() 生成一个共享库。然后,假设 bar() 调用 foo()。如果有可能在运行时干预 foo(),则不要使用 -xipo=1-xipo=2 编译 foo() 或 bar() 的源文件。否则,foo() 会内联到 bar() 中,从而导致出现错误的结果。