X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fllvm-lto%2Fllvm-lto.cpp;h=4a421f9e76611c64b9e3154f8f7a7b691316698f;hb=a0ea8fafdf83736039de389321cb35cad26c7e53;hp=f25037c37aab13357779d8fb660cf87b771a8e38;hpb=88fae0edcce84920ba7c5685c36f6bd6cfb9b86d;p=oota-llvm.git diff --git a/tools/llvm-lto/llvm-lto.cpp b/tools/llvm-lto/llvm-lto.cpp index f25037c37aa..4a421f9e766 100644 --- a/tools/llvm-lto/llvm-lto.cpp +++ b/tools/llvm-lto/llvm-lto.cpp @@ -12,22 +12,55 @@ // //===----------------------------------------------------------------------===// -#include "llvm-c/lto.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/CodeGen/CommandFlags.h" +#include "llvm/LTO/LTOCodeGenerator.h" +#include "llvm/LTO/LTOModule.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" +#include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; -static cl::list InputFilenames(cl::Positional, cl::OneOrMore, - cl::desc("")); - -static cl::opt OutputFilename("o", - cl::desc("Override output filename"), - cl::init(""), - cl::value_desc("filename")); +static cl::opt +DisableOpt("disable-opt", cl::init(false), + cl::desc("Do not run any optimization passes")); + +static cl::opt +DisableInline("disable-inlining", cl::init(false), + cl::desc("Do not run the inliner pass")); + +static cl::opt +DisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false), + cl::desc("Do not run the GVN load PRE pass")); + +static cl::list +InputFilenames(cl::Positional, cl::OneOrMore, + cl::desc("")); + +static cl::opt +OutputFilename("o", cl::init(""), + cl::desc("Override output filename"), + cl::value_desc("filename")); + +static cl::list +ExportedSymbols("exported-symbol", + cl::desc("Symbol to export from the resulting object file"), + cl::ZeroOrMore); + +static cl::list +DSOSymbols("dso-symbol", + cl::desc("Symbol to put in the symtab in the resulting dso"), + cl::ZeroOrMore); + +namespace { +struct ModuleInfo { + std::vector CanBeHidden; +}; +} int main(int argc, char **argv) { // Print a stack trace if we signal out. @@ -37,47 +70,98 @@ int main(int argc, char **argv) { llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. cl::ParseCommandLineOptions(argc, argv, "llvm LTO linker\n"); + // Initialize the configured targets. + InitializeAllTargets(); + InitializeAllTargetMCs(); + InitializeAllAsmPrinters(); + InitializeAllAsmParsers(); + + // set up the TargetOptions for the machine + TargetOptions Options; + Options.LessPreciseFPMADOption = EnableFPMAD; + Options.NoFramePointerElim = DisableFPElim; + Options.AllowFPOpFusion = FuseFPOps; + Options.UnsafeFPMath = EnableUnsafeFPMath; + Options.NoInfsFPMath = EnableNoInfsFPMath; + Options.NoNaNsFPMath = EnableNoNaNsFPMath; + Options.HonorSignDependentRoundingFPMathOption = + EnableHonorSignDependentRoundingFPMath; + Options.UseSoftFloat = GenerateSoftFloatCalls; + if (FloatABIForCalls != FloatABI::Default) + Options.FloatABIType = FloatABIForCalls; + Options.NoZerosInBSS = DontPlaceZerosInBSS; + Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt; + Options.DisableTailCalls = DisableTailCalls; + Options.StackAlignmentOverride = OverrideStackAlignment; + Options.TrapFuncName = TrapFuncName; + Options.PositionIndependentExecutable = EnablePIE; + Options.EnableSegmentedStacks = SegmentedStacks; + Options.UseInitArray = UseInitArray; + unsigned BaseArg = 0; - std::string ErrorMessage; - lto_code_gen_t code_gen = lto_codegen_create(); - if (code_gen == NULL) - errs() << argv[0] << ": error creating a code generation module: " - << lto_get_error_message() << "\n"; + LTOCodeGenerator CodeGen; + + CodeGen.setCodePICModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC); + CodeGen.setDebugInfo(LTO_DEBUG_MODEL_DWARF); + CodeGen.setTargetOptions(Options); - lto_codegen_set_pic_model(code_gen, LTO_CODEGEN_PIC_MODEL_DYNAMIC); - lto_codegen_set_debug_model(code_gen, LTO_DEBUG_MODEL_DWARF); + llvm::StringSet DSOSymbolsSet; + for (unsigned i = 0; i < DSOSymbols.size(); ++i) + DSOSymbolsSet.insert(DSOSymbols[i]); + + std::vector KeptDSOSyms; for (unsigned i = BaseArg; i < InputFilenames.size(); ++i) { - lto_module_t BitcodeModule = lto_module_create(InputFilenames[i].c_str()); - if (BitcodeModule == NULL) { + std::string error; + OwningPtr Module(LTOModule::makeLTOModule(InputFilenames[i].c_str(), + Options, error)); + if (!error.empty()) { errs() << argv[0] << ": error loading file '" << InputFilenames[i] - << "': " << lto_get_error_message() << "\n"; + << "': " << error << "\n"; return 1; } - if (lto_codegen_add_module(code_gen, BitcodeModule)) { + + if (!CodeGen.addModule(Module.get(), error)) { errs() << argv[0] << ": error adding file '" << InputFilenames[i] - << "': " << lto_get_error_message() << "\n"; - lto_module_dispose(BitcodeModule); + << "': " << error << "\n"; return 1; } - lto_module_dispose(BitcodeModule); + unsigned NumSyms = Module->getSymbolCount(); + for (unsigned I = 0; I < NumSyms; ++I) { + StringRef Name = Module->getSymbolName(I); + if (!DSOSymbolsSet.count(Name)) + continue; + lto_symbol_attributes Attrs = Module->getSymbolAttributes(I); + unsigned Scope = Attrs & LTO_SYMBOL_SCOPE_MASK; + if (Scope != LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN) + KeptDSOSyms.push_back(Name); + } } + // Add all the exported symbols to the table of symbols to preserve. + for (unsigned i = 0; i < ExportedSymbols.size(); ++i) + CodeGen.addMustPreserveSymbol(ExportedSymbols[i].c_str()); + + // Add all the dso symbols to the table of symbols to expose. + for (unsigned i = 0; i < KeptDSOSyms.size(); ++i) + CodeGen.addMustPreserveSymbol(KeptDSOSyms[i].c_str()); + if (!OutputFilename.empty()) { size_t len = 0; - const void *Code = lto_codegen_compile(code_gen, &len); + std::string ErrorInfo; + const void *Code = CodeGen.compile(&len, DisableOpt, DisableInline, + DisableGVNLoadPRE, ErrorInfo); if (Code == NULL) { errs() << argv[0] - << ": error compiling the code: " << lto_get_error_message() - << "\n"; + << ": error compiling the code: " << ErrorInfo << "\n"; return 1; } - std::string ErrorInfo; - raw_fd_ostream FileStream(OutputFilename.c_str(), ErrorInfo); + raw_fd_ostream FileStream(OutputFilename.c_str(), ErrorInfo, + sys::fs::F_Binary); if (!ErrorInfo.empty()) { errs() << argv[0] << ": error opening the file '" << OutputFilename << "': " << ErrorInfo << "\n"; @@ -86,10 +170,12 @@ int main(int argc, char **argv) { FileStream.write(reinterpret_cast(Code), len); } else { + std::string ErrorInfo; const char *OutputName = NULL; - if (lto_codegen_compile_to_file(code_gen, &OutputName)) { + if (!CodeGen.compile_to_file(&OutputName, DisableOpt, DisableInline, + DisableGVNLoadPRE, ErrorInfo)) { errs() << argv[0] - << ": error compiling the code: " << lto_get_error_message() + << ": error compiling the code: " << ErrorInfo << "\n"; return 1; } @@ -97,7 +183,5 @@ int main(int argc, char **argv) { outs() << "Wrote native object file '" << OutputName << "'\n"; } - lto_codegen_dispose(code_gen); - return 0; }