-xipo 选项通过调用过程间分析传递来执行部分程序优化。与 -xcrossfile 不同,-xipo 会对链接步骤中的所有目标文件执行优化,且优化不限于只是编译命令中的那些源文件。但是,和 -xcrossfile 一样,使用 -xipo 执行的整个程序优化不包括汇编 (.s) 源文件。
编译和链接大型多文件应用程序时,-xipo 选项特别有用。用该标志编译的对象目标文件具有在这些文件内编译的分析信息,这些信息实现了在源代码和预编译的程序文件中的过程间分析。但分析和优化只限于使用 -xipo 编译的目标文件,并不扩展到目标文件或库。
-xipo 选项可以是下列值。
表 A–35 -xipo 值
值 |
含义 |
---|---|
0 |
不执行过程间的优化 |
1 |
执行过程间的优化 |
2 |
执行过程间的别名分析和内存分配及布局的优化,以提高缓存的性能 |
如果未指定 -xipo,则假定 -xipo=0。
如果仅指定了 -xipo,则假定 -xipo=1。
以下示例在相同的步骤中编译和链接。
example% CC -xipo -xO4 -o prog part1.cc part2.cc part3.cc |
优化器在三个源文件之间执行交叉文件内联。这在链接的最后一步完成,因此不必在一次编译所有源文件,可以分多次单独进行编译,每次编译时都指定 -xipo 选项。
以下示例在不同的步骤中编译和链接。
example% CC -xipo -xO4 -c part1.cc part2.cc example% CC -xipo -xO4 -c part3.cc example% CC -xipo -xO4 -o prog part1.o part2.o part3.o |
在编译步骤中创建的目标文件具有在文件内部编译的附加分析信息,这样就可以在链接步骤中执行跨文件优化。
-xipo 选项要求优化级别至少为 -xO4。
不能在同一编译器命令行上同时使用 -xipo 选项和 -xcrossfile 选项。
在不同的步骤中进行编译和链接时,必须在这两个步骤中都指定 -xipo 才有效。
没有使用 -xipo 编译的对象可以自由地与使用 -xipo 编译的对象链接。
即使使用 -xipo 对库进行了编译,这些库也不参与交叉文件的过程间分析,如以下示例中所示。
example% CC -xipo -xO4 one.cc two.cc three.cc example% CC -xar -o mylib.a one.o two.o three.o ... example% CC -xipo -xO4 -o myprog main.cc four.cc mylib.a |
本示例中,在 one.cc、two.cc 和 three.cc 之间以及main.cc 和 four.cc 之间执行过程间优化,但不在 main.cc 或 four.cc 和 mylib.a 中的例程之间执行过程间优化。(第一个编译可能生成有关未定义符号的警告,但仍可执行过程间优化,因为过程间优化是编译和链接的一个步骤。)
由于跨文件执行优化时需要附加信息,因此 -xipo 选项会生成更大的目标文件。不过,该附加信息不会成为最后可执行的二进制文件的一部分。可执行程序大小的增加都是由于执行的附加优化导致的。
在链接步骤中使用目标文件集合时,编译器试图执行整个程序分析和优化。对于该目标文件集合中定义的任何函数或子例程 foo(),编译器做出以下两个假定:
运行时在该目标文件集合之外定义的其他例程不显式调用 foo()。
该目标文件集合中的任何例程调用 foo() 时,不会插入该目标文件集合之外定义的不同版本的 foo()。
如果假定 1 对于给定的应用程序不成立,请勿使用 -xipo=2 进行编译。
如果假定 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() 中,从而导致出现错误的结果。
-xjobs