diff options
Diffstat (limited to 'tools')
43 files changed, 778 insertions, 1318 deletions
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 9668c76..1bfc2fe 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -2,14 +2,6 @@ # three small executables. This is done to minimize memory load in parallel # builds. Please retain this ordering. -# If polly exists and is not disabled compile it and add it to the LLVM tools. -option(LLVM_BUILD_POLLY "Compile polly" ON) -if( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/polly/CMakeLists.txt ) - if (LLVM_BUILD_POLLY) - add_subdirectory( ${CMAKE_CURRENT_SOURCE_DIR}/polly) - endif (LLVM_BUILD_POLLY) -endif( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/polly/CMakeLists.txt ) - if( NOT WIN32 OR MSYS OR CYGWIN ) # We currently require 'sed' to build llvm-config, so don't try to build it # on pure Win32. @@ -27,7 +19,6 @@ add_subdirectory(llvm-ar) add_subdirectory(llvm-nm) add_subdirectory(llvm-size) -add_subdirectory(llvm-ld) add_subdirectory(llvm-cov) add_subdirectory(llvm-prof) add_subdirectory(llvm-link) @@ -44,7 +35,6 @@ add_subdirectory(llvm-dwarfdump) add_subdirectory(bugpoint) add_subdirectory(bugpoint-passes) add_subdirectory(llvm-bcanalyzer) -add_subdirectory(llvm-stub) add_subdirectory(llvm-stress) if( NOT WIN32 ) @@ -58,14 +48,8 @@ if( LLVM_ENABLE_PIC ) endif() endif() -set(LLVM_CLANG_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/clang" CACHE PATH "Path to Clang source directory") - -if (NOT ${LLVM_CLANG_SOURCE_DIR} STREQUAL "" - AND EXISTS ${LLVM_CLANG_SOURCE_DIR}/CMakeLists.txt) - option(LLVM_BUILD_CLANG "Whether to build Clang as part of LLVM" ON) - if (${LLVM_BUILD_CLANG}) - add_subdirectory(${LLVM_CLANG_SOURCE_DIR} clang) - endif() -endif () +add_llvm_external_project(clang) +add_llvm_external_project(lld) +add_llvm_external_project(polly) set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} PARENT_SCOPE) diff --git a/tools/LLVMBuild.txt b/tools/LLVMBuild.txt index aba990f..df4aa9f 100644 --- a/tools/LLVMBuild.txt +++ b/tools/LLVMBuild.txt @@ -16,7 +16,7 @@ ;===------------------------------------------------------------------------===; [common] -subdirectories = bugpoint llc lli llvm-ar llvm-as llvm-bcanalyzer llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-ld llvm-link llvm-mc llvm-nm llvm-objdump llvm-prof llvm-ranlib llvm-rtdyld llvm-size llvm-stub macho-dump opt +subdirectories = bugpoint llc lli llvm-ar llvm-as llvm-bcanalyzer llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-link llvm-mc llvm-nm llvm-objdump llvm-prof llvm-ranlib llvm-rtdyld llvm-size macho-dump opt [component_0] type = Group diff --git a/tools/Makefile b/tools/Makefile index 8bf091a..2b4b9b7 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -29,9 +29,9 @@ OPTIONAL_DIRS := lldb DIRS := llvm-config PARALLEL_DIRS := opt llvm-as llvm-dis \ llc llvm-ranlib llvm-ar llvm-nm \ - llvm-ld llvm-prof llvm-link \ + llvm-prof llvm-link \ lli llvm-extract llvm-mc \ - bugpoint llvm-bcanalyzer llvm-stub \ + bugpoint llvm-bcanalyzer \ llvm-diff macho-dump llvm-objdump llvm-readobj \ llvm-rtdyld llvm-dwarfdump llvm-cov \ llvm-size llvm-stress diff --git a/tools/bugpoint/BugDriver.cpp b/tools/bugpoint/BugDriver.cpp index 6b219bf..21636ea 100644 --- a/tools/bugpoint/BugDriver.cpp +++ b/tools/bugpoint/BugDriver.cpp @@ -156,7 +156,7 @@ bool BugDriver::run(std::string &ErrMsg) { // If we're not running as a child, the first thing that we must do is // determine what the problem is. Does the optimization series crash the // compiler, or does it produce illegal code? We make the top-level - // decision by trying to run all of the passes on the the input program, + // decision by trying to run all of the passes on the input program, // which should generate a bitcode file. If it does generate a bitcode // file, then we know the compiler didn't crash, so try to diagnose a // miscompilation. diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp index ac8e159..888d2c8 100644 --- a/tools/bugpoint/ExtractFunction.cpp +++ b/tools/bugpoint/ExtractFunction.cpp @@ -24,7 +24,7 @@ #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Cloning.h" -#include "llvm/Transforms/Utils/FunctionUtils.h" +#include "llvm/Transforms/Utils/CodeExtractor.h" #include "llvm/Target/TargetData.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" diff --git a/tools/bugpoint/ToolRunner.cpp b/tools/bugpoint/ToolRunner.cpp index 25a2bae..d975d68 100644 --- a/tools/bugpoint/ToolRunner.cpp +++ b/tools/bugpoint/ToolRunner.cpp @@ -128,7 +128,7 @@ static int RunProgramRemotelyWithTimeout(const sys::Path &RemoteClientPath, ErrorFile.close(); } - errs() << OS; + errs() << OS.str(); } return ReturnCode; diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp index cfd84c0..9c17da6 100644 --- a/tools/gold/gold-plugin.cpp +++ b/tools/gold/gold-plugin.cpp @@ -153,6 +153,8 @@ ld_plugin_status onload(ld_plugin_tv *tv) { switch (tv->tv_u.tv_val) { case LDPO_REL: // .o case LDPO_DYN: // .so + // FIXME: Replace 3 with LDPO_PIE once that is in a released binutils. + case 3: // position independent executable output_type = LTO_CODEGEN_PIC_MODEL_DYNAMIC; break; case LDPO_EXEC: // .exe diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index ceff8a6..8951050 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -18,6 +18,7 @@ #include "llvm/PassManager.h" #include "llvm/Pass.h" #include "llvm/ADT/Triple.h" +#include "llvm/Assembly/PrintModulePass.h" #include "llvm/Support/IRReader.h" #include "llvm/CodeGen/LinkAllAsmWriterComponents.h" #include "llvm/CodeGen/LinkAllCodegenComponents.h" @@ -34,6 +35,7 @@ #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetLibraryInfo.h" #include "llvm/Target/TargetMachine.h" #include <memory> using namespace llvm; @@ -118,7 +120,7 @@ FileType("filetype", cl::init(TargetMachine::CGFT_AssemblyFile), clEnumValN(TargetMachine::CGFT_AssemblyFile, "asm", "Emit an assembly ('.s') file"), clEnumValN(TargetMachine::CGFT_ObjectFile, "obj", - "Emit a native object ('.o') file [experimental]"), + "Emit a native object ('.o') file"), clEnumValN(TargetMachine::CGFT_Null, "null", "Emit nothing, for performance testing"), clEnumValEnd)); @@ -146,11 +148,6 @@ EnableFPMAD("enable-fp-mad", cl::init(false)); static cl::opt<bool> -PrintCode("print-machineinstrs", - cl::desc("Print generated machine code"), - cl::init(false)); - -static cl::opt<bool> DisableFPElim("disable-fp-elim", cl::desc("Disable frame pointer elimination optimization"), cl::init(false)); @@ -161,11 +158,6 @@ DisableFPElimNonLeaf("disable-non-leaf-fp-elim", cl::init(false)); static cl::opt<bool> -DisableExcessPrecision("disable-excess-fp-precision", - cl::desc("Disable optimizations that may increase FP precision"), - cl::init(false)); - -static cl::opt<bool> EnableUnsafeFPMath("enable-unsafe-fp-math", cl::desc("Enable optimizations that may decrease FP precision"), cl::init(false)); @@ -204,12 +196,30 @@ FloatABIForCalls("float-abi", "Hard float ABI (uses FP registers)"), clEnumValEnd)); +static cl::opt<llvm::FPOpFusion::FPOpFusionMode> +FuseFPOps("fp-contract", + cl::desc("Enable aggresive formation of fused FP ops"), + cl::init(FPOpFusion::Standard), + cl::values( + clEnumValN(FPOpFusion::Fast, "fast", + "Fuse FP ops whenever profitable"), + clEnumValN(FPOpFusion::Standard, "on", + "Only fuse 'blessed' FP ops."), + clEnumValN(FPOpFusion::Strict, "off", + "Only fuse FP ops when the result won't be effected."), + clEnumValEnd)); + static cl::opt<bool> DontPlaceZerosInBSS("nozero-initialized-in-bss", cl::desc("Don't place zero-initialized symbols into bss section"), cl::init(false)); static cl::opt<bool> +DisableSimplifyLibCalls("disable-simplify-libcalls", + cl::desc("Disable simplify-libcalls"), + cl::init(false)); + +static cl::opt<bool> EnableGuaranteedTailCallOpt("tailcallopt", cl::desc("Turn fastcc calls into tail calls by (potentially) changing ABI."), cl::init(false)); @@ -229,11 +239,6 @@ EnableRealignStack("realign-stack", cl::desc("Realign stack if needed"), cl::init(true)); -static cl::opt<bool> -DisableSwitchTables(cl::Hidden, "disable-jump-tables", - cl::desc("Do not generate jump tables."), - cl::init(false)); - static cl::opt<std::string> TrapFuncName("trap-func", cl::Hidden, cl::desc("Emit a call to trap function rather than a trap instruction"), @@ -249,6 +254,19 @@ SegmentedStacks("segmented-stacks", cl::desc("Use segmented stacks if possible."), cl::init(false)); +static cl::opt<bool> +UseInitArray("use-init-array", + cl::desc("Use .init_array instead of .ctors."), + cl::init(false)); + +static cl::opt<std::string> StopAfter("stop-after", + cl::desc("Stop compilation after a specific pass"), + cl::value_desc("pass-name"), + cl::init("")); +static cl::opt<std::string> StartAfter("start-after", + cl::desc("Resume compilation after a specific pass"), + cl::value_desc("pass-name"), + cl::init("")); // GetFileNameRoot - Helper function to get the basename of a filename. static inline std::string @@ -346,6 +364,15 @@ int main(int argc, char **argv) { InitializeAllAsmPrinters(); InitializeAllAsmParsers(); + // Initialize codegen and IR passes used by llc so that the -print-after, + // -print-before, and -stop-after options work. + PassRegistry *Registry = PassRegistry::getPassRegistry(); + initializeCore(*Registry); + initializeCodeGen(*Registry); + initializeLoopStrengthReducePass(*Registry); + initializeLowerIntrinsicsPass(*Registry); + initializeUnreachableBlockElimPass(*Registry); + // Register the target printer for --version. cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); @@ -354,54 +381,39 @@ int main(int argc, char **argv) { // Load the module to be compiled... SMDiagnostic Err; std::auto_ptr<Module> M; + Module *mod = 0; + Triple TheTriple; + + bool SkipModule = MCPU == "help" || + (!MAttrs.empty() && MAttrs.front() == "help"); + + // If user just wants to list available options, skip module loading + if (!SkipModule) { + M.reset(ParseIRFile(InputFilename, Err, Context)); + mod = M.get(); + if (mod == 0) { + Err.print(argv[0], errs()); + return 1; + } - M.reset(ParseIRFile(InputFilename, Err, Context)); - if (M.get() == 0) { - Err.print(argv[0], errs()); - return 1; + // If we are supposed to override the target triple, do so now. + if (!TargetTriple.empty()) + mod->setTargetTriple(Triple::normalize(TargetTriple)); + TheTriple = Triple(mod->getTargetTriple()); + } else { + TheTriple = Triple(Triple::normalize(TargetTriple)); } - Module &mod = *M.get(); - // If we are supposed to override the target triple, do so now. - if (!TargetTriple.empty()) - mod.setTargetTriple(Triple::normalize(TargetTriple)); - - Triple TheTriple(mod.getTargetTriple()); if (TheTriple.getTriple().empty()) TheTriple.setTriple(sys::getDefaultTargetTriple()); - // Allocate target machine. First, check whether the user has explicitly - // specified an architecture to compile for. If so we have to look it up by - // name, because it might be a backend that has no mapping to a target triple. - const Target *TheTarget = 0; - if (!MArch.empty()) { - for (TargetRegistry::iterator it = TargetRegistry::begin(), - ie = TargetRegistry::end(); it != ie; ++it) { - if (MArch == it->getName()) { - TheTarget = &*it; - break; - } - } - - if (!TheTarget) { - errs() << argv[0] << ": error: invalid target '" << MArch << "'.\n"; - return 1; - } - - // Adjust the triple to match (if known), otherwise stick with the - // module/host triple. - Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch); - if (Type != Triple::UnknownArch) - TheTriple.setArch(Type); - } else { - std::string Err; - TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Err); - if (TheTarget == 0) { - errs() << argv[0] << ": error auto-selecting target for module '" - << Err << "'. Please use the -march option to explicitly " - << "pick a target.\n"; - return 1; - } + // Get the target specific parser. + std::string Error; + const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, + Error); + if (!TheTarget) { + errs() << argv[0] << ": " << Error; + return 1; } // Package up features to be passed to target/subtarget @@ -427,10 +439,9 @@ int main(int argc, char **argv) { TargetOptions Options; Options.LessPreciseFPMADOption = EnableFPMAD; - Options.PrintMachineCode = PrintCode; Options.NoFramePointerElim = DisableFPElim; Options.NoFramePointerElimNonLeaf = DisableFPElimNonLeaf; - Options.NoExcessFPPrecision = DisableExcessPrecision; + Options.AllowFPOpFusion = FuseFPOps; Options.UnsafeFPMath = EnableUnsafeFPMath; Options.NoInfsFPMath = EnableNoInfsFPMath; Options.NoNaNsFPMath = EnableNoNaNsFPMath; @@ -444,16 +455,17 @@ int main(int argc, char **argv) { Options.DisableTailCalls = DisableTailCalls; Options.StackAlignmentOverride = OverrideStackAlignment; Options.RealignStack = EnableRealignStack; - Options.DisableJumpTables = DisableSwitchTables; Options.TrapFuncName = TrapFuncName; Options.PositionIndependentExecutable = EnablePIE; Options.EnableSegmentedStacks = SegmentedStacks; + Options.UseInitArray = UseInitArray; std::auto_ptr<TargetMachine> target(TheTarget->createTargetMachine(TheTriple.getTriple(), MCPU, FeaturesStr, Options, RelocModel, CMModel, OLvl)); assert(target.get() && "Could not allocate target machine!"); + assert(mod && "Should have exited after outputting help!"); TargetMachine &Target = *target.get(); if (DisableDotLoc) @@ -473,7 +485,7 @@ int main(int argc, char **argv) { TheTriple.isMacOSXVersionLT(10, 6)) Target.setMCUseLoc(false); - // Figure out where we are going to send the output... + // Figure out where we are going to send the output. OwningPtr<tool_output_file> Out (GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0])); if (!Out) return 1; @@ -481,11 +493,17 @@ int main(int argc, char **argv) { // Build up all of the passes that we want to do to the module. PassManager PM; + // Add an appropriate TargetLibraryInfo pass for the module's triple. + TargetLibraryInfo *TLI = new TargetLibraryInfo(TheTriple); + if (DisableSimplifyLibCalls) + TLI->disableAllFunctions(); + PM.add(TLI); + // Add the target data from the target machine, if it exists, or the module. if (const TargetData *TD = Target.getTargetData()) PM.add(new TargetData(*TD)); else - PM.add(new TargetData(&mod)); + PM.add(new TargetData(mod)); // Override default to generate verbose assembly. Target.setAsmVerbosityDefault(true); @@ -501,8 +519,29 @@ int main(int argc, char **argv) { { formatted_raw_ostream FOS(Out->os()); + AnalysisID StartAfterID = 0; + AnalysisID StopAfterID = 0; + const PassRegistry *PR = PassRegistry::getPassRegistry(); + if (!StartAfter.empty()) { + const PassInfo *PI = PR->getPassInfo(StartAfter); + if (!PI) { + errs() << argv[0] << ": start-after pass is not registered.\n"; + return 1; + } + StartAfterID = PI->getTypeInfo(); + } + if (!StopAfter.empty()) { + const PassInfo *PI = PR->getPassInfo(StopAfter); + if (!PI) { + errs() << argv[0] << ": stop-after pass is not registered.\n"; + return 1; + } + StopAfterID = PI->getTypeInfo(); + } + // Ask the target to add backend passes as necessary. - if (Target.addPassesToEmitFile(PM, FOS, FileType, NoVerify)) { + if (Target.addPassesToEmitFile(PM, FOS, FileType, NoVerify, + StartAfterID, StopAfterID)) { errs() << argv[0] << ": target does not support generation of this" << " file type!\n"; return 1; @@ -511,7 +550,7 @@ int main(int argc, char **argv) { // Before executing passes, print the final values of the LLVM options. cl::PrintOptionValues(); - PM.run(mod); + PM.run(*mod); } // Declare success. diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index 2e2bf7d..b6c9299 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -35,8 +35,20 @@ #include "llvm/Support/Process.h" #include "llvm/Support/Signals.h" #include "llvm/Support/TargetSelect.h" +#include "llvm/Support/DynamicLibrary.h" +#include "llvm/Support/Memory.h" #include <cerrno> +#ifdef __linux__ +// These includes used by LLIMCJITMemoryManager::getPointerToNamedFunction() +// for Glibc trickery. Look comments in this function for more information. +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif +#include <fcntl.h> +#include <unistd.h> +#endif + #ifdef __CYGWIN__ #include <cygwin/version.h> #if defined(CYGWIN_VERSION_DLL_MAJOR) && CYGWIN_VERSION_DLL_MAJOR<1007 @@ -175,6 +187,191 @@ static void do_shutdown() { #endif } +// Memory manager for MCJIT +class LLIMCJITMemoryManager : public JITMemoryManager { +public: + SmallVector<sys::MemoryBlock, 16> AllocatedDataMem; + SmallVector<sys::MemoryBlock, 16> AllocatedCodeMem; + SmallVector<sys::MemoryBlock, 16> FreeCodeMem; + + LLIMCJITMemoryManager() { } + ~LLIMCJITMemoryManager(); + + virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID); + + virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID); + + virtual void *getPointerToNamedFunction(const std::string &Name, + bool AbortOnFailure = true); + + // Invalidate instruction cache for code sections. Some platforms with + // separate data cache and instruction cache require explicit cache flush, + // otherwise JIT code manipulations (like resolved relocations) will get to + // the data cache but not to the instruction cache. + virtual void invalidateInstructionCache(); + + // The MCJITMemoryManager doesn't use the following functions, so we don't + // need implement them. + virtual void setMemoryWritable() { + llvm_unreachable("Unexpected call!"); + } + virtual void setMemoryExecutable() { + llvm_unreachable("Unexpected call!"); + } + virtual void setPoisonMemory(bool poison) { + llvm_unreachable("Unexpected call!"); + } + virtual void AllocateGOT() { + llvm_unreachable("Unexpected call!"); + } + virtual uint8_t *getGOTBase() const { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual uint8_t *startFunctionBody(const Function *F, + uintptr_t &ActualSize){ + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize, + unsigned Alignment) { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart, + uint8_t *FunctionEnd) { + llvm_unreachable("Unexpected call!"); + } + virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual void deallocateFunctionBody(void *Body) { + llvm_unreachable("Unexpected call!"); + } + virtual uint8_t* startExceptionTable(const Function* F, + uintptr_t &ActualSize) { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual void endExceptionTable(const Function *F, uint8_t *TableStart, + uint8_t *TableEnd, uint8_t* FrameRegister) { + llvm_unreachable("Unexpected call!"); + } + virtual void deallocateExceptionTable(void *ET) { + llvm_unreachable("Unexpected call!"); + } +}; + +uint8_t *LLIMCJITMemoryManager::allocateDataSection(uintptr_t Size, + unsigned Alignment, + unsigned SectionID) { + if (!Alignment) + Alignment = 16; + uint8_t *Addr = (uint8_t*)calloc((Size + Alignment - 1)/Alignment, Alignment); + AllocatedDataMem.push_back(sys::MemoryBlock(Addr, Size)); + return Addr; +} + +uint8_t *LLIMCJITMemoryManager::allocateCodeSection(uintptr_t Size, + unsigned Alignment, + unsigned SectionID) { + if (!Alignment) + Alignment = 16; + unsigned NeedAllocate = Alignment * ((Size + Alignment - 1)/Alignment + 1); + uintptr_t Addr = 0; + // Look in the list of free code memory regions and use a block there if one + // is available. + for (int i = 0, e = FreeCodeMem.size(); i != e; ++i) { + sys::MemoryBlock &MB = FreeCodeMem[i]; + if (MB.size() >= NeedAllocate) { + Addr = (uintptr_t)MB.base(); + uintptr_t EndOfBlock = Addr + MB.size(); + // Align the address. + Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1); + // Store cutted free memory block. + FreeCodeMem[i] = sys::MemoryBlock((void*)(Addr + Size), + EndOfBlock - Addr - Size); + return (uint8_t*)Addr; + } + } + + // No pre-allocated free block was large enough. Allocate a new memory region. + sys::MemoryBlock MB = sys::Memory::AllocateRWX(NeedAllocate, 0, 0); + + AllocatedCodeMem.push_back(MB); + Addr = (uintptr_t)MB.base(); + uintptr_t EndOfBlock = Addr + MB.size(); + // Align the address. + Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1); + // The AllocateRWX may allocate much more memory than we need. In this case, + // we store the unused memory as a free memory block. + unsigned FreeSize = EndOfBlock-Addr-Size; + if (FreeSize > 16) + FreeCodeMem.push_back(sys::MemoryBlock((void*)(Addr + Size), FreeSize)); + + // Return aligned address + return (uint8_t*)Addr; +} + +void LLIMCJITMemoryManager::invalidateInstructionCache() { + for (int i = 0, e = AllocatedCodeMem.size(); i != e; ++i) + sys::Memory::InvalidateInstructionCache(AllocatedCodeMem[i].base(), + AllocatedCodeMem[i].size()); +} + +void *LLIMCJITMemoryManager::getPointerToNamedFunction(const std::string &Name, + bool AbortOnFailure) { +#if defined(__linux__) + //===--------------------------------------------------------------------===// + // Function stubs that are invoked instead of certain library calls + // + // Force the following functions to be linked in to anything that uses the + // JIT. This is a hack designed to work around the all-too-clever Glibc + // strategy of making these functions work differently when inlined vs. when + // not inlined, and hiding their real definitions in a separate archive file + // that the dynamic linker can't see. For more info, search for + // 'libc_nonshared.a' on Google, or read http://llvm.org/PR274. + if (Name == "stat") return (void*)(intptr_t)&stat; + if (Name == "fstat") return (void*)(intptr_t)&fstat; + if (Name == "lstat") return (void*)(intptr_t)&lstat; + if (Name == "stat64") return (void*)(intptr_t)&stat64; + if (Name == "fstat64") return (void*)(intptr_t)&fstat64; + if (Name == "lstat64") return (void*)(intptr_t)&lstat64; + if (Name == "atexit") return (void*)(intptr_t)&atexit; + if (Name == "mknod") return (void*)(intptr_t)&mknod; +#endif // __linux__ + + const char *NameStr = Name.c_str(); + void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr); + if (Ptr) return Ptr; + + // If it wasn't found and if it starts with an underscore ('_') character, + // try again without the underscore. + if (NameStr[0] == '_') { + Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr+1); + if (Ptr) return Ptr; + } + + if (AbortOnFailure) + report_fatal_error("Program used external function '" + Name + + "' which could not be resolved!"); + return 0; +} + +LLIMCJITMemoryManager::~LLIMCJITMemoryManager() { + for (unsigned i = 0, e = AllocatedCodeMem.size(); i != e; ++i) + sys::Memory::ReleaseRWX(AllocatedCodeMem[i]); + for (unsigned i = 0, e = AllocatedDataMem.size(); i != e; ++i) + free(AllocatedDataMem[i].base()); +} + //===----------------------------------------------------------------------===// // main Driver function // @@ -222,8 +419,6 @@ int main(int argc, char **argv, char * const *envp) { builder.setRelocationModel(RelocModel); builder.setCodeModel(CMModel); builder.setErrorStr(&ErrorMsg); - builder.setJITMemoryManager(ForceInterpreter ? 0 : - JITMemoryManager::CreateDefaultMemManager()); builder.setEngineKind(ForceInterpreter ? EngineKind::Interpreter : EngineKind::JIT); @@ -233,9 +428,14 @@ int main(int argc, char **argv, char * const *envp) { Mod->setTargetTriple(Triple::normalize(TargetTriple)); // Enable MCJIT if desired. + LLIMCJITMemoryManager *JMM = 0; if (UseMCJIT && !ForceInterpreter) { builder.setUseMCJIT(true); - builder.setJITMemoryManager(JITMemoryManager::CreateDefaultMemManager()); + JMM = new LLIMCJITMemoryManager(); + builder.setJITMemoryManager(JMM); + } else { + builder.setJITMemoryManager(ForceInterpreter ? 0 : + JITMemoryManager::CreateDefaultMemManager()); } CodeGenOpt::Level OLvl = CodeGenOpt::Default; @@ -266,6 +466,10 @@ int main(int argc, char **argv, char * const *envp) { exit(1); } + // Clear instruction cache before code will be executed. + if (JMM) + JMM->invalidateInstructionCache(); + // The following functions have no effect if their respective profiling // support wasn't enabled in the build configuration. EE->RegisterJITEventListener( diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp index c1c8b24..7c53701 100644 --- a/tools/llvm-ar/llvm-ar.cpp +++ b/tools/llvm-ar/llvm-ar.cpp @@ -50,7 +50,7 @@ static cl::extrahelp MoreHelp( " m[abiSs] - move file(s) in the archive\n" " p[kN] - print file(s) found in the archive\n" " q[ufsS] - quick append file(s) to the archive\n" - " r[abfiuzRsS] - replace or insert file(s) into the archive\n" + " r[abfiuRsS] - replace or insert file(s) into the archive\n" " t - display contents of archive\n" " x[No] - extract file(s) from the archive\n" "\nMODIFIERS (operation specific):\n" @@ -66,7 +66,6 @@ static cl::extrahelp MoreHelp( " [s] - create an archive index (cf. ranlib)\n" " [S] - do not build a symbol table\n" " [u] - update only files newer than archive contents\n" - " [z] - compress files before inserting/extracting\n" "\nMODIFIERS (generic):\n" " [c] - do not warn if the library had to be created\n" " [v] - be verbose about actions taken\n" @@ -101,7 +100,6 @@ bool SymTable = true; ///< 's' & 'S' modifiers bool OnlyUpdate = false; ///< 'u' modifier bool Verbose = false; ///< 'v' modifier bool ReallyVerbose = false; ///< 'V' modifier -bool Compression = false; ///< 'z' modifier // Relative Positional Argument (for insert/move). This variable holds // the name of the archive member to which the 'a', 'b' or 'i' modifier @@ -208,7 +206,6 @@ ArchiveOperation parseCommandLine() { case 'u': OnlyUpdate = true; break; case 'v': Verbose = true; break; case 'V': Verbose = ReallyVerbose = true; break; - case 'z': Compression = true; break; case 'a': getRelPos(); AddAfter = true; @@ -260,8 +257,6 @@ ArchiveOperation parseCommandLine() { throw "The 'f' modifier is only applicable to the 'q' and 'r' operations"; if (OnlyUpdate && Operation != ReplaceOrInsert) throw "The 'u' modifier is only applicable to the 'r' operation"; - if (Compression && Operation!=ReplaceOrInsert && Operation!=Extract) - throw "The 'z' modifier is only applicable to the 'r' and 'x' operations"; if (Count > 1 && Members.size() > 1) throw "Only one member name may be specified with the 'N' modifier"; @@ -413,8 +408,6 @@ doDisplayTable(std::string* ErrMsg) { // Zrw-r--r-- 500/ 500 525 Nov 8 17:42 2004 Makefile if (I->isBitcode()) outs() << "b"; - else if (I->isCompressed()) - outs() << "Z"; else outs() << " "; unsigned mode = I->getMode(); @@ -437,7 +430,7 @@ doDisplayTable(std::string* ErrMsg) { } // doExtract - Implement the 'x' operation. This function extracts files back to -// the file system, making sure to uncompress any that were compressed +// the file system. bool doExtract(std::string* ErrMsg) { if (buildPaths(false, ErrMsg)) @@ -503,7 +496,7 @@ doDelete(std::string* ErrMsg) { } // We're done editting, reconstruct the archive. - if (TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ErrMsg)) + if (TheArchive->writeToDisk(SymTable,TruncateNames,ErrMsg)) return true; if (ReallyVerbose) printSymbolTable(); @@ -558,7 +551,7 @@ doMove(std::string* ErrMsg) { } // We're done editting, reconstruct the archive. - if (TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ErrMsg)) + if (TheArchive->writeToDisk(SymTable,TruncateNames,ErrMsg)) return true; if (ReallyVerbose) printSymbolTable(); @@ -583,7 +576,7 @@ doQuickAppend(std::string* ErrMsg) { } // We're done editting, reconstruct the archive. - if (TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ErrMsg)) + if (TheArchive->writeToDisk(SymTable,TruncateNames,ErrMsg)) return true; if (ReallyVerbose) printSymbolTable(); @@ -681,7 +674,7 @@ doReplaceOrInsert(std::string* ErrMsg) { } // We're done editting, reconstruct the archive. - if (TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ErrMsg)) + if (TheArchive->writeToDisk(SymTable,TruncateNames,ErrMsg)) return true; if (ReallyVerbose) printSymbolTable(); diff --git a/tools/llvm-config/Makefile b/tools/llvm-config/Makefile index 3f11730..e8c8692 100644 --- a/tools/llvm-config/Makefile +++ b/tools/llvm-config/Makefile @@ -57,3 +57,11 @@ $(ObjDir)/BuildVariables.inc: $(BUILDVARIABLES_SRCPATH) Makefile $(ObjDir)/.dir >> temp.sed $(Verb) $(SED) -f temp.sed < $< > $@ $(Verb) $(RM) temp.sed + +# When cross-compiling, install a version of llvm-config that runs on the host. +ifeq ($(LLVM_CROSS_COMPILING),1) +install:: $(DESTDIR)$(PROJ_bindir) + $(Echo) Installing llvm-config-host + $(Verb) $(ProgInstall) $(BuildLLVMToolDir)/llvm-config \ + $(DESTDIR)$(PROJ_bindir)/llvm-config-host +endif diff --git a/tools/llvm-config/llvm-config.cpp b/tools/llvm-config/llvm-config.cpp index 126542c..7edf5ec 100644 --- a/tools/llvm-config/llvm-config.cpp +++ b/tools/llvm-config/llvm-config.cpp @@ -190,9 +190,9 @@ int main(int argc, char **argv) { sys::path::parent_path(CurrentPath)).str(); // Check to see if we are inside a development tree by comparing to possible - // locations (prefix style or CMake style). This could be wrong in the face of - // symbolic links, but is good enough. - if (CurrentExecPrefix == std::string(LLVM_OBJ_ROOT) + "/" + LLVM_BUILDMODE) { + // locations (prefix style or CMake style). + if (sys::fs::equivalent(CurrentExecPrefix, + Twine(LLVM_OBJ_ROOT) + "/" + LLVM_BUILDMODE)) { IsInDevelopmentTree = true; DevelopmentTreeLayout = MakefileStyle; @@ -204,11 +204,12 @@ int main(int argc, char **argv) { } else { ActiveObjRoot = LLVM_OBJ_ROOT; } - } else if (CurrentExecPrefix == std::string(LLVM_OBJ_ROOT)) { + } else if (sys::fs::equivalent(CurrentExecPrefix, LLVM_OBJ_ROOT)) { IsInDevelopmentTree = true; DevelopmentTreeLayout = CMakeStyle; ActiveObjRoot = LLVM_OBJ_ROOT; - } else if (CurrentExecPrefix == std::string(LLVM_OBJ_ROOT) + "/bin") { + } else if (sys::fs::equivalent(CurrentExecPrefix, + Twine(LLVM_OBJ_ROOT) + "/bin")) { IsInDevelopmentTree = true; DevelopmentTreeLayout = CMakeBuildModeStyle; ActiveObjRoot = LLVM_OBJ_ROOT; diff --git a/tools/llvm-diff/DiffConsumer.cpp b/tools/llvm-diff/DiffConsumer.cpp index 0528039..91c1699 100644 --- a/tools/llvm-diff/DiffConsumer.cpp +++ b/tools/llvm-diff/DiffConsumer.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This files implements the the LLVM difference Consumer +// This files implements the LLVM difference Consumer // //===----------------------------------------------------------------------===// diff --git a/tools/llvm-diff/DiffConsumer.h b/tools/llvm-diff/DiffConsumer.h index 2060fe1..98e369b 100644 --- a/tools/llvm-diff/DiffConsumer.h +++ b/tools/llvm-diff/DiffConsumer.h @@ -67,8 +67,6 @@ namespace llvm { }; raw_ostream &out; - Module *LModule; - Module *RModule; SmallVector<DiffContext, 5> contexts; bool Differences; unsigned Indent; @@ -78,8 +76,8 @@ namespace llvm { void indent(); public: - DiffConsumer(Module *L, Module *R) - : out(errs()), LModule(L), RModule(R), Differences(false), Indent(0) {} + DiffConsumer() + : out(errs()), Differences(false), Indent(0) {} bool hadDifferences() const; void enterContext(Value *L, Value *R); diff --git a/tools/llvm-diff/DifferenceEngine.cpp b/tools/llvm-diff/DifferenceEngine.cpp index a5a99f5..0c1e30c 100644 --- a/tools/llvm-diff/DifferenceEngine.cpp +++ b/tools/llvm-diff/DifferenceEngine.cpp @@ -318,15 +318,15 @@ class FunctionDifferenceEngine { bool Difference = false; - DenseMap<ConstantInt*,BasicBlock*> LCases; + DenseMap<Constant*, BasicBlock*> LCases; for (SwitchInst::CaseIt I = LI->case_begin(), E = LI->case_end(); I != E; ++I) - LCases[I.getCaseValue()] = I.getCaseSuccessor(); + LCases[I.getCaseValueEx()] = I.getCaseSuccessor(); for (SwitchInst::CaseIt I = RI->case_begin(), E = RI->case_end(); I != E; ++I) { - ConstantInt *CaseValue = I.getCaseValue(); + IntegersSubset CaseValue = I.getCaseValueEx(); BasicBlock *LCase = LCases[CaseValue]; if (LCase) { if (TryUnify) tryUnify(LCase, I.getCaseSuccessor()); @@ -338,7 +338,7 @@ class FunctionDifferenceEngine { } } if (!Difference) - for (DenseMap<ConstantInt*,BasicBlock*>::iterator + for (DenseMap<Constant*, BasicBlock*>::iterator I = LCases.begin(), E = LCases.end(); I != E; ++I) { if (Complain) Engine.logf("left switch has extra case %l") << I->first; diff --git a/tools/llvm-diff/DifferenceEngine.h b/tools/llvm-diff/DifferenceEngine.h index 7ea79e4..0246d8f 100644 --- a/tools/llvm-diff/DifferenceEngine.h +++ b/tools/llvm-diff/DifferenceEngine.h @@ -59,8 +59,8 @@ namespace llvm { virtual ~Oracle() {} }; - DifferenceEngine(LLVMContext &context, Consumer &consumer) - : context(context), consumer(consumer), globalValueOracle(0) {} + DifferenceEngine(Consumer &consumer) + : consumer(consumer), globalValueOracle(0) {} void diff(Module *L, Module *R); void diff(Function *L, Function *R); @@ -84,7 +84,6 @@ namespace llvm { bool equivalentAsOperands(GlobalValue *L, GlobalValue *R); private: - LLVMContext &context; Consumer &consumer; Oracle *globalValueOracle; }; diff --git a/tools/llvm-diff/llvm-diff.cpp b/tools/llvm-diff/llvm-diff.cpp index 774169b..45957b3 100644 --- a/tools/llvm-diff/llvm-diff.cpp +++ b/tools/llvm-diff/llvm-diff.cpp @@ -78,8 +78,8 @@ int main(int argc, char **argv) { Module *RModule = ReadModule(Context, RightFilename); if (!LModule || !RModule) return 1; - DiffConsumer Consumer(LModule, RModule); - DifferenceEngine Engine(Context, Consumer); + DiffConsumer Consumer; + DifferenceEngine Engine(Consumer); // If any global names were given, just diff those. if (!GlobalsToCompare.empty()) { diff --git a/tools/llvm-dis/llvm-dis.cpp b/tools/llvm-dis/llvm-dis.cpp index 6450ea6..41f023d 100644 --- a/tools/llvm-dis/llvm-dis.cpp +++ b/tools/llvm-dis/llvm-dis.cpp @@ -17,11 +17,11 @@ //===----------------------------------------------------------------------===// #include "llvm/LLVMContext.h" +#include "llvm/DebugInfo.h" #include "llvm/Module.h" #include "llvm/Type.h" #include "llvm/IntrinsicInst.h" #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Assembly/AssemblyAnnotationWriter.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/DataStream.h" @@ -93,7 +93,6 @@ public: DIVariable Var(DDI->getVariable()); if (!Padded) { OS.PadToColumn(50); - Padded = true; OS << ";"; } OS << " [debug variable = " << Var.getName() << "]"; @@ -102,7 +101,6 @@ public: DIVariable Var(DVI->getVariable()); if (!Padded) { OS.PadToColumn(50); - Padded = true; OS << ";"; } OS << " [debug variable = " << Var.getName() << "]"; diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index ca0493d..ec0b4ae 100644 --- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -39,6 +39,11 @@ static cl::opt<unsigned long long> Address("address", cl::init(-1ULL), cl::desc("Print line information for a given address")); +static cl::opt<bool> +PrintFunctions("functions", cl::init(false), + cl::desc("Print function names as well as line information " + "for a given address")); + static void DumpInput(const StringRef &Filename) { OwningPtr<MemoryBuffer> Buff; @@ -92,7 +97,14 @@ static void DumpInput(const StringRef &Filename) { dictx->dump(outs()); } else { // Print line info for the specified address. - DILineInfo dli = dictx->getLineInfoForAddress(Address); + int spec_flags = DILineInfoSpecifier::FileLineInfo | + DILineInfoSpecifier::AbsoluteFilePath; + if (PrintFunctions) + spec_flags |= DILineInfoSpecifier::FunctionName; + DILineInfo dli = dictx->getLineInfoForAddress(Address, spec_flags); + if (PrintFunctions) + outs() << (dli.getFunctionName() ? dli.getFunctionName() : "<unknown>") + << "\n"; outs() << (dli.getFileName() ? dli.getFileName() : "<unknown>") << ':' << dli.getLine() << ':' << dli.getColumn() << '\n'; } diff --git a/tools/llvm-ld/CMakeLists.txt b/tools/llvm-ld/CMakeLists.txt deleted file mode 100644 index d328a04..0000000 --- a/tools/llvm-ld/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -set(LLVM_LINK_COMPONENTS ipo scalaropts linker archive bitwriter vectorize) - -add_llvm_tool(llvm-ld - Optimize.cpp - llvm-ld.cpp - ) - -add_dependencies(llvm-ld llvm-stub) diff --git a/tools/llvm-ld/LLVMBuild.txt b/tools/llvm-ld/LLVMBuild.txt deleted file mode 100644 index eed0452..0000000 --- a/tools/llvm-ld/LLVMBuild.txt +++ /dev/null @@ -1,22 +0,0 @@ -;===- ./tools/llvm-ld/LLVMBuild.txt ----------------------------*- Conf -*--===; -; -; The LLVM Compiler Infrastructure -; -; This file is distributed under the University of Illinois Open Source -; License. See LICENSE.TXT for details. -; -;===------------------------------------------------------------------------===; -; -; This is an LLVMBuild description file for the components in this subdirectory. -; -; For more information on the LLVMBuild system, please see: -; -; http://llvm.org/docs/LLVMBuild.html -; -;===------------------------------------------------------------------------===; - -[component_0] -type = Tool -name = llvm-ld -parent = Tools -required_libraries = Archive BitWriter IPO Linker Scalar diff --git a/tools/llvm-ld/Makefile b/tools/llvm-ld/Makefile deleted file mode 100644 index 8793ca9..0000000 --- a/tools/llvm-ld/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -##===- tools/llvm-ld/Makefile ------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL := ../.. -TOOLNAME := llvm-ld -LINK_COMPONENTS := ipo scalaropts linker archive bitwriter vectorize - -include $(LEVEL)/Makefile.common diff --git a/tools/llvm-ld/Optimize.cpp b/tools/llvm-ld/Optimize.cpp deleted file mode 100644 index 7f3f900..0000000 --- a/tools/llvm-ld/Optimize.cpp +++ /dev/null @@ -1,130 +0,0 @@ -//===- Optimize.cpp - Optimize a complete program -------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements all optimization of the linked module for llvm-ld. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Module.h" -#include "llvm/PassManager.h" -#include "llvm/Analysis/Verifier.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/DynamicLibrary.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Support/PassNameParser.h" -#include "llvm/Support/PluginLoader.h" -#include "llvm/Transforms/IPO.h" -#include "llvm/Transforms/IPO/PassManagerBuilder.h" -#include "llvm/Transforms/Scalar.h" -using namespace llvm; - -// Pass Name Options as generated by the PassNameParser -static cl::list<const PassInfo*, bool, PassNameParser> - OptimizationList(cl::desc("Optimizations available:")); - -//Don't verify at the end -static cl::opt<bool> DontVerify("disable-verify", cl::ReallyHidden); - -static cl::opt<bool> DisableInline("disable-inlining", - cl::desc("Do not run the inliner pass")); - -static cl::opt<bool> -DisableOptimizations("disable-opt", - cl::desc("Do not run any optimization passes")); - -static cl::opt<bool> DisableInternalize("disable-internalize", - cl::desc("Do not mark all symbols as internal")); - -static cl::opt<bool> VerifyEach("verify-each", - cl::desc("Verify intermediate results of all passes")); - -static cl::alias ExportDynamic("export-dynamic", - cl::aliasopt(DisableInternalize), - cl::desc("Alias for -disable-internalize")); - -static cl::opt<bool> Strip("strip-all", - cl::desc("Strip all symbol info from executable")); - -static cl::alias A0("s", cl::desc("Alias for --strip-all"), - cl::aliasopt(Strip)); - -static cl::opt<bool> StripDebug("strip-debug", - cl::desc("Strip debugger symbol info from executable")); - -static cl::alias A1("S", cl::desc("Alias for --strip-debug"), - cl::aliasopt(StripDebug)); - -// A utility function that adds a pass to the pass manager but will also add -// a verifier pass after if we're supposed to verify. -static inline void addPass(PassManager &PM, Pass *P) { - // Add the pass to the pass manager... - PM.add(P); - - // If we are verifying all of the intermediate steps, add the verifier... - if (VerifyEach) - PM.add(createVerifierPass()); -} - -namespace llvm { -/// Optimize - Perform link time optimizations. This will run the scalar -/// optimizations, any loaded plugin-optimization modules, and then the -/// inter-procedural optimizations if applicable. -void Optimize(Module *M) { - - // Instantiate the pass manager to organize the passes. - PassManager Passes; - - // If we're verifying, start off with a verification pass. - if (VerifyEach) - Passes.add(createVerifierPass()); - - // Add an appropriate TargetData instance for this module... - addPass(Passes, new TargetData(M)); - - if (!DisableOptimizations) - PassManagerBuilder().populateLTOPassManager(Passes, !DisableInternalize, - !DisableInline); - - // If the -s or -S command line options were specified, strip the symbols out - // of the resulting program to make it smaller. -s and -S are GNU ld options - // that we are supporting; they alias -strip-all and -strip-debug. - if (Strip || StripDebug) - addPass(Passes, createStripSymbolsPass(StripDebug && !Strip)); - - // Create a new optimization pass for each one specified on the command line - std::auto_ptr<TargetMachine> target; - for (unsigned i = 0; i < OptimizationList.size(); ++i) { - const PassInfo *Opt = OptimizationList[i]; - if (Opt->getNormalCtor()) - addPass(Passes, Opt->getNormalCtor()()); - else - errs() << "llvm-ld: cannot create pass: " << Opt->getPassName() - << "\n"; - } - - // The user's passes may leave cruft around. Clean up after them them but - // only if we haven't got DisableOptimizations set - if (!DisableOptimizations) { - addPass(Passes, createInstructionCombiningPass()); - addPass(Passes, createCFGSimplificationPass()); - addPass(Passes, createAggressiveDCEPass()); - addPass(Passes, createGlobalDCEPass()); - } - - // Make sure everything is still good. - if (!DontVerify) - Passes.add(createVerifierPass()); - - // Run our queue of passes all at once now, efficiently. - Passes.run(*M); -} - -} diff --git a/tools/llvm-ld/llvm-ld.cpp b/tools/llvm-ld/llvm-ld.cpp deleted file mode 100644 index ecf0476..0000000 --- a/tools/llvm-ld/llvm-ld.cpp +++ /dev/null @@ -1,732 +0,0 @@ -//===- llvm-ld.cpp - LLVM 'ld' compatible linker --------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This utility is intended to be compatible with GCC, and follows standard -// system 'ld' conventions. As such, the default output file is ./a.out. -// Additionally, this program outputs a shell script that is used to invoke LLI -// to execute the program. In this manner, the generated executable (a.out for -// example), is directly executable, whereas the bitcode file actually lives in -// the a.out.bc file generated by this program. -// -// Note that if someone (or a script) deletes the executable program generated, -// the .bc file will be left around. Considering that this is a temporary hack, -// I'm not too worried about this. -// -//===----------------------------------------------------------------------===// - -#include "llvm/LinkAllVMCore.h" -#include "llvm/Linker.h" -#include "llvm/LLVMContext.h" -#include "llvm/Support/Program.h" -#include "llvm/Module.h" -#include "llvm/PassManager.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/FileUtilities.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/SystemUtils.h" -#include "llvm/Support/ToolOutputFile.h" -#include "llvm/Support/Signals.h" -#include <memory> -#include <cstring> -using namespace llvm; - -// Rightly this should go in a header file but it just seems such a waste. -namespace llvm { -extern void Optimize(Module*); -} - -// Input/Output Options -static cl::list<std::string> InputFilenames(cl::Positional, cl::OneOrMore, - cl::desc("<input bitcode files>")); - -static cl::opt<std::string> OutputFilename("o", cl::init("a.out"), - cl::desc("Override output filename"), - cl::value_desc("filename")); - -static cl::opt<std::string> BitcodeOutputFilename("b", cl::init(""), - cl::desc("Override bitcode output filename"), - cl::value_desc("filename")); - -static cl::opt<bool> Verbose("v", - cl::desc("Print information about actions taken")); - -static cl::list<std::string> LibPaths("L", cl::Prefix, - cl::desc("Specify a library search path"), - cl::value_desc("directory")); - -static cl::list<std::string> FrameworkPaths("F", cl::Prefix, - cl::desc("Specify a framework search path"), - cl::value_desc("directory")); - -static cl::list<std::string> Libraries("l", cl::Prefix, - cl::desc("Specify libraries to link to"), - cl::value_desc("library prefix")); - -static cl::list<std::string> Frameworks("framework", - cl::desc("Specify frameworks to link to"), - cl::value_desc("framework")); - -// Options to control the linking, optimization, and code gen processes -static cl::opt<bool> LinkAsLibrary("link-as-library", - cl::desc("Link the .bc files together as a library, not an executable")); - -static cl::alias Relink("r", cl::aliasopt(LinkAsLibrary), - cl::desc("Alias for -link-as-library")); - -static cl::opt<bool> Native("native", - cl::desc("Generate a native binary instead of a shell script")); - -static cl::opt<bool>NativeCBE("native-cbe", - cl::desc("Generate a native binary with the C backend and GCC")); - -static cl::list<std::string> PostLinkOpts("post-link-opts", - cl::value_desc("path"), - cl::desc("Run one or more optimization programs after linking")); - -static cl::list<std::string> XLinker("Xlinker", cl::value_desc("option"), - cl::desc("Pass options to the system linker")); - -// Compatibility options that llvm-ld ignores but are supported for -// compatibility with LD -static cl::opt<std::string> CO3("soname", cl::Hidden, - cl::desc("Compatibility option: ignored")); - -static cl::opt<std::string> CO4("version-script", cl::Hidden, - cl::desc("Compatibility option: ignored")); - -static cl::opt<bool> CO5("eh-frame-hdr", cl::Hidden, - cl::desc("Compatibility option: ignored")); - -static cl::opt<std::string> CO6("h", cl::Hidden, - cl::desc("Compatibility option: ignored")); - -static cl::opt<bool> CO7("start-group", cl::Hidden, - cl::desc("Compatibility option: ignored")); - -static cl::opt<bool> CO8("end-group", cl::Hidden, - cl::desc("Compatibility option: ignored")); - -static cl::opt<std::string> CO9("m", cl::Hidden, - cl::desc("Compatibility option: ignored")); - -/// This is just for convenience so it doesn't have to be passed around -/// everywhere. -static std::string progname; - -/// FileRemover objects to clean up output files in the event of an error. -static FileRemover OutputRemover; -static FileRemover BitcodeOutputRemover; - -/// PrintAndExit - Prints a message to standard error and exits with error code -/// -/// Inputs: -/// Message - The message to print to standard error. -/// -static void PrintAndExit(const std::string &Message, Module *M, int errcode = 1) { - errs() << progname << ": " << Message << "\n"; - delete M; - llvm_shutdown(); - exit(errcode); -} - -static void PrintCommand(const std::vector<const char*> &args) { - std::vector<const char*>::const_iterator I = args.begin(), E = args.end(); - for (; I != E; ++I) - if (*I) - errs() << "'" << *I << "'" << " "; - errs() << "\n"; -} - -/// CopyEnv - This function takes an array of environment variables and makes a -/// copy of it. This copy can then be manipulated any way the caller likes -/// without affecting the process's real environment. -/// -/// Inputs: -/// envp - An array of C strings containing an environment. -/// -/// Return value: -/// NULL - An error occurred. -/// -/// Otherwise, a pointer to a new array of C strings is returned. Every string -/// in the array is a duplicate of the one in the original array (i.e. we do -/// not copy the char *'s from one array to another). -/// -static char ** CopyEnv(char ** const envp) { - // Count the number of entries in the old list; - unsigned entries; // The number of entries in the old environment list - for (entries = 0; envp[entries] != NULL; entries++) - /*empty*/; - - // Add one more entry for the NULL pointer that ends the list. - ++entries; - - // If there are no entries at all, just return NULL. - if (entries == 0) - return NULL; - - // Allocate a new environment list. - char **newenv = new char* [entries]; - if (newenv == NULL) - return NULL; - - // Make a copy of the list. Don't forget the NULL that ends the list. - entries = 0; - while (envp[entries] != NULL) { - size_t len = strlen(envp[entries]) + 1; - newenv[entries] = new char[len]; - memcpy(newenv[entries], envp[entries], len); - ++entries; - } - newenv[entries] = NULL; - - return newenv; -} - - -/// RemoveEnv - Remove the specified environment variable from the environment -/// array. -/// -/// Inputs: -/// name - The name of the variable to remove. It cannot be NULL. -/// envp - The array of environment variables. It cannot be NULL. -/// -/// Notes: -/// This is mainly done because functions to remove items from the environment -/// are not available across all platforms. In particular, Solaris does not -/// seem to have an unsetenv() function or a setenv() function (or they are -/// undocumented if they do exist). -/// -static void RemoveEnv(const char * name, char ** const envp) { - for (unsigned index=0; envp[index] != NULL; index++) { - // Find the first equals sign in the array and make it an EOS character. - char *p = strchr (envp[index], '='); - if (p == NULL) - continue; - else - *p = '\0'; - - // Compare the two strings. If they are equal, zap this string. - // Otherwise, restore it. - if (!strcmp(name, envp[index])) - *envp[index] = '\0'; - else - *p = '='; - } - - return; -} - -/// GenerateBitcode - generates a bitcode file from the module provided -void GenerateBitcode(Module* M, const std::string& FileName) { - - if (Verbose) - errs() << "Generating Bitcode To " << FileName << '\n'; - - // Create the output file. - std::string ErrorInfo; - tool_output_file Out(FileName.c_str(), ErrorInfo, - raw_fd_ostream::F_Binary); - if (!ErrorInfo.empty()) { - PrintAndExit(ErrorInfo, M); - return; - } - - // Write it out - WriteBitcodeToFile(M, Out.os()); - Out.keep(); -} - -/// GenerateAssembly - generates a native assembly language source file from the -/// specified bitcode file. -/// -/// Inputs: -/// InputFilename - The name of the input bitcode file. -/// OutputFilename - The name of the file to generate. -/// llc - The pathname to use for LLC. -/// envp - The environment to use when running LLC. -/// -/// Return non-zero value on error. -/// -static int GenerateAssembly(const std::string &OutputFilename, - const std::string &InputFilename, - const sys::Path &llc, - std::string &ErrMsg ) { - // Run LLC to convert the bitcode file into assembly code. - std::vector<const char*> args; - args.push_back(llc.c_str()); - // We will use GCC to assemble the program so set the assembly syntax to AT&T, - // regardless of what the target in the bitcode file is. - args.push_back("-x86-asm-syntax=att"); - args.push_back("-o"); - args.push_back(OutputFilename.c_str()); - args.push_back(InputFilename.c_str()); - args.push_back(0); - - if (Verbose) { - errs() << "Generating Assembly With: \n"; - PrintCommand(args); - } - - return sys::Program::ExecuteAndWait(llc, &args[0], 0, 0, 0, 0, &ErrMsg); -} - -/// GenerateCFile - generates a C source file from the specified bitcode file. -static int GenerateCFile(const std::string &OutputFile, - const std::string &InputFile, - const sys::Path &llc, - std::string& ErrMsg) { - // Run LLC to convert the bitcode file into C. - std::vector<const char*> args; - args.push_back(llc.c_str()); - args.push_back("-march=c"); - args.push_back("-o"); - args.push_back(OutputFile.c_str()); - args.push_back(InputFile.c_str()); - args.push_back(0); - - if (Verbose) { - errs() << "Generating C Source With: \n"; - PrintCommand(args); - } - - return sys::Program::ExecuteAndWait(llc, &args[0], 0, 0, 0, 0, &ErrMsg); -} - -/// GenerateNative - generates a native object file from the -/// specified bitcode file. -/// -/// Inputs: -/// InputFilename - The name of the input bitcode file. -/// OutputFilename - The name of the file to generate. -/// NativeLinkItems - The native libraries, files, code with which to link -/// LibPaths - The list of directories in which to find libraries. -/// FrameworksPaths - The list of directories in which to find frameworks. -/// Frameworks - The list of frameworks (dynamic libraries) -/// gcc - The pathname to use for GGC. -/// envp - A copy of the process's current environment. -/// -/// Outputs: -/// None. -/// -/// Returns non-zero value on error. -/// -static int GenerateNative(const std::string &OutputFilename, - const std::string &InputFilename, - const Linker::ItemList &LinkItems, - const sys::Path &gcc, char ** const envp, - std::string& ErrMsg) { - // Remove these environment variables from the environment of the - // programs that we will execute. It appears that GCC sets these - // environment variables so that the programs it uses can configure - // themselves identically. - // - // However, when we invoke GCC below, we want it to use its normal - // configuration. Hence, we must sanitize its environment. - char ** clean_env = CopyEnv(envp); - if (clean_env == NULL) - return 1; - RemoveEnv("LIBRARY_PATH", clean_env); - RemoveEnv("COLLECT_GCC_OPTIONS", clean_env); - RemoveEnv("GCC_EXEC_PREFIX", clean_env); - RemoveEnv("COMPILER_PATH", clean_env); - RemoveEnv("COLLECT_GCC", clean_env); - - - // Run GCC to assemble and link the program into native code. - // - // Note: - // We can't just assemble and link the file with the system assembler - // and linker because we don't know where to put the _start symbol. - // GCC mysteriously knows how to do it. - std::vector<std::string> args; - args.push_back(gcc.c_str()); - args.push_back("-fno-strict-aliasing"); - args.push_back("-O3"); - args.push_back("-o"); - args.push_back(OutputFilename); - args.push_back(InputFilename); - - // Add in the library and framework paths - for (unsigned index = 0; index < LibPaths.size(); index++) { - args.push_back("-L" + LibPaths[index]); - } - for (unsigned index = 0; index < FrameworkPaths.size(); index++) { - args.push_back("-F" + FrameworkPaths[index]); - } - - // Add the requested options - for (unsigned index = 0; index < XLinker.size(); index++) - args.push_back(XLinker[index]); - - // Add in the libraries to link. - for (unsigned index = 0; index < LinkItems.size(); index++) - if (LinkItems[index].first != "crtend") { - if (LinkItems[index].second) - args.push_back("-l" + LinkItems[index].first); - else - args.push_back(LinkItems[index].first); - } - - // Add in frameworks to link. - for (unsigned index = 0; index < Frameworks.size(); index++) { - args.push_back("-framework"); - args.push_back(Frameworks[index]); - } - - // Now that "args" owns all the std::strings for the arguments, call the c_str - // method to get the underlying string array. We do this game so that the - // std::string array is guaranteed to outlive the const char* array. - std::vector<const char *> Args; - for (unsigned i = 0, e = args.size(); i != e; ++i) - Args.push_back(args[i].c_str()); - Args.push_back(0); - - if (Verbose) { - errs() << "Generating Native Executable With:\n"; - PrintCommand(Args); - } - - // Run the compiler to assembly and link together the program. - int R = sys::Program::ExecuteAndWait( - gcc, &Args[0], const_cast<const char **>(clean_env), 0, 0, 0, &ErrMsg); - delete [] clean_env; - return R; -} - -/// EmitShellScript - Output the wrapper file that invokes the JIT on the LLVM -/// bitcode file for the program. -static void EmitShellScript(char **argv, Module *M) { - if (Verbose) - errs() << "Emitting Shell Script\n"; -#if defined(_WIN32) - // Windows doesn't support #!/bin/sh style shell scripts in .exe files. To - // support windows systems, we copy the llvm-stub.exe executable from the - // build tree to the destination file. - std::string ErrMsg; - sys::Path llvmstub = PrependMainExecutablePath("llvm-stub", argv[0], - (void *)(intptr_t)&Optimize); - if (llvmstub.isEmpty()) - PrintAndExit("Could not find llvm-stub.exe executable!", M); - - if (0 != sys::CopyFile(sys::Path(OutputFilename), llvmstub, &ErrMsg)) - PrintAndExit(ErrMsg, M); - - return; -#else - - // Output the script to start the program... - std::string ErrorInfo; - tool_output_file Out2(OutputFilename.c_str(), ErrorInfo); - if (!ErrorInfo.empty()) - PrintAndExit(ErrorInfo, M); - - Out2.os() << "#!/bin/sh\n"; - // Allow user to setenv LLVMINTERP if lli is not in their PATH. - Out2.os() << "lli=${LLVMINTERP-lli}\n"; - Out2.os() << "exec $lli \\\n"; - // gcc accepts -l<lib> and implicitly searches /lib and /usr/lib. - LibPaths.push_back("/lib"); - LibPaths.push_back("/usr/lib"); - LibPaths.push_back("/usr/X11R6/lib"); - // We don't need to link in libc! In fact, /usr/lib/libc.so may not be a - // shared object at all! See RH 8: plain text. - std::vector<std::string>::iterator libc = - std::find(Libraries.begin(), Libraries.end(), "c"); - if (libc != Libraries.end()) Libraries.erase(libc); - // List all the shared object (native) libraries this executable will need - // on the command line, so that we don't have to do this manually! - for (std::vector<std::string>::iterator i = Libraries.begin(), - e = Libraries.end(); i != e; ++i) { - // try explicit -L arguments first: - sys::Path FullLibraryPath; - for (cl::list<std::string>::const_iterator P = LibPaths.begin(), - E = LibPaths.end(); P != E; ++P) { - FullLibraryPath = *P; - FullLibraryPath.appendComponent("lib" + *i); - FullLibraryPath.appendSuffix(sys::Path::GetDLLSuffix()); - if (!FullLibraryPath.isEmpty()) { - if (!FullLibraryPath.isDynamicLibrary()) { - // Not a native shared library; mark as invalid - FullLibraryPath = sys::Path(); - } else break; - } - } - if (FullLibraryPath.isEmpty()) - FullLibraryPath = sys::Path::FindLibrary(*i); - if (!FullLibraryPath.isEmpty()) - Out2.os() << " -load=" << FullLibraryPath.str() << " \\\n"; - } - Out2.os() << " " << BitcodeOutputFilename << " ${1+\"$@\"}\n"; - Out2.keep(); -#endif -} - -// BuildLinkItems -- This function generates a LinkItemList for the LinkItems -// linker function by combining the Files and Libraries in the order they were -// declared on the command line. -static void BuildLinkItems( - Linker::ItemList& Items, - const cl::list<std::string>& Files, - const cl::list<std::string>& Libraries) { - - // Build the list of linkage items for LinkItems. - - cl::list<std::string>::const_iterator fileIt = Files.begin(); - cl::list<std::string>::const_iterator libIt = Libraries.begin(); - - int libPos = -1, filePos = -1; - while ( libIt != Libraries.end() || fileIt != Files.end() ) { - if (libIt != Libraries.end()) - libPos = Libraries.getPosition(libIt - Libraries.begin()); - else - libPos = -1; - if (fileIt != Files.end()) - filePos = Files.getPosition(fileIt - Files.begin()); - else - filePos = -1; - - if (filePos != -1 && (libPos == -1 || filePos < libPos)) { - // Add a source file - Items.push_back(std::make_pair(*fileIt++, false)); - } else if (libPos != -1 && (filePos == -1 || libPos < filePos)) { - // Add a library - Items.push_back(std::make_pair(*libIt++, true)); - } - } -} - -int main(int argc, char **argv, char **envp) { - // Print a stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(); - PrettyStackTraceProgram X(argc, argv); - - LLVMContext &Context = getGlobalContext(); - llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - - // Initialize passes - PassRegistry &Registry = *PassRegistry::getPassRegistry(); - initializeCore(Registry); - initializeScalarOpts(Registry); - initializeIPO(Registry); - initializeAnalysis(Registry); - initializeIPA(Registry); - initializeTransformUtils(Registry); - initializeInstCombine(Registry); - initializeTarget(Registry); - - // Initial global variable above for convenience printing of program name. - progname = sys::path::stem(argv[0]); - - // Parse the command line options - cl::ParseCommandLineOptions(argc, argv, "llvm linker\n"); - -#if defined(_WIN32) || defined(__CYGWIN__) - if (!LinkAsLibrary) { - // Default to "a.exe" instead of "a.out". - if (OutputFilename.getNumOccurrences() == 0) - OutputFilename = "a.exe"; - - // If there is no suffix add an "exe" one. - if (sys::path::extension(OutputFilename).empty()) - OutputFilename.append(".exe"); - } -#endif - - // Generate the bitcode for the optimized module. - // If -b wasn't specified, use the name specified - // with -o to construct BitcodeOutputFilename. - if (BitcodeOutputFilename.empty()) { - BitcodeOutputFilename = OutputFilename; - if (!LinkAsLibrary) BitcodeOutputFilename += ".bc"; - } - - // Arrange for the bitcode output file to be deleted on any errors. - BitcodeOutputRemover.setFile(BitcodeOutputFilename); - sys::RemoveFileOnSignal(sys::Path(BitcodeOutputFilename)); - - // Arrange for the output file to be deleted on any errors. - if (!LinkAsLibrary) { - OutputRemover.setFile(OutputFilename); - sys::RemoveFileOnSignal(sys::Path(OutputFilename)); - } - - // Construct a Linker (now that Verbose is set) - Linker TheLinker(progname, OutputFilename, Context, Verbose); - - // Keep track of the native link items (versus the bitcode items) - Linker::ItemList NativeLinkItems; - - // Add library paths to the linker - TheLinker.addPaths(LibPaths); - TheLinker.addSystemPaths(); - - // Remove any consecutive duplicates of the same library... - Libraries.erase(std::unique(Libraries.begin(), Libraries.end()), - Libraries.end()); - - if (LinkAsLibrary) { - std::vector<sys::Path> Files; - for (unsigned i = 0; i < InputFilenames.size(); ++i ) - Files.push_back(sys::Path(InputFilenames[i])); - if (TheLinker.LinkInFiles(Files)) - return 1; // Error already printed - - // The libraries aren't linked in but are noted as "dependent" in the - // module. - for (cl::list<std::string>::const_iterator I = Libraries.begin(), - E = Libraries.end(); I != E ; ++I) { - TheLinker.getModule()->addLibrary(*I); - } - } else { - // Build a list of the items from our command line - Linker::ItemList Items; - BuildLinkItems(Items, InputFilenames, Libraries); - - // Link all the items together - if (TheLinker.LinkInItems(Items, NativeLinkItems) ) - return 1; // Error already printed - } - - std::auto_ptr<Module> Composite(TheLinker.releaseModule()); - - // Optimize the module - Optimize(Composite.get()); - - // Generate the bitcode output. - GenerateBitcode(Composite.get(), BitcodeOutputFilename); - - // If we are not linking a library, generate either a native executable - // or a JIT shell script, depending upon what the user wants. - if (!LinkAsLibrary) { - // If the user wants to run a post-link optimization, run it now. - if (!PostLinkOpts.empty()) { - std::vector<std::string> opts = PostLinkOpts; - for (std::vector<std::string>::iterator I = opts.begin(), - E = opts.end(); I != E; ++I) { - sys::Path prog(*I); - if (!prog.canExecute()) { - prog = sys::Program::FindProgramByName(*I); - if (prog.isEmpty()) - PrintAndExit(std::string("Optimization program '") + *I + - "' is not found or not executable.", Composite.get()); - } - // Get the program arguments - sys::Path tmp_output("opt_result"); - std::string ErrMsg; - if (tmp_output.createTemporaryFileOnDisk(true, &ErrMsg)) - PrintAndExit(ErrMsg, Composite.get()); - - const char* args[4]; - args[0] = I->c_str(); - args[1] = BitcodeOutputFilename.c_str(); - args[2] = tmp_output.c_str(); - args[3] = 0; - if (0 == sys::Program::ExecuteAndWait(prog, args, 0,0,0,0, &ErrMsg)) { - if (tmp_output.isBitcodeFile()) { - sys::Path target(BitcodeOutputFilename); - target.eraseFromDisk(); - if (tmp_output.renamePathOnDisk(target, &ErrMsg)) - PrintAndExit(ErrMsg, Composite.get(), 2); - } else - PrintAndExit("Post-link optimization output is not bitcode", - Composite.get()); - } else { - PrintAndExit(ErrMsg, Composite.get()); - } - } - } - - // If the user wants to generate a native executable, compile it from the - // bitcode file. - // - // Otherwise, create a script that will run the bitcode through the JIT. - if (Native) { - // Name of the Assembly Language output file - sys::Path AssemblyFile ( OutputFilename); - AssemblyFile.appendSuffix("s"); - - // Mark the output files for removal. - FileRemover AssemblyFileRemover(AssemblyFile.str()); - sys::RemoveFileOnSignal(AssemblyFile); - - // Determine the locations of the llc and gcc programs. - sys::Path llc = PrependMainExecutablePath("llc", argv[0], - (void *)(intptr_t)&Optimize); - if (llc.isEmpty()) - PrintAndExit("Failed to find llc", Composite.get()); - - sys::Path gcc = sys::Program::FindProgramByName("gcc"); - if (gcc.isEmpty()) - PrintAndExit("Failed to find gcc", Composite.get()); - - // Generate an assembly language file for the bitcode. - std::string ErrMsg; - if (0 != GenerateAssembly(AssemblyFile.str(), BitcodeOutputFilename, - llc, ErrMsg)) - PrintAndExit(ErrMsg, Composite.get()); - - if (0 != GenerateNative(OutputFilename, AssemblyFile.str(), - NativeLinkItems, gcc, envp, ErrMsg)) - PrintAndExit(ErrMsg, Composite.get()); - } else if (NativeCBE) { - sys::Path CFile (OutputFilename); - CFile.appendSuffix("cbe.c"); - - // Mark the output files for removal. - FileRemover CFileRemover(CFile.str()); - sys::RemoveFileOnSignal(CFile); - - // Determine the locations of the llc and gcc programs. - sys::Path llc = PrependMainExecutablePath("llc", argv[0], - (void *)(intptr_t)&Optimize); - if (llc.isEmpty()) - PrintAndExit("Failed to find llc", Composite.get()); - - sys::Path gcc = sys::Program::FindProgramByName("gcc"); - if (gcc.isEmpty()) - PrintAndExit("Failed to find gcc", Composite.get()); - - // Generate an assembly language file for the bitcode. - std::string ErrMsg; - if (GenerateCFile(CFile.str(), BitcodeOutputFilename, llc, ErrMsg)) - PrintAndExit(ErrMsg, Composite.get()); - - if (GenerateNative(OutputFilename, CFile.str(), - NativeLinkItems, gcc, envp, ErrMsg)) - PrintAndExit(ErrMsg, Composite.get()); - } else { - EmitShellScript(argv, Composite.get()); - } - - // Make the script executable... - std::string ErrMsg; - if (sys::Path(OutputFilename).makeExecutableOnDisk(&ErrMsg)) - PrintAndExit(ErrMsg, Composite.get()); - - // Make the bitcode file readable and directly executable in LLEE as well - if (sys::Path(BitcodeOutputFilename).makeExecutableOnDisk(&ErrMsg)) - PrintAndExit(ErrMsg, Composite.get()); - - if (sys::Path(BitcodeOutputFilename).makeReadableOnDisk(&ErrMsg)) - PrintAndExit(ErrMsg, Composite.get()); - } - - // Operations which may fail are now complete. - BitcodeOutputRemover.releaseFile(); - if (!LinkAsLibrary) - OutputRemover.releaseFile(); - - // Graceful exit - return 0; -} diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index 36a482e..3bceb14 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -180,38 +180,16 @@ static const Target *GetTarget(const char *ProgName) { TripleName = sys::getDefaultTargetTriple(); Triple TheTriple(Triple::normalize(TripleName)); - const Target *TheTarget = 0; - if (!ArchName.empty()) { - for (TargetRegistry::iterator it = TargetRegistry::begin(), - ie = TargetRegistry::end(); it != ie; ++it) { - if (ArchName == it->getName()) { - TheTarget = &*it; - break; - } - } - - if (!TheTarget) { - errs() << ProgName << ": error: invalid target '" << ArchName << "'.\n"; - return 0; - } - - // Adjust the triple to match (if known), otherwise stick with the - // module/host triple. - Triple::ArchType Type = Triple::getArchTypeForLLVMName(ArchName); - if (Type != Triple::UnknownArch) - TheTriple.setArch(Type); - } else { - // Get the target specific parser. - std::string Error; - TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Error); - if (TheTarget == 0) { - errs() << ProgName << ": error: unable to get target for '" - << TheTriple.getTriple() - << "', see --version and --triple.\n"; - return 0; - } + // Get the target specific parser. + std::string Error; + const Target *TheTarget = TargetRegistry::lookupTarget(ArchName, TheTriple, + Error); + if (!TheTarget) { + errs() << ProgName << ": " << Error; + return 0; } + // Update the triple name and return the found target. TripleName = TheTriple.getTriple(); return TheTarget; } @@ -430,7 +408,7 @@ int main(int argc, char **argv) { MCCodeEmitter *CE = 0; MCAsmBackend *MAB = 0; if (ShowEncoding) { - CE = TheTarget->createMCCodeEmitter(*MCII, *STI, Ctx); + CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx); MAB = TheTarget->createMCAsmBackend(TripleName); } Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/true, @@ -443,7 +421,7 @@ int main(int argc, char **argv) { Str.reset(createNullStreamer(Ctx)); } else { assert(FileType == OFT_ObjectFile && "Invalid file type!"); - MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *STI, Ctx); + MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx); MCAsmBackend *MAB = TheTarget->createMCAsmBackend(TripleName); Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB, FOS, CE, RelaxAll, diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index 8d9e51e..9afbd4d 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -7,12 +7,12 @@ // //===----------------------------------------------------------------------===// // -// This program is a utility that works like traditional Unix "nm", -// that is, it prints out the names of symbols in a bitcode file, -// along with some information about each symbol. +// This program is a utility that works like traditional Unix "nm", that is, it +// prints out the names of symbols in a bitcode or object file, along with some +// information about each symbol. // -// This "nm" does not print symbols' addresses. It supports many of -// the features of GNU "nm", including its different output formats. +// This "nm" supports many of the features of GNU "nm", including its different +// output formats. // //===----------------------------------------------------------------------===// diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 0e7f3fd..1feea42 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -44,7 +44,7 @@ using namespace object; static cl::opt<bool> CFG("cfg", cl::desc("Create a CFG for every symbol in the object file and" - "write it to a graphviz file (MachO-only)")); + " write it to a graphviz file (MachO-only)")); static cl::opt<bool> UseDbg("g", cl::desc("Print line information from debug info if available")); @@ -286,8 +286,10 @@ void llvm::DisassembleInputMachO(StringRef Filename) { // Read and register the symbol table data. InMemoryStruct<macho::SymtabLoadCommand> SymtabLC; - MachOObj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC); - MachOObj->RegisterStringTable(*SymtabLC); + if (SymtabLCI) { + MachOObj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC); + MachOObj->RegisterStringTable(*SymtabLC); + } std::vector<SectionRef> Sections; std::vector<SymbolRef> Symbols; @@ -430,7 +432,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) { // Stop disassembling either at the beginning of the next symbol or at // the end of the section. - bool containsNextSym = true; + bool containsNextSym = false; uint64_t NextSym = 0; uint64_t NextSymIdx = SymIdx+1; while (Symbols.size() > NextSymIdx) { @@ -498,6 +500,29 @@ void llvm::DisassembleInputMachO(StringRef Filename) { InstrAnalysis.get(), Start, DebugOut, FunctionMap, Functions); } } + if (!CFG && !symbolTableWorked) { + // Reading the symbol table didn't work, disassemble the whole section. + uint64_t SectAddress; + Sections[SectIdx].getAddress(SectAddress); + uint64_t SectSize; + Sections[SectIdx].getSize(SectSize); + uint64_t InstSize; + for (uint64_t Index = 0; Index < SectSize; Index += InstSize) { + MCInst Inst; + + if (DisAsm->getInstruction(Inst, InstSize, memoryObject, Index, + DebugOut, nulls())) { + outs() << format("%8" PRIx64 ":\t", SectAddress + Index); + DumpBytes(StringRef(Bytes.data() + Index, InstSize)); + IP->printInst(&Inst, outs(), ""); + outs() << "\n"; + } else { + errs() << "llvm-objdump: warning: invalid instruction encoding\n"; + if (InstSize == 0) + InstSize = 1; // skip illegible bytes + } + } + } if (CFG) { if (!symbolTableWorked) { diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 5a6f94a..b431c76 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -104,29 +104,27 @@ static bool error(error_code ec) { return true; } -static const Target *GetTarget(const ObjectFile *Obj = NULL) { +static const Target *getTarget(const ObjectFile *Obj = NULL) { // Figure out the target triple. - llvm::Triple TT("unknown-unknown-unknown"); + llvm::Triple TheTriple("unknown-unknown-unknown"); if (TripleName.empty()) { if (Obj) - TT.setArch(Triple::ArchType(Obj->getArch())); + TheTriple.setArch(Triple::ArchType(Obj->getArch())); } else - TT.setTriple(Triple::normalize(TripleName)); - - if (!ArchName.empty()) - TT.setArchName(ArchName); - - TripleName = TT.str(); + TheTriple.setTriple(Triple::normalize(TripleName)); // Get the target specific parser. std::string Error; - const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error); - if (TheTarget) - return TheTarget; + const Target *TheTarget = TargetRegistry::lookupTarget(ArchName, TheTriple, + Error); + if (!TheTarget) { + errs() << ToolName << ": " << Error; + return 0; + } - errs() << ToolName << ": error: unable to get target for '" << TripleName - << "', see --version and --triple.\n"; - return 0; + // Update the triple name and return the found target. + TripleName = TheTriple.getTriple(); + return TheTarget; } void llvm::StringRefMemoryObject::anchor() { } @@ -165,11 +163,11 @@ static bool RelocAddressLess(RelocationRef a, RelocationRef b) { } static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { - const Target *TheTarget = GetTarget(Obj); - if (!TheTarget) { - // GetTarget prints out stuff. + const Target *TheTarget = getTarget(Obj); + // getTarget() will have already issued a diagnostic if necessary, so + // just bail here if it failed. + if (!TheTarget) return; - } error_code ec; for (section_iterator i = Obj->begin_sections(), @@ -208,7 +206,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { if (InlineRelocs) { for (relocation_iterator ri = i->begin_relocations(), re = i->end_relocations(); - ri != re; ri.increment(ec)) { + ri != re; ri.increment(ec)) { if (error(ec)) break; Rels.push_back(*ri); } @@ -465,9 +463,8 @@ static void PrintCOFFSymbolTable(const COFFObjectFile *coff) { << format("assoc %d comdat %d\n" , unsigned(asd->Number) , unsigned(asd->Selection)); - } else { + } else outs() << "AUX Unknown\n"; - } } else { StringRef name; if (error(coff->getSymbol(i, symbol))) return; @@ -611,13 +608,12 @@ static void DumpInput(StringRef file) { return; } - if (Archive *a = dyn_cast<Archive>(binary.get())) { + if (Archive *a = dyn_cast<Archive>(binary.get())) DumpArchive(a); - } else if (ObjectFile *o = dyn_cast<ObjectFile>(binary.get())) { + else if (ObjectFile *o = dyn_cast<ObjectFile>(binary.get())) DumpObject(o); - } else { + else errs() << ToolName << ": '" << file << "': " << "Unrecognized file type.\n"; - } } int main(int argc, char **argv) { @@ -632,6 +628,9 @@ int main(int argc, char **argv) { llvm::InitializeAllAsmParsers(); llvm::InitializeAllDisassemblers(); + // Register the target printer for --version. + cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); + cl::ParseCommandLineOptions(argc, argv, "llvm object file dumper\n"); TripleName = Triple::normalize(TripleName); diff --git a/tools/llvm-prof/llvm-prof.cpp b/tools/llvm-prof/llvm-prof.cpp index d9b6713..81e9503 100644 --- a/tools/llvm-prof/llvm-prof.cpp +++ b/tools/llvm-prof/llvm-prof.cpp @@ -281,7 +281,7 @@ int main(int argc, char **argv) { // using the standard profile info provider pass, but for now this gives us // access to additional information not exposed via the ProfileInfo // interface. - ProfileInfoLoader PIL(argv[0], ProfileDataFile, *M); + ProfileInfoLoader PIL(argv[0], ProfileDataFile); // Run the printer pass. PassManager PassMgr; diff --git a/tools/llvm-ranlib/llvm-ranlib.cpp b/tools/llvm-ranlib/llvm-ranlib.cpp index 64f795f..4006765 100644 --- a/tools/llvm-ranlib/llvm-ranlib.cpp +++ b/tools/llvm-ranlib/llvm-ranlib.cpp @@ -81,7 +81,7 @@ int main(int argc, char **argv) { if (!TheArchive) throw err_msg; - if (TheArchive->writeToDisk(true, false, false, &err_msg )) + if (TheArchive->writeToDisk(true, false, &err_msg )) throw err_msg; if (Verbose) diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp index 01a7d15..95de8d8 100644 --- a/tools/llvm-rtdyld/llvm-rtdyld.cpp +++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -63,18 +63,37 @@ public: return 0; } + // Invalidate instruction cache for sections with execute permissions. + // Some platforms with separate data cache and instruction cache require + // explicit cache flush, otherwise JIT code manipulations (like resolved + // relocations) will get to the data cache but not to the instruction cache. + virtual void invalidateInstructionCache(); }; uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) { - return (uint8_t*)sys::Memory::AllocateRWX(Size, 0, 0).base(); + sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, 0, 0); + FunctionMemory.push_back(MB); + return (uint8_t*)MB.base(); } uint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) { - return (uint8_t*)sys::Memory::AllocateRWX(Size, 0, 0).base(); + sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, 0, 0); + DataMemory.push_back(MB); + return (uint8_t*)MB.base(); +} + +void TrivialMemoryManager::invalidateInstructionCache() { + for (int i = 0, e = FunctionMemory.size(); i != e; ++i) + sys::Memory::InvalidateInstructionCache(FunctionMemory[i].base(), + FunctionMemory[i].size()); + + for (int i = 0, e = DataMemory.size(); i != e; ++i) + sys::Memory::InvalidateInstructionCache(DataMemory[i].base(), + DataMemory[i].size()); } static const char *ProgramName; @@ -113,6 +132,8 @@ static int executeInput() { // Resolve all the relocations we can. Dyld.resolveRelocations(); + // Clear instruction cache before code will be executed. + MemMgr->invalidateInstructionCache(); // FIXME: Error out if there are unresolved relocations. diff --git a/tools/llvm-shlib/Makefile b/tools/llvm-shlib/Makefile index 75bee07..6d6c6e9 100644 --- a/tools/llvm-shlib/Makefile +++ b/tools/llvm-shlib/Makefile @@ -63,7 +63,7 @@ ifeq ($(HOST_OS),Darwin) endif endif -ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux FreeBSD OpenBSD GNU)) +ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux FreeBSD OpenBSD GNU Bitrig)) # Include everything from the .a's into the shared library. LLVMLibsOptions := -Wl,--whole-archive $(LLVMLibsOptions) \ -Wl,--no-whole-archive diff --git a/tools/llvm-stress/llvm-stress.cpp b/tools/llvm-stress/llvm-stress.cpp index fb05a58..31252dd 100644 --- a/tools/llvm-stress/llvm-stress.cpp +++ b/tools/llvm-stress/llvm-stress.cpp @@ -82,6 +82,12 @@ public: uint64_t Val = Rand32(); return Val | (uint64_t(Rand32()) << 32); } + + /// Rand operator for STL algorithms. + ptrdiff_t operator()(ptrdiff_t y) { + return Rand64() % y; + } + private: unsigned Seed; }; @@ -599,15 +605,13 @@ struct CmpModifier: public Modifier { } }; -void FillFunction(Function *F) { +void FillFunction(Function *F, Random &R) { // Create a legal entry block. BasicBlock *BB = BasicBlock::Create(F->getContext(), "BB", F); ReturnInst::Create(F->getContext(), BB); // Create the value table. Modifier::PieceTable PT; - // Pick an initial seed value - Random R(SeedCL); // Consider arguments as legal values. for (Function::arg_iterator it = F->arg_begin(), e = F->arg_end(); @@ -648,15 +652,17 @@ void FillFunction(Function *F) { SM->ActN(5); // Throw in a few stores. } -void IntroduceControlFlow(Function *F) { - std::set<Instruction*> BoolInst; +void IntroduceControlFlow(Function *F, Random &R) { + std::vector<Instruction*> BoolInst; for (BasicBlock::iterator it = F->begin()->begin(), e = F->begin()->end(); it != e; ++it) { if (it->getType() == IntegerType::getInt1Ty(F->getContext())) - BoolInst.insert(it); + BoolInst.push_back(it); } - for (std::set<Instruction*>::iterator it = BoolInst.begin(), + std::random_shuffle(BoolInst.begin(), BoolInst.end(), R); + + for (std::vector<Instruction*>::iterator it = BoolInst.begin(), e = BoolInst.end(); it != e; ++it) { Instruction *Instr = *it; BasicBlock *Curr = Instr->getParent(); @@ -678,8 +684,13 @@ int main(int argc, char **argv) { std::auto_ptr<Module> M(new Module("/tmp/autogen.bc", getGlobalContext())); Function *F = GenEmptyFunction(M.get()); - FillFunction(F); - IntroduceControlFlow(F); + + // Pick an initial seed value + Random R(SeedCL); + // Generate lots of random instructions inside a single basic block. + FillFunction(F, R); + // Break the basic block into many loops. + IntroduceControlFlow(F, R); // Figure out what stream we are supposed to write to... OwningPtr<tool_output_file> Out; diff --git a/tools/llvm-stub/CMakeLists.txt b/tools/llvm-stub/CMakeLists.txt deleted file mode 100644 index a98dc9e..0000000 --- a/tools/llvm-stub/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_llvm_tool(llvm-stub - llvm-stub.c - ) diff --git a/tools/llvm-stub/LLVMBuild.txt b/tools/llvm-stub/LLVMBuild.txt deleted file mode 100644 index 5c3534c..0000000 --- a/tools/llvm-stub/LLVMBuild.txt +++ /dev/null @@ -1,22 +0,0 @@ -;===- ./tools/llvm-stub/LLVMBuild.txt --------------------------*- Conf -*--===; -; -; The LLVM Compiler Infrastructure -; -; This file is distributed under the University of Illinois Open Source -; License. See LICENSE.TXT for details. -; -;===------------------------------------------------------------------------===; -; -; This is an LLVMBuild description file for the components in this subdirectory. -; -; For more information on the LLVMBuild system, please see: -; -; http://llvm.org/docs/LLVMBuild.html -; -;===------------------------------------------------------------------------===; - -[component_0] -type = Tool -name = llvm-stub -parent = Tools -required_libraries = diff --git a/tools/llvm-stub/Makefile b/tools/llvm-stub/Makefile deleted file mode 100644 index 077efa2..0000000 --- a/tools/llvm-stub/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -##===- tools/llvm-stub/Makefile ----------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL := ../.. -TOOLNAME := llvm-stub -LINK_COMPONENTS := object - -include $(LEVEL)/Makefile.common - diff --git a/tools/llvm-stub/llvm-stub.c b/tools/llvm-stub/llvm-stub.c deleted file mode 100644 index 69cd6ed..0000000 --- a/tools/llvm-stub/llvm-stub.c +++ /dev/null @@ -1,77 +0,0 @@ -/*===- llvm-stub.c - Stub executable to run llvm bitcode files ------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This tool is used by the gccld program to enable transparent execution of -// bitcode files by the user. Specifically, gccld outputs two files when asked -// to compile a <program> file: -// 1. It outputs the LLVM bitcode file to <program>.bc -// 2. It outputs a stub executable that runs lli on <program>.bc -// -// This allows the end user to just say ./<program> and have the JIT executed -// automatically. On unix, the stub executable emitted is actually a bourne -// shell script that does the forwarding. Windows does not like #!/bin/sh -// programs in .exe files, so we make it an actual program, defined here. -// -//===----------------------------------------------------------------------===*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "llvm/Config/config.h" - -#if defined(HAVE_UNISTD_H) && !defined(_MSC_VER) -#include <unistd.h> -#endif - -#ifdef _WIN32 -#include <process.h> -#include <io.h> -#endif - -int main(int argc, char** argv) { - const char *Interp = getenv("LLVMINTERP"); - const char **Args; - if (Interp == 0) Interp = "lli"; - - /* Set up the command line options to pass to the JIT. */ - Args = (const char**)malloc(sizeof(char*) * (argc+2)); - /* argv[0] is the JIT */ - Args[0] = Interp; - -#ifdef LLVM_ON_WIN32 - { - int len = strlen(argv[0]); - if (len < 4 || strcmp(argv[0] + len - 4, ".exe") != 0) { - /* .exe suffix is stripped off of argv[0] if the executable was run on the - * command line without one. Put it back on. - */ - argv[0] = strcat(strcpy((char*)malloc(len + 5), argv[0]), ".exe"); - } - } -#endif - - /* argv[1] is argv[0] + ".bc". */ - Args[1] = strcat(strcpy((char*)malloc(strlen(argv[0])+4), argv[0]), ".bc"); - - /* The rest of the args are as before. */ - memcpy((char **)Args+2, argv+1, sizeof(char*)*argc); - - /* Run the JIT. */ -#if !defined(_WIN32) || defined(__MINGW64__) - execvp(Interp, (char **)Args); /* POSIX execvp takes a char *const[]. */ -#else - execvp(Interp, Args); /* windows execvp takes a const char *const *. */ -#endif - /* if _execv returns, the JIT could not be started. */ - fprintf(stderr, "Could not execute the LLVM JIT. Either add 'lli' to your" - " path, or set the\ninterpreter you want to use in the LLVMINTERP " - "environment variable.\n"); - return 1; -} diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index 6382a3f..b80bc34 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -46,10 +46,12 @@ #include "llvm/ADT/StringExtras.h" using namespace llvm; -static cl::opt<bool> DisableInline("disable-inlining", cl::init(false), +static cl::opt<bool> +DisableInline("disable-inlining", cl::init(false), cl::desc("Do not run the inliner pass")); -static cl::opt<bool> DisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false), +static cl::opt<bool> +DisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false), cl::desc("Do not run the GVN load PRE pass")); const char* LTOCodeGenerator::getVersionString() { @@ -152,7 +154,7 @@ bool LTOCodeGenerator::writeMergedModules(const char *path, bool LTOCodeGenerator::compile_to_file(const char** name, std::string& errMsg) { // make unique temp .o file to put generated object file sys::PathWithStatus uniqueObjPath("lto-llvm.o"); - if ( uniqueObjPath.createTemporaryFileOnDisk(false, &errMsg) ) { + if (uniqueObjPath.createTemporaryFileOnDisk(false, &errMsg)) { uniqueObjPath.eraseFromDisk(); return true; } @@ -172,7 +174,7 @@ bool LTOCodeGenerator::compile_to_file(const char** name, std::string& errMsg) { } objFile.keep(); - if ( genResult ) { + if (genResult) { uniqueObjPath.eraseFromDisk(); return true; } @@ -202,46 +204,49 @@ const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg) { sys::Path(_nativeObjectPath).eraseFromDisk(); // return buffer, unless error - if ( _nativeObjectFile == NULL ) + if (_nativeObjectFile == NULL) return NULL; *length = _nativeObjectFile->getBufferSize(); return _nativeObjectFile->getBufferStart(); } bool LTOCodeGenerator::determineTarget(std::string& errMsg) { - if ( _target == NULL ) { - std::string Triple = _linker.getModule()->getTargetTriple(); - if (Triple.empty()) - Triple = sys::getDefaultTargetTriple(); - - // create target machine from info for merged modules - const Target *march = TargetRegistry::lookupTarget(Triple, errMsg); - if ( march == NULL ) - return true; - - // The relocation model is actually a static member of TargetMachine and - // needs to be set before the TargetMachine is instantiated. - Reloc::Model RelocModel = Reloc::Default; - switch( _codeModel ) { - case LTO_CODEGEN_PIC_MODEL_STATIC: - RelocModel = Reloc::Static; - break; - case LTO_CODEGEN_PIC_MODEL_DYNAMIC: - RelocModel = Reloc::PIC_; - break; - case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC: - RelocModel = Reloc::DynamicNoPIC; - break; - } - - // construct LTOModule, hand over ownership of module and target - SubtargetFeatures Features; - Features.getDefaultSubtargetFeatures(llvm::Triple(Triple)); - std::string FeatureStr = Features.getString(); - TargetOptions Options; - _target = march->createTargetMachine(Triple, _mCpu, FeatureStr, Options, - RelocModel); + if (_target != NULL) + return false; + + std::string Triple = _linker.getModule()->getTargetTriple(); + if (Triple.empty()) + Triple = sys::getDefaultTargetTriple(); + + // create target machine from info for merged modules + const Target *march = TargetRegistry::lookupTarget(Triple, errMsg); + if (march == NULL) + return true; + + // The relocation model is actually a static member of TargetMachine and + // needs to be set before the TargetMachine is instantiated. + Reloc::Model RelocModel = Reloc::Default; + switch (_codeModel) { + case LTO_CODEGEN_PIC_MODEL_STATIC: + RelocModel = Reloc::Static; + break; + case LTO_CODEGEN_PIC_MODEL_DYNAMIC: + RelocModel = Reloc::PIC_; + break; + case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC: + RelocModel = Reloc::DynamicNoPIC; + break; } + + // construct LTOModule, hand over ownership of module and target + SubtargetFeatures Features; + Features.getDefaultSubtargetFeatures(llvm::Triple(Triple)); + std::string FeatureStr = Features.getString(); + TargetOptions Options; + LTOModule::getTargetOptions(Options); + _target = march->createTargetMachine(Triple, _mCpu, FeatureStr, Options, + RelocModel, CodeModel::Default, + CodeGenOpt::Aggressive); return false; } @@ -333,13 +338,13 @@ void LTOCodeGenerator::applyScopeRestrictions() { /// Optimize merged modules using various IPO passes bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, std::string &errMsg) { - if ( this->determineTarget(errMsg) ) + if (this->determineTarget(errMsg)) return true; Module* mergedModule = _linker.getModule(); // if options were requested, set them - if ( !_codegenOptions.empty() ) + if (!_codegenOptions.empty()) cl::ParseCommandLineOptions(_codegenOptions.size(), const_cast<char **>(&_codegenOptions[0])); @@ -372,8 +377,7 @@ bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, formatted_raw_ostream Out(out); if (_target->addPassesToEmitFile(*codeGenPasses, Out, - TargetMachine::CGFT_ObjectFile, - CodeGenOpt::Aggressive)) { + TargetMachine::CGFT_ObjectFile)) { errMsg = "target file type not supported"; return true; } @@ -402,7 +406,7 @@ void LTOCodeGenerator::setCodeGenDebugOptions(const char *options) { !o.first.empty(); o = getToken(o.second)) { // ParseCommandLineOptions() expects argv[0] to be program name. Lazily add // that. - if ( _codegenOptions.empty() ) + if (_codegenOptions.empty()) _codegenOptions.push_back(strdup("libLTO")); _codegenOptions.push_back(strdup(o.first.str().c_str())); } diff --git a/tools/lto/LTOCodeGenerator.h b/tools/lto/LTOCodeGenerator.h index 032dc37..3081b7d 100644 --- a/tools/lto/LTOCodeGenerator.h +++ b/tools/lto/LTOCodeGenerator.h @@ -70,7 +70,6 @@ private: llvm::TargetMachine* _target; bool _emitDwarfDebugInfo; bool _scopeRestrictionsDone; - bool _runInternalizePass; lto_codegen_model _codeModel; StringSet _mustPreserveSymbols; StringSet _asmUndefinedRefs; diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp index 1dbd64b..c5b3d10 100644 --- a/tools/lto/LTOModule.cpp +++ b/tools/lto/LTOModule.cpp @@ -26,6 +26,7 @@ #include "llvm/MC/SubtargetFeature.h" #include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Host.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" @@ -37,6 +38,118 @@ #include "llvm/ADT/Triple.h" using namespace llvm; +static cl::opt<bool> +EnableFPMAD("enable-fp-mad", + cl::desc("Enable less precise MAD instructions to be generated"), + cl::init(false)); + +static cl::opt<bool> +DisableFPElim("disable-fp-elim", + cl::desc("Disable frame pointer elimination optimization"), + cl::init(false)); + +static cl::opt<bool> +DisableFPElimNonLeaf("disable-non-leaf-fp-elim", + cl::desc("Disable frame pointer elimination optimization for non-leaf funcs"), + cl::init(false)); + +static cl::opt<bool> +EnableUnsafeFPMath("enable-unsafe-fp-math", + cl::desc("Enable optimizations that may decrease FP precision"), + cl::init(false)); + +static cl::opt<bool> +EnableNoInfsFPMath("enable-no-infs-fp-math", + cl::desc("Enable FP math optimizations that assume no +-Infs"), + cl::init(false)); + +static cl::opt<bool> +EnableNoNaNsFPMath("enable-no-nans-fp-math", + cl::desc("Enable FP math optimizations that assume no NaNs"), + cl::init(false)); + +static cl::opt<bool> +EnableHonorSignDependentRoundingFPMath("enable-sign-dependent-rounding-fp-math", + cl::Hidden, + cl::desc("Force codegen to assume rounding mode can change dynamically"), + cl::init(false)); + +static cl::opt<bool> +GenerateSoftFloatCalls("soft-float", + cl::desc("Generate software floating point library calls"), + cl::init(false)); + +static cl::opt<llvm::FloatABI::ABIType> +FloatABIForCalls("float-abi", + cl::desc("Choose float ABI type"), + cl::init(FloatABI::Default), + cl::values( + clEnumValN(FloatABI::Default, "default", + "Target default float ABI type"), + clEnumValN(FloatABI::Soft, "soft", + "Soft float ABI (implied by -soft-float)"), + clEnumValN(FloatABI::Hard, "hard", + "Hard float ABI (uses FP registers)"), + clEnumValEnd)); + +static cl::opt<llvm::FPOpFusion::FPOpFusionMode> +FuseFPOps("fp-contract", + cl::desc("Enable aggresive formation of fused FP ops"), + cl::init(FPOpFusion::Standard), + cl::values( + clEnumValN(FPOpFusion::Fast, "fast", + "Fuse FP ops whenever profitable"), + clEnumValN(FPOpFusion::Standard, "on", + "Only fuse 'blessed' FP ops."), + clEnumValN(FPOpFusion::Strict, "off", + "Only fuse FP ops when the result won't be effected."), + clEnumValEnd)); + +static cl::opt<bool> +DontPlaceZerosInBSS("nozero-initialized-in-bss", + cl::desc("Don't place zero-initialized symbols into bss section"), + cl::init(false)); + +static cl::opt<bool> +EnableGuaranteedTailCallOpt("tailcallopt", + cl::desc("Turn fastcc calls into tail calls by (potentially) changing ABI."), + cl::init(false)); + +static cl::opt<bool> +DisableTailCalls("disable-tail-calls", + cl::desc("Never emit tail calls"), + cl::init(false)); + +static cl::opt<unsigned> +OverrideStackAlignment("stack-alignment", + cl::desc("Override default stack alignment"), + cl::init(0)); + +static cl::opt<bool> +EnableRealignStack("realign-stack", + cl::desc("Realign stack if needed"), + cl::init(true)); + +static cl::opt<std::string> +TrapFuncName("trap-func", cl::Hidden, + cl::desc("Emit a call to trap function rather than a trap instruction"), + cl::init("")); + +static cl::opt<bool> +EnablePIE("enable-pie", + cl::desc("Assume the creation of a position independent executable."), + cl::init(false)); + +static cl::opt<bool> +SegmentedStacks("segmented-stacks", + cl::desc("Use segmented stacks if possible."), + cl::init(false)); + +static cl::opt<bool> +UseInitArray("use-init-array", + cl::desc("Use .init_array instead of .ctors."), + cl::init(false)); + LTOModule::LTOModule(llvm::Module *m, llvm::TargetMachine *t) : _module(m), _target(t), _context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(), NULL), @@ -117,6 +230,30 @@ LTOModule *LTOModule::makeLTOModule(const void *mem, size_t length, return makeLTOModule(buffer.take(), errMsg); } +void LTOModule::getTargetOptions(TargetOptions &Options) { + Options.LessPreciseFPMADOption = EnableFPMAD; + Options.NoFramePointerElim = DisableFPElim; + Options.NoFramePointerElimNonLeaf = DisableFPElimNonLeaf; + 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.RealignStack = EnableRealignStack; + Options.TrapFuncName = TrapFuncName; + Options.PositionIndependentExecutable = EnablePIE; + Options.EnableSegmentedStacks = SegmentedStacks; + Options.UseInitArray = UseInitArray; +} + LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer, std::string &errMsg) { static bool Initialized = false; @@ -150,6 +287,7 @@ LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer, std::string FeatureStr = Features.getString(); std::string CPU; TargetOptions Options; + getTargetOptions(Options); TargetMachine *target = march->createTargetMachine(Triple, CPU, FeatureStr, Options); LTOModule *Ret = new LTOModule(m.take(), target); @@ -271,6 +409,9 @@ void LTOModule::addDefinedDataSymbol(GlobalValue *v) { // Add to list of defined symbols. addDefinedSymbol(v, false); + if (!v->hasSection() /* || !isTargetDarwin */) + return; + // Special case i386/ppc ObjC data structures in magic sections: // The issue is that the old ObjC object format did some strange // contortions to avoid real linker symbols. For instance, the @@ -290,26 +431,25 @@ void LTOModule::addDefinedDataSymbol(GlobalValue *v) { // a class was missing. // The following synthesizes the implicit .objc_* symbols for the linker // from the ObjC data structures generated by the front end. - if (v->hasSection() /* && isTargetDarwin */) { - // special case if this data blob is an ObjC class definition - if (v->getSection().compare(0, 15, "__OBJC,__class,") == 0) { - if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { - addObjCClass(gv); - } + + // special case if this data blob is an ObjC class definition + if (v->getSection().compare(0, 15, "__OBJC,__class,") == 0) { + if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { + addObjCClass(gv); } + } - // special case if this data blob is an ObjC category definition - else if (v->getSection().compare(0, 18, "__OBJC,__category,") == 0) { - if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { - addObjCCategory(gv); - } + // special case if this data blob is an ObjC category definition + else if (v->getSection().compare(0, 18, "__OBJC,__category,") == 0) { + if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { + addObjCCategory(gv); } + } - // special case if this data blob is the list of referenced classes - else if (v->getSection().compare(0, 18, "__OBJC,__cls_refs,") == 0) { - if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { - addObjCClassRef(gv); - } + // special case if this data blob is the list of referenced classes + else if (v->getSection().compare(0, 18, "__OBJC,__cls_refs,") == 0) { + if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { + addObjCClassRef(gv); } } } @@ -409,7 +549,7 @@ void LTOModule::addAsmGlobalSymbol(const char *name, // much. // fill information structure - info.name = name; + info.name = entry.getKey().data(); info.attributes = LTO_SYMBOL_PERMISSIONS_DATA | LTO_SYMBOL_DEFINITION_REGULAR | scope; info.isFunction = false; @@ -599,7 +739,7 @@ namespace { markGlobal(*Symbol); } virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol, - unsigned Size , unsigned ByteAlignment) { + uint64_t Size , unsigned ByteAlignment) { markDefined(*Symbol); } virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, @@ -658,21 +798,20 @@ bool LTOModule::addAsmGlobalSymbols(std::string &errMsg) { OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, _context, *Streamer, *_target->getMCAsmInfo())); - OwningPtr<MCSubtargetInfo> STI(_target->getTarget(). - createMCSubtargetInfo(_target->getTargetTriple(), - _target->getTargetCPU(), - _target->getTargetFeatureString())); - OwningPtr<MCTargetAsmParser> - TAP(_target->getTarget().createMCAsmParser(*STI, *Parser.get())); + const Target &T = _target->getTarget(); + OwningPtr<MCSubtargetInfo> + STI(T.createMCSubtargetInfo(_target->getTargetTriple(), + _target->getTargetCPU(), + _target->getTargetFeatureString())); + OwningPtr<MCTargetAsmParser> TAP(T.createMCAsmParser(*STI, *Parser.get())); if (!TAP) { - errMsg = "target " + std::string(_target->getTarget().getName()) + - " does not define AsmParser."; + errMsg = "target " + std::string(T.getName()) + + " does not define AsmParser."; return true; } Parser->setTargetParser(*TAP); - int Res = Parser->Run(false); - if (Res) + if (Parser->Run(false)) return true; for (RecordStreamer::const_iterator i = Streamer->begin(), @@ -687,6 +826,7 @@ bool LTOModule::addAsmGlobalSymbols(std::string &errMsg) { Value == RecordStreamer::Used) addAsmGlobalSymbolUndef(Key.data()); } + return false; } @@ -694,8 +834,10 @@ bool LTOModule::addAsmGlobalSymbols(std::string &errMsg) { static bool isDeclaration(const GlobalValue &V) { if (V.hasAvailableExternallyLinkage()) return true; + if (V.isMaterializable()) return false; + return V.isDeclaration(); } diff --git a/tools/lto/LTOModule.h b/tools/lto/LTOModule.h index cafb927..8e52206 100644 --- a/tools/lto/LTOModule.h +++ b/tools/lto/LTOModule.h @@ -29,6 +29,7 @@ namespace llvm { class Function; class GlobalValue; class MemoryBuffer; + class TargetOptions; class Value; } @@ -126,6 +127,10 @@ public: return _asm_undefines; } + /// getTargetOptions - Fill the TargetOptions object with the options + /// specified on the command line. + static void getTargetOptions(llvm::TargetOptions &Options); + private: /// parseSymbols - Parse the symbols from the module and model-level ASM and /// add them to either the defined or undefined lists. diff --git a/tools/macho-dump/macho-dump.cpp b/tools/macho-dump/macho-dump.cpp index 2b22c3b..20deda9 100644 --- a/tools/macho-dump/macho-dump.cpp +++ b/tools/macho-dump/macho-dump.cpp @@ -194,7 +194,7 @@ static int DumpSegment64Command(MachOObject &Obj, } outs() << " ])\n"; - return 0; + return Res; } static void DumpSymbolTableEntryData(MachOObject &Obj, @@ -332,6 +332,35 @@ static int DumpLinkeditDataCommand(MachOObject &Obj, return 0; } +static int DumpDataInCodeDataCommand(MachOObject &Obj, + const MachOObject::LoadCommandInfo &LCI) { + InMemoryStruct<macho::LinkeditDataLoadCommand> LLC; + Obj.ReadLinkeditDataLoadCommand(LCI, LLC); + if (!LLC) + return Error("unable to read segment load command"); + + outs() << " ('dataoff', " << LLC->DataOffset << ")\n" + << " ('datasize', " << LLC->DataSize << ")\n" + << " ('_data_regions', [\n"; + + + unsigned NumRegions = LLC->DataSize / 8; + for (unsigned i = 0; i < NumRegions; ++i) { + InMemoryStruct<macho::DataInCodeTableEntry> DICE; + Obj.ReadDataInCodeTableEntry(LLC->DataOffset, i, DICE); + if (!DICE) + return Error("unable to read DataInCodeTableEntry"); + outs() << " # DICE " << i << "\n" + << " ('offset', " << DICE->Offset << ")\n" + << " ('length', " << DICE->Length << ")\n" + << " ('kind', " << DICE->Kind << ")\n"; + } + + outs() <<" ])\n"; + + return 0; +} + static int DumpLoadCommand(MachOObject &Obj, unsigned Index) { const MachOObject::LoadCommandInfo &LCI = Obj.getLoadCommandInfo(Index); @@ -358,6 +387,9 @@ static int DumpLoadCommand(MachOObject &Obj, unsigned Index) { case macho::LCT_FunctionStarts: Res = DumpLinkeditDataCommand(Obj, LCI); break; + case macho::LCT_DataInCode: + Res = DumpDataInCodeDataCommand(Obj, LCI); + break; default: Warning("unknown load command: " + Twine(LCI.Command.Type)); break; diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index a5b0511..4ada7d1 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -13,12 +13,12 @@ //===----------------------------------------------------------------------===// #include "llvm/LLVMContext.h" +#include "llvm/DebugInfo.h" #include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/CallGraphSCCPass.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/Assembly/PrintModulePass.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/RegionPass.h" @@ -104,15 +104,23 @@ StandardLinkOpts("std-link-opts", static cl::opt<bool> OptLevelO1("O1", - cl::desc("Optimization level 1. Similar to llvm-gcc -O1")); + cl::desc("Optimization level 1. Similar to clang -O1")); static cl::opt<bool> OptLevelO2("O2", - cl::desc("Optimization level 2. Similar to llvm-gcc -O2")); + cl::desc("Optimization level 2. Similar to clang -O2")); + +static cl::opt<bool> +OptLevelOs("Os", + cl::desc("Like -O2 with extra optimizations for size. Similar to clang -Os")); + +static cl::opt<bool> +OptLevelOz("Oz", + cl::desc("Like -Os but reduces code size further. Similar to clang -Oz")); static cl::opt<bool> OptLevelO3("O3", - cl::desc("Optimization level 3. Similar to llvm-gcc -O3")); + cl::desc("Optimization level 3. Similar to clang -O3")); static cl::opt<std::string> TargetTriple("mtriple", cl::desc("Override target triple for module")); @@ -409,16 +417,21 @@ static inline void addPass(PassManagerBase &PM, Pass *P) { /// /// OptLevel - Optimization Level static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, - unsigned OptLevel) { + unsigned OptLevel, unsigned SizeLevel) { FPM.add(createVerifierPass()); // Verify that input is correct PassManagerBuilder Builder; Builder.OptLevel = OptLevel; + Builder.SizeLevel = SizeLevel; if (DisableInline) { // No inlining pass } else if (OptLevel > 1) { unsigned Threshold = 225; + if (SizeLevel == 1) // -Os + Threshold = 75; + else if (SizeLevel == 2) // -Oz + Threshold = 25; if (OptLevel > 2) Threshold = 275; Builder.Inliner = createFunctionInliningPass(Threshold); @@ -571,7 +584,7 @@ int main(int argc, char **argv) { Passes.add(TD); OwningPtr<FunctionPassManager> FPasses; - if (OptLevelO1 || OptLevelO2 || OptLevelO3) { + if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { FPasses.reset(new FunctionPassManager(M.get())); if (TD) FPasses->add(new TargetData(*TD)); @@ -617,17 +630,27 @@ int main(int argc, char **argv) { } if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) { - AddOptimizationPasses(Passes, *FPasses, 1); + AddOptimizationPasses(Passes, *FPasses, 1, 0); OptLevelO1 = false; } if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) { - AddOptimizationPasses(Passes, *FPasses, 2); + AddOptimizationPasses(Passes, *FPasses, 2, 0); OptLevelO2 = false; } + if (OptLevelOs && OptLevelOs.getPosition() < PassList.getPosition(i)) { + AddOptimizationPasses(Passes, *FPasses, 2, 1); + OptLevelOs = false; + } + + if (OptLevelOz && OptLevelOz.getPosition() < PassList.getPosition(i)) { + AddOptimizationPasses(Passes, *FPasses, 2, 2); + OptLevelOz = false; + } + if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) { - AddOptimizationPasses(Passes, *FPasses, 3); + AddOptimizationPasses(Passes, *FPasses, 3, 0); OptLevelO3 = false; } @@ -682,15 +705,21 @@ int main(int argc, char **argv) { } if (OptLevelO1) - AddOptimizationPasses(Passes, *FPasses, 1); + AddOptimizationPasses(Passes, *FPasses, 1, 0); if (OptLevelO2) - AddOptimizationPasses(Passes, *FPasses, 2); + AddOptimizationPasses(Passes, *FPasses, 2, 0); + + if (OptLevelOs) + AddOptimizationPasses(Passes, *FPasses, 2, 1); + + if (OptLevelOz) + AddOptimizationPasses(Passes, *FPasses, 2, 2); if (OptLevelO3) - AddOptimizationPasses(Passes, *FPasses, 3); + AddOptimizationPasses(Passes, *FPasses, 3, 0); - if (OptLevelO1 || OptLevelO2 || OptLevelO3) { + if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { FPasses->doInitialization(); for (Module::iterator F = M->begin(), E = M->end(); F != E; ++F) FPasses->run(*F); |