http://llvm.org/docs/LinkTimeOptimization.html
goal:
enable LTO to cross build benchmark
llvm 3.3svn
usage:
Install LLVMgold.so and libLTO.so to /usr/lib/bfd-plugins.
LTO bug 1:
$clang
a.o main.o -o main -mcpu=cortex-a9 -mfloat-abi=hard -mfpu=vfpv3 -O3 -Wl,-plugin-opt=-float-abi=hard
:
error: lto-llvm.o-SchABH uses VFP register
arguments, output does not
@@ -355,16 +363,17 @@ void LTOCodeGenerator::applyScopeRestrictions() {
/// Optimize merged modules using various IPO passes
bool LTOCodeGenerator::generateObjectFile(raw_ostream &out,
std::string &errMsg) {
- if (this->determineTarget(errMsg))
- return true;
-
- Module* mergedModule = _linker.getModule();
// if options were requested, set them
if (!_codegenOptions.empty())
cl::ParseCommandLineOptions(_codegenOptions.size(),
const_cast<char **>(&_codegenOptions[0]));
+ if (this->determineTarget(errMsg))
+ return true;
+
+ Module* mergedModule = _linker.getModule();
bool LTOCodeGenerator::generateObjectFile(raw_ostream &out,
std::string &errMsg) {
- if (this->determineTarget(errMsg))
- return true;
-
- Module* mergedModule = _linker.getModule();
// if options were requested, set them
if (!_codegenOptions.empty())
cl::ParseCommandLineOptions(_codegenOptions.size(),
const_cast<char **>(&_codegenOptions[0]));
+ if (this->determineTarget(errMsg))
+ return true;
+
+ Module* mergedModule = _linker.getModule();
$clang -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -flto 1.o 2.o -o main
(*.o is LLVM bitcode file)
$readelf main -A
Attribute Section: aeabi
File Attributes
Tag_CPU_name: "ARM v7"
Tag_CPU_arch: v7
Tag_CPU_arch_profile: Application
Tag_ARM_ISA_use: Yes
Tag_THUMB_ISA_use: Thumb-2
Tag_FP_arch: VFPv3
Tag_Advanced_SIMD_arch: NEONv1 <=why?
Tag_ABI_PCS_wchar_t: 4
Tag_ABI_FP_denormal: Needed
Tag_ABI_FP_exceptions: Needed
Tag_ABI_FP_number_model: IEEE 754
Tag_ABI_align_needed: 8-byte
Tag_ABI_enum_size: int
Tag_ABI_HardFP_use: SP and DP
Tag_ABI_VFP_args: VFP registers
Tag_CPU_unaligned_access: v6
Tag_MPextension_use: Allowed
Tag_Virtualization_use: TrustZone
Because clang does not pass mfpu option to LTO, it only pass mcpu option to LTO.
in clang
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 244bf74..1edaf39 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -6050,6 +6071,11 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(
Args.MakeArgString(Twine("-plugin-opt=-float-abi=") +
getARMFloatABI(ToolChain.getDriver(), Args, ToolChain.getTriple())));
+ if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) {
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine("-plugin-opt=-mattr=") +
+ getFPUArgs(D, A, Args)));
+ }
}
in LLVM
diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp
@@ -47,6 +47,10 @@
#include "llvm/Transforms/ObjCARC.h"
using namespace llvm;
+static cl::opt<std::string>
+Mattr("mattr", cl::Hidden,
+ cl::desc("Target specific attributes"),
+ cl::init(""));
@@ -251,7 +255,11 @@ bool LTOCodeGenerator::determineTarget(std::string& errMsg) {
// construct LTOModule, hand over ownership of module and target
SubtargetFeatures Features;
Features.getDefaultSubtargetFeatures(Triple);
- std::string FeatureStr = Features.getString();
+ std::string FeatureStr;
+ if (Mattr.empty())
+ FeatureStr = Features.getString();
+ else
+ FeatureStr = Mattr;
what's ranlib?
http://blog.csdn.net/yuntongsf/article/details/6284517
GNU工具中ar是用来制作库文件.a的,但同时还提供了一个ranlib,从手册上看ranlib相当于ar -s,为什么这样呢?
GNU工具中ar是用来制作库文件.a的,但同时还提供了一个ranlib,从手册上看ranlib相当于ar -s,为什么这样呢?
这是由于最早在Unix系统上ar程序是单纯用来打包多个.o到.a(类似于tar做的事情),而不处理.o里的符号表。Linker程序则需 要.a文件提供一个完整的符号表,所以当时就写了单独的ranlib程序用来产生linker所需要的符号信息,也就是说那时,产生一个对linker合 格的的.a文件需要做ar和ranlib两步 。
很快,Unix厂商就发现ranlib做得事情完全可以合并到ar里面去,于是ar程序的升级版本就包括了ranlib的功能,但早期的很多项目的Makefile都已经是按照两步式的方法生成.a,所以为了保证这些早期文件的兼容性,ranlib被保留下来了。
如今,GNU/Linux系统上,ranlib依然存在,当然大部分项目已经不使用它了,因为ar -s就做了ranlib的工作。
历史通常是进步和妥协的混合!
历史通常是进步和妥协的混合!
http://clang-developers.42468.n3.nabble.com/Question-about-LTO-pass-driver-level-flags-to-the-plugin-td4034045.html
回覆刪除