diff options
Diffstat (limited to 'tools')
47 files changed, 1225 insertions, 138 deletions
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 75d203e..9668c76 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -37,6 +37,7 @@ add_subdirectory(llvm-extract) add_subdirectory(llvm-diff) add_subdirectory(macho-dump) add_subdirectory(llvm-objdump) +add_subdirectory(llvm-readobj) add_subdirectory(llvm-rtdyld) add_subdirectory(llvm-dwarfdump) @@ -44,6 +45,7 @@ add_subdirectory(bugpoint) add_subdirectory(bugpoint-passes) add_subdirectory(llvm-bcanalyzer) add_subdirectory(llvm-stub) +add_subdirectory(llvm-stress) if( NOT WIN32 ) add_subdirectory(lto) diff --git a/tools/Makefile b/tools/Makefile index 1953cb6..8bf091a 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -32,9 +32,9 @@ PARALLEL_DIRS := opt llvm-as llvm-dis \ llvm-ld llvm-prof llvm-link \ lli llvm-extract llvm-mc \ bugpoint llvm-bcanalyzer llvm-stub \ - llvm-diff macho-dump llvm-objdump \ + llvm-diff macho-dump llvm-objdump llvm-readobj \ llvm-rtdyld llvm-dwarfdump llvm-cov \ - llvm-size + llvm-size llvm-stress # Let users override the set of tools to build from the command line. ifdef ONLY_TOOLS diff --git a/tools/bugpoint/CMakeLists.txt b/tools/bugpoint/CMakeLists.txt index e06feb1..ee2235b 100644 --- a/tools/bugpoint/CMakeLists.txt +++ b/tools/bugpoint/CMakeLists.txt @@ -1,5 +1,5 @@ set(LLVM_LINK_COMPONENTS asmparser instrumentation scalaropts ipo - linker bitreader bitwriter) + linker bitreader bitwriter vectorize) add_llvm_tool(bugpoint BugDriver.cpp diff --git a/tools/bugpoint/CrashDebugger.cpp b/tools/bugpoint/CrashDebugger.cpp index a0aaf53..aed16f4 100644 --- a/tools/bugpoint/CrashDebugger.cpp +++ b/tools/bugpoint/CrashDebugger.cpp @@ -169,7 +169,7 @@ ReduceCrashingGlobalVariables::TestGlobalVariables( return false; } -namespace llvm { +namespace { /// ReduceCrashingFunctions reducer - This works by removing functions and /// seeing if the program still crashes. If it does, then keep the newer, /// smaller program. @@ -569,7 +569,7 @@ static bool DebugACrash(BugDriver &BD, for (Function::const_iterator BI = FI->begin(), E = FI->end(); BI != E; ++BI) for (BasicBlock::const_iterator I = BI->begin(), E = --BI->end(); - I != E; ++I, ++CurInstructionNum) + I != E; ++I, ++CurInstructionNum) { if (InstructionsToSkipBeforeDeleting) { --InstructionsToSkipBeforeDeleting; } else { @@ -594,6 +594,7 @@ static bool DebugACrash(BugDriver &BD, // one. delete M; } + } if (InstructionsToSkipBeforeDeleting) { InstructionsToSkipBeforeDeleting = 0; diff --git a/tools/bugpoint/ExecutionDriver.cpp b/tools/bugpoint/ExecutionDriver.cpp index 77c01ac..adf5587 100644 --- a/tools/bugpoint/ExecutionDriver.cpp +++ b/tools/bugpoint/ExecutionDriver.cpp @@ -209,9 +209,6 @@ bool BugDriver::initializeExecutionEnvironment() { Interpreter = AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand); break; - default: - Message = "Sorry, this back-end is not supported by bugpoint right now!\n"; - break; } if (!Interpreter) errs() << Message; diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp index f2e61f8..ac8e159 100644 --- a/tools/bugpoint/ExtractFunction.cpp +++ b/tools/bugpoint/ExtractFunction.cpp @@ -47,7 +47,39 @@ namespace { cl::opt<bool, true> NoSCFG("disable-simplifycfg", cl::location(DisableSimplifyCFG), cl::desc("Do not use the -simplifycfg pass to reduce testcases")); -} + + Function* globalInitUsesExternalBA(GlobalVariable* GV) { + if (!GV->hasInitializer()) + return 0; + + Constant *I = GV->getInitializer(); + + // walk the values used by the initializer + // (and recurse into things like ConstantExpr) + std::vector<Constant*> Todo; + std::set<Constant*> Done; + Todo.push_back(I); + + while (!Todo.empty()) { + Constant* V = Todo.back(); + Todo.pop_back(); + Done.insert(V); + + if (BlockAddress *BA = dyn_cast<BlockAddress>(V)) { + Function *F = BA->getFunction(); + if (F->isDeclaration()) + return F; + } + + for (User::op_iterator i = V->op_begin(), e = V->op_end(); i != e; ++i) { + Constant *C = dyn_cast<Constant>(*i); + if (C && !isa<GlobalValue>(C) && !Done.count(C)) + Todo.push_back(C); + } + } + return 0; + } +} // end anonymous namespace /// deleteInstructionFromProgram - This method clones the current Program and /// deletes the specified instruction from the cloned module. It then runs a @@ -272,11 +304,6 @@ llvm::SplitFunctionsOutOfModule(Module *M, ValueToValueMapTy NewVMap; Module *New = CloneModule(M, NewVMap); - // Make sure global initializers exist only in the safe module (CBE->.so) - for (Module::global_iterator I = New->global_begin(), E = New->global_end(); - I != E; ++I) - I->setInitializer(0); // Delete the initializer to make it external - // Remove the Test functions from the Safe module std::set<Function *> TestFunctions; for (unsigned i = 0, e = F.size(); i != e; ++i) { @@ -295,6 +322,27 @@ llvm::SplitFunctionsOutOfModule(Module *M, DeleteFunctionBody(I); + // Try to split the global initializers evenly + for (Module::global_iterator I = M->global_begin(), E = M->global_end(); + I != E; ++I) { + GlobalVariable *GV = cast<GlobalVariable>(NewVMap[I]); + if (Function *TestFn = globalInitUsesExternalBA(I)) { + if (Function *SafeFn = globalInitUsesExternalBA(GV)) { + errs() << "*** Error: when reducing functions, encountered " + "the global '"; + WriteAsOperand(errs(), GV, false); + errs() << "' with an initializer that references blockaddresses " + "from safe function '" << SafeFn->getName() + << "' and from test function '" << TestFn->getName() << "'.\n"; + exit(1); + } + I->setInitializer(0); // Delete the initializer to make it external + } else { + // If we keep it in the safe module, then delete it in the test module + GV->setInitializer(0); + } + } + // Make sure that there is a global ctor/dtor array in both halves of the // module if they both have static ctor/dtor functions. SplitStaticCtorDtor("llvm.global_ctors", M, New, NewVMap); diff --git a/tools/bugpoint/Makefile b/tools/bugpoint/Makefile index eacaa47..34f4bdd 100644 --- a/tools/bugpoint/Makefile +++ b/tools/bugpoint/Makefile @@ -10,6 +10,6 @@ LEVEL := ../.. TOOLNAME := bugpoint LINK_COMPONENTS := asmparser instrumentation scalaropts ipo linker bitreader \ - bitwriter + bitwriter vectorize include $(LEVEL)/Makefile.common diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp index 7ff16db..82a3a86 100644 --- a/tools/bugpoint/Miscompilation.cpp +++ b/tools/bugpoint/Miscompilation.cpp @@ -820,7 +820,8 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test, // Don't forward functions which are external in the test module too. if (TestFn && !TestFn->isDeclaration()) { // 1. Add a string constant with its name to the global file - Constant *InitArray = ConstantArray::get(F->getContext(), F->getName()); + Constant *InitArray = + ConstantDataArray::getString(F->getContext(), F->getName()); GlobalVariable *funcName = new GlobalVariable(*Safe, InitArray->getType(), true /*isConstant*/, GlobalValue::InternalLinkage, InitArray, diff --git a/tools/bugpoint/ToolRunner.cpp b/tools/bugpoint/ToolRunner.cpp index c2d3720..b80a5b4 100644 --- a/tools/bugpoint/ToolRunner.cpp +++ b/tools/bugpoint/ToolRunner.cpp @@ -234,6 +234,8 @@ int LLI::ExecuteProgram(const std::string &Bitcode, Timeout, MemoryLimit, Error); } +void AbstractInterpreter::anchor() { } + // LLI create method - Try to find the LLI executable AbstractInterpreter *AbstractInterpreter::createLLI(const char *Argv0, std::string &Message, diff --git a/tools/bugpoint/ToolRunner.h b/tools/bugpoint/ToolRunner.h index cfa8acf..7b93394 100644 --- a/tools/bugpoint/ToolRunner.h +++ b/tools/bugpoint/ToolRunner.h @@ -86,6 +86,7 @@ public: /// complexity behind a simple interface. /// class AbstractInterpreter { + virtual void anchor(); public: static CBE *createCBE(const char *Argv0, std::string &Message, const std::string &GCCBinary, diff --git a/tools/bugpoint/bugpoint.cpp b/tools/bugpoint/bugpoint.cpp index 6a87521..8f15b02 100644 --- a/tools/bugpoint/bugpoint.cpp +++ b/tools/bugpoint/bugpoint.cpp @@ -120,6 +120,7 @@ int main(int argc, char **argv) { PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); initializeScalarOpts(Registry); + initializeVectorization(Registry); initializeIPO(Registry); initializeAnalysis(Registry); initializeIPA(Registry); diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp index 6f547b3..cfd84c0 100644 --- a/tools/gold/gold-plugin.cpp +++ b/tools/gold/gold-plugin.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Config/config.h" +#include "llvm/Config/config.h" // plugin-api.h requires HAVE_STDINT_H #include "plugin-api.h" #include "llvm-c/lto.h" diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index 58dafca..191b649 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -21,7 +21,6 @@ #include "llvm/Support/IRReader.h" #include "llvm/CodeGen/LinkAllAsmWriterComponents.h" #include "llvm/CodeGen/LinkAllCodegenComponents.h" -#include "llvm/Config/config.h" #include "llvm/MC/SubtargetFeature.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -238,6 +237,11 @@ 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"), @@ -249,15 +253,10 @@ EnableRealignStack("realign-stack", cl::init(true)); static cl::opt<bool> -DisableSwitchTables(cl::Hidden, "disable-jump-tables", +DisableSwitchTables(cl::Hidden, "disable-jump-tables", cl::desc("Do not generate jump tables."), cl::init(false)); -static cl::opt<bool> -EnableStrongPHIElim(cl::Hidden, "strong-phi-elim", - cl::desc("Use strong PHI elimination."), - 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"), @@ -297,7 +296,6 @@ static tool_output_file *GetOutputStream(const char *TargetName, OutputFilename = GetFileNameRoot(InputFilename); switch (FileType) { - default: assert(0 && "Unknown file type"); case TargetMachine::CGFT_AssemblyFile: if (TargetName[0] == 'c') { if (TargetName[1] == 0) @@ -325,7 +323,6 @@ static tool_output_file *GetOutputStream(const char *TargetName, // Decide if we need "binary" output. bool Binary = false; switch (FileType) { - default: assert(0 && "Unknown file type"); case TargetMachine::CGFT_AssemblyFile: break; case TargetMachine::CGFT_ObjectFile: @@ -465,6 +462,7 @@ int main(int argc, char **argv) { Options.JITEmitDebugInfo = EmitJitDebugInfo; Options.JITEmitDebugInfoToDisk = EmitJitDebugInfoToDisk; Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt; + Options.DisableTailCalls = DisableTailCalls; Options.StackAlignmentOverride = OverrideStackAlignment; Options.RealignStack = EnableRealignStack; Options.DisableJumpTables = DisableSwitchTables; diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index f855eda..0e8d1d8 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -23,6 +23,7 @@ #include "llvm/ExecutionEngine/Interpreter.h" #include "llvm/ExecutionEngine/JIT.h" #include "llvm/ExecutionEngine/JITEventListener.h" +#include "llvm/ExecutionEngine/JITMemoryManager.h" #include "llvm/ExecutionEngine/MCJIT.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/IRReader.h" @@ -94,12 +95,12 @@ namespace { "of the executable"), cl::value_desc("function"), cl::init("main")); - + cl::opt<std::string> FakeArgv0("fake-argv0", cl::desc("Override the 'argv[0]' value passed into the executing" " program"), cl::value_desc("executable")); - + cl::opt<bool> DisableCoreFiles("disable-core-files", cl::Hidden, cl::desc("Disable emission of core files if possible")); @@ -158,7 +159,7 @@ static void do_shutdown() { int main(int argc, char **argv, char * const *envp) { sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); - + LLVMContext &Context = getGlobalContext(); atexit(do_shutdown); // Call llvm_shutdown() on exit. @@ -173,7 +174,7 @@ int main(int argc, char **argv, char * const *envp) { // If the user doesn't want core files, disable them. if (DisableCoreFiles) sys::Process::PreventCoreFiles(); - + // Load the bitcode... SMDiagnostic Err; Module *Mod = ParseIRFile(InputFile, Err, Context); @@ -199,6 +200,8 @@ 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); @@ -207,9 +210,11 @@ int main(int argc, char **argv, char * const *envp) { if (!TargetTriple.empty()) Mod->setTargetTriple(Triple::normalize(TargetTriple)); - // Enable MCJIT, if desired. - if (UseMCJIT) + // Enable MCJIT if desired. + if (UseMCJIT && !ForceInterpreter) { builder.setUseMCJIT(true); + builder.setJITMemoryManager(JITMemoryManager::CreateDefaultMemManager()); + } CodeGenOpt::Level OLvl = CodeGenOpt::Default; switch (OptLevel) { @@ -262,15 +267,15 @@ int main(int argc, char **argv, char * const *envp) { return -1; } - // If the program doesn't explicitly call exit, we will need the Exit - // function later on to make an explicit call, so get the function now. + // If the program doesn't explicitly call exit, we will need the Exit + // function later on to make an explicit call, so get the function now. Constant *Exit = Mod->getOrInsertFunction("exit", Type::getVoidTy(Context), Type::getInt32Ty(Context), NULL); - + // Reset errno to zero on entry to main. errno = 0; - + // Run static constructors. EE->runStaticConstructorsDestructors(false); @@ -287,8 +292,8 @@ int main(int argc, char **argv, char * const *envp) { // Run static destructors. EE->runStaticConstructorsDestructors(true); - - // If the program didn't call exit explicitly, we should call it now. + + // If the program didn't call exit explicitly, we should call it now. // This ensures that any atexit handlers get called correctly. if (Function *ExitF = dyn_cast<Function>(Exit)) { std::vector<GenericValue> Args; diff --git a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp index f1cb523..bf068c4 100644 --- a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp +++ b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp @@ -208,6 +208,8 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID, case bitc::CST_CODE_CE_CMP: return "CE_CMP"; case bitc::CST_CODE_INLINEASM: return "INLINEASM"; case bitc::CST_CODE_CE_SHUFVEC_EX: return "CE_SHUFVEC_EX"; + case bitc::CST_CODE_BLOCKADDRESS: return "CST_CODE_BLOCKADDRESS"; + case bitc::CST_CODE_DATA: return "DATA"; } case bitc::FUNCTION_BLOCK_ID: switch (CodeID) { @@ -228,7 +230,6 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID, case bitc::FUNC_CODE_INST_BR: return "INST_BR"; case bitc::FUNC_CODE_INST_SWITCH: return "INST_SWITCH"; case bitc::FUNC_CODE_INST_INVOKE: return "INST_INVOKE"; - case bitc::FUNC_CODE_INST_UNWIND: return "INST_UNWIND"; case bitc::FUNC_CODE_INST_UNREACHABLE: return "INST_UNREACHABLE"; case bitc::FUNC_CODE_INST_PHI: return "INST_PHI"; @@ -482,13 +483,13 @@ static int AnalyzeBitcode() { if (MemBuf->getBufferSize() & 3) return Error("Bitcode stream should be a multiple of 4 bytes in length"); - unsigned char *BufPtr = (unsigned char *)MemBuf->getBufferStart(); - unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize(); + const unsigned char *BufPtr = (unsigned char *)MemBuf->getBufferStart(); + const unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize(); // If we have a wrapper header, parse it and ignore the non-bc file contents. // The magic number is 0x0B17C0DE stored in little endian. if (isBitcodeWrapper(BufPtr, EndBufPtr)) - if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr)) + if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr, true)) return Error("Invalid bitcode wrapper header"); BitstreamReader StreamFile(BufPtr, EndBufPtr); @@ -534,7 +535,6 @@ static int AnalyzeBitcode() { errs() << "\n"; errs() << " Stream type: "; switch (CurStreamType) { - default: assert(0 && "Unknown bitstream type"); case UnknownBitstream: errs() << "unknown\n"; break; case LLVMIRBitstream: errs() << "LLVM IR\n"; break; } diff --git a/tools/llvm-config/llvm-config.cpp b/tools/llvm-config/llvm-config.cpp index 2bb0aeb..79fd7f8 100644 --- a/tools/llvm-config/llvm-config.cpp +++ b/tools/llvm-config/llvm-config.cpp @@ -169,7 +169,8 @@ int main(int argc, char **argv) { // and from an installed path. We try and auto-detect which case we are in so // that we can report the correct information when run from a development // tree. - bool IsInDevelopmentTree, DevelopmentTreeLayoutIsCMakeStyle; + bool IsInDevelopmentTree; + enum { MakefileStyle, CMakeStyle, CMakeBuildModeStyle } DevelopmentTreeLayout; llvm::SmallString<256> CurrentPath(GetExecutablePath(argv[0]).str()); std::string CurrentExecPrefix; std::string ActiveObjRoot; @@ -185,7 +186,7 @@ int main(int argc, char **argv) { // symbolic links, but is good enough. if (CurrentExecPrefix == std::string(LLVM_OBJ_ROOT) + "/" + LLVM_BUILDMODE) { IsInDevelopmentTree = true; - DevelopmentTreeLayoutIsCMakeStyle = false; + DevelopmentTreeLayout = MakefileStyle; // If we are in a development tree, then check if we are in a BuildTools // directory. This indicates we are built for the build triple, but we @@ -195,12 +196,17 @@ int main(int argc, char **argv) { } else { ActiveObjRoot = LLVM_OBJ_ROOT; } + } else if (CurrentExecPrefix == std::string(LLVM_OBJ_ROOT)) { + IsInDevelopmentTree = true; + DevelopmentTreeLayout = CMakeStyle; + ActiveObjRoot = LLVM_OBJ_ROOT; } else if (CurrentExecPrefix == std::string(LLVM_OBJ_ROOT) + "/bin") { IsInDevelopmentTree = true; - DevelopmentTreeLayoutIsCMakeStyle = true; + DevelopmentTreeLayout = CMakeBuildModeStyle; ActiveObjRoot = LLVM_OBJ_ROOT; } else { IsInDevelopmentTree = false; + DevelopmentTreeLayout = MakefileStyle; // Initialized to avoid warnings. } // Compute various directory locations based on the derived location @@ -213,12 +219,19 @@ int main(int argc, char **argv) { // CMake organizes the products differently than a normal prefix style // layout. - if (DevelopmentTreeLayoutIsCMakeStyle) { - ActiveBinDir = ActiveObjRoot + "/bin/" + LLVM_BUILDMODE; - ActiveLibDir = ActiveObjRoot + "/lib/" + LLVM_BUILDMODE; - } else { + switch (DevelopmentTreeLayout) { + case MakefileStyle: ActiveBinDir = ActiveObjRoot + "/" + LLVM_BUILDMODE + "/bin"; ActiveLibDir = ActiveObjRoot + "/" + LLVM_BUILDMODE + "/lib"; + break; + case CMakeStyle: + ActiveBinDir = ActiveObjRoot + "/bin"; + ActiveLibDir = ActiveObjRoot + "/lib"; + break; + case CMakeBuildModeStyle: + ActiveBinDir = ActiveObjRoot + "/bin/" + LLVM_BUILDMODE; + ActiveLibDir = ActiveObjRoot + "/lib/" + LLVM_BUILDMODE; + break; } // We need to include files from both the source and object trees. diff --git a/tools/llvm-diff/DiffConsumer.cpp b/tools/llvm-diff/DiffConsumer.cpp index d9e1814..0528039 100644 --- a/tools/llvm-diff/DiffConsumer.cpp +++ b/tools/llvm-diff/DiffConsumer.cpp @@ -44,6 +44,8 @@ static void ComputeNumbering(Function *F, DenseMap<Value*,unsigned> &Numbering){ } +void Consumer::anchor() { } + void DiffConsumer::printValue(Value *V, bool isL) { if (V->hasName()) { out << (isa<GlobalValue>(V) ? '@' : '%') << V->getName(); diff --git a/tools/llvm-diff/DiffConsumer.h b/tools/llvm-diff/DiffConsumer.h index b95d427..2060fe1 100644 --- a/tools/llvm-diff/DiffConsumer.h +++ b/tools/llvm-diff/DiffConsumer.h @@ -29,6 +29,7 @@ namespace llvm { /// The interface for consumers of difference data. class Consumer { + virtual void anchor(); public: /// Record that a local context has been entered. Left and /// Right are IR "containers" of some sort which are being diff --git a/tools/llvm-diff/DifferenceEngine.cpp b/tools/llvm-diff/DifferenceEngine.cpp index 435cd87..8113fd4 100644 --- a/tools/llvm-diff/DifferenceEngine.cpp +++ b/tools/llvm-diff/DifferenceEngine.cpp @@ -319,13 +319,13 @@ class FunctionDifferenceEngine { bool Difference = false; DenseMap<ConstantInt*,BasicBlock*> LCases; - for (unsigned I = 1, E = LI->getNumCases(); I != E; ++I) - LCases[LI->getCaseValue(I)] = LI->getSuccessor(I); - for (unsigned I = 1, E = RI->getNumCases(); I != E; ++I) { + for (unsigned I = 0, E = LI->getNumCases(); I != E; ++I) + LCases[LI->getCaseValue(I)] = LI->getCaseSuccessor(I); + for (unsigned I = 0, E = RI->getNumCases(); I != E; ++I) { ConstantInt *CaseValue = RI->getCaseValue(I); BasicBlock *LCase = LCases[CaseValue]; if (LCase) { - if (TryUnify) tryUnify(LCase, RI->getSuccessor(I)); + if (TryUnify) tryUnify(LCase, RI->getCaseSuccessor(I)); LCases.erase(CaseValue); } else if (Complain || !Difference) { if (Complain) @@ -628,6 +628,8 @@ void FunctionDifferenceEngine::runBlockDiff(BasicBlock::iterator LStart, } +void DifferenceEngine::Oracle::anchor() { } + void DifferenceEngine::diff(Function *L, Function *R) { Context C(*this, L, R); diff --git a/tools/llvm-diff/DifferenceEngine.h b/tools/llvm-diff/DifferenceEngine.h index 5b4f80b..7ea79e4 100644 --- a/tools/llvm-diff/DifferenceEngine.h +++ b/tools/llvm-diff/DifferenceEngine.h @@ -50,7 +50,9 @@ namespace llvm { /// An oracle for answering whether two values are equivalent as /// operands. - struct Oracle { + class Oracle { + virtual void anchor(); + public: virtual bool operator()(Value *L, Value *R) = 0; protected: diff --git a/tools/llvm-dis/llvm-dis.cpp b/tools/llvm-dis/llvm-dis.cpp index 9020a52..6450ea6 100644 --- a/tools/llvm-dis/llvm-dis.cpp +++ b/tools/llvm-dis/llvm-dis.cpp @@ -24,6 +24,7 @@ #include "llvm/Analysis/DebugInfo.h" #include "llvm/Assembly/AssemblyAnnotationWriter.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/DataStream.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" @@ -126,12 +127,19 @@ int main(int argc, char **argv) { std::string ErrorMessage; std::auto_ptr<Module> M; - { - OwningPtr<MemoryBuffer> BufferPtr; - if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) - ErrorMessage = ec.message(); + // Use the bitcode streaming interface + DataStreamer *streamer = getDataFileStreamer(InputFilename, &ErrorMessage); + if (streamer) { + std::string DisplayFilename; + if (InputFilename == "-") + DisplayFilename = "<stdin>"; else - M.reset(ParseBitcodeFile(BufferPtr.get(), Context, &ErrorMessage)); + DisplayFilename = InputFilename; + M.reset(getStreamedBitcodeModule(DisplayFilename, streamer, Context, + &ErrorMessage)); + if(M.get() != 0 && M->MaterializeAllPermanently(&ErrorMessage)) { + M.reset(); + } } if (M.get() == 0) { @@ -183,4 +191,3 @@ int main(int argc, char **argv) { return 0; } - diff --git a/tools/llvm-extract/llvm-extract.cpp b/tools/llvm-extract/llvm-extract.cpp index 6cd528d..2ed11c5 100644 --- a/tools/llvm-extract/llvm-extract.cpp +++ b/tools/llvm-extract/llvm-extract.cpp @@ -99,7 +99,7 @@ int main(int argc, char **argv) { // Figure out which globals we should extract. for (size_t i = 0, e = ExtractGlobals.size(); i != e; ++i) { - GlobalValue *GV = M.get()->getNamedGlobal(ExtractGlobals[i]); + GlobalValue *GV = M->getNamedGlobal(ExtractGlobals[i]); if (!GV) { errs() << argv[0] << ": program doesn't contain global named '" << ExtractGlobals[i] << "'!\n"; @@ -117,8 +117,8 @@ int main(int argc, char **argv) { "invalid regex: " << Error; } bool match = false; - for (Module::global_iterator GV = M.get()->global_begin(), - E = M.get()->global_end(); GV != E; GV++) { + for (Module::global_iterator GV = M->global_begin(), + E = M->global_end(); GV != E; GV++) { if (RegEx.match(GV->getName())) { GVs.insert(&*GV); match = true; @@ -133,7 +133,7 @@ int main(int argc, char **argv) { // Figure out which functions we should extract. for (size_t i = 0, e = ExtractFuncs.size(); i != e; ++i) { - GlobalValue *GV = M.get()->getFunction(ExtractFuncs[i]); + GlobalValue *GV = M->getFunction(ExtractFuncs[i]); if (!GV) { errs() << argv[0] << ": program doesn't contain function named '" << ExtractFuncs[i] << "'!\n"; @@ -151,7 +151,7 @@ int main(int argc, char **argv) { "invalid regex: " << Error; } bool match = false; - for (Module::iterator F = M.get()->begin(), E = M.get()->end(); F != E; + for (Module::iterator F = M->begin(), E = M->end(); F != E; F++) { if (RegEx.match(F->getName())) { GVs.insert(&*F); diff --git a/tools/llvm-ld/CMakeLists.txt b/tools/llvm-ld/CMakeLists.txt index 370bcb4..d328a04 100644 --- a/tools/llvm-ld/CMakeLists.txt +++ b/tools/llvm-ld/CMakeLists.txt @@ -1,4 +1,4 @@ -set(LLVM_LINK_COMPONENTS ipo scalaropts linker archive bitwriter) +set(LLVM_LINK_COMPONENTS ipo scalaropts linker archive bitwriter vectorize) add_llvm_tool(llvm-ld Optimize.cpp diff --git a/tools/llvm-ld/Makefile b/tools/llvm-ld/Makefile index 2ec6e0a..8793ca9 100644 --- a/tools/llvm-ld/Makefile +++ b/tools/llvm-ld/Makefile @@ -9,6 +9,6 @@ LEVEL := ../.. TOOLNAME := llvm-ld -LINK_COMPONENTS := ipo scalaropts linker archive bitwriter +LINK_COMPONENTS := ipo scalaropts linker archive bitwriter vectorize include $(LEVEL)/Makefile.common diff --git a/tools/llvm-ld/llvm-ld.cpp b/tools/llvm-ld/llvm-ld.cpp index 6b4c3c7..ecf0476 100644 --- a/tools/llvm-ld/llvm-ld.cpp +++ b/tools/llvm-ld/llvm-ld.cpp @@ -37,7 +37,6 @@ #include "llvm/Support/SystemUtils.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/Support/Signals.h" -#include "llvm/Config/config.h" #include <memory> #include <cstring> using namespace llvm; @@ -424,7 +423,7 @@ static void EmitShellScript(char **argv, Module *M) { PrintAndExit(ErrMsg, M); return; -#endif +#else // Output the script to start the program... std::string ErrorInfo; @@ -470,6 +469,7 @@ static void EmitShellScript(char **argv, Module *M) { } Out2.os() << " " << BitcodeOutputFilename << " ${1+\"$@\"}\n"; Out2.keep(); +#endif } // BuildLinkItems -- This function generates a LinkItemList for the LinkItems diff --git a/tools/llvm-mc/Disassembler.cpp b/tools/llvm-mc/Disassembler.cpp index 1b5aa57..6793d7e 100644 --- a/tools/llvm-mc/Disassembler.cpp +++ b/tools/llvm-mc/Disassembler.cpp @@ -21,6 +21,7 @@ #include "llvm/MC/MCDisassembler.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/Triple.h" @@ -160,16 +161,22 @@ int Disassembler::disassemble(const Target &T, errs() << "error: no subtarget info for target " << Triple << "\n"; return -1; } - + OwningPtr<const MCDisassembler> DisAsm(T.createMCDisassembler(*STI)); if (!DisAsm) { errs() << "error: no disassembler for target " << Triple << "\n"; return -1; } + OwningPtr<const MCRegisterInfo> MRI(T.createMCRegInfo(Triple)); + if (!MRI) { + errs() << "error: no register info for target " << Triple << "\n"; + return -1; + } + int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); OwningPtr<MCInstPrinter> IP(T.createMCInstPrinter(AsmPrinterVariant, - *AsmInfo, *STI)); + *AsmInfo, *MRI, *STI)); if (!IP) { errs() << "error: no instruction printer for target " << Triple << '\n'; return -1; @@ -295,7 +302,6 @@ int Disassembler::disassembleEnhanced(const std::string &TS, Out << operandIndex << "-"; switch (token->type()) { - default: Out << "?"; break; case EDToken::kTokenWhitespace: Out << "w"; break; case EDToken::kTokenPunctuation: Out << "p"; break; case EDToken::kTokenOpcode: Out << "o"; break; @@ -366,4 +372,3 @@ int Disassembler::disassembleEnhanced(const std::string &TS, return 0; } - diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index 4281259..dc72974 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -70,9 +70,6 @@ RelaxAll("mc-relax-all", cl::desc("Relax all fixups")); static cl::opt<bool> NoExecStack("mc-no-exec-stack", cl::desc("File doesn't need an exec stack")); -static cl::opt<bool> -EnableLogging("enable-api-logging", cl::desc("Enable MC API logging")); - enum OutputFileType { OFT_Null, OFT_AssemblyFile, @@ -386,7 +383,7 @@ static int AssembleInput(const char *ProgName) { // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and // MCObjectFileInfo needs a MCContext reference in order to initialize itself. OwningPtr<MCObjectFileInfo> MOFI(new MCObjectFileInfo()); - MCContext Ctx(*MAI, *MRI, MOFI.get()); + MCContext Ctx(*MAI, *MRI, MOFI.get(), &SrcMgr); MOFI->InitMCObjectFileInfo(TripleName, RelocModel, CMModel, Ctx); if (SaveTempLabels) @@ -419,7 +416,7 @@ static int AssembleInput(const char *ProgName) { // FIXME: There is a bit of code duplication with addPassesToEmitFile. if (FileType == OFT_AssemblyFile) { MCInstPrinter *IP = - TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *STI); + TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MRI, *STI); MCCodeEmitter *CE = 0; MCAsmBackend *MAB = 0; if (ShowEncoding) { @@ -443,10 +440,6 @@ static int AssembleInput(const char *ProgName) { NoExecStack)); } - if (EnableLogging) { - Str.reset(createLoggingStreamer(Str.take(), errs())); - } - OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI)); OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(*STI, *Parser)); @@ -524,7 +517,6 @@ int main(int argc, char **argv) { setDwarfDebugFlags(argc, argv); switch (Action) { - default: case AC_AsLex: return AsLexInput(argv[0]); case AC_Assemble: @@ -534,6 +526,4 @@ int main(int argc, char **argv) { case AC_EDisassemble: return DisassembleInput(argv[0], true); } - - return 0; } diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index 3e159c7..9cf83b6 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -61,6 +61,12 @@ namespace { cl::alias UndefinedOnly2("u", cl::desc("Alias for --undefined-only"), cl::aliasopt(UndefinedOnly)); + cl::opt<bool> DynamicSyms("dynamic", + cl::desc("Display the dynamic symbols instead " + "of normal symbols.")); + cl::alias DynamicSyms2("D", cl::desc("Alias for --dynamic"), + cl::aliasopt(DynamicSyms)); + cl::opt<bool> DefinedOnly("defined-only", cl::desc("Show only defined symbols")); @@ -277,13 +283,17 @@ static void DumpSymbolNamesFromModule(Module *M) { static void DumpSymbolNamesFromObject(ObjectFile *obj) { error_code ec; - for (symbol_iterator i = obj->begin_symbols(), - e = obj->end_symbols(); - i != e; i.increment(ec)) { + symbol_iterator ibegin = obj->begin_symbols(); + symbol_iterator iend = obj->end_symbols(); + if (DynamicSyms) { + ibegin = obj->begin_dynamic_symbols(); + iend = obj->end_dynamic_symbols(); + } + for (symbol_iterator i = ibegin; i != iend; i.increment(ec)) { if (error(ec)) break; - bool internal; - if (error(i->isInternal(internal))) break; - if (!DebugSyms && internal) + uint32_t symflags; + if (error(i->getFlags(symflags))) break; + if (!DebugSyms && (symflags & SymbolRef::SF_FormatSpecific)) continue; NMSymbol s; s.Size = object::UnknownAddressOrSize; @@ -335,7 +345,7 @@ static void DumpSymbolNamesFromFile(std::string &Filename) { for (object::Archive::child_iterator i = a->begin_children(), e = a->end_children(); i != e; ++i) { OwningPtr<Binary> child; - if (error_code ec = i->getAsBinary(child)) { + if (i->getAsBinary(child)) { // Try opening it as a bitcode file. OwningPtr<MemoryBuffer> buff(i->getBuffer()); Module *Result = 0; diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index ffeea88..b9ea041 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -26,6 +26,7 @@ #include "llvm/MC/MCInstrAnalysis.h" #include "llvm/MC/MCInstrDesc.h" #include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -53,27 +54,28 @@ static cl::opt<std::string> static const Target *GetTarget(const MachOObject *MachOObj) { // Figure out the target triple. - llvm::Triple TT("unknown-unknown-unknown"); - switch (MachOObj->getHeader().CPUType) { - case llvm::MachO::CPUTypeI386: - TT.setArch(Triple::ArchType(Triple::x86)); - break; - case llvm::MachO::CPUTypeX86_64: - TT.setArch(Triple::ArchType(Triple::x86_64)); - break; - case llvm::MachO::CPUTypeARM: - TT.setArch(Triple::ArchType(Triple::arm)); - break; - case llvm::MachO::CPUTypePowerPC: - TT.setArch(Triple::ArchType(Triple::ppc)); - break; - case llvm::MachO::CPUTypePowerPC64: - TT.setArch(Triple::ArchType(Triple::ppc64)); - break; + if (TripleName.empty()) { + llvm::Triple TT("unknown-unknown-unknown"); + switch (MachOObj->getHeader().CPUType) { + case llvm::MachO::CPUTypeI386: + TT.setArch(Triple::ArchType(Triple::x86)); + break; + case llvm::MachO::CPUTypeX86_64: + TT.setArch(Triple::ArchType(Triple::x86_64)); + break; + case llvm::MachO::CPUTypeARM: + TT.setArch(Triple::ArchType(Triple::arm)); + break; + case llvm::MachO::CPUTypePowerPC: + TT.setArch(Triple::ArchType(Triple::ppc)); + break; + case llvm::MachO::CPUTypePowerPC64: + TT.setArch(Triple::ArchType(Triple::ppc64)); + break; + } + TripleName = TT.str(); } - TripleName = TT.str(); - // Get the target specific parser. std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error); @@ -256,9 +258,10 @@ void llvm::DisassembleInputMachO(StringRef Filename) { OwningPtr<const MCSubtargetInfo> STI(TheTarget->createMCSubtargetInfo(TripleName, "", "")); OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI)); + OwningPtr<const MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter( - AsmPrinterVariant, *AsmInfo, *STI)); + AsmPrinterVariant, *AsmInfo, *MRI, *STI)); if (!InstrAnalysis || !AsmInfo || !STI || !DisAsm || !IP) { errs() << "error: couldn't initialize disassembler for target " @@ -418,8 +421,11 @@ void llvm::DisassembleInputMachO(StringRef Filename) { continue; // Start at the address of the symbol relative to the section's address. + uint64_t SectionAddress = 0; uint64_t Start = 0; + Sections[SectIdx].getAddress(SectionAddress); Symbols[SymIdx].getAddress(Start); + Start -= SectionAddress; // Stop disassembling either at the beginning of the next symbol or at // the end of the section. @@ -433,6 +439,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) { Sections[SectIdx].containsSymbol(Symbols[NextSymIdx], containsNextSym); Symbols[NextSymIdx].getAddress(NextSym); + NextSym -= SectionAddress; break; } ++NextSymIdx; diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index bcfecb3..deb4dd1 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -26,6 +26,7 @@ #include "llvm/MC/MCDisassembler.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" @@ -126,6 +127,8 @@ static const Target *GetTarget(const ObjectFile *Obj = NULL) { return 0; } +void llvm::StringRefMemoryObject::anchor() { } + void llvm::DumpBytes(StringRef bytes) { static const char hex_rep[] = "0123456789abcdef"; // FIXME: The real way to do this is to figure out the longest instruction @@ -187,6 +190,8 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { if (!error(i->containsSymbol(*si, contains)) && contains) { uint64_t Address; if (error(si->getAddress(Address))) break; + Address -= SectionAddr; + StringRef Name; if (error(si->getName(Name))) break; Symbols.push_back(std::make_pair(Address, Name)); @@ -242,9 +247,15 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { return; } + OwningPtr<const MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); + if (!MRI) { + errs() << "error: no register info for target " << TripleName << "\n"; + return; + } + int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter( - AsmPrinterVariant, *AsmInfo, *STI)); + AsmPrinterVariant, *AsmInfo, *MRI, *STI)); if (!IP) { errs() << "error: no instruction printer for target " << TripleName << '\n'; @@ -478,27 +489,27 @@ static void PrintSymbolTable(const ObjectFile *o) { if (error(ec)) return; StringRef Name; uint64_t Address; - bool Global; SymbolRef::Type Type; - bool Weak; - bool Absolute; uint64_t Size; + uint32_t Flags; section_iterator Section = o->end_sections(); if (error(si->getName(Name))) continue; if (error(si->getAddress(Address))) continue; - if (error(si->isGlobal(Global))) continue; + if (error(si->getFlags(Flags))) continue; if (error(si->getType(Type))) continue; - if (error(si->isWeak(Weak))) continue; - if (error(si->isAbsolute(Absolute))) continue; if (error(si->getSize(Size))) continue; if (error(si->getSection(Section))) continue; + bool Global = Flags & SymbolRef::SF_Global; + bool Weak = Flags & SymbolRef::SF_Weak; + bool Absolute = Flags & SymbolRef::SF_Absolute; + if (Address == UnknownAddressOrSize) Address = 0; if (Size == UnknownAddressOrSize) Size = 0; char GlobLoc = ' '; - if (Type != SymbolRef::ST_External) + if (Type != SymbolRef::ST_Unknown) GlobLoc = Global ? 'g' : 'l'; char Debug = (Type == SymbolRef::ST_Debug || Type == SymbolRef::ST_File) ? 'd' : ' '; diff --git a/tools/llvm-objdump/llvm-objdump.h b/tools/llvm-objdump/llvm-objdump.h index 75f852a..aa71b77 100644 --- a/tools/llvm-objdump/llvm-objdump.h +++ b/tools/llvm-objdump/llvm-objdump.h @@ -25,7 +25,7 @@ void DumpBytes(StringRef bytes); void DisassembleInputMachO(StringRef Filename); class StringRefMemoryObject : public MemoryObject { -private: + virtual void anchor(); StringRef Bytes; public: StringRefMemoryObject(StringRef bytes) : Bytes(bytes) {} diff --git a/tools/llvm-readobj/CMakeLists.txt b/tools/llvm-readobj/CMakeLists.txt new file mode 100644 index 0000000..be80469 --- /dev/null +++ b/tools/llvm-readobj/CMakeLists.txt @@ -0,0 +1,5 @@ +set(LLVM_LINK_COMPONENTS archive bitreader object) + +add_llvm_tool(llvm-readobj + llvm-readobj.cpp + ) diff --git a/tools/llvm-readobj/LLVMBuild.txt b/tools/llvm-readobj/LLVMBuild.txt new file mode 100644 index 0000000..c9f934f --- /dev/null +++ b/tools/llvm-readobj/LLVMBuild.txt @@ -0,0 +1,22 @@ +;===- ./tools/llvm-readobj/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-readobj +parent = Tools +required_libraries = Archive BitReader Object diff --git a/tools/llvm-readobj/Makefile b/tools/llvm-readobj/Makefile new file mode 100644 index 0000000..a7a7de3 --- /dev/null +++ b/tools/llvm-readobj/Makefile @@ -0,0 +1,18 @@ +##===- tools/llvm-readobj/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-readobj +LINK_COMPONENTS := archive bitreader object + +# This tool has no plugins, optimize startup time. +TOOL_NO_EXPORTS := 1 + +include $(LEVEL)/Makefile.common + diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp new file mode 100644 index 0000000..3f8789d --- /dev/null +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -0,0 +1,204 @@ +//===- llvm-readobj.cpp - Dump contents of an Object File -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This program is a utility that works like traditional Unix "readelf", +// except that it can handle any type of object file recognized by lib/Object. +// +// It makes use of the generic ObjectFile interface. +// +// Caution: This utility is new, experimental, unsupported, and incomplete. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Object/ObjectFile.h" +#include "llvm/Analysis/Verifier.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/FormattedStream.h" + +using namespace llvm; +using namespace llvm::object; + +static cl::opt<std::string> +InputFilename(cl::Positional, cl::desc("<input object>"), cl::init("")); + +void DumpSymbolHeader() { + outs() << format(" %-32s", (const char*)"Name") + << format(" %-4s", (const char*)"Type") + << format(" %-16s", (const char*)"Address") + << format(" %-16s", (const char*)"Size") + << format(" %-16s", (const char*)"FileOffset") + << format(" %-26s", (const char*)"Flags") + << "\n"; +} + +const char *GetTypeStr(SymbolRef::Type Type) { + switch (Type) { + case SymbolRef::ST_Unknown: return "?"; + case SymbolRef::ST_Data: return "DATA"; + case SymbolRef::ST_Debug: return "DBG"; + case SymbolRef::ST_File: return "FILE"; + case SymbolRef::ST_Function: return "FUNC"; + case SymbolRef::ST_Other: return "-"; + } + return "INV"; +} + +std::string GetFlagStr(uint32_t Flags) { + std::string result; + if (Flags & SymbolRef::SF_Undefined) + result += "undef,"; + if (Flags & SymbolRef::SF_Global) + result += "global,"; + if (Flags & SymbolRef::SF_Weak) + result += "weak,"; + if (Flags & SymbolRef::SF_Absolute) + result += "absolute,"; + if (Flags & SymbolRef::SF_ThreadLocal) + result += "threadlocal,"; + if (Flags & SymbolRef::SF_Common) + result += "common,"; + if (Flags & SymbolRef::SF_FormatSpecific) + result += "formatspecific,"; + + // Remove trailing comma + if (result.size() > 0) { + result.erase(result.size() - 1); + } + return result; +} + +void DumpSymbol(const SymbolRef &sym) { + StringRef Name; + SymbolRef::Type Type; + uint32_t Flags; + uint64_t Address; + uint64_t Size; + uint64_t FileOffset; + sym.getName(Name); + sym.getAddress(Address); + sym.getSize(Size); + sym.getFileOffset(FileOffset); + sym.getType(Type); + sym.getFlags(Flags); + + // format() can't handle StringRefs + outs() << format(" %-32s", Name.str().c_str()) + << format(" %-4s", GetTypeStr(Type)) + << format(" %16"PRIx64, Address) + << format(" %16"PRIx64, Size) + << format(" %16"PRIx64, FileOffset) + << " " << GetFlagStr(Flags) + << "\n"; +} + + +// Iterate through the normal symbols in the ObjectFile +void DumpSymbols(const ObjectFile *obj) { + error_code ec; + uint32_t count = 0; + outs() << "Symbols:\n"; + symbol_iterator it = obj->begin_symbols(); + symbol_iterator ie = obj->end_symbols(); + while (it != ie) { + DumpSymbol(*it); + it.increment(ec); + if (ec) + report_fatal_error("Symbol iteration failed"); + ++count; + } + outs() << " Total: " << count << "\n\n"; +} + +// Iterate through the dynamic symbols in the ObjectFile. +void DumpDynamicSymbols(const ObjectFile *obj) { + error_code ec; + uint32_t count = 0; + outs() << "Dynamic Symbols:\n"; + symbol_iterator it = obj->begin_dynamic_symbols(); + symbol_iterator ie = obj->end_dynamic_symbols(); + while (it != ie) { + DumpSymbol(*it); + it.increment(ec); + if (ec) + report_fatal_error("Symbol iteration failed"); + ++count; + } + outs() << " Total: " << count << "\n\n"; +} + +void DumpLibrary(const LibraryRef &lib) { + StringRef path; + lib.getPath(path); + outs() << " " << path << "\n"; +} + +// Iterate through needed libraries +void DumpLibrariesNeeded(const ObjectFile *obj) { + error_code ec; + uint32_t count = 0; + library_iterator it = obj->begin_libraries_needed(); + library_iterator ie = obj->end_libraries_needed(); + outs() << "Libraries needed:\n"; + while (it != ie) { + DumpLibrary(*it); + it.increment(ec); + if (ec) + report_fatal_error("Needed libraries iteration failed"); + ++count; + } + outs() << " Total: " << count << "\n\n"; +} + +void DumpHeaders(const ObjectFile *obj) { + outs() << "File Format : " << obj->getFileFormatName() << "\n"; + outs() << "Arch : " + << Triple::getArchTypeName((llvm::Triple::ArchType)obj->getArch()) + << "\n"; + outs() << "Address Size: " << (8*obj->getBytesInAddress()) << " bits\n"; + outs() << "Load Name : " << obj->getLoadName() << "\n"; + outs() << "\n"; +} + +int main(int argc, char** argv) { + error_code ec; + sys::PrintStackTraceOnErrorSignal(); + PrettyStackTraceProgram X(argc, argv); + + cl::ParseCommandLineOptions(argc, argv, + "LLVM Object Reader\n"); + + if (InputFilename.empty()) { + errs() << "Please specify an input filename\n"; + return 1; + } + + // Open the object file + OwningPtr<MemoryBuffer> File; + if (MemoryBuffer::getFile(InputFilename, File)) { + errs() << InputFilename << ": Open failed\n"; + return 1; + } + + ObjectFile *obj = ObjectFile::createObjectFile(File.take()); + if (!obj) { + errs() << InputFilename << ": Object type not recognized\n"; + } + + DumpHeaders(obj); + DumpSymbols(obj); + DumpDynamicSymbols(obj); + DumpLibrariesNeeded(obj); + return 0; +} + diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp index ec9d652..990582d 100644 --- a/tools/llvm-rtdyld/llvm-rtdyld.cpp +++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -51,12 +51,30 @@ EntryPoint("entry", class TrivialMemoryManager : public RTDyldMemoryManager { public: SmallVector<sys::MemoryBlock, 16> FunctionMemory; + SmallVector<sys::MemoryBlock, 16> DataMemory; + + uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID); + uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID); uint8_t *startFunctionBody(const char *Name, uintptr_t &Size); void endFunctionBody(const char *Name, uint8_t *FunctionStart, uint8_t *FunctionEnd); }; +uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size, + unsigned Alignment, + unsigned SectionID) { + return (uint8_t*)sys::Memory::AllocateRWX(Size, 0, 0).base(); +} + +uint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size, + unsigned Alignment, + unsigned SectionID) { + return (uint8_t*)sys::Memory::AllocateRWX(Size, 0, 0).base(); +} + uint8_t *TrivialMemoryManager::startFunctionBody(const char *Name, uintptr_t &Size) { return (uint8_t*)sys::Memory::AllocateRWX(Size, 0, 0).base(); @@ -142,10 +160,7 @@ int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, "llvm MC-JIT tool\n"); switch (Action) { - default: case AC_Execute: return executeInput(); } - - return 0; } diff --git a/tools/llvm-stress/CMakeLists.txt b/tools/llvm-stress/CMakeLists.txt new file mode 100644 index 0000000..e2d07a5 --- /dev/null +++ b/tools/llvm-stress/CMakeLists.txt @@ -0,0 +1,5 @@ +set(LLVM_LINK_COMPONENTS bitreader asmparser bitwriter instrumentation scalaropts ipo) + +add_llvm_tool(llvm-stress + llvm-stress.cpp + ) diff --git a/tools/llvm-stress/LLVMBuild.txt b/tools/llvm-stress/LLVMBuild.txt new file mode 100644 index 0000000..f383d35 --- /dev/null +++ b/tools/llvm-stress/LLVMBuild.txt @@ -0,0 +1,22 @@ +;===- ./tools/llvm-stress/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-stress +parent = Tools +required_libraries = AsmParser BitReader BitWriter IPO Instrumentation Scalar diff --git a/tools/llvm-stress/Makefile b/tools/llvm-stress/Makefile new file mode 100644 index 0000000..90d57c3 --- /dev/null +++ b/tools/llvm-stress/Makefile @@ -0,0 +1,18 @@ +##===- tools/llvm-stress/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-stress +LINK_COMPONENTS := object +LINK_COMPONENTS := bitreader bitwriter asmparser instrumentation scalaropts ipo + +# This tool has no plugins, optimize startup time. +TOOL_NO_EXPORTS = 1 + +include $(LEVEL)/Makefile.common diff --git a/tools/llvm-stress/llvm-stress.cpp b/tools/llvm-stress/llvm-stress.cpp new file mode 100644 index 0000000..c095059 --- /dev/null +++ b/tools/llvm-stress/llvm-stress.cpp @@ -0,0 +1,672 @@ +//===-- llvm-stress.cpp - Generate random LL files to stress-test LLVM ----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This program is a utility that generates random .ll files to stress-test +// different components in LLVM. +// +//===----------------------------------------------------------------------===// +#include "llvm/LLVMContext.h" +#include "llvm/Module.h" +#include "llvm/PassManager.h" +#include "llvm/Constants.h" +#include "llvm/Instruction.h" +#include "llvm/CallGraphSCCPass.h" +#include "llvm/Assembly/PrintModulePass.h" +#include "llvm/Analysis/Verifier.h" +#include "llvm/Support/PassNameParser.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/PluginLoader.h" +#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/ToolOutputFile.h" +#include <memory> +#include <sstream> +#include <set> +#include <vector> +#include <algorithm> +using namespace llvm; + +static cl::opt<unsigned> SeedCL("seed", + cl::desc("Seed used for randomness"), cl::init(0)); +static cl::opt<unsigned> SizeCL("size", + cl::desc("The estimated size of the generated function (# of instrs)"), + cl::init(100)); +static cl::opt<std::string> +OutputFilename("o", cl::desc("Override output filename"), + cl::value_desc("filename")); + +static cl::opt<bool> GenHalfFloat("generate-half-float", + cl::desc("Generate half-length floating-point values"), cl::init(false)); +static cl::opt<bool> GenX86FP80("generate-x86-fp80", + cl::desc("Generate 80-bit X86 floating-point values"), cl::init(false)); +static cl::opt<bool> GenFP128("generate-fp128", + cl::desc("Generate 128-bit floating-point values"), cl::init(false)); +static cl::opt<bool> GenPPCFP128("generate-ppc-fp128", + cl::desc("Generate 128-bit PPC floating-point values"), cl::init(false)); +static cl::opt<bool> GenX86MMX("generate-x86-mmx", + cl::desc("Generate X86 MMX floating-point values"), cl::init(false)); + +/// A utility class to provide a pseudo-random number generator which is +/// the same across all platforms. This is somewhat close to the libc +/// implementation. Note: This is not a cryptographically secure pseudorandom +/// number generator. +class Random { +public: + /// C'tor + Random(unsigned _seed):Seed(_seed) {} + /// Return the next random value. + unsigned Rand() { + unsigned Val = Seed + 0x000b07a1; + Seed = (Val * 0x3c7c0ac1); + // Only lowest 19 bits are random-ish. + return Seed & 0x7ffff; + } + +private: + unsigned Seed; +}; + +/// Generate an empty function with a default argument list. +Function *GenEmptyFunction(Module *M) { + // Type Definitions + std::vector<Type*> ArgsTy; + // Define a few arguments + LLVMContext &Context = M->getContext(); + ArgsTy.push_back(PointerType::get(IntegerType::getInt8Ty(Context), 0)); + ArgsTy.push_back(PointerType::get(IntegerType::getInt32Ty(Context), 0)); + ArgsTy.push_back(PointerType::get(IntegerType::getInt64Ty(Context), 0)); + ArgsTy.push_back(IntegerType::getInt32Ty(Context)); + ArgsTy.push_back(IntegerType::getInt64Ty(Context)); + ArgsTy.push_back(IntegerType::getInt8Ty(Context)); + + FunctionType *FuncTy = FunctionType::get(Type::getVoidTy(Context), ArgsTy, 0); + // Pick a unique name to describe the input parameters + std::stringstream ss; + ss<<"autogen_SD"<<SeedCL; + Function *Func = Function::Create(FuncTy, GlobalValue::ExternalLinkage, + ss.str(), M); + + Func->setCallingConv(CallingConv::C); + return Func; +} + +/// A base class, implementing utilities needed for +/// modifying and adding new random instructions. +struct Modifier { + /// Used to store the randomly generated values. + typedef std::vector<Value*> PieceTable; + +public: + /// C'tor + Modifier(BasicBlock *Block, PieceTable *PT, Random *R): + BB(Block),PT(PT),Ran(R),Context(BB->getContext()) {} + /// Add a new instruction. + virtual void Act() = 0; + /// Add N new instructions, + virtual void ActN(unsigned n) { + for (unsigned i=0; i<n; ++i) + Act(); + } + +protected: + /// Return a random value from the list of known values. + Value *getRandomVal() { + assert(PT->size()); + return PT->at(Ran->Rand() % PT->size()); + } + + Constant *getRandomConstant(Type *Tp) { + if (Tp->isIntegerTy()) { + if (Ran->Rand() & 1) + return ConstantInt::getAllOnesValue(Tp); + return ConstantInt::getNullValue(Tp); + } else if (Tp->isFloatingPointTy()) { + if (Ran->Rand() & 1) + return ConstantFP::getAllOnesValue(Tp); + return ConstantFP::getNullValue(Tp); + } + return UndefValue::get(Tp); + } + + /// Return a random value with a known type. + Value *getRandomValue(Type *Tp) { + unsigned index = Ran->Rand(); + for (unsigned i=0; i<PT->size(); ++i) { + Value *V = PT->at((index + i) % PT->size()); + if (V->getType() == Tp) + return V; + } + + // If the requested type was not found, generate a constant value. + if (Tp->isIntegerTy()) { + if (Ran->Rand() & 1) + return ConstantInt::getAllOnesValue(Tp); + return ConstantInt::getNullValue(Tp); + } else if (Tp->isFloatingPointTy()) { + if (Ran->Rand() & 1) + return ConstantFP::getAllOnesValue(Tp); + return ConstantFP::getNullValue(Tp); + } else if (Tp->isVectorTy()) { + VectorType *VTp = cast<VectorType>(Tp); + + std::vector<Constant*> TempValues; + TempValues.reserve(VTp->getNumElements()); + for (unsigned i = 0; i < VTp->getNumElements(); ++i) + TempValues.push_back(getRandomConstant(VTp->getScalarType())); + + ArrayRef<Constant*> VectorValue(TempValues); + return ConstantVector::get(VectorValue); + } + + return UndefValue::get(Tp); + } + + /// Return a random value of any pointer type. + Value *getRandomPointerValue() { + unsigned index = Ran->Rand(); + for (unsigned i=0; i<PT->size(); ++i) { + Value *V = PT->at((index + i) % PT->size()); + if (V->getType()->isPointerTy()) + return V; + } + return UndefValue::get(pickPointerType()); + } + + /// Return a random value of any vector type. + Value *getRandomVectorValue() { + unsigned index = Ran->Rand(); + for (unsigned i=0; i<PT->size(); ++i) { + Value *V = PT->at((index + i) % PT->size()); + if (V->getType()->isVectorTy()) + return V; + } + return UndefValue::get(pickVectorType()); + } + + /// Pick a random type. + Type *pickType() { + return (Ran->Rand() & 1 ? pickVectorType() : pickScalarType()); + } + + /// Pick a random pointer type. + Type *pickPointerType() { + Type *Ty = pickType(); + return PointerType::get(Ty, 0); + } + + /// Pick a random vector type. + Type *pickVectorType(unsigned len = (unsigned)-1) { + Type *Ty = pickScalarType(); + // Pick a random vector width in the range 2**0 to 2**4. + // by adding two randoms we are generating a normal-like distribution + // around 2**3. + unsigned width = 1<<((Ran->Rand() % 3) + (Ran->Rand() % 3)); + if (len != (unsigned)-1) + width = len; + return VectorType::get(Ty, width); + } + + /// Pick a random scalar type. + Type *pickScalarType() { + Type *t = 0; + do { + switch (Ran->Rand() % 30) { + case 0: t = Type::getInt1Ty(Context); break; + case 1: t = Type::getInt8Ty(Context); break; + case 2: t = Type::getInt16Ty(Context); break; + case 3: case 4: + case 5: t = Type::getFloatTy(Context); break; + case 6: case 7: + case 8: t = Type::getDoubleTy(Context); break; + case 9: case 10: + case 11: t = Type::getInt32Ty(Context); break; + case 12: case 13: + case 14: t = Type::getInt64Ty(Context); break; + case 15: case 16: + case 17: if (GenHalfFloat) t = Type::getHalfTy(Context); break; + case 18: case 19: + case 20: if (GenX86FP80) t = Type::getX86_FP80Ty(Context); break; + case 21: case 22: + case 23: if (GenFP128) t = Type::getFP128Ty(Context); break; + case 24: case 25: + case 26: if (GenPPCFP128) t = Type::getPPC_FP128Ty(Context); break; + case 27: case 28: + case 29: if (GenX86MMX) t = Type::getX86_MMXTy(Context); break; + default: llvm_unreachable("Invalid scalar value"); + } + } while (t == 0); + + return t; + } + + /// Basic block to populate + BasicBlock *BB; + /// Value table + PieceTable *PT; + /// Random number generator + Random *Ran; + /// Context + LLVMContext &Context; +}; + +struct LoadModifier: public Modifier { + LoadModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual void Act() { + // Try to use predefined pointers. If non exist, use undef pointer value; + Value *Ptr = getRandomPointerValue(); + Value *V = new LoadInst(Ptr, "L", BB->getTerminator()); + PT->push_back(V); + } +}; + +struct StoreModifier: public Modifier { + StoreModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual void Act() { + // Try to use predefined pointers. If non exist, use undef pointer value; + Value *Ptr = getRandomPointerValue(); + Type *Tp = Ptr->getType(); + Value *Val = getRandomValue(Tp->getContainedType(0)); + Type *ValTy = Val->getType(); + + // Do not store vectors of i1s because they are unsupported + // by the codegen. + if (ValTy->isVectorTy() && ValTy->getScalarSizeInBits() == 1) + return; + + new StoreInst(Val, Ptr, BB->getTerminator()); + } +}; + +struct BinModifier: public Modifier { + BinModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + + virtual void Act() { + Value *Val0 = getRandomVal(); + Value *Val1 = getRandomValue(Val0->getType()); + + // Don't handle pointer types. + if (Val0->getType()->isPointerTy() || + Val1->getType()->isPointerTy()) + return; + + // Don't handle i1 types. + if (Val0->getType()->getScalarSizeInBits() == 1) + return; + + + bool isFloat = Val0->getType()->getScalarType()->isFloatingPointTy(); + Instruction* Term = BB->getTerminator(); + unsigned R = Ran->Rand() % (isFloat ? 7 : 13); + Instruction::BinaryOps Op; + + switch (R) { + default: llvm_unreachable("Invalid BinOp"); + case 0:{Op = (isFloat?Instruction::FAdd : Instruction::Add); break; } + case 1:{Op = (isFloat?Instruction::FSub : Instruction::Sub); break; } + case 2:{Op = (isFloat?Instruction::FMul : Instruction::Mul); break; } + case 3:{Op = (isFloat?Instruction::FDiv : Instruction::SDiv); break; } + case 4:{Op = (isFloat?Instruction::FDiv : Instruction::UDiv); break; } + case 5:{Op = (isFloat?Instruction::FRem : Instruction::SRem); break; } + case 6:{Op = (isFloat?Instruction::FRem : Instruction::URem); break; } + case 7: {Op = Instruction::Shl; break; } + case 8: {Op = Instruction::LShr; break; } + case 9: {Op = Instruction::AShr; break; } + case 10:{Op = Instruction::And; break; } + case 11:{Op = Instruction::Or; break; } + case 12:{Op = Instruction::Xor; break; } + } + + PT->push_back(BinaryOperator::Create(Op, Val0, Val1, "B", Term)); + } +}; + +/// Generate constant values. +struct ConstModifier: public Modifier { + ConstModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual void Act() { + Type *Ty = pickType(); + + if (Ty->isVectorTy()) { + switch (Ran->Rand() % 2) { + case 0: if (Ty->getScalarType()->isIntegerTy()) + return PT->push_back(ConstantVector::getAllOnesValue(Ty)); + case 1: if (Ty->getScalarType()->isIntegerTy()) + return PT->push_back(ConstantVector::getNullValue(Ty)); + } + } + + if (Ty->isFloatingPointTy()) { + if (Ran->Rand() & 1) + return PT->push_back(ConstantFP::getNullValue(Ty)); + return PT->push_back(ConstantFP::get(Ty, + static_cast<double>(1)/Ran->Rand())); + } + + if (Ty->isIntegerTy()) { + switch (Ran->Rand() % 7) { + case 0: if (Ty->isIntegerTy()) + return PT->push_back(ConstantInt::get(Ty, + APInt::getAllOnesValue(Ty->getPrimitiveSizeInBits()))); + case 1: if (Ty->isIntegerTy()) + return PT->push_back(ConstantInt::get(Ty, + APInt::getNullValue(Ty->getPrimitiveSizeInBits()))); + case 2: case 3: case 4: case 5: + case 6: if (Ty->isIntegerTy()) + PT->push_back(ConstantInt::get(Ty, Ran->Rand())); + } + } + + } +}; + +struct AllocaModifier: public Modifier { + AllocaModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R){} + + virtual void Act() { + Type *Tp = pickType(); + PT->push_back(new AllocaInst(Tp, "A", BB->getFirstNonPHI())); + } +}; + +struct ExtractElementModifier: public Modifier { + ExtractElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): + Modifier(BB, PT, R) {} + + virtual void Act() { + Value *Val0 = getRandomVectorValue(); + Value *V = ExtractElementInst::Create(Val0, + ConstantInt::get(Type::getInt32Ty(BB->getContext()), + Ran->Rand() % cast<VectorType>(Val0->getType())->getNumElements()), + "E", BB->getTerminator()); + return PT->push_back(V); + } +}; + +struct ShuffModifier: public Modifier { + ShuffModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual void Act() { + + Value *Val0 = getRandomVectorValue(); + Value *Val1 = getRandomValue(Val0->getType()); + + unsigned Width = cast<VectorType>(Val0->getType())->getNumElements(); + std::vector<Constant*> Idxs; + + Type *I32 = Type::getInt32Ty(BB->getContext()); + for (unsigned i=0; i<Width; ++i) { + Constant *CI = ConstantInt::get(I32, Ran->Rand() % (Width*2)); + // Pick some undef values. + if (!(Ran->Rand() % 5)) + CI = UndefValue::get(I32); + Idxs.push_back(CI); + } + + Constant *Mask = ConstantVector::get(Idxs); + + Value *V = new ShuffleVectorInst(Val0, Val1, Mask, "Shuff", + BB->getTerminator()); + PT->push_back(V); + } +}; + +struct InsertElementModifier: public Modifier { + InsertElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): + Modifier(BB, PT, R) {} + + virtual void Act() { + Value *Val0 = getRandomVectorValue(); + Value *Val1 = getRandomValue(Val0->getType()->getScalarType()); + + Value *V = InsertElementInst::Create(Val0, Val1, + ConstantInt::get(Type::getInt32Ty(BB->getContext()), + Ran->Rand() % cast<VectorType>(Val0->getType())->getNumElements()), + "I", BB->getTerminator()); + return PT->push_back(V); + } + +}; + +struct CastModifier: public Modifier { + CastModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual void Act() { + + Value *V = getRandomVal(); + Type *VTy = V->getType(); + Type *DestTy = pickScalarType(); + + // Handle vector casts vectors. + if (VTy->isVectorTy()) { + VectorType *VecTy = cast<VectorType>(VTy); + DestTy = pickVectorType(VecTy->getNumElements()); + } + + // no need to casr. + if (VTy == DestTy) return; + + // Pointers: + if (VTy->isPointerTy()) { + if (!DestTy->isPointerTy()) + DestTy = PointerType::get(DestTy, 0); + return PT->push_back( + new BitCastInst(V, DestTy, "PC", BB->getTerminator())); + } + + // Generate lots of bitcasts. + if ((Ran->Rand() & 1) && + VTy->getPrimitiveSizeInBits() == DestTy->getPrimitiveSizeInBits()) { + return PT->push_back( + new BitCastInst(V, DestTy, "BC", BB->getTerminator())); + } + + // Both types are integers: + if (VTy->getScalarType()->isIntegerTy() && + DestTy->getScalarType()->isIntegerTy()) { + if (VTy->getScalarType()->getPrimitiveSizeInBits() > + DestTy->getScalarType()->getPrimitiveSizeInBits()) { + return PT->push_back( + new TruncInst(V, DestTy, "Tr", BB->getTerminator())); + } else { + if (Ran->Rand() & 1) + return PT->push_back( + new ZExtInst(V, DestTy, "ZE", BB->getTerminator())); + return PT->push_back(new SExtInst(V, DestTy, "Se", BB->getTerminator())); + } + } + + // Fp to int. + if (VTy->getScalarType()->isFloatingPointTy() && + DestTy->getScalarType()->isIntegerTy()) { + if (Ran->Rand() & 1) + return PT->push_back( + new FPToSIInst(V, DestTy, "FC", BB->getTerminator())); + return PT->push_back(new FPToUIInst(V, DestTy, "FC", BB->getTerminator())); + } + + // Int to fp. + if (VTy->getScalarType()->isIntegerTy() && + DestTy->getScalarType()->isFloatingPointTy()) { + if (Ran->Rand() & 1) + return PT->push_back( + new SIToFPInst(V, DestTy, "FC", BB->getTerminator())); + return PT->push_back(new UIToFPInst(V, DestTy, "FC", BB->getTerminator())); + + } + + // Both floats. + if (VTy->getScalarType()->isFloatingPointTy() && + DestTy->getScalarType()->isFloatingPointTy()) { + if (VTy->getScalarType()->getPrimitiveSizeInBits() > + DestTy->getScalarType()->getPrimitiveSizeInBits()) { + return PT->push_back( + new FPTruncInst(V, DestTy, "Tr", BB->getTerminator())); + } else { + return PT->push_back( + new FPExtInst(V, DestTy, "ZE", BB->getTerminator())); + } + } + } + +}; + +struct SelectModifier: public Modifier { + SelectModifier(BasicBlock *BB, PieceTable *PT, Random *R): + Modifier(BB, PT, R) {} + + virtual void Act() { + // Try a bunch of different select configuration until a valid one is found. + Value *Val0 = getRandomVal(); + Value *Val1 = getRandomValue(Val0->getType()); + + Type *CondTy = Type::getInt1Ty(Context); + + // If the value type is a vector, and we allow vector select, then in 50% + // of the cases generate a vector select. + if (Val0->getType()->isVectorTy() && (Ran->Rand() % 1)) { + unsigned NumElem = cast<VectorType>(Val0->getType())->getNumElements(); + CondTy = VectorType::get(CondTy, NumElem); + } + + Value *Cond = getRandomValue(CondTy); + Value *V = SelectInst::Create(Cond, Val0, Val1, "Sl", BB->getTerminator()); + return PT->push_back(V); + } +}; + + +struct CmpModifier: public Modifier { + CmpModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual void Act() { + + Value *Val0 = getRandomVal(); + Value *Val1 = getRandomValue(Val0->getType()); + + if (Val0->getType()->isPointerTy()) return; + bool fp = Val0->getType()->getScalarType()->isFloatingPointTy(); + + int op; + if (fp) { + op = Ran->Rand() % + (CmpInst::LAST_FCMP_PREDICATE - CmpInst::FIRST_FCMP_PREDICATE) + + CmpInst::FIRST_FCMP_PREDICATE; + } else { + op = Ran->Rand() % + (CmpInst::LAST_ICMP_PREDICATE - CmpInst::FIRST_ICMP_PREDICATE) + + CmpInst::FIRST_ICMP_PREDICATE; + } + + Value *V = CmpInst::Create(fp ? Instruction::FCmp : Instruction::ICmp, + op, Val0, Val1, "Cmp", BB->getTerminator()); + return PT->push_back(V); + } +}; + +void FillFunction(Function *F) { + // 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(); + it != e; ++it) + PT.push_back(it); + + // List of modifiers which add new random instructions. + std::vector<Modifier*> Modifiers; + std::auto_ptr<Modifier> LM(new LoadModifier(BB, &PT, &R)); + std::auto_ptr<Modifier> SM(new StoreModifier(BB, &PT, &R)); + std::auto_ptr<Modifier> EE(new ExtractElementModifier(BB, &PT, &R)); + std::auto_ptr<Modifier> SHM(new ShuffModifier(BB, &PT, &R)); + std::auto_ptr<Modifier> IE(new InsertElementModifier(BB, &PT, &R)); + std::auto_ptr<Modifier> BM(new BinModifier(BB, &PT, &R)); + std::auto_ptr<Modifier> CM(new CastModifier(BB, &PT, &R)); + std::auto_ptr<Modifier> SLM(new SelectModifier(BB, &PT, &R)); + std::auto_ptr<Modifier> PM(new CmpModifier(BB, &PT, &R)); + Modifiers.push_back(LM.get()); + Modifiers.push_back(SM.get()); + Modifiers.push_back(EE.get()); + Modifiers.push_back(SHM.get()); + Modifiers.push_back(IE.get()); + Modifiers.push_back(BM.get()); + Modifiers.push_back(CM.get()); + Modifiers.push_back(SLM.get()); + Modifiers.push_back(PM.get()); + + // Generate the random instructions + AllocaModifier AM(BB, &PT, &R); AM.ActN(5); // Throw in a few allocas + ConstModifier COM(BB, &PT, &R); COM.ActN(40); // Throw in a few constants + + for (unsigned i=0; i< SizeCL / Modifiers.size(); ++i) + for (std::vector<Modifier*>::iterator it = Modifiers.begin(), + e = Modifiers.end(); it != e; ++it) { + (*it)->Act(); + } + + SM->ActN(5); // Throw in a few stores. +} + +void IntroduceControlFlow(Function *F) { + std::set<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); + } + + for (std::set<Instruction*>::iterator it = BoolInst.begin(), + e = BoolInst.end(); it != e; ++it) { + Instruction *Instr = *it; + BasicBlock *Curr = Instr->getParent(); + BasicBlock::iterator Loc= Instr; + BasicBlock *Next = Curr->splitBasicBlock(Loc, "CF"); + Instr->moveBefore(Curr->getTerminator()); + if (Curr != &F->getEntryBlock()) { + BranchInst::Create(Curr, Next, Instr, Curr->getTerminator()); + Curr->getTerminator()->eraseFromParent(); + } + } +} + +int main(int argc, char **argv) { + // Init LLVM, call llvm_shutdown() on exit, parse args, etc. + llvm::PrettyStackTraceProgram X(argc, argv); + cl::ParseCommandLineOptions(argc, argv, "llvm codegen stress-tester\n"); + llvm_shutdown_obj Y; + + std::auto_ptr<Module> M(new Module("/tmp/autogen.bc", getGlobalContext())); + Function *F = GenEmptyFunction(M.get()); + FillFunction(F); + IntroduceControlFlow(F); + + // Figure out what stream we are supposed to write to... + OwningPtr<tool_output_file> Out; + // Default to standard output. + if (OutputFilename.empty()) + OutputFilename = "-"; + + std::string ErrorInfo; + Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, + raw_fd_ostream::F_Binary)); + if (!ErrorInfo.empty()) { + errs() << ErrorInfo << '\n'; + return 1; + } + + PassManager Passes; + Passes.add(createVerifierPass()); + Passes.add(createPrintModulePass(&Out->os())); + Passes.run(*M.get()); + Out->keep(); + + return 0; +} diff --git a/tools/lto/CMakeLists.txt b/tools/lto/CMakeLists.txt index 7e2c5f0..9112976 100644 --- a/tools/lto/CMakeLists.txt +++ b/tools/lto/CMakeLists.txt @@ -1,6 +1,6 @@ set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} - ipo scalaropts linker bitreader bitwriter mcdisassembler) + ipo scalaropts linker bitreader bitwriter mcdisassembler vectorize) add_definitions( -DLLVM_VERSION_INFO=\"${PACKAGE_VERSION}\" ) diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index 77d7dfe..111f8c8 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -34,6 +34,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SystemUtils.h" @@ -111,8 +112,7 @@ bool LTOCodeGenerator::setDebugInfo(lto_debug_model debug, std::string& errMsg) _emitDwarfDebugInfo = true; return false; } - errMsg = "unknown debug format"; - return true; + llvm_unreachable("Unknown debug format!"); } @@ -126,8 +126,7 @@ bool LTOCodeGenerator::setCodePICModel(lto_codegen_model model, _codeModel = model; return false; } - errMsg = "unknown pic model"; - return true; + llvm_unreachable("Unknown PIC model!"); } void LTOCodeGenerator::setCpu(const char* mCpu) diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp index 0b73729..8ce8cd2 100644 --- a/tools/lto/LTOModule.cpp +++ b/tools/lto/LTOModule.cpp @@ -190,9 +190,9 @@ bool LTOModule::objcClassNameFromExpression(Constant *c, std::string &name) { Constant *op = ce->getOperand(0); if (GlobalVariable *gvn = dyn_cast<GlobalVariable>(op)) { Constant *cn = gvn->getInitializer(); - if (ConstantArray *ca = dyn_cast<ConstantArray>(cn)) { + if (ConstantDataArray *ca = dyn_cast<ConstantDataArray>(cn)) { if (ca->isCString()) { - name = ".objc_class_name_" + ca->getAsCString(); + name = ".objc_class_name_" + ca->getAsCString().str(); return true; } } @@ -589,8 +589,8 @@ namespace { unsigned MaxBytesToEmit) {} virtual void EmitCodeAlignment(unsigned ByteAlignment, unsigned MaxBytesToEmit) {} - virtual void EmitValueToOffset(const MCExpr *Offset, - unsigned char Value ) {} + virtual bool EmitValueToOffset(const MCExpr *Offset, + unsigned char Value ) { return false; } virtual void EmitFileDirective(StringRef Filename) {} virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, @@ -603,7 +603,7 @@ namespace { if (Inst.getOperand(i).isExpr()) AddValueSymbols(Inst.getOperand(i).getExpr()); } - virtual void Finish() {} + virtual void FinishImpl() {} }; } diff --git a/tools/lto/Makefile b/tools/lto/Makefile index ef78f82..153fa03 100644 --- a/tools/lto/Makefile +++ b/tools/lto/Makefile @@ -10,7 +10,7 @@ LEVEL := ../.. LIBRARYNAME := LTO LINK_COMPONENTS := all-targets ipo scalaropts linker bitreader bitwriter \ - mcdisassembler + mcdisassembler vectorize LINK_LIBS_IN_SHARED := 1 SHARED_LIBRARY := 1 diff --git a/tools/opt/CMakeLists.txt b/tools/opt/CMakeLists.txt index 0570d0e..7daf22a 100644 --- a/tools/opt/CMakeLists.txt +++ b/tools/opt/CMakeLists.txt @@ -1,4 +1,4 @@ -set(LLVM_LINK_COMPONENTS bitreader asmparser bitwriter instrumentation scalaropts ipo) +set(LLVM_LINK_COMPONENTS bitreader asmparser bitwriter instrumentation scalaropts ipo vectorize) add_llvm_tool(opt AnalysisWrappers.cpp diff --git a/tools/opt/Makefile b/tools/opt/Makefile index e8cd7e2..16d116d 100644 --- a/tools/opt/Makefile +++ b/tools/opt/Makefile @@ -9,6 +9,6 @@ LEVEL := ../.. TOOLNAME := opt -LINK_COMPONENTS := bitreader bitwriter asmparser instrumentation scalaropts ipo +LINK_COMPONENTS := bitreader bitwriter asmparser instrumentation scalaropts ipo vectorize include $(LEVEL)/Makefile.common diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 5161364..30da863 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -480,6 +480,7 @@ int main(int argc, char **argv) { PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); initializeScalarOpts(Registry); + initializeVectorization(Registry); initializeIPO(Registry); initializeAnalysis(Registry); initializeIPA(Registry); |