summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/CMakeLists.txt20
-rw-r--r--tools/LLVMBuild.txt24
-rw-r--r--tools/Makefile24
-rw-r--r--tools/bugpoint-passes/Makefile8
-rw-r--r--tools/bugpoint/BugDriver.cpp4
-rw-r--r--tools/bugpoint/CMakeLists.txt2
-rw-r--r--tools/bugpoint/CrashDebugger.cpp11
-rw-r--r--tools/bugpoint/ExecutionDriver.cpp50
-rw-r--r--tools/bugpoint/ExtractFunction.cpp62
-rw-r--r--tools/bugpoint/LLVMBuild.txt22
-rw-r--r--tools/bugpoint/Makefile9
-rw-r--r--tools/bugpoint/Miscompilation.cpp3
-rw-r--r--tools/bugpoint/OptimizerDriver.cpp12
-rw-r--r--tools/bugpoint/ToolRunner.cpp93
-rw-r--r--tools/bugpoint/ToolRunner.h1
-rw-r--r--tools/bugpoint/bugpoint.cpp1
-rw-r--r--tools/edis/CMakeLists.txt21
-rw-r--r--tools/edis/EDMain.cpp284
-rw-r--r--tools/edis/Makefile53
-rw-r--r--tools/gold/CMakeLists.txt3
-rw-r--r--tools/gold/Makefile18
-rw-r--r--tools/gold/gold-plugin.cpp2
-rw-r--r--tools/llc/LLVMBuild.txt22
-rw-r--r--tools/llc/Makefile14
-rw-r--r--tools/llc/llc.cpp206
-rw-r--r--tools/lli/CMakeLists.txt17
-rw-r--r--tools/lli/LLVMBuild.txt22
-rw-r--r--tools/lli/Makefile20
-rw-r--r--tools/lli/lli.cpp38
-rw-r--r--tools/llvm-ar/LLVMBuild.txt22
-rw-r--r--tools/llvm-ar/Makefile15
-rw-r--r--tools/llvm-as/LLVMBuild.txt22
-rw-r--r--tools/llvm-as/Makefile6
-rw-r--r--tools/llvm-as/llvm-as.cpp2
-rw-r--r--tools/llvm-bcanalyzer/LLVMBuild.txt22
-rw-r--r--tools/llvm-bcanalyzer/Makefile6
-rw-r--r--tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp123
-rw-r--r--tools/llvm-config/BuildVariables.inc.in27
-rw-r--r--tools/llvm-config/CMakeLists.txt154
-rw-r--r--tools/llvm-config/Makefile134
-rwxr-xr-xtools/llvm-config/find-cycles.pl170
-rw-r--r--tools/llvm-config/llvm-config.cpp342
-rw-r--r--tools/llvm-config/llvm-config.in.in463
-rw-r--r--tools/llvm-cov/LLVMBuild.txt22
-rw-r--r--tools/llvm-cov/Makefile7
-rw-r--r--tools/llvm-diff/DiffConsumer.cpp6
-rw-r--r--tools/llvm-diff/DiffConsumer.h1
-rw-r--r--tools/llvm-diff/DifferenceEngine.cpp18
-rw-r--r--tools/llvm-diff/DifferenceEngine.h4
-rw-r--r--tools/llvm-diff/LLVMBuild.txt22
-rw-r--r--tools/llvm-diff/Makefile6
-rw-r--r--tools/llvm-diff/llvm-diff.cpp2
-rw-r--r--tools/llvm-dis/LLVMBuild.txt22
-rw-r--r--tools/llvm-dis/Makefile6
-rw-r--r--tools/llvm-dis/llvm-dis.cpp19
-rw-r--r--tools/llvm-dwarfdump/LLVMBuild.txt22
-rw-r--r--tools/llvm-dwarfdump/Makefile8
-rw-r--r--tools/llvm-extract/LLVMBuild.txt22
-rw-r--r--tools/llvm-extract/Makefile7
-rw-r--r--tools/llvm-extract/llvm-extract.cpp12
-rw-r--r--tools/llvm-ld/CMakeLists.txt2
-rw-r--r--tools/llvm-ld/LLVMBuild.txt22
-rw-r--r--tools/llvm-ld/Makefile7
-rw-r--r--tools/llvm-ld/llvm-ld.cpp4
-rw-r--r--tools/llvm-link/LLVMBuild.txt22
-rw-r--r--tools/llvm-link/Makefile8
-rw-r--r--tools/llvm-link/llvm-link.cpp2
-rw-r--r--tools/llvm-mc/Disassembler.cpp36
-rw-r--r--tools/llvm-mc/LLVMBuild.txt22
-rw-r--r--tools/llvm-mc/Makefile17
-rw-r--r--tools/llvm-mc/llvm-mc.cpp49
-rw-r--r--tools/llvm-nm/LLVMBuild.txt22
-rw-r--r--tools/llvm-nm/Makefile8
-rw-r--r--tools/llvm-nm/llvm-nm.cpp102
-rw-r--r--tools/llvm-objdump/LLVMBuild.txt22
-rw-r--r--tools/llvm-objdump/MachODump.cpp404
-rw-r--r--tools/llvm-objdump/Makefile9
-rw-r--r--tools/llvm-objdump/llvm-objdump.cpp228
-rw-r--r--tools/llvm-objdump/llvm-objdump.h2
-rw-r--r--tools/llvm-prof/LLVMBuild.txt22
-rw-r--r--tools/llvm-prof/Makefile6
-rw-r--r--tools/llvm-prof/llvm-prof.cpp18
-rw-r--r--tools/llvm-ranlib/LLVMBuild.txt22
-rw-r--r--tools/llvm-ranlib/Makefile8
-rw-r--r--tools/llvm-readobj/CMakeLists.txt5
-rw-r--r--tools/llvm-readobj/LLVMBuild.txt22
-rw-r--r--tools/llvm-readobj/Makefile18
-rw-r--r--tools/llvm-readobj/llvm-readobj.cpp218
-rw-r--r--tools/llvm-rtdyld/LLVMBuild.txt22
-rw-r--r--tools/llvm-rtdyld/Makefile16
-rw-r--r--tools/llvm-rtdyld/llvm-rtdyld.cpp31
-rw-r--r--tools/llvm-shlib/Makefile14
-rw-r--r--tools/llvm-size/LLVMBuild.txt22
-rw-r--r--tools/llvm-size/Makefile6
-rw-r--r--tools/llvm-size/llvm-size.cpp10
-rw-r--r--tools/llvm-stress/CMakeLists.txt5
-rw-r--r--tools/llvm-stress/LLVMBuild.txt22
-rw-r--r--tools/llvm-stress/Makefile18
-rw-r--r--tools/llvm-stress/llvm-stress.cpp702
-rw-r--r--tools/llvm-stub/LLVMBuild.txt22
-rw-r--r--tools/llvm-stub/Makefile6
-rw-r--r--tools/lto/CMakeLists.txt2
-rw-r--r--tools/lto/LTOCodeGenerator.cpp340
-rw-r--r--tools/lto/LTOCodeGenerator.h105
-rw-r--r--tools/lto/LTOModule.cpp437
-rw-r--r--tools/lto/LTOModule.h250
-rw-r--r--tools/lto/Makefile19
-rw-r--r--tools/lto/lto.cpp348
-rw-r--r--tools/lto/lto.exports1
-rw-r--r--tools/macho-dump/LLVMBuild.txt22
-rw-r--r--tools/macho-dump/Makefile16
-rw-r--r--tools/opt/CMakeLists.txt2
-rw-r--r--tools/opt/LLVMBuild.txt22
-rw-r--r--tools/opt/Makefile6
-rw-r--r--tools/opt/PrintSCC.cpp4
-rw-r--r--tools/opt/opt.cpp9
116 files changed, 3843 insertions, 2743 deletions
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index e66648b..9668c76 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -11,11 +11,8 @@ if( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/polly/CMakeLists.txt )
endif( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/polly/CMakeLists.txt )
if( NOT WIN32 OR MSYS OR CYGWIN )
- # It is useful to build llvm-config before the other tools, so we
- # have a fresh LibDeps.txt for regenerating the hard-coded library
- # dependencies. llvm-config/CMakeLists.txt takes care of this but we
- # must keep llvm-config as the first entry on the list of tools to
- # be built.
+ # We currently require 'sed' to build llvm-config, so don't try to build it
+ # on pure Win32.
add_subdirectory(llvm-config)
endif()
@@ -31,6 +28,7 @@ add_subdirectory(llvm-nm)
add_subdirectory(llvm-size)
add_subdirectory(llvm-ld)
+add_subdirectory(llvm-cov)
add_subdirectory(llvm-prof)
add_subdirectory(llvm-link)
add_subdirectory(lli)
@@ -39,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)
@@ -46,7 +45,7 @@ add_subdirectory(bugpoint)
add_subdirectory(bugpoint-passes)
add_subdirectory(llvm-bcanalyzer)
add_subdirectory(llvm-stub)
-add_subdirectory(edis)
+add_subdirectory(llvm-stress)
if( NOT WIN32 )
add_subdirectory(lto)
@@ -59,11 +58,14 @@ if( LLVM_ENABLE_PIC )
endif()
endif()
-if( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/clang/CMakeLists.txt )
+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( ${CMAKE_CURRENT_SOURCE_DIR}/clang )
+ add_subdirectory(${LLVM_CLANG_SOURCE_DIR} clang)
endif()
-endif( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/clang/CMakeLists.txt )
+endif ()
set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} PARENT_SCOPE)
diff --git a/tools/LLVMBuild.txt b/tools/LLVMBuild.txt
new file mode 100644
index 0000000..aba990f
--- /dev/null
+++ b/tools/LLVMBuild.txt
@@ -0,0 +1,24 @@
+;===- ./tools/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
+;
+;===------------------------------------------------------------------------===;
+
+[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
+
+[component_0]
+type = Group
+name = Tools
+parent = $ROOT
diff --git a/tools/Makefile b/tools/Makefile
index 68ce314..8bf091a 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -9,8 +9,15 @@
LEVEL := ..
+include $(LEVEL)/Makefile.config
+
# Build clang if present.
-OPTIONAL_PARALLEL_DIRS := clang
+
+ifneq ($(CLANG_SRC_ROOT),)
+ OPTIONAL_PARALLEL_DIRS := $(CLANG_SRC_ROOT)
+else
+ OPTIONAL_PARALLEL_DIRS := clang
+endif
# Build LLDB if present. Note LLDB must be built last as it depends on the
# wider LLVM infrastructure (including Clang).
@@ -25,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
@@ -36,9 +43,6 @@ ifdef ONLY_TOOLS
PARALLEL_DIRS := $(filter-out lldb,$(ONLY_TOOLS))
endif
-include $(LEVEL)/Makefile.config
-
-
# These libraries build as dynamic libraries (.dylib /.so), they can only be
# built if ENABLE_PIC is set.
ifndef ONLY_TOOLS
@@ -52,14 +56,6 @@ ifeq ($(ENABLE_PIC),1)
endif
PARALLEL_DIRS += bugpoint-passes
-
- # The edis library is only supported if ARM and/or X86 are enabled, and if
- # LLVM is being built PIC on platforms that support dylibs.
- ifneq ($(DISABLE_EDIS),1)
- ifneq ($(filter $(TARGETS_TO_BUILD), X86 ARM),)
- PARALLEL_DIRS += edis
- endif
- endif
endif
ifdef LLVM_HAS_POLLY
diff --git a/tools/bugpoint-passes/Makefile b/tools/bugpoint-passes/Makefile
index b4ad3e4..61f96bc 100644
--- a/tools/bugpoint-passes/Makefile
+++ b/tools/bugpoint-passes/Makefile
@@ -7,10 +7,10 @@
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-LIBRARYNAME = BugpointPasses
-LOADABLE_MODULE = 1
-USEDLIBS =
+LEVEL := ../..
+LIBRARYNAME := BugpointPasses
+LOADABLE_MODULE := 1
+USEDLIBS :=
# If we don't need RTTI or EH, there's no reason to export anything
# from this plugin.
diff --git a/tools/bugpoint/BugDriver.cpp b/tools/bugpoint/BugDriver.cpp
index 677d178..6b219bf 100644
--- a/tools/bugpoint/BugDriver.cpp
+++ b/tools/bugpoint/BugDriver.cpp
@@ -87,7 +87,7 @@ Module *llvm::ParseInputFile(const std::string &Filename,
SMDiagnostic Err;
Module *Result = ParseIRFile(Filename, Err, Ctxt);
if (!Result)
- Err.Print("bugpoint", errs());
+ Err.print("bugpoint", errs());
// If we don't have an override triple, use the first one to configure
// bugpoint, or use the host triple if none provided.
@@ -96,7 +96,7 @@ Module *llvm::ParseInputFile(const std::string &Filename,
Triple TheTriple(Result->getTargetTriple());
if (TheTriple.getTriple().empty())
- TheTriple.setTriple(sys::getHostTriple());
+ TheTriple.setTriple(sys::getDefaultTargetTriple());
TargetTriple.setTriple(TheTriple.getTriple());
}
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 f19ef62..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.
@@ -401,7 +401,8 @@ bool ReduceCrashingInstructions::TestInsts(std::vector<const Instruction*>
for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE; ++FI)
for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E;) {
Instruction *Inst = I++;
- if (!Instructions.count(Inst) && !isa<TerminatorInst>(Inst)) {
+ if (!Instructions.count(Inst) && !isa<TerminatorInst>(Inst) &&
+ !isa<LandingPadInst>(Inst)) {
if (!Inst->getType()->isVoidTy())
Inst->replaceAllUsesWith(UndefValue::get(Inst->getType()));
Inst->eraseFromParent();
@@ -568,12 +569,15 @@ 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 {
if (BugpointIsInterrupted) goto ExitLoops;
+ if (isa<LandingPadInst>(I))
+ continue;
+
outs() << "Checking instruction: " << *I;
Module *M = BD.deleteInstructionFromProgram(I, Simplification);
@@ -590,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..218a559 100644
--- a/tools/bugpoint/ExecutionDriver.cpp
+++ b/tools/bugpoint/ExecutionDriver.cpp
@@ -28,8 +28,7 @@ namespace {
// for miscompilation.
//
enum OutputType {
- AutoPick, RunLLI, RunJIT, RunLLC, RunLLCIA, RunCBE, CBE_bug, LLC_Safe,
- CompileCustom, Custom
+ AutoPick, RunLLI, RunJIT, RunLLC, RunLLCIA, LLC_Safe, CompileCustom, Custom
};
cl::opt<double>
@@ -48,8 +47,6 @@ namespace {
clEnumValN(RunLLC, "run-llc", "Compile with LLC"),
clEnumValN(RunLLCIA, "run-llc-ia",
"Compile with LLC with integrated assembler"),
- clEnumValN(RunCBE, "run-cbe", "Compile with CBE"),
- clEnumValN(CBE_bug,"cbe-bug", "Find CBE bugs"),
clEnumValN(LLC_Safe, "llc-safe", "Use LLC for all"),
clEnumValN(CompileCustom, "compile-custom",
"Use -compile-command to define a command to "
@@ -64,7 +61,6 @@ namespace {
SafeInterpreterSel(cl::desc("Specify \"safe\" i.e. known-good backend:"),
cl::values(clEnumValN(AutoPick, "safe-auto", "Use best guess"),
clEnumValN(RunLLC, "safe-run-llc", "Compile with LLC"),
- clEnumValN(RunCBE, "safe-run-cbe", "Compile with CBE"),
clEnumValN(Custom, "safe-run-custom",
"Use -exec-command to define a command to execute "
"the bitcode. Useful for cross-compilation."),
@@ -154,10 +150,6 @@ bool BugDriver::initializeExecutionEnvironment() {
switch (InterpreterSel) {
case AutoPick:
- InterpreterSel = RunCBE;
- Interpreter =
- AbstractInterpreter::createCBE(getToolName(), Message, GCCBinary,
- &ToolArgv, &GCCToolArgv);
if (!Interpreter) {
InterpreterSel = RunJIT;
Interpreter = AbstractInterpreter::createJIT(getToolName(), Message,
@@ -195,12 +187,6 @@ bool BugDriver::initializeExecutionEnvironment() {
Interpreter = AbstractInterpreter::createJIT(getToolName(), Message,
&ToolArgv);
break;
- case RunCBE:
- case CBE_bug:
- Interpreter = AbstractInterpreter::createCBE(getToolName(), Message,
- GCCBinary, &ToolArgv,
- &GCCToolArgv);
- break;
case CompileCustom:
Interpreter =
AbstractInterpreter::createCustomCompiler(Message, CustomCompileCommand);
@@ -209,9 +195,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;
@@ -224,17 +207,6 @@ bool BugDriver::initializeExecutionEnvironment() {
std::vector<std::string> SafeToolArgs = SafeToolArgv;
switch (SafeInterpreterSel) {
case AutoPick:
- // In "cbe-bug" mode, default to using LLC as the "safe" backend.
- if (!SafeInterpreter &&
- InterpreterSel == CBE_bug) {
- SafeInterpreterSel = RunLLC;
- SafeToolArgs.push_back("--relocation-model=pic");
- SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
- GCCBinary,
- &SafeToolArgs,
- &GCCToolArgv);
- }
-
// In "llc-safe" mode, default to using LLC as the "safe" backend.
if (!SafeInterpreter &&
InterpreterSel == LLC_Safe) {
@@ -246,17 +218,6 @@ bool BugDriver::initializeExecutionEnvironment() {
&GCCToolArgv);
}
- // Pick a backend that's different from the test backend. The JIT and
- // LLC backends share a lot of code, so prefer to use the CBE as the
- // safe back-end when testing them.
- if (!SafeInterpreter &&
- InterpreterSel != RunCBE) {
- SafeInterpreterSel = RunCBE;
- SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message,
- GCCBinary,
- &SafeToolArgs,
- &GCCToolArgv);
- }
if (!SafeInterpreter &&
InterpreterSel != RunLLC &&
InterpreterSel != RunJIT) {
@@ -280,11 +241,6 @@ bool BugDriver::initializeExecutionEnvironment() {
&GCCToolArgv,
SafeInterpreterSel == RunLLCIA);
break;
- case RunCBE:
- SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message,
- GCCBinary, &SafeToolArgs,
- &GCCToolArgv);
- break;
case Custom:
SafeInterpreter =
AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand);
@@ -462,8 +418,8 @@ bool BugDriver::createReferenceFile(Module *M, const std::string &Filename) {
errs() << Error;
if (Interpreter != SafeInterpreter) {
errs() << "*** There is a bug running the \"safe\" backend. Either"
- << " debug it (for example with the -run-cbe bugpoint option,"
- << " if CBE is being used as the \"safe\" backend), or fix the"
+ << " debug it (for example with the -run-jit bugpoint option,"
+ << " if JIT is being used as the \"safe\" backend), or fix the"
<< " error some other way.\n";
}
return false;
diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp
index 73b65ca..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);
@@ -340,7 +388,7 @@ Module *BugDriver::ExtractMappedBlocksFromModule(const
// If the BB doesn't have a name, give it one so we have something to key
// off of.
if (!BB->hasName()) BB->setName("tmpbb");
- BlocksToNotExtractFile.os() << BB->getParent()->getNameStr() << " "
+ BlocksToNotExtractFile.os() << BB->getParent()->getName() << " "
<< BB->getName() << "\n";
}
BlocksToNotExtractFile.os().close();
diff --git a/tools/bugpoint/LLVMBuild.txt b/tools/bugpoint/LLVMBuild.txt
new file mode 100644
index 0000000..549d9d0
--- /dev/null
+++ b/tools/bugpoint/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/bugpoint/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 = bugpoint
+parent = Tools
+required_libraries = AsmParser BitReader BitWriter IPO Instrumentation Linker Scalar
diff --git a/tools/bugpoint/Makefile b/tools/bugpoint/Makefile
index 5d287ef..34f4bdd 100644
--- a/tools/bugpoint/Makefile
+++ b/tools/bugpoint/Makefile
@@ -6,11 +6,10 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = bugpoint
-
-LINK_COMPONENTS := asmparser instrumentation scalaropts ipo \
- linker bitreader bitwriter
+LEVEL := ../..
+TOOLNAME := bugpoint
+LINK_COMPONENTS := asmparser instrumentation scalaropts ipo linker bitreader \
+ 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/OptimizerDriver.cpp b/tools/bugpoint/OptimizerDriver.cpp
index 336c83d..fb090ee 100644
--- a/tools/bugpoint/OptimizerDriver.cpp
+++ b/tools/bugpoint/OptimizerDriver.cpp
@@ -85,8 +85,11 @@ void BugDriver::EmitProgressBitcode(const Module *M,
if (NoFlyer || PassesToRun.empty()) return;
outs() << "\n*** You can reproduce the problem with: ";
if (UseValgrind) outs() << "valgrind ";
- outs() << "opt " << Filename << " ";
- outs() << getPassesString(PassesToRun) << "\n";
+ outs() << "opt " << Filename;
+ for (unsigned i = 0, e = PluginLoader::getNumPlugins(); i != e; ++i) {
+ outs() << " -load " << PluginLoader::getPlugin(i);
+ }
+ outs() << " " << getPassesString(PassesToRun) << "\n";
}
cl::opt<bool> SilencePasses("silence-passes",
@@ -145,10 +148,9 @@ bool BugDriver::runPasses(Module *Program,
return 1;
}
- sys::Path tool = PrependMainExecutablePath("opt", getToolName(),
- (void*)"opt");
+ sys::Path tool = sys::Program::FindProgramByName("opt");
if (tool.empty()) {
- errs() << "Cannot find `opt' in executable directory!\n";
+ errs() << "Cannot find `opt' in PATH!\n";
return 1;
}
diff --git a/tools/bugpoint/ToolRunner.cpp b/tools/bugpoint/ToolRunner.cpp
index 0d98262..25a2bae 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,
@@ -621,94 +623,6 @@ AbstractInterpreter *AbstractInterpreter::createJIT(const char *Argv0,
return 0;
}
-GCC::FileType CBE::OutputCode(const std::string &Bitcode,
- sys::Path &OutputCFile, std::string &Error,
- unsigned Timeout, unsigned MemoryLimit) {
- sys::Path uniqueFile(Bitcode+".cbe.c");
- std::string ErrMsg;
- if (uniqueFile.makeUnique(true, &ErrMsg)) {
- errs() << "Error making unique filename: " << ErrMsg << "\n";
- exit(1);
- }
- OutputCFile = uniqueFile;
- std::vector<const char *> LLCArgs;
- LLCArgs.push_back(LLCPath.c_str());
-
- // Add any extra LLC args.
- for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
- LLCArgs.push_back(ToolArgs[i].c_str());
-
- LLCArgs.push_back("-o");
- LLCArgs.push_back(OutputCFile.c_str()); // Output to the C file
- LLCArgs.push_back("-march=c"); // Output C language
- LLCArgs.push_back(Bitcode.c_str()); // This is the input bitcode
- LLCArgs.push_back(0);
-
- outs() << "<cbe>"; outs().flush();
- DEBUG(errs() << "\nAbout to run:\t";
- for (unsigned i = 0, e = LLCArgs.size()-1; i != e; ++i)
- errs() << " " << LLCArgs[i];
- errs() << "\n";
- );
- if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], sys::Path(), sys::Path(),
- sys::Path(), Timeout, MemoryLimit))
- Error = ProcessFailure(LLCPath, &LLCArgs[0], Timeout, MemoryLimit);
- return GCC::CFile;
-}
-
-void CBE::compileProgram(const std::string &Bitcode, std::string *Error,
- unsigned Timeout, unsigned MemoryLimit) {
- sys::Path OutputCFile;
- OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit);
- OutputCFile.eraseFromDisk();
-}
-
-int CBE::ExecuteProgram(const std::string &Bitcode,
- const std::vector<std::string> &Args,
- const std::string &InputFile,
- const std::string &OutputFile,
- std::string *Error,
- const std::vector<std::string> &ArgsForGCC,
- const std::vector<std::string> &SharedLibs,
- unsigned Timeout,
- unsigned MemoryLimit) {
- sys::Path OutputCFile;
- OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit);
-
- FileRemover CFileRemove(OutputCFile.str(), !SaveTemps);
-
- std::vector<std::string> GCCArgs(ArgsForGCC);
- GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end());
-
- return gcc->ExecuteProgram(OutputCFile.str(), Args, GCC::CFile,
- InputFile, OutputFile, Error, GCCArgs,
- Timeout, MemoryLimit);
-}
-
-/// createCBE - Try to find the 'llc' executable
-///
-CBE *AbstractInterpreter::createCBE(const char *Argv0,
- std::string &Message,
- const std::string &GCCBinary,
- const std::vector<std::string> *Args,
- const std::vector<std::string> *GCCArgs) {
- sys::Path LLCPath =
- PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createCBE);
- if (LLCPath.isEmpty()) {
- Message =
- "Cannot find `llc' in executable directory!\n";
- return 0;
- }
-
- Message = "Found llc: " + LLCPath.str() + "\n";
- GCC *gcc = GCC::create(Message, GCCBinary, GCCArgs);
- if (!gcc) {
- errs() << Message << "\n";
- exit(1);
- }
- return new CBE(LLCPath, gcc, Args);
-}
-
//===---------------------------------------------------------------------===//
// GCC abstraction
//
@@ -920,8 +834,7 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
} else
GCCArgs.push_back("-shared"); // `-shared' for Linux/X86, maybe others
- if ((TargetTriple.getArch() == Triple::alpha) ||
- (TargetTriple.getArch() == Triple::x86_64))
+ if (TargetTriple.getArch() == Triple::x86_64)
GCCArgs.push_back("-fPIC"); // Requires shared objs to contain PIC
if (TargetTriple.getArch() == Triple::sparc)
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/edis/CMakeLists.txt b/tools/edis/CMakeLists.txt
deleted file mode 100644
index 1e162f9..0000000
--- a/tools/edis/CMakeLists.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-
-set(SOURCES
- ../../include/llvm-c/EnhancedDisassembly.h
- EDMain.cpp
- )
-
-set(EDIS_DEPENDS LLVMMCDisassembler LLVMMCParser)
-if( LLVM_TARGETS_TO_BUILD MATCHES X86 )
- list(APPEND EDIS_DEPENDS LLVMX86AsmPrinter LLVMX86AsmParser LLVMX86Disassembler LLVMX86Desc)
-endif()
-if( LLVM_TARGETS_TO_BUILD MATCHES ARM )
- list(APPEND EDIS_DEPENDS LLVMARMAsmPrinter LLVMARMAsmParser LLVMARMDisassembler LLVMARMDesc)
-endif()
-
-add_llvm_library(EnhancedDisassembly ${SOURCES})
-set_property(TARGET EnhancedDisassembly PROPERTY
- OUTPUT_NAME "EnhancedDisassembly")
-
-add_llvm_library_dependencies(EnhancedDisassembly
- ${EDIS_DEPENDS})
diff --git a/tools/edis/EDMain.cpp b/tools/edis/EDMain.cpp
deleted file mode 100644
index 16855b3..0000000
--- a/tools/edis/EDMain.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-//===-- EDMain.cpp - LLVM Enhanced Disassembly C API ----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the enhanced disassembler's public C API.
-//
-//===----------------------------------------------------------------------===//
-
-// FIXME: This code isn't layered right, the headers should be moved to
-// include llvm/MC/MCDisassembler or something.
-#include "../../lib/MC/MCDisassembler/EDDisassembler.h"
-#include "../../lib/MC/MCDisassembler/EDInst.h"
-#include "../../lib/MC/MCDisassembler/EDOperand.h"
-#include "../../lib/MC/MCDisassembler/EDToken.h"
-#include "llvm-c/EnhancedDisassembly.h"
-using namespace llvm;
-
-int EDGetDisassembler(EDDisassemblerRef *disassembler,
- const char *triple,
- EDAssemblySyntax_t syntax) {
- EDDisassembler::initialize();
-
- EDDisassembler::AssemblySyntax Syntax;
- switch (syntax) {
- default: assert(0 && "Unknown assembly syntax!");
- case kEDAssemblySyntaxX86Intel:
- Syntax = EDDisassembler::kEDAssemblySyntaxX86Intel;
- break;
- case kEDAssemblySyntaxX86ATT:
- Syntax = EDDisassembler::kEDAssemblySyntaxX86ATT;
- break;
- case kEDAssemblySyntaxARMUAL:
- Syntax = EDDisassembler::kEDAssemblySyntaxARMUAL;
- break;
- }
-
- EDDisassemblerRef ret = EDDisassembler::getDisassembler(triple, Syntax);
-
- if (!ret)
- return -1;
- *disassembler = ret;
- return 0;
-}
-
-int EDGetRegisterName(const char** regName,
- EDDisassemblerRef disassembler,
- unsigned regID) {
- const char *name = ((EDDisassembler*)disassembler)->nameWithRegisterID(regID);
- if (!name)
- return -1;
- *regName = name;
- return 0;
-}
-
-int EDRegisterIsStackPointer(EDDisassemblerRef disassembler,
- unsigned regID) {
- return ((EDDisassembler*)disassembler)->registerIsStackPointer(regID) ? 1 : 0;
-}
-
-int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler,
- unsigned regID) {
- return ((EDDisassembler*)disassembler)->registerIsProgramCounter(regID) ? 1:0;
-}
-
-unsigned int EDCreateInsts(EDInstRef *insts,
- unsigned int count,
- EDDisassemblerRef disassembler,
- ::EDByteReaderCallback byteReader,
- uint64_t address,
- void *arg) {
- unsigned int index;
-
- for (index = 0; index < count; ++index) {
- EDInst *inst = ((EDDisassembler*)disassembler)->createInst(byteReader,
- address, arg);
-
- if (!inst)
- return index;
-
- insts[index] = inst;
- address += inst->byteSize();
- }
-
- return count;
-}
-
-void EDReleaseInst(EDInstRef inst) {
- delete ((EDInst*)inst);
-}
-
-int EDInstByteSize(EDInstRef inst) {
- return ((EDInst*)inst)->byteSize();
-}
-
-int EDGetInstString(const char **buf,
- EDInstRef inst) {
- return ((EDInst*)inst)->getString(*buf);
-}
-
-int EDInstID(unsigned *instID, EDInstRef inst) {
- *instID = ((EDInst*)inst)->instID();
- return 0;
-}
-
-int EDInstIsBranch(EDInstRef inst) {
- return ((EDInst*)inst)->isBranch();
-}
-
-int EDInstIsMove(EDInstRef inst) {
- return ((EDInst*)inst)->isMove();
-}
-
-int EDBranchTargetID(EDInstRef inst) {
- return ((EDInst*)inst)->branchTargetID();
-}
-
-int EDMoveSourceID(EDInstRef inst) {
- return ((EDInst*)inst)->moveSourceID();
-}
-
-int EDMoveTargetID(EDInstRef inst) {
- return ((EDInst*)inst)->moveTargetID();
-}
-
-int EDNumTokens(EDInstRef inst) {
- return ((EDInst*)inst)->numTokens();
-}
-
-int EDGetToken(EDTokenRef *token,
- EDInstRef inst,
- int index) {
- return ((EDInst*)inst)->getToken(*(EDToken**)token, index);
-}
-
-int EDGetTokenString(const char **buf,
- EDTokenRef token) {
- return ((EDToken*)token)->getString(*buf);
-}
-
-int EDOperandIndexForToken(EDTokenRef token) {
- return ((EDToken*)token)->operandID();
-}
-
-int EDTokenIsWhitespace(EDTokenRef token) {
- return ((EDToken*)token)->type() == EDToken::kTokenWhitespace;
-}
-
-int EDTokenIsPunctuation(EDTokenRef token) {
- return ((EDToken*)token)->type() == EDToken::kTokenPunctuation;
-}
-
-int EDTokenIsOpcode(EDTokenRef token) {
- return ((EDToken*)token)->type() == EDToken::kTokenOpcode;
-}
-
-int EDTokenIsLiteral(EDTokenRef token) {
- return ((EDToken*)token)->type() == EDToken::kTokenLiteral;
-}
-
-int EDTokenIsRegister(EDTokenRef token) {
- return ((EDToken*)token)->type() == EDToken::kTokenRegister;
-}
-
-int EDTokenIsNegativeLiteral(EDTokenRef token) {
- if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
- return -1;
-
- return ((EDToken*)token)->literalSign();
-}
-
-int EDLiteralTokenAbsoluteValue(uint64_t *value, EDTokenRef token) {
- if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
- return -1;
-
- return ((EDToken*)token)->literalAbsoluteValue(*value);
-}
-
-int EDRegisterTokenValue(unsigned *registerID,
- EDTokenRef token) {
- if (((EDToken*)token)->type() != EDToken::kTokenRegister)
- return -1;
-
- return ((EDToken*)token)->registerID(*registerID);
-}
-
-int EDNumOperands(EDInstRef inst) {
- return ((EDInst*)inst)->numOperands();
-}
-
-int EDGetOperand(EDOperandRef *operand,
- EDInstRef inst,
- int index) {
- return ((EDInst*)inst)->getOperand(*(EDOperand**)operand, index);
-}
-
-int EDOperandIsRegister(EDOperandRef operand) {
- return ((EDOperand*)operand)->isRegister();
-}
-
-int EDOperandIsImmediate(EDOperandRef operand) {
- return ((EDOperand*)operand)->isImmediate();
-}
-
-int EDOperandIsMemory(EDOperandRef operand) {
- return ((EDOperand*)operand)->isMemory();
-}
-
-int EDRegisterOperandValue(unsigned *value, EDOperandRef operand) {
- if (!((EDOperand*)operand)->isRegister())
- return -1;
- *value = ((EDOperand*)operand)->regVal();
- return 0;
-}
-
-int EDImmediateOperandValue(uint64_t *value, EDOperandRef operand) {
- if (!((EDOperand*)operand)->isImmediate())
- return -1;
- *value = ((EDOperand*)operand)->immediateVal();
- return 0;
-}
-
-int EDEvaluateOperand(uint64_t *result, EDOperandRef operand,
- ::EDRegisterReaderCallback regReader, void *arg) {
- return ((EDOperand*)operand)->evaluate(*result, regReader, arg);
-}
-
-#ifdef __BLOCKS__
-
-struct ByteReaderWrapper {
- EDByteBlock_t byteBlock;
-};
-
-static int readerWrapperCallback(uint8_t *byte,
- uint64_t address,
- void *arg) {
- struct ByteReaderWrapper *wrapper = (struct ByteReaderWrapper *)arg;
- return wrapper->byteBlock(byte, address);
-}
-
-unsigned int EDBlockCreateInsts(EDInstRef *insts,
- int count,
- EDDisassemblerRef disassembler,
- EDByteBlock_t byteBlock,
- uint64_t address) {
- struct ByteReaderWrapper wrapper;
- wrapper.byteBlock = byteBlock;
-
- return EDCreateInsts(insts,
- count,
- disassembler,
- readerWrapperCallback,
- address,
- (void*)&wrapper);
-}
-
-int EDBlockEvaluateOperand(uint64_t *result, EDOperandRef operand,
- EDRegisterBlock_t regBlock) {
- return ((EDOperand*)operand)->evaluate(*result, regBlock);
-}
-
-int EDBlockVisitTokens(EDInstRef inst, ::EDTokenVisitor_t visitor) {
- return ((EDInst*)inst)->visitTokens((llvm::EDTokenVisitor_t)visitor);
-}
-
-#else
-
-extern "C" unsigned int EDBlockCreateInsts() {
- return 0;
-}
-
-extern "C" int EDBlockEvaluateOperand() {
- return -1;
-}
-
-extern "C" int EDBlockVisitTokens() {
- return -1;
-}
-
-#endif
diff --git a/tools/edis/Makefile b/tools/edis/Makefile
deleted file mode 100644
index 3fcb408..0000000
--- a/tools/edis/Makefile
+++ /dev/null
@@ -1,53 +0,0 @@
-##===- tools/edis/Makefile -----------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-LIBRARYNAME = EnhancedDisassembly
-LINK_LIBS_IN_SHARED = 1
-
-EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/EnhancedDisassembly.exports
-
-# Include this here so we can get the configuration of the targets
-# that have been configured for construction. We have to do this
-# early so we can set up LINK_COMPONENTS before including Makefile.rules
-include $(LEVEL)/Makefile.config
-
-LINK_COMPONENTS := mcdisassembler
-
-# If the X86 target is enabled, link in the asmprinter and disassembler.
-ifneq ($(filter $(TARGETS_TO_BUILD), X86),)
-LINK_COMPONENTS += x86asmprinter x86disassembler
-endif
-
-# If the ARM target is enabled, link in the asmprinter and disassembler.
-ifneq ($(filter $(TARGETS_TO_BUILD), ARM),)
-LINK_COMPONENTS += armasmprinter armdisassembler
-endif
-
-include $(LEVEL)/Makefile.common
-
-ifeq ($(HOST_OS),Darwin)
- # extra options to override libtool defaults
- LLVMLibsOptions := $(LLVMLibsOptions) \
- -Wl,-dead_strip
-
- ifdef EDIS_VERSION
- LLVMLibsOptions := $(LLVMLibsOptions) -Wl,-current_version -Wl,$(EDIS_VERSION) \
- -Wl,-compatibility_version -Wl,1
- endif
-
- # Mac OS X 10.4 and earlier tools do not allow a second -install_name on command line
- DARWIN_VERS := $(shell echo $(TARGET_TRIPLE) | sed 's/.*darwin\([0-9]*\).*/\1/')
- ifneq ($(DARWIN_VERS),8)
- LLVMLibsOptions := $(LLVMLibsOptions) \
- -Wl,-install_name \
- -Wl,"@rpath/lib$(LIBRARYNAME)$(SHLIBEXT)"
- endif
-endif
-
diff --git a/tools/gold/CMakeLists.txt b/tools/gold/CMakeLists.txt
index eb4b6e6..2cc132f 100644
--- a/tools/gold/CMakeLists.txt
+++ b/tools/gold/CMakeLists.txt
@@ -40,6 +40,7 @@ else()
set_property(SOURCE gold-plugin.cpp APPEND PROPERTY
OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/exportsfile)
- target_link_libraries(LLVMgold LTO -Wl,--version-script,exportsfile)
+ target_link_libraries(LLVMgold LTO
+ -Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/exportsfile)
add_dependencies(LLVMgold gold_exports)
endif()
diff --git a/tools/gold/Makefile b/tools/gold/Makefile
index 759406f..02f66d7 100644
--- a/tools/gold/Makefile
+++ b/tools/gold/Makefile
@@ -7,8 +7,12 @@
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-LIBRARYNAME = LLVMgold
+LEVEL := ../..
+LIBRARYNAME := LLVMgold
+LINK_COMPONENTS := support
+LINK_LIBS_IN_SHARED := 1
+SHARED_LIBRARY := 1
+LOADABLE_MODULE := 1
EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/gold.exports
@@ -17,15 +21,9 @@ EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/gold.exports
# early so we can set up LINK_COMPONENTS before including Makefile.rules
include $(LEVEL)/Makefile.config
-LINK_LIBS_IN_SHARED=1
-SHARED_LIBRARY = 1
-LOADABLE_MODULE = 1
-
-LINK_COMPONENTS := support
-
# Because off_t is used in the public API, the largefile parts are required for
# ABI compatibility.
-CXXFLAGS+=-I$(BINUTILS_INCDIR) -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
-CXXFLAGS+=$(SharedLibDir)/$(SharedPrefix)LTO$(SHLIBEXT)
+CXXFLAGS += -I$(BINUTILS_INCDIR) -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
+CXXFLAGS += -L$(SharedLibDir)/$(SharedPrefix) -lLTO
include $(LEVEL)/Makefile.common
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/LLVMBuild.txt b/tools/llc/LLVMBuild.txt
new file mode 100644
index 0000000..8c8794f
--- /dev/null
+++ b/tools/llc/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llc/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 = llc
+parent = Tools
+required_libraries = AsmParser BitReader all-targets
diff --git a/tools/llc/Makefile b/tools/llc/Makefile
index 7319aad..b32d557 100644
--- a/tools/llc/Makefile
+++ b/tools/llc/Makefile
@@ -7,15 +7,9 @@
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = llc
+LEVEL := ../..
+TOOLNAME := llc
+LINK_COMPONENTS := all-targets bitreader asmparser
-# Include this here so we can get the configuration of the targets
-# that have been configured for construction. We have to do this
-# early so we can set up LINK_COMPONENTS before including Makefile.rules
-include $(LEVEL)/Makefile.config
-
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) bitreader asmparser
-
-include $(LLVM_SRC_ROOT)/Makefile.rules
+include $(LEVEL)/Makefile.common
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp
index d29bd9b..9e30ac1 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"
@@ -133,11 +132,147 @@ cl::opt<bool> DisableDotLoc("disable-dot-loc", cl::Hidden,
cl::opt<bool> DisableCFI("disable-cfi", cl::Hidden,
cl::desc("Do not use .cfi_* directives"));
+cl::opt<bool> EnableDwarfDirectory("enable-dwarf-directory", cl::Hidden,
+ cl::desc("Use .file directives with an explicit directory."));
+
static cl::opt<bool>
DisableRedZone("disable-red-zone",
cl::desc("Do not emit code that uses the red zone."),
cl::init(false));
+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>
+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));
+
+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>
+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));
+
+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<bool>
+DontPlaceZerosInBSS("nozero-initialized-in-bss",
+ cl::desc("Don't place zero-initialized symbols into bss section"),
+ cl::init(false));
+
+static cl::opt<bool>
+EnableJITExceptionHandling("jit-enable-eh",
+ cl::desc("Emit exception handling information"),
+ cl::init(false));
+
+// In debug builds, make this default to true.
+#ifdef NDEBUG
+#define EMIT_DEBUG false
+#else
+#define EMIT_DEBUG true
+#endif
+static cl::opt<bool>
+EmitJitDebugInfo("jit-emit-debug",
+ cl::desc("Emit debug information to debugger"),
+ cl::init(EMIT_DEBUG));
+#undef EMIT_DEBUG
+
+static cl::opt<bool>
+EmitJitDebugInfoToDisk("jit-emit-debug-to-disk",
+ cl::Hidden,
+ cl::desc("Emit debug info objfiles to disk"),
+ 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<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"),
+ 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));
+
+
// GetFileNameRoot - Helper function to get the basename of a filename.
static inline std::string
GetFileNameRoot(const std::string &InputFilename) {
@@ -166,7 +301,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)
@@ -194,7 +328,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:
@@ -247,7 +380,7 @@ int main(int argc, char **argv) {
M.reset(ParseIRFile(InputFilename, Err, Context));
if (M.get() == 0) {
- Err.Print(argv[0], errs());
+ Err.print(argv[0], errs());
return 1;
}
Module &mod = *M.get();
@@ -258,7 +391,7 @@ int main(int argc, char **argv) {
Triple TheTriple(mod.getTargetTriple());
if (TheTriple.getTriple().empty())
- TheTriple.setTriple(sys::getHostTriple());
+ 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
@@ -303,10 +436,49 @@ int main(int argc, char **argv) {
FeaturesStr = Features.getString();
}
+ CodeGenOpt::Level OLvl = CodeGenOpt::Default;
+ switch (OptLevel) {
+ default:
+ errs() << argv[0] << ": invalid optimization level.\n";
+ return 1;
+ case ' ': break;
+ case '0': OLvl = CodeGenOpt::None; break;
+ case '1': OLvl = CodeGenOpt::Less; break;
+ case '2': OLvl = CodeGenOpt::Default; break;
+ case '3': OLvl = CodeGenOpt::Aggressive; break;
+ }
+
+ TargetOptions Options;
+ Options.LessPreciseFPMADOption = EnableFPMAD;
+ Options.PrintMachineCode = PrintCode;
+ Options.NoFramePointerElim = DisableFPElim;
+ Options.NoFramePointerElimNonLeaf = DisableFPElimNonLeaf;
+ Options.NoExcessFPPrecision = DisableExcessPrecision;
+ 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.JITExceptionHandling = EnableJITExceptionHandling;
+ Options.JITEmitDebugInfo = EmitJitDebugInfo;
+ Options.JITEmitDebugInfoToDisk = EmitJitDebugInfoToDisk;
+ Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt;
+ Options.DisableTailCalls = DisableTailCalls;
+ Options.StackAlignmentOverride = OverrideStackAlignment;
+ Options.RealignStack = EnableRealignStack;
+ Options.DisableJumpTables = DisableSwitchTables;
+ Options.TrapFuncName = TrapFuncName;
+ Options.PositionIndependentExecutable = EnablePIE;
+ Options.EnableSegmentedStacks = SegmentedStacks;
+
std::auto_ptr<TargetMachine>
target(TheTarget->createTargetMachine(TheTriple.getTriple(),
- MCPU, FeaturesStr,
- RelocModel, CMModel));
+ MCPU, FeaturesStr, Options,
+ RelocModel, CMModel, OLvl));
assert(target.get() && "Could not allocate target machine!");
TargetMachine &Target = *target.get();
@@ -316,6 +488,12 @@ int main(int argc, char **argv) {
if (DisableCFI)
Target.setMCUseCFI(false);
+ if (EnableDwarfDirectory)
+ Target.setMCUseDwarfDirectory(true);
+
+ if (GenerateSoftFloatCalls)
+ FloatABIForCalls = FloatABI::Soft;
+
// Disable .loc support for older OS X versions.
if (TheTriple.isMacOSX() &&
TheTriple.isMacOSXVersionLT(10, 6))
@@ -326,18 +504,6 @@ int main(int argc, char **argv) {
(GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]));
if (!Out) return 1;
- CodeGenOpt::Level OLvl = CodeGenOpt::Default;
- switch (OptLevel) {
- default:
- errs() << argv[0] << ": invalid optimization level.\n";
- return 1;
- case ' ': break;
- case '0': OLvl = CodeGenOpt::None; break;
- case '1': OLvl = CodeGenOpt::Less; break;
- case '2': OLvl = CodeGenOpt::Default; break;
- case '3': OLvl = CodeGenOpt::Aggressive; break;
- }
-
// Build up all of the passes that we want to do to the module.
PassManager PM;
@@ -362,7 +528,7 @@ int main(int argc, char **argv) {
formatted_raw_ostream FOS(Out->os());
// Ask the target to add backend passes as necessary.
- if (Target.addPassesToEmitFile(PM, FOS, FileType, OLvl, NoVerify)) {
+ if (Target.addPassesToEmitFile(PM, FOS, FileType, NoVerify)) {
errs() << argv[0] << ": target does not support generation of this"
<< " file type!\n";
return 1;
diff --git a/tools/lli/CMakeLists.txt b/tools/lli/CMakeLists.txt
index 9378ef2..a5d2e61 100644
--- a/tools/lli/CMakeLists.txt
+++ b/tools/lli/CMakeLists.txt
@@ -1,5 +1,22 @@
+
+link_directories( ${LLVM_INTEL_JITEVENTS_LIBDIR} )
+
set(LLVM_LINK_COMPONENTS mcjit jit interpreter nativecodegen bitreader asmparser selectiondag)
+if( LLVM_USE_OPROFILE )
+ set(LLVM_LINK_COMPONENTS
+ ${LLVM_LINK_COMPONENTS}
+ OProfileJIT
+ )
+endif( LLVM_USE_OPROFILE )
+
+if( LLVM_USE_INTEL_JITEVENTS )
+ set(LLVM_LINK_COMPONENTS
+ ${LLVM_LINK_COMPONENTS}
+ IntelJITEvents
+ )
+endif( LLVM_USE_INTEL_JITEVENTS )
+
add_llvm_tool(lli
lli.cpp
)
diff --git a/tools/lli/LLVMBuild.txt b/tools/lli/LLVMBuild.txt
new file mode 100644
index 0000000..4eb82bd
--- /dev/null
+++ b/tools/lli/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/lli/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 = lli
+parent = Tools
+required_libraries = AsmParser BitReader Interpreter JIT MCJIT NativeCodeGen SelectionDAG
diff --git a/tools/lli/Makefile b/tools/lli/Makefile
index 80aa82b..100fc2e 100644
--- a/tools/lli/Makefile
+++ b/tools/lli/Makefile
@@ -7,9 +7,23 @@
#
##===----------------------------------------------------------------------===##
-LEVEL := ../..
+LEVEL := ../..
TOOLNAME := lli
+
+include $(LEVEL)/Makefile.config
+
LINK_COMPONENTS := mcjit jit interpreter nativecodegen bitreader asmparser selectiondag
-# Enable JIT support
-include $(LEVEL)/Makefile.common
+# If Intel JIT Events support is confiured, link against the LLVM Intel JIT
+# Events interface library
+ifeq ($(USE_INTEL_JITEVENTS), 1)
+ LINK_COMPONENTS += inteljitevents
+endif
+
+# If oprofile support is confiured, link against the LLVM oprofile interface
+# library
+ifeq ($(USE_OPROFILE), 1)
+ LINK_COMPONENTS += oprofilejit
+endif
+
+include $(LLVM_SRC_ROOT)/Makefile.rules
diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp
index 50c7a49..efcc1f5 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,12 +174,12 @@ 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);
if (!Mod) {
- Err.Print(argv[0], errs());
+ Err.print(argv[0], errs());
return 1;
}
@@ -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) {
@@ -233,7 +238,12 @@ int main(int argc, char **argv, char * const *envp) {
exit(1);
}
- EE->RegisterJITEventListener(createOProfileJITEventListener());
+ // The following functions have no effect if their respective profiling
+ // support wasn't enabled in the build configuration.
+ EE->RegisterJITEventListener(
+ JITEventListener::createOProfileJITEventListener());
+ EE->RegisterJITEventListener(
+ JITEventListener::createIntelJITEventListener());
EE->DisableLazyCompilation(NoLazyCompilation);
@@ -262,15 +272,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 +297,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-ar/LLVMBuild.txt b/tools/llvm-ar/LLVMBuild.txt
new file mode 100644
index 0000000..1f61a32
--- /dev/null
+++ b/tools/llvm-ar/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-ar/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-ar
+parent = Tools
+required_libraries = Archive
diff --git a/tools/llvm-ar/Makefile b/tools/llvm-ar/Makefile
index e4fe4e8..6ee6f34 100644
--- a/tools/llvm-ar/Makefile
+++ b/tools/llvm-ar/Makefile
@@ -6,20 +6,13 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = llvm-ar
-LINK_COMPONENTS = archive
+LEVEL := ../..
+TOOLNAME := llvm-ar
+LINK_COMPONENTS := archive
REQUIRES_EH := 1
# This tool has no plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
+TOOL_NO_EXPORTS := 1
include $(LEVEL)/Makefile.common
-
-check-local::
- $(Echo) Checking llvm-ar
- $(Verb) $(ToolDir)/llvm-ar zRrS nada.a .
- $(Verb) $(ToolDir)/llvm-ar tv nada.a | \
- grep Debug/llvm-ar.d >/dev/null 2>&1
- $(Verb) $(RM) -f nada.a
diff --git a/tools/llvm-as/LLVMBuild.txt b/tools/llvm-as/LLVMBuild.txt
new file mode 100644
index 0000000..542470b
--- /dev/null
+++ b/tools/llvm-as/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-as/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-as
+parent = Tools
+required_libraries = AsmParser BitWriter
diff --git a/tools/llvm-as/Makefile b/tools/llvm-as/Makefile
index e1e5853..dfd71b2 100644
--- a/tools/llvm-as/Makefile
+++ b/tools/llvm-as/Makefile
@@ -7,11 +7,11 @@
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = llvm-as
+LEVEL := ../..
+TOOLNAME := llvm-as
LINK_COMPONENTS := asmparser bitwriter
# This tool has no plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
+TOOL_NO_EXPORTS := 1
include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-as/llvm-as.cpp b/tools/llvm-as/llvm-as.cpp
index c1661cd..1def9a4 100644
--- a/tools/llvm-as/llvm-as.cpp
+++ b/tools/llvm-as/llvm-as.cpp
@@ -96,7 +96,7 @@ int main(int argc, char **argv) {
SMDiagnostic Err;
std::auto_ptr<Module> M(ParseAssemblyFile(InputFilename, Err, Context));
if (M.get() == 0) {
- Err.Print(argv[0], errs());
+ Err.print(argv[0], errs());
return 1;
}
diff --git a/tools/llvm-bcanalyzer/LLVMBuild.txt b/tools/llvm-bcanalyzer/LLVMBuild.txt
new file mode 100644
index 0000000..ee77a7d
--- /dev/null
+++ b/tools/llvm-bcanalyzer/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-bcanalyzer/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-bcanalyzer
+parent = Tools
+required_libraries = BitReader
diff --git a/tools/llvm-bcanalyzer/Makefile b/tools/llvm-bcanalyzer/Makefile
index 488387d..2fc61db 100644
--- a/tools/llvm-bcanalyzer/Makefile
+++ b/tools/llvm-bcanalyzer/Makefile
@@ -6,12 +6,12 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = llvm-bcanalyzer
+LEVEL := ../..
+TOOLNAME := llvm-bcanalyzer
LINK_COMPONENTS := bitreader
# This tool has no plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
+TOOL_NO_EXPORTS := 1
include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
index 4ada64a..d630087 100644
--- a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
+++ b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
@@ -102,14 +102,13 @@ static const char *GetBlockName(unsigned BlockID,
default: return 0;
case bitc::MODULE_BLOCK_ID: return "MODULE_BLOCK";
case bitc::PARAMATTR_BLOCK_ID: return "PARAMATTR_BLOCK";
- case bitc::TYPE_BLOCK_ID_OLD: return "TYPE_BLOCK_ID_OLD";
case bitc::TYPE_BLOCK_ID_NEW: return "TYPE_BLOCK_ID";
case bitc::CONSTANTS_BLOCK_ID: return "CONSTANTS_BLOCK";
case bitc::FUNCTION_BLOCK_ID: return "FUNCTION_BLOCK";
- case bitc::TYPE_SYMTAB_BLOCK_ID_OLD: return "TYPE_SYMTAB_OLD";
case bitc::VALUE_SYMTAB_BLOCK_ID: return "VALUE_SYMTAB";
case bitc::METADATA_BLOCK_ID: return "METADATA_BLOCK";
case bitc::METADATA_ATTACHMENT_ID: return "METADATA_ATTACHMENT_BLOCK";
+ case bitc::USELIST_BLOCK_ID: return "USELIST_BLOCK_ID";
}
}
@@ -163,7 +162,6 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
default: return 0;
case bitc::PARAMATTR_CODE_ENTRY: return "ENTRY";
}
- case bitc::TYPE_BLOCK_ID_OLD:
case bitc::TYPE_BLOCK_ID_NEW:
switch (CodeID) {
default: return 0;
@@ -175,8 +173,6 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
case bitc::TYPE_CODE_OPAQUE: return "OPAQUE";
case bitc::TYPE_CODE_INTEGER: return "INTEGER";
case bitc::TYPE_CODE_POINTER: return "POINTER";
- case bitc::TYPE_CODE_FUNCTION: return "FUNCTION";
- case bitc::TYPE_CODE_STRUCT_OLD: return "STRUCT_OLD";
case bitc::TYPE_CODE_ARRAY: return "ARRAY";
case bitc::TYPE_CODE_VECTOR: return "VECTOR";
case bitc::TYPE_CODE_X86_FP80: return "X86_FP80";
@@ -186,6 +182,7 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
case bitc::TYPE_CODE_STRUCT_ANON: return "STRUCT_ANON";
case bitc::TYPE_CODE_STRUCT_NAME: return "STRUCT_NAME";
case bitc::TYPE_CODE_STRUCT_NAMED: return "STRUCT_NAMED";
+ case bitc::TYPE_CODE_FUNCTION: return "FUNCTION";
}
case bitc::CONSTANTS_BLOCK_ID:
@@ -211,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) {
@@ -231,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";
@@ -247,11 +245,6 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
case bitc::FUNC_CODE_INST_CALL: return "INST_CALL";
case bitc::FUNC_CODE_DEBUG_LOC: return "DEBUG_LOC";
}
- case bitc::TYPE_SYMTAB_BLOCK_ID_OLD:
- switch (CodeID) {
- default: return 0;
- case bitc::TST_CODE_ENTRY: return "ENTRY";
- }
case bitc::VALUE_SYMTAB_BLOCK_ID:
switch (CodeID) {
default: return 0;
@@ -273,6 +266,11 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
case bitc::METADATA_FN_NODE: return "METADATA_FN_NODE";
case bitc::METADATA_NAMED_NODE: return "METADATA_NAMED_NODE";
}
+ case bitc::USELIST_BLOCK_ID:
+ switch(CodeID) {
+ default:return 0;
+ case bitc::USELIST_CODE_ENTRY: return "USELIST_CODE_ENTRY";
+ }
}
}
@@ -333,7 +331,7 @@ static bool ParseBlock(BitstreamCursor &Stream, unsigned IndentLevel) {
// BLOCKINFO is a special part of the stream.
if (BlockID == bitc::BLOCKINFO_BLOCK_ID) {
- if (Dump) errs() << Indent << "<BLOCKINFO_BLOCK/>\n";
+ if (Dump) outs() << Indent << "<BLOCKINFO_BLOCK/>\n";
if (Stream.ReadBlockInfoBlock())
return Error("Malformed BlockInfoBlock");
uint64_t BlockBitEnd = Stream.GetCurrentBitNo();
@@ -347,16 +345,16 @@ static bool ParseBlock(BitstreamCursor &Stream, unsigned IndentLevel) {
const char *BlockName = 0;
if (Dump) {
- errs() << Indent << "<";
+ outs() << Indent << "<";
if ((BlockName = GetBlockName(BlockID, *Stream.getBitStreamReader())))
- errs() << BlockName;
+ outs() << BlockName;
else
- errs() << "UnknownBlock" << BlockID;
+ outs() << "UnknownBlock" << BlockID;
if (NonSymbolic && BlockName)
- errs() << " BlockID=" << BlockID;
+ outs() << " BlockID=" << BlockID;
- errs() << " NumWords=" << NumWords
+ outs() << " NumWords=" << NumWords
<< " BlockCodeSize=" << Stream.GetAbbrevIDWidth() << ">\n";
}
@@ -378,11 +376,11 @@ static bool ParseBlock(BitstreamCursor &Stream, unsigned IndentLevel) {
uint64_t BlockBitEnd = Stream.GetCurrentBitNo();
BlockStats.NumBits += BlockBitEnd-BlockBitStart;
if (Dump) {
- errs() << Indent << "</";
+ outs() << Indent << "</";
if (BlockName)
- errs() << BlockName << ">\n";
+ outs() << BlockName << ">\n";
else
- errs() << "UnknownBlock" << BlockID << ">\n";
+ outs() << "UnknownBlock" << BlockID << ">\n";
}
return false;
}
@@ -424,25 +422,25 @@ static bool ParseBlock(BitstreamCursor &Stream, unsigned IndentLevel) {
BlockStats.CodeFreq[Code].NumAbbrev++;
if (Dump) {
- errs() << Indent << " <";
+ outs() << Indent << " <";
if (const char *CodeName =
GetCodeName(Code, BlockID, *Stream.getBitStreamReader()))
- errs() << CodeName;
+ outs() << CodeName;
else
- errs() << "UnknownCode" << Code;
+ outs() << "UnknownCode" << Code;
if (NonSymbolic &&
GetCodeName(Code, BlockID, *Stream.getBitStreamReader()))
- errs() << " codeid=" << Code;
+ outs() << " codeid=" << Code;
if (AbbrevID != bitc::UNABBREV_RECORD)
- errs() << " abbrevid=" << AbbrevID;
+ outs() << " abbrevid=" << AbbrevID;
for (unsigned i = 0, e = Record.size(); i != e; ++i)
- errs() << " op" << i << "=" << (int64_t)Record[i];
+ outs() << " op" << i << "=" << (int64_t)Record[i];
- errs() << "/>";
+ outs() << "/>";
if (BlobStart) {
- errs() << " blob data = ";
+ outs() << " blob data = ";
bool BlobIsPrintable = true;
for (unsigned i = 0; i != BlobLen; ++i)
if (!isprint(BlobStart[i])) {
@@ -451,12 +449,12 @@ static bool ParseBlock(BitstreamCursor &Stream, unsigned IndentLevel) {
}
if (BlobIsPrintable)
- errs() << "'" << std::string(BlobStart, BlobStart+BlobLen) <<"'";
+ outs() << "'" << std::string(BlobStart, BlobStart+BlobLen) <<"'";
else
- errs() << "unprintable, " << BlobLen << " bytes.";
+ outs() << "unprintable, " << BlobLen << " bytes.";
}
- errs() << "\n";
+ outs() << "\n";
}
break;
@@ -485,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);
@@ -527,59 +525,58 @@ static int AnalyzeBitcode() {
++NumTopBlocks;
}
- if (Dump) errs() << "\n\n";
+ if (Dump) outs() << "\n\n";
uint64_t BufferSizeBits = (EndBufPtr-BufPtr)*CHAR_BIT;
// Print a summary of the read file.
- errs() << "Summary of " << InputFilename << ":\n";
- errs() << " Total size: ";
+ outs() << "Summary of " << InputFilename << ":\n";
+ outs() << " Total size: ";
PrintSize(BufferSizeBits);
- errs() << "\n";
- errs() << " Stream type: ";
+ outs() << "\n";
+ outs() << " Stream type: ";
switch (CurStreamType) {
- default: assert(0 && "Unknown bitstream type");
- case UnknownBitstream: errs() << "unknown\n"; break;
- case LLVMIRBitstream: errs() << "LLVM IR\n"; break;
+ case UnknownBitstream: outs() << "unknown\n"; break;
+ case LLVMIRBitstream: outs() << "LLVM IR\n"; break;
}
- errs() << " # Toplevel Blocks: " << NumTopBlocks << "\n";
- errs() << "\n";
+ outs() << " # Toplevel Blocks: " << NumTopBlocks << "\n";
+ outs() << "\n";
// Emit per-block stats.
- errs() << "Per-block Summary:\n";
+ outs() << "Per-block Summary:\n";
for (std::map<unsigned, PerBlockIDStats>::iterator I = BlockIDStats.begin(),
E = BlockIDStats.end(); I != E; ++I) {
- errs() << " Block ID #" << I->first;
+ outs() << " Block ID #" << I->first;
if (const char *BlockName = GetBlockName(I->first, StreamFile))
- errs() << " (" << BlockName << ")";
- errs() << ":\n";
+ outs() << " (" << BlockName << ")";
+ outs() << ":\n";
const PerBlockIDStats &Stats = I->second;
- errs() << " Num Instances: " << Stats.NumInstances << "\n";
- errs() << " Total Size: ";
+ outs() << " Num Instances: " << Stats.NumInstances << "\n";
+ outs() << " Total Size: ";
PrintSize(Stats.NumBits);
- errs() << "\n";
+ outs() << "\n";
double pct = (Stats.NumBits * 100.0) / BufferSizeBits;
errs() << " Percent of file: " << format("%2.4f%%", pct) << "\n";
if (Stats.NumInstances > 1) {
- errs() << " Average Size: ";
+ outs() << " Average Size: ";
PrintSize(Stats.NumBits/(double)Stats.NumInstances);
- errs() << "\n";
- errs() << " Tot/Avg SubBlocks: " << Stats.NumSubBlocks << "/"
+ outs() << "\n";
+ outs() << " Tot/Avg SubBlocks: " << Stats.NumSubBlocks << "/"
<< Stats.NumSubBlocks/(double)Stats.NumInstances << "\n";
- errs() << " Tot/Avg Abbrevs: " << Stats.NumAbbrevs << "/"
+ outs() << " Tot/Avg Abbrevs: " << Stats.NumAbbrevs << "/"
<< Stats.NumAbbrevs/(double)Stats.NumInstances << "\n";
- errs() << " Tot/Avg Records: " << Stats.NumRecords << "/"
+ outs() << " Tot/Avg Records: " << Stats.NumRecords << "/"
<< Stats.NumRecords/(double)Stats.NumInstances << "\n";
} else {
- errs() << " Num SubBlocks: " << Stats.NumSubBlocks << "\n";
- errs() << " Num Abbrevs: " << Stats.NumAbbrevs << "\n";
- errs() << " Num Records: " << Stats.NumRecords << "\n";
+ outs() << " Num SubBlocks: " << Stats.NumSubBlocks << "\n";
+ outs() << " Num Abbrevs: " << Stats.NumAbbrevs << "\n";
+ outs() << " Num Records: " << Stats.NumRecords << "\n";
}
if (Stats.NumRecords) {
double pct = (Stats.NumAbbreviatedRecords * 100.0) / Stats.NumRecords;
- errs() << " Percent Abbrevs: " << format("%2.4f%%", pct) << "\n";
+ outs() << " Percent Abbrevs: " << format("%2.4f%%", pct) << "\n";
}
- errs() << "\n";
+ outs() << "\n";
// Print a histogram of the codes we see.
if (!NoHistogram && !Stats.CodeFreq.empty()) {
@@ -590,7 +587,7 @@ static int AnalyzeBitcode() {
std::stable_sort(FreqPairs.begin(), FreqPairs.end());
std::reverse(FreqPairs.begin(), FreqPairs.end());
- errs() << "\tRecord Histogram:\n";
+ outs() << "\tRecord Histogram:\n";
fprintf(stderr, "\t\t Count # Bits %% Abv Record Kind\n");
for (unsigned i = 0, e = FreqPairs.size(); i != e; ++i) {
const PerRecordStats &RecStats = Stats.CodeFreq[FreqPairs[i].second];
@@ -610,7 +607,7 @@ static int AnalyzeBitcode() {
else
fprintf(stderr, "UnknownCode%d\n", FreqPairs[i].second);
}
- errs() << "\n";
+ outs() << "\n";
}
}
diff --git a/tools/llvm-config/BuildVariables.inc.in b/tools/llvm-config/BuildVariables.inc.in
new file mode 100644
index 0000000..fe87afb
--- /dev/null
+++ b/tools/llvm-config/BuildVariables.inc.in
@@ -0,0 +1,27 @@
+//===-- BuildVariables.inc.in - llvm-config build variables -*- C++ -*-----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is configured by the build system to define the variables
+// llvm-config wants to report to the user, but which can only be determined at
+// build time.
+//
+// The non .in variant of this file has been autogenerated by the LLVM build. Do
+// not edit!
+//
+//===----------------------------------------------------------------------===//
+
+#define LLVM_SRC_ROOT "@LLVM_SRC_ROOT@"
+#define LLVM_OBJ_ROOT "@LLVM_OBJ_ROOT@"
+#define LLVM_CPPFLAGS "@LLVM_CPPFLAGS@"
+#define LLVM_CFLAGS "@LLVM_CFLAGS@"
+#define LLVM_LDFLAGS "@LLVM_LDFLAGS@"
+#define LLVM_CXXFLAGS "@LLVM_CXXFLAGS@"
+#define LLVM_BUILDMODE "@LLVM_BUILDMODE@"
+#define LLVM_TARGETS_BUILT "@LLVM_TARGETS_BUILT@"
+#define LLVM_SYSTEM_LIBS "@LLVM_SYSTEM_LIBS@"
diff --git a/tools/llvm-config/CMakeLists.txt b/tools/llvm-config/CMakeLists.txt
index 6016862..5ad58bf 100644
--- a/tools/llvm-config/CMakeLists.txt
+++ b/tools/llvm-config/CMakeLists.txt
@@ -1,140 +1,42 @@
-include(TestBigEndian)
+set(LLVM_LINK_COMPONENTS support)
-include(FindPerl)
-if( NOT PERL_FOUND )
- message(FATAL_ERROR "Perl required but not found!")
-endif( NOT PERL_FOUND )
-
-set(PERL ${PERL_EXECUTABLE})
-set(VERSION PACKAGE_VERSION)
-set(PREFIX ${CMAKE_INSTALL_PREFIX})
-set(abs_top_srcdir ${LLVM_MAIN_SRC_DIR})
-set(abs_top_builddir ${LLVM_BINARY_DIR})
-execute_process(COMMAND date
- OUTPUT_VARIABLE LLVM_CONFIGTIME
- OUTPUT_STRIP_TRAILING_WHITESPACE)
-# LLVM_ON_UNIX and LLVM_ON_WIN32 already set.
-# those are set to blank by `autoconf' on MinGW, so it seems they are not required:
-#set(LLVMGCCDIR "")
-#set(LLVMGCC "")
-#set(LLVMGXX "")
-test_big_endian(IS_BIG_ENDIAN)
-if( IS_BIG_ENDIAN )
- set(ENDIAN "big")
-else( IS_BIG_ENDIAN )
- set(ENDIAN "little")
-endif( IS_BIG_ENDIAN )
-set(SHLIBEXT ${LTDL_SHLIB_EXT})
-#EXEEXT already set.
-set(OS "${CMAKE_SYSTEM}")
-set(target "${TARGET_TRIPLE}")
-set(ARCH "${LLVM_NATIVE_ARCH}")
+# We need to generate the BuildVariables.inc file containing values which are
+# only defined when under certain build modes. Unfortunately, that precludes
+# doing this inside CMake so we have to shell out to sed. For now, that means we
+# can't expect to build llvm-config on Window.s
+set(BUILDVARIABLES_SRCPATH ${CMAKE_CURRENT_SOURCE_DIR}/BuildVariables.inc.in)
+set(BUILDVARIABLES_OBJPATH ${CMAKE_CURRENT_BINARY_DIR}/BuildVariables.inc)
+set(SEDSCRIPT_OBJPATH ${CMAKE_CURRENT_BINARY_DIR}/BuildVariables.configure.sed)
+# Compute the substitution values for various items.
get_system_libs(LLVM_SYSTEM_LIBS_LIST)
foreach(l ${LLVM_SYSTEM_LIBS_LIST})
- set(LLVM_SYSTEM_LIBS ${LLVM_SYSTEM_LIBS} "-l${l}")
+ set(SYSTEM_LIBS ${SYSTEM_LIBS} "-l${l}")
endforeach()
-
-foreach(c ${LLVM_TARGETS_TO_BUILD})
- set(TARGETS_BUILT "${TARGETS_BUILT} ${c}")
-endforeach(c)
-set(TARGETS_TO_BUILD ${TARGETS_BUILT})
-set(TARGET_HAS_JIT "1") # TODO
-
-# Avoids replacement at config-time:
-set(LLVM_CPPFLAGS "@LLVM_CPPFLAGS@")
-set(LLVM_CFLAGS "@LLVM_CFLAGS@")
-set(LLVM_CXXFLAGS "@LLVM_CXXFLAGS@")
-set(LLVM_LDFLAGS "@LLVM_LDFLAGS@")
-set(LIBS "@LIBS@")
-set(LLVM_BUILDMODE "@LLVM_BUILDMODE@")
-
-configure_file(
- ${CMAKE_CURRENT_SOURCE_DIR}/llvm-config.in.in
- ${CMAKE_CURRENT_BINARY_DIR}/llvm-config.in
- @ONLY
-)
-
-set(LIBDEPS LibDeps.txt)
-set(LIBDEPS_TMP LibDeps.txt.tmp)
-set(FINAL_LIBDEPS FinalLibDeps.txt)
-set(LLVM_CONFIG ${LLVM_TOOLS_BINARY_DIR}/llvm-config)
-set(LLVM_CONFIG_IN ${CMAKE_CURRENT_BINARY_DIR}/llvm-config.in)
-
-if( CMAKE_CROSSCOMPILING )
- set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
-endif()
-
-find_program(NM_PATH nm PATH_SUFFIXES /bin)
-
-if( NOT NM_PATH )
- message(FATAL_ERROR "`nm' not found")
-endif()
-
-get_property(llvm_libs GLOBAL PROPERTY LLVM_LIBS)
-
-add_custom_command(OUTPUT ${LIBDEPS_TMP}
- COMMAND ${PERL_EXECUTABLE} ${LLVM_MAIN_SRC_DIR}/utils/GenLibDeps.pl -flat ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR} ${NM_PATH} > ${LIBDEPS_TMP}
- DEPENDS ${llvm_libs}
- COMMENT "Regenerating ${LIBDEPS_TMP}")
-
-add_custom_command(OUTPUT ${LIBDEPS}
- COMMAND ${CMAKE_COMMAND} -E copy_if_different ${LIBDEPS_TMP} ${LIBDEPS}
- DEPENDS ${LIBDEPS_TMP}
- COMMENT "Updating ${LIBDEPS} if necessary...")
-
-# This must stop the build if find-cycles.pl returns error:
-add_custom_command(OUTPUT ${FINAL_LIBDEPS}
- COMMAND ${CMAKE_COMMAND} -E remove -f ${FINAL_LIBDEPS} ${FINAL_LIBDEPS}.tmp
- COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/find-cycles.pl < ${LIBDEPS} > ${FINAL_LIBDEPS}.tmp
- COMMAND ${CMAKE_COMMAND} -E copy ${FINAL_LIBDEPS}.tmp ${FINAL_LIBDEPS}
- DEPENDS ${LIBDEPS}
- COMMENT "Checking for cyclic dependencies between LLVM libraries.")
-
set(C_FLGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}")
set(CXX_FLGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}")
set(CPP_FLGS "${CMAKE_CPP_FLAGS} ${CMAKE_CPP_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}")
-# We don't want certain flags on the output of
-# llvm-config --cflags --cxxflags
-macro(remove_option_from_llvm_config option)
- llvm_replace_compiler_option(C_FLGS "${option}" "")
- llvm_replace_compiler_option(CXX_FLGS "${option}" "")
- llvm_replace_compiler_option(CPP_FLGS "${option}" "")
-endmacro(remove_option_from_llvm_config)
-remove_option_from_llvm_config("-pedantic")
-remove_option_from_llvm_config("-Wall")
-remove_option_from_llvm_config("-W")
-
-add_custom_command(OUTPUT ${LLVM_CONFIG}
- COMMAND echo s!@LLVM_CPPFLAGS@!${CPP_FLGS}! > temp.sed
- COMMAND echo s!@LLVM_CFLAGS@!${C_FLGS}! >> temp.sed
- COMMAND echo s!@LLVM_CXXFLAGS@!${CXX_FLGS}! >> temp.sed
+add_custom_command(OUTPUT ${BUILDVARIABLES_OBJPATH}
+ COMMAND echo s!@LLVM_SRC_ROOT@!${LLVM_MAIN_SRC_DIR}! > ${SEDSCRIPT_OBJPATH}
+ COMMAND echo s!@LLVM_OBJ_ROOT@!${LLVM_BINARY_DIR}! >> ${SEDSCRIPT_OBJPATH}
+ COMMAND echo s!@LLVM_CPPFLAGS@!${CPP_FLGS}! >> ${SEDSCRIPT_OBJPATH}
+ COMMAND echo s!@LLVM_CFLAGS@!${C_FLGS}! >> ${SEDSCRIPT_OBJPATH}
+ COMMAND echo s!@LLVM_CXXFLAGS@!${CXX_FLGS}! >> ${SEDSCRIPT_OBJPATH}
# TODO: Use general flags for linking! not just for shared libs:
- COMMAND echo s!@LLVM_LDFLAGS@!${CMAKE_SHARED_LINKER_FLAGS}! >> temp.sed
- COMMAND echo s!@LIBS@!${LLVM_SYSTEM_LIBS}! >> temp.sed
- COMMAND echo s!@LLVM_BUILDMODE@!${CMAKE_BUILD_TYPE}! >> temp.sed
- COMMAND sed -f temp.sed < ${LLVM_CONFIG_IN} > ${LLVM_CONFIG}
- COMMAND ${CMAKE_COMMAND} -E remove -f temp.sed
- COMMAND cat ${FINAL_LIBDEPS} >> ${LLVM_CONFIG}
- COMMAND chmod +x ${LLVM_CONFIG}
+ COMMAND echo s!@LLVM_LDFLAGS@!${CMAKE_SHARED_LINKER_FLAGS}! >> ${SEDSCRIPT_OBJPATH}
+ COMMAND echo s!@LLVM_BUILDMODE@!${CMAKE_BUILD_TYPE}! >> ${SEDSCRIPT_OBJPATH}
+ COMMAND echo s!@LLVM_SYSTEM_LIBS@!${SYSTEM_LIBS}! >> ${SEDSCRIPT_OBJPATH}
+ COMMAND echo s!@LLVM_TARGETS_BUILT@!${LLVM_TARGETS_TO_BUILD}! >> ${SEDSCRIPT_OBJPATH}
+ COMMAND sed -f ${SEDSCRIPT_OBJPATH} < ${BUILDVARIABLES_SRCPATH} > ${BUILDVARIABLES_OBJPATH}
VERBATIM
- DEPENDS ${FINAL_LIBDEPS} ${LLVM_CONFIG_IN}
- COMMENT "Building llvm-config script."
+ COMMENT "Building BuildVariables.inc include."
)
-add_custom_target(llvm-config.target ALL
- DEPENDS ${LLVM_CONFIG})
-
-add_dependencies( llvm-config.target ${llvm_libs} )
-
-# Make sure that llvm-config builds before the llvm tools, so we have
-# LibDeps.txt and can use it for updating the hard-coded library
-# dependencies on cmake/modules/LLVMLibDeps.cmake when the tools'
-# build fail due to outdated dependencies:
-set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} llvm-config.target)
+# Add the llvm-config tool.
+add_llvm_tool(llvm-config
+ llvm-config.cpp
+ )
-install(FILES ${LLVM_CONFIG}
- PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE
- WORLD_READ WORLD_EXECUTE
- DESTINATION bin)
+# Add the dependency on the generation step.
+add_file_dependencies(${CMAKE_CURRENT_SOURCE_DIR}/llvm-config.cpp ${BUILDVARIABLES_OBJPATH})
diff --git a/tools/llvm-config/Makefile b/tools/llvm-config/Makefile
index c7f7b32..3f11730 100644
--- a/tools/llvm-config/Makefile
+++ b/tools/llvm-config/Makefile
@@ -1,5 +1,5 @@
-##===- tools/llvm-config/Makefile --------------------------*- Makefile -*-===##
-#
+##===- tools/llvm-config/Makefile---------------------------*- Makefile -*-===##
+#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
@@ -7,97 +7,42 @@
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
+LEVEL := ../..
+TOOLNAME := llvm-config
+USEDLIBS := LLVMSupport.a
-EXTRA_DIST = LibDeps.txt FinalLibDeps.txt llvm-config.in.in find-cycles.pl
+# We generate sources in the build directory, make sure it is in the include
+# paths.
+INCLUDE_BUILD_DIR := 1
-include $(LEVEL)/Makefile.common
+# This tool has no plugins, optimize startup time.
+TOOL_NO_EXPORTS := 1
-# If we don't have Perl, we can't generate the library dependencies upon which
-# llvm-config depends. Therefore, only if we detect perl will we do anything
-# useful.
-ifeq ($(HAVE_PERL),1)
+# Note that we have to use lazy expansion here.
+BUILDVARIABLES_SRCPATH = $(PROJ_SRC_ROOT)/tools/$(TOOLNAME)/BuildVariables.inc.in
+BUILDVARIABLES_OBJPATH = $(ObjDir)/BuildVariables.inc
+BUILT_SOURCES = $(BUILDVARIABLES_OBJPATH)
+
+include $(LEVEL)/Makefile.common
# Combine preprocessor flags (except for -I) and CXX flags.
-SUB_CPPFLAGS = ${CPP.BaseFlags}
-SUB_CFLAGS = ${CPP.BaseFlags} ${C.Flags}
-SUB_CXXFLAGS = ${CPP.BaseFlags} ${CXX.Flags}
+SUB_CPPFLAGS := ${CPP.BaseFlags}
+SUB_CFLAGS := ${CPP.BaseFlags} ${C.Flags}
+SUB_CXXFLAGS := ${CPP.BaseFlags} ${CXX.Flags}
# This is blank for now. We need to be careful about adding stuff here:
# LDFLAGS tend not to be portable, and we don't currently require the
# user to use libtool when linking against LLVM.
-SUB_LDFLAGS =
-
-FinalLibDeps = $(PROJ_OBJ_DIR)/FinalLibDeps.txt
-LibDeps = $(PROJ_OBJ_DIR)/LibDeps.txt
-LibDepsTemp = $(PROJ_OBJ_DIR)/LibDeps.txt.tmp
-GenLibDeps = $(PROJ_SRC_ROOT)/utils/GenLibDeps.pl
-
-$(LibDepsTemp): $(GenLibDeps) $(LibDir) $(wildcard $(LibDir)/*.a $(LibDir)/*.o)
- $(Echo) "Regenerating LibDeps.txt.tmp"
- $(Verb) $(PERL) $(GenLibDeps) -flat $(LibDir) "$(NM_PATH)" > $(LibDepsTemp)
-
-$(LibDeps): $(LibDepsTemp)
- $(Verb) $(CMP) -s $@ $< || ( $(CP) $< $@ && \
- $(EchoCmd) Updated LibDeps.txt because dependencies changed )
-
-# Find all the cyclic dependencies between various LLVM libraries, so we
-# don't have to process them at runtime.
-$(FinalLibDeps): find-cycles.pl $(LibDeps)
- $(Echo) "Checking for cyclic dependencies between LLVM libraries."
- $(Verb) $(PERL) $< < $(LibDeps) > $@ || rm -f $@
-
-# Rerun our configure substitutions as needed.
-ConfigInIn = $(PROJ_SRC_DIR)/llvm-config.in.in
-llvm-config.in: $(ConfigInIn) $(ConfigStatusScript)
- $(Verb) cd $(PROJ_OBJ_ROOT) ; \
- $(ConfigStatusScript) tools/llvm-config/llvm-config.in
-
-llvm-config-perobj: llvm-config.in $(GenLibDeps) $(LibDir) $(wildcard $(LibDir)/*.a)
- $(Echo) "Generating llvm-config-perobj"
- $(Verb) $(PERL) $(GenLibDeps) -perobj -flat $(LibDir) "$(NM_PATH)" >PerobjDeps.txt
- $(Echo) "Checking for cyclic dependencies between LLVM objects."
- $(Verb) $(PERL) $(PROJ_SRC_DIR)/find-cycles.pl < PerobjDepsIncl.txt > PerobjDepsInclFinal.txt || rm -f $@
- $(Verb) $(ECHO) 's/@LLVM_CPPFLAGS@/$(subst /,\/,$(SUB_CPPFLAGS))/' \
- > temp.sed
- $(Verb) $(ECHO) 's/@LLVM_CFLAGS@/$(subst /,\/,$(SUB_CFLAGS))/' \
- >> temp.sed
- $(Verb) $(ECHO) 's/@LLVM_CXXFLAGS@/$(subst /,\/,$(SUB_CXXFLAGS))/' \
- >> temp.sed
- $(Verb) $(ECHO) 's/@LLVM_LDFLAGS@/$(subst /,\/,$(SUB_LDFLAGS))/' \
- >> temp.sed
- $(Verb) $(ECHO) 's/@LLVM_BUILDMODE@/$(subst /,\/,$(BuildMode))/' \
- >> temp.sed
- $(Verb) $(SED) -f temp.sed < $< > $@
- $(Verb) $(RM) temp.sed
- $(Verb) cat PerobjDepsFinal.txt >> $@
- $(Verb) chmod +x $@
+SUB_LDFLAGS :=
-llvm-config-perobjincl: llvm-config.in $(GenLibDeps) $(LibDir) $(wildcard $(LibDir)/*.a)
- $(Echo) "Generating llvm-config-perobjincl"
- $(Verb) $(PERL) $(GenLibDeps) -perobj -perobjincl -flat $(LibDir) "$(NM_PATH)" >PerobjDepsIncl.txt
- $(Echo) "Checking for cyclic dependencies between LLVM objects."
- $(Verb) $(PERL) $(PROJ_SRC_DIR)/find-cycles.pl < PerobjDepsIncl.txt > PerobjDepsInclFinal.txt
- $(Verb) $(ECHO) 's/@LLVM_CPPFLAGS@/$(subst /,\/,$(SUB_CPPFLAGS))/' \
- > temp.sed
- $(Verb) $(ECHO) 's/@LLVM_CFLAGS@/$(subst /,\/,$(SUB_CFLAGS))/' \
- >> temp.sed
- $(Verb) $(ECHO) 's/@LLVM_CXXFLAGS@/$(subst /,\/,$(SUB_CXXFLAGS))/' \
- >> temp.sed
- $(Verb) $(ECHO) 's/@LLVM_LDFLAGS@/$(subst /,\/,$(SUB_LDFLAGS))/' \
- >> temp.sed
- $(Verb) $(ECHO) 's/@LLVM_BUILDMODE@/$(subst /,\/,$(BuildMode))/' \
- >> temp.sed
- $(Verb) $(SED) -f temp.sed < $< > $@
- $(Verb) $(RM) temp.sed
- $(Verb) cat PerobjDepsInclFinal.txt >> $@
- $(Verb) chmod +x $@
-
-# Build our final script.
-$(ToolDir)/llvm-config: llvm-config.in $(FinalLibDeps)
- $(Echo) "Building llvm-config script."
- $(Verb) $(ECHO) 's/@LLVM_CPPFLAGS@/$(subst /,\/,$(SUB_CPPFLAGS))/' \
+$(ObjDir)/BuildVariables.inc: $(BUILDVARIABLES_SRCPATH) Makefile $(ObjDir)/.dir
+ $(Echo) "Building llvm-config BuildVariables.inc file."
+ $(Verb) $(ECHO) 's/@LLVM_SRC_ROOT@/$(subst /,\/,$(LLVM_SRC_ROOT))/' \
> temp.sed
+ $(Verb) $(ECHO) 's/@LLVM_OBJ_ROOT@/$(subst /,\/,$(LLVM_OBJ_ROOT))/' \
+ >> temp.sed
+ $(Verb) $(ECHO) 's/@LLVM_CPPFLAGS@/$(subst /,\/,$(SUB_CPPFLAGS))/' \
+ >> temp.sed
$(Verb) $(ECHO) 's/@LLVM_CFLAGS@/$(subst /,\/,$(SUB_CFLAGS))/' \
>> temp.sed
$(Verb) $(ECHO) 's/@LLVM_CXXFLAGS@/$(subst /,\/,$(SUB_CXXFLAGS))/' \
@@ -106,26 +51,9 @@ $(ToolDir)/llvm-config: llvm-config.in $(FinalLibDeps)
>> temp.sed
$(Verb) $(ECHO) 's/@LLVM_BUILDMODE@/$(subst /,\/,$(BuildMode))/' \
>> temp.sed
+ $(Verb) $(ECHO) 's/@LLVM_SYSTEM_LIBS@/$(subst /,\/,$(LIBS))/' \
+ >> temp.sed
+ $(Verb) $(ECHO) 's/@LLVM_TARGETS_BUILT@/$(subst /,\/,$(TARGETS_TO_BUILD))/' \
+ >> temp.sed
$(Verb) $(SED) -f temp.sed < $< > $@
$(Verb) $(RM) temp.sed
- $(Verb) cat $(FinalLibDeps) >> $@
- $(Verb) chmod +x $@
-
-else
-# We don't have perl, just generate a dummy llvm-config
-$(ToolDir)/llvm-config:
- $(Echo) "Building place holder llvm-config script."
- $(Verb) $(ECHO) 'echo llvm-config: Perl not found so llvm-config could not be generated' >> $@
- $(Verb) chmod +x $@
-
-endif
-# Hook into the standard Makefile rules.
-all-local:: $(ToolDir)/llvm-config
-clean-local::
- $(Verb) $(RM) -f $(ToolDir)/llvm-config llvm-config.in $(FinalLibDeps) \
- $(LibDeps) GenLibDeps.out
-install-local:: all-local
- $(Echo) Installing llvm-config
- $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_bindir)
- $(Verb) $(ScriptInstall) $(ToolDir)/llvm-config $(DESTDIR)$(PROJ_bindir)
-
diff --git a/tools/llvm-config/find-cycles.pl b/tools/llvm-config/find-cycles.pl
deleted file mode 100755
index 5cbf5b4..0000000
--- a/tools/llvm-config/find-cycles.pl
+++ /dev/null
@@ -1,170 +0,0 @@
-#!/usr/bin/perl
-#
-# Program: find-cycles.pl
-#
-# Synopsis: Given a list of possibly cyclic dependencies, merge all the
-# cycles. This makes it possible to topologically sort the
-# dependencies between different parts of LLVM.
-#
-# Syntax: find-cycles.pl < LibDeps.txt > FinalLibDeps.txt
-#
-# Input: cycmem1: cycmem2 dep1 dep2
-# cycmem2: cycmem1 dep3 dep4
-# boring: dep4
-#
-# Output: cycmem1 cycmem2: dep1 dep2 dep3 dep4
-# boring: dep4
-#
-# This file was written by Eric Kidd, and is placed into the public domain.
-#
-
-use 5.006;
-use strict;
-use warnings;
-
-my %DEPS;
-my @CYCLES;
-sub find_all_cycles;
-
-# Read our dependency information.
-while (<>) {
- chomp;
- my ($module, $dependency_str) = /^\s*([^:]+):\s*(.*)\s*$/;
- die "Malformed data: $_" unless defined $dependency_str;
- my @dependencies = split(/ /, $dependency_str);
- $DEPS{$module} = \@dependencies;
-}
-
-# Partition our raw dependencies into sets of cyclically-connected nodes.
-find_all_cycles();
-
-# Print out the finished cycles, with their dependencies.
-my @output;
-my $cycles_found = 0;
-foreach my $cycle (@CYCLES) {
- my @modules = sort keys %{$cycle};
-
- # Merge the dependencies of all modules in this cycle.
- my %dependencies;
- foreach my $module (@modules) {
- @dependencies{@{$DEPS{$module}}} = 1;
- }
-
- # Prune the known cyclic dependencies.
- foreach my $module (@modules) {
- delete $dependencies{$module};
- }
-
- # Warn about possible linker problems.
- my @archives = grep(/\.a$/, @modules);
- if (@archives > 1) {
- $cycles_found = $cycles_found + 1;
- print STDERR "find-cycles.pl: Circular dependency between *.a files:\n";
- print STDERR "find-cycles.pl: ", join(' ', @archives), "\n";
- push @modules, @archives; # WORKAROUND: Duplicate *.a files. Ick.
- } elsif (@modules > 1) {
- $cycles_found = $cycles_found + 1;
- print STDERR "find-cycles.pl: Circular dependency between *.o files:\n";
- print STDERR "find-cycles.pl: ", join(' ', @modules), "\n";
- push @modules, @modules; # WORKAROUND: Duplicate *.o files. Ick.
- }
-
- # Add to our output. (@modules is already as sorted as we need it to be.)
- push @output, (join(' ', @modules) . ': ' .
- join(' ', sort keys %dependencies) . "\n");
-}
-print sort @output;
-
-exit $cycles_found;
-
-#==========================================================================
-# Depedency Cycle Support
-#==========================================================================
-# For now, we have cycles in our dependency graph. Ideally, each cycle
-# would be collapsed down to a single *.a file, saving us all this work.
-#
-# To understand this code, you'll need a working knowledge of Perl 5,
-# and possibly some quality time with 'man perlref'.
-
-my %SEEN;
-my %CYCLES;
-sub find_cycles ($@);
-sub found_cycles ($@);
-
-sub find_all_cycles {
- # Find all multi-item cycles.
- my @modules = sort keys %DEPS;
- foreach my $module (@modules) { find_cycles($module); }
-
- # Build fake one-item "cycles" for the remaining modules, so we can
- # treat them uniformly.
- foreach my $module (@modules) {
- unless (defined $CYCLES{$module}) {
- my %cycle = ($module, 1);
- $CYCLES{$module} = \%cycle;
- }
- }
-
- # Find all our unique cycles. We have to do this the hard way because
- # we apparently can't store hash references as hash keys without making
- # 'strict refs' sad.
- my %seen;
- foreach my $cycle (values %CYCLES) {
- unless ($seen{$cycle}) {
- $seen{$cycle} = 1;
- push @CYCLES, $cycle;
- }
- }
-}
-
-# Walk through our graph depth-first (keeping a trail in @path), and report
-# any cycles we find.
-sub find_cycles ($@) {
- my ($module, @path) = @_;
- if (str_in_list($module, @path)) {
- found_cycle($module, @path);
- } else {
- return if defined $SEEN{$module};
- $SEEN{$module} = 1;
- foreach my $dep (@{$DEPS{$module}}) {
- find_cycles($dep, @path, $module);
- }
- }
-}
-
-# Give a cycle, attempt to merge it with pre-existing cycle data.
-sub found_cycle ($@) {
- my ($module, @path) = @_;
-
- # Pop any modules which aren't part of our cycle.
- while ($path[0] ne $module) { shift @path; }
- #print join("->", @path, $module) . "\n";
-
- # Collect the modules in our cycle into a hash.
- my %cycle;
- foreach my $item (@path) {
- $cycle{$item} = 1;
- if (defined $CYCLES{$item}) {
- # Looks like we intersect with an existing cycle, so merge
- # all those in, too.
- foreach my $old_item (keys %{$CYCLES{$item}}) {
- $cycle{$old_item} = 1;
- }
- }
- }
-
- # Update our global cycle table.
- my $cycle_ref = \%cycle;
- foreach my $item (keys %cycle) {
- $CYCLES{$item} = $cycle_ref;
- }
- #print join(":", sort keys %cycle) . "\n";
-}
-
-sub str_in_list ($@) {
- my ($str, @list) = @_;
- foreach my $item (@list) {
- return 1 if ($item eq $str);
- }
- return 0;
-}
diff --git a/tools/llvm-config/llvm-config.cpp b/tools/llvm-config/llvm-config.cpp
new file mode 100644
index 0000000..79fd7f8
--- /dev/null
+++ b/tools/llvm-config/llvm-config.cpp
@@ -0,0 +1,342 @@
+//===-- llvm-config.cpp - LLVM project configuration utility --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tool encapsulates information about an LLVM project configuration for
+// use by other project's build environments (to determine installed path,
+// available features, required libraries, etc.).
+//
+// Note that although this tool *may* be used by some parts of LLVM's build
+// itself (i.e., the Makefiles use it to compute required libraries when linking
+// tools), this tool is primarily designed to support external projects.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Config/config.h"
+#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdlib>
+#include <set>
+#include <vector>
+
+using namespace llvm;
+
+// Include the build time variables we can report to the user. This is generated
+// at build time from the BuildVariables.inc.in file by the build system.
+#include "BuildVariables.inc"
+
+// Include the component table. This creates an array of struct
+// AvailableComponent entries, which record the component name, library name,
+// and required components for all of the available libraries.
+//
+// Not all components define a library, we also use "library groups" as a way to
+// create entries for pseudo groups like x86 or all-targets.
+#include "LibraryDependencies.inc"
+
+/// \brief Traverse a single component adding to the topological ordering in
+/// \arg RequiredLibs.
+///
+/// \param Name - The component to traverse.
+/// \param ComponentMap - A prebuilt map of component names to descriptors.
+/// \param VisitedComponents [in] [out] - The set of already visited components.
+/// \param RequiredLibs [out] - The ordered list of required libraries.
+static void VisitComponent(StringRef Name,
+ const StringMap<AvailableComponent*> &ComponentMap,
+ std::set<AvailableComponent*> &VisitedComponents,
+ std::vector<StringRef> &RequiredLibs) {
+ // Lookup the component.
+ AvailableComponent *AC = ComponentMap.lookup(Name);
+ assert(AC && "Invalid component name!");
+
+ // Add to the visited table.
+ if (!VisitedComponents.insert(AC).second) {
+ // We are done if the component has already been visited.
+ return;
+ }
+
+ // Otherwise, visit all the dependencies.
+ for (unsigned i = 0; AC->RequiredLibraries[i]; ++i) {
+ VisitComponent(AC->RequiredLibraries[i], ComponentMap, VisitedComponents,
+ RequiredLibs);
+ }
+
+ // Add to the required library list.
+ if (AC->Library)
+ RequiredLibs.push_back(AC->Library);
+}
+
+/// \brief Compute the list of required libraries for a given list of
+/// components, in an order suitable for passing to a linker (that is, libraries
+/// appear prior to their dependencies).
+///
+/// \param Components - The names of the components to find libraries for.
+/// \param RequiredLibs [out] - On return, the ordered list of libraries that
+/// are required to link the given components.
+void ComputeLibsForComponents(const std::vector<StringRef> &Components,
+ std::vector<StringRef> &RequiredLibs) {
+ std::set<AvailableComponent*> VisitedComponents;
+
+ // Build a map of component names to information.
+ StringMap<AvailableComponent*> ComponentMap;
+ for (unsigned i = 0; i != array_lengthof(AvailableComponents); ++i) {
+ AvailableComponent *AC = &AvailableComponents[i];
+ ComponentMap[AC->Name] = AC;
+ }
+
+ // Visit the components.
+ for (unsigned i = 0, e = Components.size(); i != e; ++i) {
+ // Users are allowed to provide mixed case component names.
+ std::string ComponentLower = Components[i].lower();
+
+ // Validate that the user supplied a valid component name.
+ if (!ComponentMap.count(ComponentLower)) {
+ llvm::errs() << "llvm-config: unknown component name: " << Components[i]
+ << "\n";
+ exit(1);
+ }
+
+ VisitComponent(ComponentLower, ComponentMap, VisitedComponents,
+ RequiredLibs);
+ }
+
+ // The list is now ordered with leafs first, we want the libraries to printed
+ // in the reverse order of dependency.
+ std::reverse(RequiredLibs.begin(), RequiredLibs.end());
+}
+
+/* *** */
+
+void usage() {
+ errs() << "\
+usage: llvm-config <OPTION>... [<COMPONENT>...]\n\
+\n\
+Get various configuration information needed to compile programs which use\n\
+LLVM. Typically called from 'configure' scripts. Examples:\n\
+ llvm-config --cxxflags\n\
+ llvm-config --ldflags\n\
+ llvm-config --libs engine bcreader scalaropts\n\
+\n\
+Options:\n\
+ --version Print LLVM version.\n\
+ --prefix Print the installation prefix.\n\
+ --src-root Print the source root LLVM was built from.\n\
+ --obj-root Print the object root used to build LLVM.\n\
+ --bindir Directory containing LLVM executables.\n\
+ --includedir Directory containing LLVM headers.\n\
+ --libdir Directory containing LLVM libraries.\n\
+ --cppflags C preprocessor flags for files that include LLVM headers.\n\
+ --cflags C compiler flags for files that include LLVM headers.\n\
+ --cxxflags C++ compiler flags for files that include LLVM headers.\n\
+ --ldflags Print Linker flags.\n\
+ --libs Libraries needed to link against LLVM components.\n\
+ --libnames Bare library names for in-tree builds.\n\
+ --libfiles Fully qualified library filenames for makefile depends.\n\
+ --components List of all possible components.\n\
+ --targets-built List of all targets currently built.\n\
+ --host-target Target triple used to configure LLVM.\n\
+ --build-mode Print build mode of LLVM tree (e.g. Debug or Release).\n\
+Typical components:\n\
+ all All LLVM libraries (default).\n\
+ engine Either a native JIT or a bitcode interpreter.\n";
+ exit(1);
+}
+
+/// \brief Compute the path to the main executable.
+llvm::sys::Path GetExecutablePath(const char *Argv0) {
+ // This just needs to be some symbol in the binary; C++ doesn't
+ // allow taking the address of ::main however.
+ void *P = (void*) (intptr_t) GetExecutablePath;
+ return llvm::sys::Path::GetMainExecutable(Argv0, P);
+}
+
+int main(int argc, char **argv) {
+ std::vector<StringRef> Components;
+ bool PrintLibs = false, PrintLibNames = false, PrintLibFiles = false;
+ bool HasAnyOption = false;
+
+ // llvm-config is designed to support being run both from a development tree
+ // 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;
+ enum { MakefileStyle, CMakeStyle, CMakeBuildModeStyle } DevelopmentTreeLayout;
+ llvm::SmallString<256> CurrentPath(GetExecutablePath(argv[0]).str());
+ std::string CurrentExecPrefix;
+ std::string ActiveObjRoot;
+
+ // Create an absolute path, and pop up one directory (we expect to be inside a
+ // bin dir).
+ sys::fs::make_absolute(CurrentPath);
+ CurrentExecPrefix = sys::path::parent_path(
+ 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) {
+ IsInDevelopmentTree = true;
+ 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
+ // always want to provide information for the host triple.
+ if (sys::path::filename(LLVM_OBJ_ROOT) == "BuildTools") {
+ ActiveObjRoot = sys::path::parent_path(LLVM_OBJ_ROOT);
+ } 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;
+ DevelopmentTreeLayout = CMakeBuildModeStyle;
+ ActiveObjRoot = LLVM_OBJ_ROOT;
+ } else {
+ IsInDevelopmentTree = false;
+ DevelopmentTreeLayout = MakefileStyle; // Initialized to avoid warnings.
+ }
+
+ // Compute various directory locations based on the derived location
+ // information.
+ std::string ActivePrefix, ActiveBinDir, ActiveIncludeDir, ActiveLibDir;
+ std::string ActiveIncludeOption;
+ if (IsInDevelopmentTree) {
+ ActiveIncludeDir = std::string(LLVM_SRC_ROOT) + "/include";
+ ActivePrefix = CurrentExecPrefix;
+
+ // CMake organizes the products differently than a normal prefix style
+ // layout.
+ 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.
+ ActiveIncludeOption = ("-I" + ActiveIncludeDir + " " +
+ "-I" + ActiveObjRoot + "/include");
+ } else {
+ ActivePrefix = CurrentExecPrefix;
+ ActiveIncludeDir = ActivePrefix + "/include";
+ ActiveBinDir = ActivePrefix + "/bin";
+ ActiveLibDir = ActivePrefix + "/lib";
+ ActiveIncludeOption = "-I" + ActiveIncludeDir;
+ }
+
+ raw_ostream &OS = outs();
+ for (int i = 1; i != argc; ++i) {
+ StringRef Arg = argv[i];
+
+ if (Arg.startswith("-")) {
+ HasAnyOption = true;
+ if (Arg == "--version") {
+ OS << PACKAGE_VERSION << '\n';
+ } else if (Arg == "--prefix") {
+ OS << ActivePrefix << '\n';
+ } else if (Arg == "--bindir") {
+ OS << ActiveBinDir << '\n';
+ } else if (Arg == "--includedir") {
+ OS << ActiveIncludeDir << '\n';
+ } else if (Arg == "--libdir") {
+ OS << ActiveLibDir << '\n';
+ } else if (Arg == "--cppflags") {
+ OS << ActiveIncludeOption << ' ' << LLVM_CPPFLAGS << '\n';
+ } else if (Arg == "--cflags") {
+ OS << ActiveIncludeOption << ' ' << LLVM_CFLAGS << '\n';
+ } else if (Arg == "--cxxflags") {
+ OS << ActiveIncludeOption << ' ' << LLVM_CXXFLAGS << '\n';
+ } else if (Arg == "--ldflags") {
+ OS << "-L" << ActiveLibDir << ' ' << LLVM_LDFLAGS
+ << ' ' << LLVM_SYSTEM_LIBS << '\n';
+ } else if (Arg == "--libs") {
+ PrintLibs = true;
+ } else if (Arg == "--libnames") {
+ PrintLibNames = true;
+ } else if (Arg == "--libfiles") {
+ PrintLibFiles = true;
+ } else if (Arg == "--components") {
+ for (unsigned j = 0; j != array_lengthof(AvailableComponents); ++j) {
+ OS << ' ';
+ OS << AvailableComponents[j].Name;
+ }
+ OS << '\n';
+ } else if (Arg == "--targets-built") {
+ OS << LLVM_TARGETS_BUILT << '\n';
+ } else if (Arg == "--host-target") {
+ OS << LLVM_DEFAULT_TARGET_TRIPLE << '\n';
+ } else if (Arg == "--build-mode") {
+ OS << LLVM_BUILDMODE << '\n';
+ } else if (Arg == "--obj-root") {
+ OS << LLVM_OBJ_ROOT << '\n';
+ } else if (Arg == "--src-root") {
+ OS << LLVM_SRC_ROOT << '\n';
+ } else {
+ usage();
+ }
+ } else {
+ Components.push_back(Arg);
+ }
+ }
+
+ if (!HasAnyOption)
+ usage();
+
+ if (PrintLibs || PrintLibNames || PrintLibFiles) {
+ // If no components were specified, default to "all".
+ if (Components.empty())
+ Components.push_back("all");
+
+ // Construct the list of all the required libraries.
+ std::vector<StringRef> RequiredLibs;
+ ComputeLibsForComponents(Components, RequiredLibs);
+
+ for (unsigned i = 0, e = RequiredLibs.size(); i != e; ++i) {
+ StringRef Lib = RequiredLibs[i];
+ if (i)
+ OS << ' ';
+
+ if (PrintLibNames) {
+ OS << Lib;
+ } else if (PrintLibFiles) {
+ OS << ActiveLibDir << '/' << Lib;
+ } else if (PrintLibs) {
+ // If this is a typical library name, include it using -l.
+ if (Lib.startswith("lib") && Lib.endswith(".a")) {
+ OS << "-l" << Lib.slice(3, Lib.size()-2);
+ continue;
+ }
+
+ // Otherwise, print the full path.
+ OS << ActiveLibDir << '/' << Lib;
+ }
+ }
+ OS << '\n';
+ } else if (!Components.empty()) {
+ errs() << "llvm-config: error: components given, but unused\n\n";
+ usage();
+ }
+
+ return 0;
+}
diff --git a/tools/llvm-config/llvm-config.in.in b/tools/llvm-config/llvm-config.in.in
deleted file mode 100644
index 840a10e..0000000
--- a/tools/llvm-config/llvm-config.in.in
+++ /dev/null
@@ -1,463 +0,0 @@
-#!@PERL@
-##===- tools/llvm-config ---------------------------------------*- perl -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# Synopsis: Prints out compiler options needed to build against an installed
-# copy of LLVM.
-#
-# Syntax: llvm-config OPTIONS... [COMPONENTS...]
-#
-##===----------------------------------------------------------------------===##
-
-use 5.006;
-use strict;
-use warnings;
-use Cwd 'abs_path';
-
-#---- begin autoconf values ----
-my $PACKAGE_NAME = q{@PACKAGE_NAME@};
-my $VERSION = q{@PACKAGE_VERSION@};
-my $PREFIX = q{@LLVM_PREFIX@};
-my $LLVM_CONFIGTIME = q{@LLVM_CONFIGTIME@};
-my $LLVM_SRC_ROOT = q{@abs_top_srcdir@};
-my $LLVM_OBJ_ROOT = q{@abs_top_builddir@};
-my $ARCH = lc(q{@ARCH@});
-my $TARGET_TRIPLE = q{@target@};
-my $TARGETS_TO_BUILD = q{@TARGETS_TO_BUILD@};
-my $TARGET_HAS_JIT = q{@TARGET_HAS_JIT@};
-my @TARGETS_BUILT = map { lc($_) } qw{@TARGETS_TO_BUILD@};
-#---- end autoconf values ----
-
-# Must pretend x86_64 architecture is really x86, otherwise the native backend
-# won't get linked in.
-$ARCH = "x86" if $ARCH eq "x86_64";
-
-#---- begin Makefile values ----
-my $CPPFLAGS = q{@LLVM_CPPFLAGS@};
-my $CFLAGS = q{@LLVM_CFLAGS@};
-my $CXXFLAGS = q{@LLVM_CXXFLAGS@};
-my $LDFLAGS = q{@LLVM_LDFLAGS@};
-my $SYSTEM_LIBS = q{@LIBS@};
-my $LLVM_BUILDMODE = q{@LLVM_BUILDMODE@};
-#---- end Makefile values ----
-
-# Figure out where llvm-config is being run from. Primarily, we care if it has
-# been installed, or is running from the build directory, which changes the
-# locations of some files.
-
-# Convert the current executable name into its directory (e.g. ".").
-my ($RUN_DIR) = ($0 =~ /^(.*)\/.*$/);
-
-# Turn the directory into an absolute directory on the file system, also pop up
-# from "bin" into the build or prefix dir.
-my $ABS_RUN_DIR = abs_path("$RUN_DIR/..");
-chomp($ABS_RUN_DIR);
-
-# Compute the absolute object directory build, e.g. "foo/llvm/Debug".
-my $ABS_OBJ_ROOT = "$LLVM_OBJ_ROOT/$LLVM_BUILDMODE";
-$ABS_OBJ_ROOT = abs_path("$ABS_OBJ_ROOT") if (-d $ABS_OBJ_ROOT);
-chomp($ABS_OBJ_ROOT);
-
-my $INCLUDEDIR = "$ABS_RUN_DIR/include";
-my $INCLUDEOPTION = "-I$INCLUDEDIR";
-my $LIBDIR = "$ABS_RUN_DIR/lib";
-my $BINDIR = "$ABS_RUN_DIR/bin";
-if ($ABS_RUN_DIR eq $ABS_OBJ_ROOT) {
- # If we are running out of the build directory, the include dir is in the
- # srcdir.
- $INCLUDEDIR = "$LLVM_SRC_ROOT/include";
- # We need include files from both the srcdir and objdir.
- $INCLUDEOPTION = "-I$INCLUDEDIR -I$LLVM_OBJ_ROOT/include"
-} else {
- # If installed, ignore the prefix the tree was configured with, use the
- # current prefix.
- $PREFIX = $ABS_RUN_DIR;
-}
-
-sub usage;
-sub fix_library_names (@);
-sub fix_library_files (@);
-sub expand_dependencies (@);
-sub name_map_entries;
-
-# Parse our command-line arguments.
-usage if @ARGV == 0;
-my @components;
-my $has_opt = 0;
-my $want_libs = 0;
-my $want_libnames = 0;
-my $want_libfiles = 0;
-my $want_components = 0;
-foreach my $arg (@ARGV) {
- if ($arg =~ /^-/) {
- if ($arg eq "--version") {
- $has_opt = 1; print "$VERSION\n";
- } elsif ($arg eq "--prefix") {
- $has_opt = 1; print "$PREFIX\n";
- } elsif ($arg eq "--bindir") {
- $has_opt = 1; print "$BINDIR\n";
- } elsif ($arg eq "--includedir") {
- $has_opt = 1; print "$INCLUDEDIR\n";
- } elsif ($arg eq "--libdir") {
- $has_opt = 1; print "$LIBDIR\n";
- } elsif ($arg eq "--cppflags") {
- $has_opt = 1; print "$INCLUDEOPTION $CPPFLAGS\n";
- } elsif ($arg eq "--cflags") {
- $has_opt = 1; print "$INCLUDEOPTION $CFLAGS\n";
- } elsif ($arg eq "--cxxflags") {
- $has_opt = 1; print "$INCLUDEOPTION $CXXFLAGS\n";
- } elsif ($arg eq "--ldflags") {
- $has_opt = 1; print "-L$LIBDIR $LDFLAGS $SYSTEM_LIBS\n";
- } elsif ($arg eq "--libs") {
- $has_opt = 1; $want_libs = 1;
- } elsif ($arg eq "--libnames") {
- $has_opt = 1; $want_libnames = 1;
- } elsif ($arg eq "--libfiles") {
- $has_opt = 1; $want_libfiles = 1;
- } elsif ($arg eq "--components") {
- $has_opt = 1; print join(' ', name_map_entries), "\n";
- } elsif ($arg eq "--targets-built") {
- $has_opt = 1; print join(' ', @TARGETS_BUILT), "\n";
- } elsif ($arg eq "--host-target") {
- $has_opt = 1; print "$TARGET_TRIPLE\n";
- } elsif ($arg eq "--build-mode") {
- $has_opt = 1; print "$LLVM_BUILDMODE\n";
- } elsif ($arg eq "--obj-root") {
- $has_opt = 1; print abs_path("$LLVM_OBJ_ROOT/");
- } elsif ($arg eq "--src-root") {
- $has_opt = 1; print abs_path("$LLVM_SRC_ROOT/");
- } else {
- usage();
- }
- } else {
- push @components, $arg;
- }
-}
-
-# If no options were specified, fail.
-usage unless $has_opt;
-
-# If no components were specified, default to 'all'.
-if (@components == 0) {
- push @components, 'all';
-}
-
-# Force component names to lower case.
-@components = map lc, @components;
-
-# Handle any arguments which require building our dependency graph.
-if ($want_libs || $want_libnames || $want_libfiles) {
- my @libs = expand_dependencies(@components);
- print join(' ', fix_library_names(@libs)), "\n" if ($want_libs);
- print join(' ', @libs), "\n" if ($want_libnames);
- print join(' ', fix_library_files(@libs)), "\n" if ($want_libfiles);
-}
-
-exit 0;
-
-#==========================================================================
-# Support Routines
-#==========================================================================
-
-sub usage {
- print STDERR <<__EOD__;
-Usage: llvm-config <OPTION>... [<COMPONENT>...]
-
-Get various configuration information needed to compile programs which use
-LLVM. Typically called from 'configure' scripts. Examples:
- llvm-config --cxxflags
- llvm-config --ldflags
- llvm-config --libs engine bcreader scalaropts
-
-Options:
- --version Print LLVM version.
- --prefix Print the installation prefix.
- --src-root Print the source root LLVM was built from.
- --obj-root Print the object root used to build LLVM.
- --bindir Directory containing LLVM executables.
- --includedir Directory containing LLVM headers.
- --libdir Directory containing LLVM libraries.
- --cppflags C preprocessor flags for files that include LLVM headers.
- --cflags C compiler flags for files that include LLVM headers.
- --cxxflags C++ compiler flags for files that include LLVM headers.
- --ldflags Print Linker flags.
- --libs Libraries needed to link against LLVM components.
- --libnames Bare library names for in-tree builds.
- --libfiles Fully qualified library filenames for makefile depends.
- --components List of all possible components.
- --targets-built List of all targets currently built.
- --host-target Target triple used to configure LLVM.
- --build-mode Print build mode of LLVM tree (e.g. Debug or Release).
-Typical components:
- all All LLVM libraries (default).
- backend Either a native backend or the C backend.
- engine Either a native JIT or a bitcode interpreter.
-__EOD__
- exit(1);
-}
-
-# Use -lfoo instead of libfoo.a whenever possible, and add directories to
-# files which can't be found using -L.
-sub fix_library_names (@) {
- my @libs = @_;
- my @result;
- foreach my $lib (@libs) {
- # Transform the bare library name appropriately.
- my ($basename) = ($lib =~ /^lib([^.]*)\.a/);
- if (defined $basename) {
- push @result, "-l$basename";
- } else {
- push @result, "$LIBDIR/$lib";
- }
- }
- return @result;
-}
-
-# Turn the list of libraries into a list of files.
-sub fix_library_files(@) {
- my @libs = @_;
- my @result;
- foreach my $lib (@libs) {
- # Transform the bare library name into a filename.
- push @result, "$LIBDIR/$lib";
- }
- return @result;
-}
-
-#==========================================================================
-# Library Dependency Analysis
-#==========================================================================
-# Given a few human-readable library names, find all their dependencies
-# and sort them into an order which the linker will like. If we packed
-# our libraries into fewer archives, we could make the linker do much
-# of this work for us.
-#
-# Libraries have two different types of names in this code: Human-friendly
-# "component" names entered on the command-line, and the raw file names
-# we use internally (and ultimately pass to the linker).
-#
-# To understand this code, you'll need a working knowledge of Perl 5,
-# and possibly some quality time with 'man perlref'.
-
-sub load_dependencies;
-sub build_name_map;
-sub have_native_backend;
-sub find_best_engine;
-sub expand_names (@);
-sub find_all_required_sets (@);
-sub find_all_required_sets_helper ($$@);
-
-# Each "set" contains one or more libraries which must be included as a
-# group (due to cyclic dependencies). Sets are represented as a Perl array
-# reference pointing to a list of internal library names.
-my @SETS;
-
-# Various mapping tables.
-my %LIB_TO_SET_MAP; # Maps internal library names to their sets.
-my %SET_DEPS; # Maps sets to a list of libraries they depend on.
-my %NAME_MAP; # Maps human-entered names to internal names.
-
-# Have our dependencies been loaded yet?
-my $DEPENDENCIES_LOADED = 0;
-
-# Given a list of human-friendly component names, translate them into a
-# complete set of linker arguments.
-sub expand_dependencies (@) {
- my @libs = @_;
- load_dependencies;
- my @required_sets = find_all_required_sets(expand_names(@libs));
- my @sorted_sets = topologically_sort_sets(@required_sets);
-
- # Expand the library sets into libraries.
- my @result;
- foreach my $set (@sorted_sets) { push @result, @{$set}; }
- return @result;
-}
-
-# Load in the raw dependency data stored at the end of this file.
-sub load_dependencies {
- return if $DEPENDENCIES_LOADED;
- $DEPENDENCIES_LOADED = 1;
- while (<DATA>) {
- # Parse our line.
- my ($libs, $deps) = /^\s*([^:]+):\s*(.*)\s*$/;
- die "Malformed dependency data" unless defined $deps;
- my @libs = split(' ', $libs);
- my @deps = split(' ', $deps);
-
- # Record our dependency data.
- my $set = \@libs;
- push @SETS, $set;
- foreach my $lib (@libs) { $LIB_TO_SET_MAP{$lib} = $set; }
- $SET_DEPS{$set} = \@deps;
- }
- build_name_map;
-}
-
-# Build a map converting human-friendly component names into internal
-# library names.
-sub build_name_map {
- # Add entries for all the actual libraries.
- foreach my $set (@SETS) {
- foreach my $lib (sort @$set) {
- my $short_name = $lib;
- $short_name =~ s/^(lib)?LLVM([^.]*)\..*$/$2/;
- $short_name =~ tr/A-Z/a-z/;
- $NAME_MAP{$short_name} = [$lib];
- }
- }
-
- # Add target-specific entries
- foreach my $target (@TARGETS_BUILT) {
- # FIXME: Temporary, until we don't switch all targets
- if (defined $NAME_MAP{$target.'asmprinter'}) {
- $NAME_MAP{$target} = [$target.'info',
- $target.'asmprinter',
- $target.'codegen']
- } elsif (defined $NAME_MAP{$target.'codegen'}) {
- $NAME_MAP{$target} = [$target.'info',
- $target.'codegen']
- } else {
- $NAME_MAP{$target} = [$target.'info',
- $NAME_MAP{$target}[0]]
- }
-
- if (defined $NAME_MAP{$target.'asmparser'}) {
- push @{$NAME_MAP{$target}},$target.'asmparser'
- }
-
- if (defined $NAME_MAP{$target.'disassembler'}) {
- push @{$NAME_MAP{$target}},$target.'disassembler'
- }
- }
-
- # Add virtual entries.
- $NAME_MAP{'native'} = have_native_backend() ? [$ARCH] : [];
- $NAME_MAP{'nativecodegen'} = have_native_backend() ? [$ARCH.'codegen'] : [];
- $NAME_MAP{'backend'} = have_native_backend() ? ['native'] : ['cbackend'];
- $NAME_MAP{'engine'} = find_best_engine;
- $NAME_MAP{'all'} = [name_map_entries]; # Must be last.
-}
-
-# Return true if we have a native backend to use.
-sub have_native_backend {
- my %BUILT;
- foreach my $target (@TARGETS_BUILT) { $BUILT{$target} = 1; }
- return defined $NAME_MAP{$ARCH} && defined $BUILT{$ARCH};
-}
-
-# Find a working subclass of ExecutionEngine for this platform.
-sub find_best_engine {
- if (have_native_backend && $TARGET_HAS_JIT) {
- return ['jit', 'native'];
- } else {
- return ['interpreter'];
- }
-}
-
-# Get all the human-friendly component names.
-sub name_map_entries {
- load_dependencies;
- return sort keys %NAME_MAP;
-}
-
-# Map human-readable names to internal library names.
-sub expand_names (@) {
- my @names = @_;
- my @result;
- foreach my $name (@names) {
- if (defined $LIB_TO_SET_MAP{$name}) {
- # We've hit bottom: An actual library name.
- push @result, $name;
- } elsif (defined $NAME_MAP{$name}) {
- # We've found a short name to expand.
- push @result, expand_names(@{$NAME_MAP{$name}});
- } else {
- print STDERR "llvm-config: unknown component name: $name\n";
- exit(1);
- }
- }
- return @result;
-}
-
-# Given a list of internal library names, return all sets of libraries which
-# will need to be included by the linker (in no particular order).
-sub find_all_required_sets (@) {
- my @libs = @_;
- my %sets_added;
- my @result;
- find_all_required_sets_helper(\%sets_added, \@result, @libs);
- return @result;
-}
-
-# Recursive closures are pretty broken in Perl, so we're going to separate
-# this function from find_all_required_sets and pass in the state we need
-# manually, as references. Yes, this is fairly unpleasant.
-sub find_all_required_sets_helper ($$@) {
- my ($sets_added, $result, @libs) = @_;
- foreach my $lib (@libs) {
- my $set = $LIB_TO_SET_MAP{$lib};
- next if defined $$sets_added{$set};
- $$sets_added{$set} = 1;
- push @$result, $set;
- find_all_required_sets_helper($sets_added, $result, @{$SET_DEPS{$set}});
- }
-}
-
-# Print a list of sets, with a label. Used for debugging.
-sub print_sets ($@) {
- my ($label, @sets) = @_;
- my @output;
- foreach my $set (@sets) { push @output, join(',', @$set); }
- print "$label: ", join(';', @output), "\n";
-}
-
-# Returns true if $lib is a key in $added.
-sub has_lib_been_added ($$) {
- my ($added, $lib) = @_;
- return defined $$added{$LIB_TO_SET_MAP{$lib}};
-}
-
-# Returns true if all the dependencies of $set appear in $added.
-sub have_all_deps_been_added ($$) {
- my ($added, $set) = @_;
- #print_sets(" Checking", $set);
- #print_sets(" Wants", $SET_DEPS{$set});
- foreach my $lib (@{$SET_DEPS{$set}}) {
- return 0 unless has_lib_been_added($added, $lib);
- }
- return 1;
-}
-
-# Given a list of sets, topologically sort them using dependencies.
-sub topologically_sort_sets (@) {
- my @sets = @_;
- my %added;
- my @result;
- SCAN: while (@sets) { # We'll delete items from @sets as we go.
- #print_sets("So far", reverse(@result));
- #print_sets("Remaining", @sets);
- for (my $i = 0; $i < @sets; ++$i) {
- my $set = $sets[$i];
- if (have_all_deps_been_added(\%added, $set)) {
- push @result, $set;
- $added{$set} = 1;
- #print "Removing $i.\n";
- splice(@sets, $i, 1);
- next SCAN; # Restart our scan.
- }
- }
- die "Can't find a library with no dependencies";
- }
- return reverse(@result);
-}
-
-# Our library dependency data will be added after the '__END__' token, and will
-# be read through the magic <DATA> filehandle.
-__END__
diff --git a/tools/llvm-cov/LLVMBuild.txt b/tools/llvm-cov/LLVMBuild.txt
new file mode 100644
index 0000000..87e00d1
--- /dev/null
+++ b/tools/llvm-cov/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-cov/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-cov
+parent = Tools
+required_libraries = Instrumentation
diff --git a/tools/llvm-cov/Makefile b/tools/llvm-cov/Makefile
index bd9fa2a..2d47ce4 100644
--- a/tools/llvm-cov/Makefile
+++ b/tools/llvm-cov/Makefile
@@ -7,12 +7,11 @@
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-
-TOOLNAME = llvm-cov
+LEVEL := ../..
+TOOLNAME := llvm-cov
LINK_COMPONENTS := instrumentation
# This tool has no plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
+TOOL_NO_EXPORTS := 1
include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-diff/DiffConsumer.cpp b/tools/llvm-diff/DiffConsumer.cpp
index c23e8fb..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();
@@ -64,6 +66,10 @@ void DiffConsumer::printValue(Value *V, bool isL) {
}
return;
}
+ if (isa<Constant>(V)) {
+ out << *V;
+ return;
+ }
unsigned N = contexts.size();
while (N > 0) {
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 b240d8c..a5a99f5 100644
--- a/tools/llvm-diff/DifferenceEngine.cpp
+++ b/tools/llvm-diff/DifferenceEngine.cpp
@@ -319,15 +319,19 @@ 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) {
- ConstantInt *CaseValue = RI->getCaseValue(I);
+
+ for (SwitchInst::CaseIt I = LI->case_begin(), E = LI->case_end();
+ I != E; ++I)
+ LCases[I.getCaseValue()] = I.getCaseSuccessor();
+
+ for (SwitchInst::CaseIt I = RI->case_begin(), E = RI->case_end();
+ I != E; ++I) {
+ ConstantInt *CaseValue = I.getCaseValue();
BasicBlock *LCase = LCases[CaseValue];
if (LCase) {
- if (TryUnify) tryUnify(LCase, RI->getSuccessor(I));
+ if (TryUnify) tryUnify(LCase, I.getCaseSuccessor());
LCases.erase(CaseValue);
- } else if (!Difference) {
+ } else if (Complain || !Difference) {
if (Complain)
Engine.logf("right switch has extra case %r") << CaseValue;
Difference = true;
@@ -628,6 +632,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-diff/LLVMBuild.txt b/tools/llvm-diff/LLVMBuild.txt
new file mode 100644
index 0000000..fa06a03
--- /dev/null
+++ b/tools/llvm-diff/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-diff/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-diff
+parent = Tools
+required_libraries = AsmParser BitReader
diff --git a/tools/llvm-diff/Makefile b/tools/llvm-diff/Makefile
index 58e49fa..f7fa715 100644
--- a/tools/llvm-diff/Makefile
+++ b/tools/llvm-diff/Makefile
@@ -7,11 +7,11 @@
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = llvm-diff
+LEVEL := ../..
+TOOLNAME := llvm-diff
LINK_COMPONENTS := asmparser bitreader
# This tool has no plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
+TOOL_NO_EXPORTS := 1
include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-diff/llvm-diff.cpp b/tools/llvm-diff/llvm-diff.cpp
index 76853f1..774169b 100644
--- a/tools/llvm-diff/llvm-diff.cpp
+++ b/tools/llvm-diff/llvm-diff.cpp
@@ -38,7 +38,7 @@ static Module *ReadModule(LLVMContext &Context, StringRef Name) {
SMDiagnostic Diag;
Module *M = ParseIRFile(Name, Diag, Context);
if (!M)
- Diag.Print("llvmdiff", errs());
+ Diag.print("llvm-diff", errs());
return M;
}
diff --git a/tools/llvm-dis/LLVMBuild.txt b/tools/llvm-dis/LLVMBuild.txt
new file mode 100644
index 0000000..4525010
--- /dev/null
+++ b/tools/llvm-dis/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-dis/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-dis
+parent = Tools
+required_libraries = Analysis BitReader
diff --git a/tools/llvm-dis/Makefile b/tools/llvm-dis/Makefile
index be71100..aeeeed0 100644
--- a/tools/llvm-dis/Makefile
+++ b/tools/llvm-dis/Makefile
@@ -6,12 +6,12 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = llvm-dis
+LEVEL := ../..
+TOOLNAME := llvm-dis
LINK_COMPONENTS := bitreader analysis
# This tool has no plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
+TOOL_NO_EXPORTS := 1
include $(LEVEL)/Makefile.common
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-dwarfdump/LLVMBuild.txt b/tools/llvm-dwarfdump/LLVMBuild.txt
new file mode 100644
index 0000000..28b7c4c
--- /dev/null
+++ b/tools/llvm-dwarfdump/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-dwarfdump/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-dwarfdump
+parent = Tools
+required_libraries = DebugInfo Object
diff --git a/tools/llvm-dwarfdump/Makefile b/tools/llvm-dwarfdump/Makefile
index e61f27d..7ca1a8d 100644
--- a/tools/llvm-dwarfdump/Makefile
+++ b/tools/llvm-dwarfdump/Makefile
@@ -6,12 +6,12 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = llvm-dwarfdump
-LINK_COMPONENTS = DebugInfo Object
+LEVEL := ../..
+TOOLNAME := llvm-dwarfdump
+LINK_COMPONENTS := DebugInfo Object
# This tool has no plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
+TOOL_NO_EXPORTS := 1
include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-extract/LLVMBuild.txt b/tools/llvm-extract/LLVMBuild.txt
new file mode 100644
index 0000000..1b1a4c3
--- /dev/null
+++ b/tools/llvm-extract/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-extract/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-extract
+parent = Tools
+required_libraries = AsmParser BitReader BitWriter IPO
diff --git a/tools/llvm-extract/Makefile b/tools/llvm-extract/Makefile
index 5672aa3..a1e93f5 100644
--- a/tools/llvm-extract/Makefile
+++ b/tools/llvm-extract/Makefile
@@ -7,12 +7,11 @@
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-
-TOOLNAME = llvm-extract
+LEVEL := ../..
+TOOLNAME := llvm-extract
LINK_COMPONENTS := ipo bitreader bitwriter asmparser
# This tool has no plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
+TOOL_NO_EXPORTS := 1
include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-extract/llvm-extract.cpp b/tools/llvm-extract/llvm-extract.cpp
index f6227ee..2ed11c5 100644
--- a/tools/llvm-extract/llvm-extract.cpp
+++ b/tools/llvm-extract/llvm-extract.cpp
@@ -90,7 +90,7 @@ int main(int argc, char **argv) {
M.reset(getLazyIRFileModule(InputFilename, Err, Context));
if (M.get() == 0) {
- Err.Print(argv[0], errs());
+ Err.print(argv[0], errs());
return 1;
}
@@ -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/LLVMBuild.txt b/tools/llvm-ld/LLVMBuild.txt
new file mode 100644
index 0000000..eed0452
--- /dev/null
+++ b/tools/llvm-ld/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./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
index 1ef9bf1..8793ca9 100644
--- a/tools/llvm-ld/Makefile
+++ b/tools/llvm-ld/Makefile
@@ -7,9 +7,8 @@
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-
-TOOLNAME = llvm-ld
-LINK_COMPONENTS = ipo scalaropts linker archive bitwriter
+LEVEL := ../..
+TOOLNAME := llvm-ld
+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-link/LLVMBuild.txt b/tools/llvm-link/LLVMBuild.txt
new file mode 100644
index 0000000..6399ded
--- /dev/null
+++ b/tools/llvm-link/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-link/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-link
+parent = Tools
+required_libraries = AsmParser BitReader BitWriter Linker
diff --git a/tools/llvm-link/Makefile b/tools/llvm-link/Makefile
index 2637018..2553db0 100644
--- a/tools/llvm-link/Makefile
+++ b/tools/llvm-link/Makefile
@@ -6,12 +6,12 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = llvm-link
-LINK_COMPONENTS = linker bitreader bitwriter asmparser
+LEVEL := ../..
+TOOLNAME := llvm-link
+LINK_COMPONENTS := linker bitreader bitwriter asmparser
# This tool has no plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
+TOOL_NO_EXPORTS := 1
include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp
index 95ad1ca..378a833 100644
--- a/tools/llvm-link/llvm-link.cpp
+++ b/tools/llvm-link/llvm-link.cpp
@@ -69,7 +69,7 @@ static inline std::auto_ptr<Module> LoadFile(const char *argv0,
Result = ParseIRFile(FNStr, Err, Context);
if (Result) return std::auto_ptr<Module>(Result); // Load successful!
- Err.Print(argv0, errs());
+ Err.print(argv0, errs());
return std::auto_ptr<Module>();
}
diff --git a/tools/llvm-mc/Disassembler.cpp b/tools/llvm-mc/Disassembler.cpp
index a9381b5..a8cd7c1 100644
--- a/tools/llvm-mc/Disassembler.cpp
+++ b/tools/llvm-mc/Disassembler.cpp
@@ -21,6 +21,8 @@
#include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/Triple.h"
@@ -72,14 +74,16 @@ static bool PrintInsts(const MCDisassembler &DisAsm,
switch (S) {
case MCDisassembler::Fail:
SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second),
- "invalid instruction encoding", "warning");
+ SourceMgr::DK_Warning,
+ "invalid instruction encoding");
if (Size == 0)
Size = 1; // skip illegible bytes
break;
case MCDisassembler::SoftFail:
SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second),
- "potentially undefined instruction encoding", "warning");
+ SourceMgr::DK_Warning,
+ "potentially undefined instruction encoding");
// Fall through
case MCDisassembler::Success:
@@ -125,8 +129,8 @@ static bool ByteArrayFromString(ByteArrayTy &ByteArray,
unsigned ByteVal;
if (Value.getAsInteger(0, ByteVal) || ByteVal > 255) {
// If we have an error, print it and skip to the end of line.
- SM.PrintMessage(SMLoc::getFromPointer(Value.data()),
- "invalid input token", "error");
+ SM.PrintMessage(SMLoc::getFromPointer(Value.data()), SourceMgr::DK_Error,
+ "invalid input token");
Str = Str.substr(Str.find('\n'));
ByteArray.clear();
continue;
@@ -153,21 +157,34 @@ int Disassembler::disassemble(const Target &T,
return -1;
}
- OwningPtr<const MCSubtargetInfo> STI(T.createMCSubtargetInfo(Triple, Cpu, FeaturesStr));
+ OwningPtr<const MCSubtargetInfo> STI(T.createMCSubtargetInfo(Triple, Cpu,
+ FeaturesStr));
if (!STI) {
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;
+ }
+
+ OwningPtr<const MCInstrInfo> MII(T.createMCInstrInfo());
+ if (!MII) {
+ errs() << "error: no instruction info for target " << Triple << "\n";
+ return -1;
+ }
+
int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
- OwningPtr<MCInstPrinter> IP(T.createMCInstPrinter(AsmPrinterVariant,
- *AsmInfo, *STI));
+ OwningPtr<MCInstPrinter> IP(T.createMCInstPrinter(AsmPrinterVariant, *AsmInfo,
+ *MII, *MRI, *STI));
if (!IP) {
errs() << "error: no instruction printer for target " << Triple << '\n';
return -1;
@@ -247,7 +264,6 @@ int Disassembler::disassembleEnhanced(const std::string &TS,
break;
}
- EDDisassembler::initialize();
OwningPtr<EDDisassembler>
disassembler(EDDisassembler::getDisassembler(TS.c_str(), AS));
@@ -294,7 +310,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;
@@ -365,4 +380,3 @@ int Disassembler::disassembleEnhanced(const std::string &TS,
return 0;
}
-
diff --git a/tools/llvm-mc/LLVMBuild.txt b/tools/llvm-mc/LLVMBuild.txt
new file mode 100644
index 0000000..dff5358
--- /dev/null
+++ b/tools/llvm-mc/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-mc/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-mc
+parent = Tools
+required_libraries = MC MCDisassembler MCParser Support all-targets
diff --git a/tools/llvm-mc/Makefile b/tools/llvm-mc/Makefile
index 934a6e4..b147fad 100644
--- a/tools/llvm-mc/Makefile
+++ b/tools/llvm-mc/Makefile
@@ -7,18 +7,11 @@
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = llvm-mc
+LEVEL := ../..
+TOOLNAME := llvm-mc
+LINK_COMPONENTS := all-targets MCDisassembler MCParser MC support
# This tool has no plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
-
-# Include this here so we can get the configuration of the targets
-# that have been configured for construction. We have to do this
-# early so we can set up LINK_COMPONENTS before including Makefile.rules
-include $(LEVEL)/Makefile.config
-
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) MCDisassembler MCParser MC support
-
-include $(LLVM_SRC_ROOT)/Makefile.rules
+TOOL_NO_EXPORTS := 1
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp
index 5fb3fdf..d882e01 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,
@@ -152,6 +149,10 @@ NoInitialTextSection("n", cl::desc("Don't assume assembly file starts "
static cl::opt<bool>
SaveTempLabels("L", cl::desc("Don't discard temporary labels"));
+static cl::opt<bool>
+GenDwarfForAssembly("g", cl::desc("Generate dwarf debugging info for assembly "
+ "source files"));
+
enum ActionType {
AC_AsLex,
AC_Assemble,
@@ -175,7 +176,7 @@ Action(cl::desc("Action to perform:"),
static const Target *GetTarget(const char *ProgName) {
// Figure out the target triple.
if (TripleName.empty())
- TripleName = sys::getHostTriple();
+ TripleName = sys::getDefaultTargetTriple();
Triple TheTriple(Triple::normalize(TripleName));
const Target *TheTarget = 0;
@@ -230,6 +231,17 @@ static tool_output_file *GetOutputStream() {
return Out;
}
+static std::string DwarfDebugFlags;
+static void setDwarfDebugFlags(int argc, char **argv) {
+ if (!getenv("RC_DEBUG_OPTIONS"))
+ return;
+ for (int i = 0; i < argc; i++) {
+ DwarfDebugFlags += argv[i];
+ if (i + 1 < argc)
+ DwarfDebugFlags += " ";
+ }
+}
+
static int AsLexInput(const char *ProgName) {
OwningPtr<MemoryBuffer> BufferPtr;
if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) {
@@ -267,7 +279,8 @@ static int AsLexInput(const char *ProgName) {
switch (Tok.getKind()) {
default:
- SrcMgr.PrintMessage(Lexer.getLoc(), "unknown token", "warning");
+ SrcMgr.PrintMessage(Lexer.getLoc(), SourceMgr::DK_Warning,
+ "unknown token");
Error = true;
break;
case AsmToken::Error:
@@ -370,12 +383,16 @@ 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)
Ctx.setAllowTemporaryLabels(false);
+ Ctx.setGenDwarfForAssembly(GenDwarfForAssembly);
+ if (!DwarfDebugFlags.empty())
+ Ctx.setDwarfDebugFlags(StringRef(DwarfDebugFlags));
+
// Package up features to be passed to target/subtarget
std::string FeaturesStr;
if (MAttrs.size()) {
@@ -399,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, *MCII, *MRI, *STI);
MCCodeEmitter *CE = 0;
MCAsmBackend *MAB = 0;
if (ShowEncoding) {
@@ -408,8 +425,10 @@ static int AssembleInput(const char *ProgName) {
}
Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/true,
/*useLoc*/ true,
- /*useCFI*/ true, IP, CE, MAB,
- ShowInst));
+ /*useCFI*/ true,
+ /*useDwarfDirectory*/ true,
+ IP, CE, MAB, ShowInst));
+
} else if (FileType == OFT_Null) {
Str.reset(createNullStreamer(Ctx));
} else {
@@ -421,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));
@@ -497,11 +512,14 @@ 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 machine code playground\n");
TripleName = Triple::normalize(TripleName);
+ setDwarfDebugFlags(argc, argv);
switch (Action) {
- default:
case AC_AsLex:
return AsLexInput(argv[0]);
case AC_Assemble:
@@ -511,7 +529,4 @@ int main(int argc, char **argv) {
case AC_EDisassemble:
return DisassembleInput(argv[0], true);
}
-
- return 0;
}
-
diff --git a/tools/llvm-nm/LLVMBuild.txt b/tools/llvm-nm/LLVMBuild.txt
new file mode 100644
index 0000000..38ecbfd
--- /dev/null
+++ b/tools/llvm-nm/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-nm/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-nm
+parent = Tools
+required_libraries = Archive BitReader Object
diff --git a/tools/llvm-nm/Makefile b/tools/llvm-nm/Makefile
index 6bb4cd4..d9cee98 100644
--- a/tools/llvm-nm/Makefile
+++ b/tools/llvm-nm/Makefile
@@ -6,12 +6,12 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = llvm-nm
-LINK_COMPONENTS = archive bitreader object
+LEVEL := ../..
+TOOLNAME := llvm-nm
+LINK_COMPONENTS := archive bitreader object
# This tool has no plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
+TOOL_NO_EXPORTS := 1
include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp
index e79d72d..8d9e51e 100644
--- a/tools/llvm-nm/llvm-nm.cpp
+++ b/tools/llvm-nm/llvm-nm.cpp
@@ -27,6 +27,7 @@
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Program.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/Format.h"
@@ -60,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"));
@@ -110,6 +117,19 @@ namespace {
std::string ToolName;
}
+
+static void error(Twine message, Twine path = Twine()) {
+ errs() << ToolName << ": " << path << ": " << message << ".\n";
+}
+
+static bool error(error_code ec, Twine path = Twine()) {
+ if (ec) {
+ error(ec.message(), path);
+ return true;
+ }
+ return false;
+}
+
namespace {
struct NMSymbol {
uint64_t Address;
@@ -144,14 +164,6 @@ namespace {
StringRef CurrentFilename;
typedef std::vector<NMSymbol> SymbolListT;
SymbolListT SymbolList;
-
- bool error(error_code ec) {
- if (!ec) return false;
-
- outs() << ToolName << ": error reading file: " << ec.message() << ".\n";
- outs().flush();
- return true;
- }
}
static void SortAndPrintSymbolList() {
@@ -192,9 +204,10 @@ static void SortAndPrintSymbolList() {
strcpy(SymbolSizeStr, " ");
if (i->Address != object::UnknownAddressOrSize)
- format("%08"PRIx64, i->Address).print(SymbolAddrStr, sizeof(SymbolAddrStr));
+ format("%08" PRIx64, i->Address).print(SymbolAddrStr,
+ sizeof(SymbolAddrStr));
if (i->Size != object::UnknownAddressOrSize)
- format("%08"PRIx64, i->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr));
+ format("%08" PRIx64, i->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr));
if (OutputFormat == posix) {
outs() << i->Name << " " << i->TypeChar << " "
@@ -271,13 +284,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;
@@ -286,7 +303,7 @@ static void DumpSymbolNamesFromObject(ObjectFile *obj) {
if (error(i->getSize(s.Size))) break;
}
if (PrintAddress)
- if (error(i->getOffset(s.Address))) break;
+ if (error(i->getAddress(s.Address))) break;
if (error(i->getNMTypeChar(s.TypeChar))) break;
if (error(i->getName(s.Name))) break;
SymbolList.push_back(s);
@@ -297,38 +314,39 @@ static void DumpSymbolNamesFromObject(ObjectFile *obj) {
}
static void DumpSymbolNamesFromFile(std::string &Filename) {
+ if (Filename != "-" && !sys::fs::exists(Filename)) {
+ errs() << ToolName << ": '" << Filename << "': " << "No such file\n";
+ return;
+ }
+
+ OwningPtr<MemoryBuffer> Buffer;
+ if (error(MemoryBuffer::getFileOrSTDIN(Filename, Buffer), Filename))
+ return;
+
+ sys::fs::file_magic magic = sys::fs::identify_magic(Buffer->getBuffer());
+
LLVMContext &Context = getGlobalContext();
std::string ErrorMessage;
- sys::Path aPath(Filename);
- bool exists;
- if (sys::fs::exists(aPath.str(), exists) || !exists)
- errs() << ToolName << ": '" << Filename << "': " << "No such file\n";
- // Note: Currently we do not support reading an archive from stdin.
- if (Filename == "-" || aPath.isBitcodeFile()) {
- OwningPtr<MemoryBuffer> Buffer;
- if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buffer))
- ErrorMessage = ec.message();
+ if (magic == sys::fs::file_magic::bitcode) {
Module *Result = 0;
- if (Buffer.get())
- Result = ParseBitcodeFile(Buffer.get(), Context, &ErrorMessage);
-
+ Result = ParseBitcodeFile(Buffer.get(), Context, &ErrorMessage);
if (Result) {
DumpSymbolNamesFromModule(Result);
delete Result;
- } else
- errs() << ToolName << ": " << Filename << ": " << ErrorMessage << "\n";
-
- } else if (aPath.isArchive()) {
- OwningPtr<Binary> arch;
- if (error_code ec = object::createBinary(aPath.str(), arch)) {
- errs() << ToolName << ": " << Filename << ": " << ec.message() << ".\n";
+ } else {
+ error(ErrorMessage, Filename);
return;
}
+ } else if (magic == sys::fs::file_magic::archive) {
+ OwningPtr<Binary> arch;
+ if (error(object::createBinary(Buffer.take(), arch), Filename))
+ return;
+
if (object::Archive *a = dyn_cast<object::Archive>(arch.get())) {
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;
@@ -347,12 +365,10 @@ static void DumpSymbolNamesFromFile(std::string &Filename) {
}
}
}
- } else if (aPath.isObjectFile()) {
+ } else if (magic.is_object()) {
OwningPtr<Binary> obj;
- if (error_code ec = object::createBinary(aPath.str(), obj)) {
- errs() << ToolName << ": " << Filename << ": " << ec.message() << ".\n";
+ if (error(object::createBinary(Buffer.take(), obj), Filename))
return;
- }
if (object::ObjectFile *o = dyn_cast<ObjectFile>(obj.get()))
DumpSymbolNamesFromObject(o);
} else {
@@ -370,6 +386,10 @@ int main(int argc, char **argv) {
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n");
+ // llvm-nm only reads binary files.
+ if (error(sys::Program::ChangeStdinToBinary()))
+ return 1;
+
ToolName = argv[0];
if (BSDFormat) OutputFormat = bsd;
if (POSIXFormat) OutputFormat = posix;
diff --git a/tools/llvm-objdump/LLVMBuild.txt b/tools/llvm-objdump/LLVMBuild.txt
new file mode 100644
index 0000000..d16c501
--- /dev/null
+++ b/tools/llvm-objdump/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-objdump/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-objdump
+parent = Tools
+required_libraries = DebugInfo MC MCDisassembler MCParser Object all-targets
diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp
index 3f44b29..0e7f3fd 100644
--- a/tools/llvm-objdump/MachODump.cpp
+++ b/tools/llvm-objdump/MachODump.cpp
@@ -14,7 +14,7 @@
#include "llvm-objdump.h"
#include "MCFunction.h"
#include "llvm/Support/MachO.h"
-#include "llvm/Object/MachOObject.h"
+#include "llvm/Object/MachO.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/STLExtras.h"
@@ -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);
@@ -85,57 +87,43 @@ static const Target *GetTarget(const MachOObject *MachOObj) {
return 0;
}
-struct Section {
- char Name[16];
- uint64_t Address;
- uint64_t Size;
- uint32_t Offset;
- uint32_t NumRelocs;
- uint64_t RelocTableOffset;
-};
-
-struct Symbol {
- uint64_t Value;
- uint32_t StringIndex;
- uint8_t SectionIndex;
- bool operator<(const Symbol &RHS) const { return Value < RHS.Value; }
+struct SymbolSorter {
+ bool operator()(const SymbolRef &A, const SymbolRef &B) {
+ SymbolRef::Type AType, BType;
+ A.getType(AType);
+ B.getType(BType);
+
+ uint64_t AAddr, BAddr;
+ if (AType != SymbolRef::ST_Function)
+ AAddr = 0;
+ else
+ A.getAddress(AAddr);
+ if (BType != SymbolRef::ST_Function)
+ BAddr = 0;
+ else
+ B.getAddress(BAddr);
+ return AAddr < BAddr;
+ }
};
-template <typename T>
-static Section copySection(const T &Sect) {
- Section S;
- memcpy(S.Name, Sect->Name, 16);
- S.Address = Sect->Address;
- S.Size = Sect->Size;
- S.Offset = Sect->Offset;
- S.NumRelocs = Sect->NumRelocationTableEntries;
- S.RelocTableOffset = Sect->RelocationTableOffset;
- return S;
-}
-
-template <typename T>
-static Symbol copySymbol(const T &STE) {
- Symbol S;
- S.StringIndex = STE->StringIndex;
- S.SectionIndex = STE->SectionIndex;
- S.Value = STE->Value;
- return S;
-}
-
// Print additional information about an address, if available.
-static void DumpAddress(uint64_t Address, ArrayRef<Section> Sections,
+static void DumpAddress(uint64_t Address, ArrayRef<SectionRef> Sections,
MachOObject *MachOObj, raw_ostream &OS) {
for (unsigned i = 0; i != Sections.size(); ++i) {
- uint64_t addr = Address-Sections[i].Address;
- if (Sections[i].Address <= Address &&
- Sections[i].Address + Sections[i].Size > Address) {
- StringRef bytes = MachOObj->getData(Sections[i].Offset,
- Sections[i].Size);
+ uint64_t SectAddr = 0, SectSize = 0;
+ Sections[i].getAddress(SectAddr);
+ Sections[i].getSize(SectSize);
+ uint64_t addr = SectAddr;
+ if (SectAddr <= Address &&
+ SectAddr + SectSize > Address) {
+ StringRef bytes, name;
+ Sections[i].getContents(bytes);
+ Sections[i].getName(name);
// Print constant strings.
- if (!strcmp(Sections[i].Name, "__cstring"))
+ if (!name.compare("__cstring"))
OS << '"' << bytes.substr(addr, bytes.find('\0', addr)) << '"';
// Print constant CFStrings.
- if (!strcmp(Sections[i].Name, "__cfstring"))
+ if (!name.compare("__cfstring"))
OS << "@\"" << bytes.substr(addr, bytes.find('\0', addr)) << '"';
}
}
@@ -212,59 +200,34 @@ static void emitDOTFile(const char *FileName, const MCFunction &f,
}
static void getSectionsAndSymbols(const macho::Header &Header,
- MachOObject *MachOObj,
+ MachOObjectFile *MachOObj,
InMemoryStruct<macho::SymtabLoadCommand> *SymtabLC,
- std::vector<Section> &Sections,
- std::vector<Symbol> &Symbols,
+ std::vector<SectionRef> &Sections,
+ std::vector<SymbolRef> &Symbols,
SmallVectorImpl<uint64_t> &FoundFns) {
- // Make a list of all symbols in the object file.
- for (unsigned i = 0; i != Header.NumLoadCommands; ++i) {
- const MachOObject::LoadCommandInfo &LCI = MachOObj->getLoadCommandInfo(i);
- if (LCI.Command.Type == macho::LCT_Segment) {
- InMemoryStruct<macho::SegmentLoadCommand> SegmentLC;
- MachOObj->ReadSegmentLoadCommand(LCI, SegmentLC);
-
- // Store the sections in this segment.
- for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) {
- InMemoryStruct<macho::Section> Sect;
- MachOObj->ReadSection(LCI, SectNum, Sect);
- Sections.push_back(copySection(Sect));
+ error_code ec;
+ for (symbol_iterator SI = MachOObj->begin_symbols(),
+ SE = MachOObj->end_symbols(); SI != SE; SI.increment(ec))
+ Symbols.push_back(*SI);
+
+ for (section_iterator SI = MachOObj->begin_sections(),
+ SE = MachOObj->end_sections(); SI != SE; SI.increment(ec)) {
+ SectionRef SR = *SI;
+ StringRef SectName;
+ SR.getName(SectName);
+ Sections.push_back(*SI);
+ }
- }
- } else if (LCI.Command.Type == macho::LCT_Segment64) {
- InMemoryStruct<macho::Segment64LoadCommand> Segment64LC;
- MachOObj->ReadSegment64LoadCommand(LCI, Segment64LC);
-
- // Store the sections in this segment.
- for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections;
- ++SectNum) {
- InMemoryStruct<macho::Section64> Sect64;
- MachOObj->ReadSection64(LCI, SectNum, Sect64);
- Sections.push_back(copySection(Sect64));
- }
- } else if (LCI.Command.Type == macho::LCT_FunctionStarts) {
+ for (unsigned i = 0; i != Header.NumLoadCommands; ++i) {
+ const MachOObject::LoadCommandInfo &LCI =
+ MachOObj->getObject()->getLoadCommandInfo(i);
+ if (LCI.Command.Type == macho::LCT_FunctionStarts) {
// We found a function starts segment, parse the addresses for later
// consumption.
InMemoryStruct<macho::LinkeditDataLoadCommand> LLC;
- MachOObj->ReadLinkeditDataLoadCommand(LCI, LLC);
+ MachOObj->getObject()->ReadLinkeditDataLoadCommand(LCI, LLC);
- MachOObj->ReadULEB128s(LLC->DataOffset, FoundFns);
- }
- }
- // Store the symbols.
- if (SymtabLC) {
- for (unsigned i = 0; i != (*SymtabLC)->NumSymbolTableEntries; ++i) {
- if (MachOObj->is64Bit()) {
- InMemoryStruct<macho::Symbol64TableEntry> STE;
- MachOObj->ReadSymbol64TableEntry((*SymtabLC)->SymbolTableOffset, i,
- STE);
- Symbols.push_back(copySymbol(STE));
- } else {
- InMemoryStruct<macho::SymbolTableEntry> STE;
- MachOObj->ReadSymbolTableEntry((*SymtabLC)->SymbolTableOffset, i,
- STE);
- Symbols.push_back(copySymbol(STE));
- }
+ MachOObj->getObject()->ReadULEB128s(LLC->DataOffset, FoundFns);
}
}
}
@@ -277,9 +240,11 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
return;
}
- OwningPtr<MachOObject> MachOObj(MachOObject::LoadFromBuffer(Buff.take()));
+ OwningPtr<MachOObjectFile> MachOOF(static_cast<MachOObjectFile*>(
+ ObjectFile::createMachOObjectFile(Buff.take())));
+ MachOObject *MachOObj = MachOOF->getObject();
- const Target *TheTarget = GetTarget(MachOObj.get());
+ const Target *TheTarget = GetTarget(MachOObj);
if (!TheTarget) {
// GetTarget prints out stuff.
return;
@@ -293,9 +258,11 @@ 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));
+ OwningPtr<MCInstPrinter>
+ IP(TheTarget->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *InstrInfo,
+ *MRI, *STI));
if (!InstrAnalysis || !AsmInfo || !STI || !DisAsm || !IP) {
errs() << "error: couldn't initialize disassembler for target "
@@ -322,17 +289,17 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
MachOObj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC);
MachOObj->RegisterStringTable(*SymtabLC);
- std::vector<Section> Sections;
- std::vector<Symbol> Symbols;
+ std::vector<SectionRef> Sections;
+ std::vector<SymbolRef> Symbols;
SmallVector<uint64_t, 8> FoundFns;
- getSectionsAndSymbols(Header, MachOObj.get(), &SymtabLC, Sections, Symbols,
+ getSectionsAndSymbols(Header, MachOOF.get(), &SymtabLC, Sections, Symbols,
FoundFns);
// Make a copy of the unsorted symbol list. FIXME: duplication
- std::vector<Symbol> UnsortedSymbols(Symbols);
+ std::vector<SymbolRef> UnsortedSymbols(Symbols);
// Sort the symbols by address, just in case they didn't come in that way.
- array_pod_sort(Symbols.begin(), Symbols.end());
+ std::sort(Symbols.begin(), Symbols.end(), SymbolSorter());
#ifndef NDEBUG
raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
@@ -343,12 +310,12 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
StringRef DebugAbbrevSection, DebugInfoSection, DebugArangesSection,
DebugLineSection, DebugStrSection;
OwningPtr<DIContext> diContext;
- OwningPtr<MachOObject> DSYMObj;
- MachOObject *DbgInfoObj = MachOObj.get();
+ OwningPtr<MachOObjectFile> DSYMObj;
+ MachOObject *DbgInfoObj = MachOObj;
// Try to find debug info and set up the DIContext for it.
if (UseDbg) {
- ArrayRef<Section> DebugSections = Sections;
- std::vector<Section> DSYMSections;
+ ArrayRef<SectionRef> DebugSections = Sections;
+ std::vector<SectionRef> DSYMSections;
// A separate DSym file path was specified, parse it as a macho file,
// get the sections and supply it to the section name parsing machinery.
@@ -358,34 +325,33 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n';
return;
}
- DSYMObj.reset(MachOObject::LoadFromBuffer(Buf.take()));
- const macho::Header &Header = DSYMObj->getHeader();
+ DSYMObj.reset(static_cast<MachOObjectFile*>(
+ ObjectFile::createMachOObjectFile(Buf.take())));
+ const macho::Header &Header = DSYMObj->getObject()->getHeader();
- std::vector<Symbol> Symbols;
+ std::vector<SymbolRef> Symbols;
SmallVector<uint64_t, 8> FoundFns;
getSectionsAndSymbols(Header, DSYMObj.get(), 0, DSYMSections, Symbols,
FoundFns);
DebugSections = DSYMSections;
- DbgInfoObj = DSYMObj.get();
+ DbgInfoObj = DSYMObj.get()->getObject();
}
// Find the named debug info sections.
for (unsigned SectIdx = 0; SectIdx != DebugSections.size(); SectIdx++) {
- if (!strcmp(DebugSections[SectIdx].Name, "__debug_abbrev"))
- DebugAbbrevSection = DbgInfoObj->getData(DebugSections[SectIdx].Offset,
- DebugSections[SectIdx].Size);
- else if (!strcmp(DebugSections[SectIdx].Name, "__debug_info"))
- DebugInfoSection = DbgInfoObj->getData(DebugSections[SectIdx].Offset,
- DebugSections[SectIdx].Size);
- else if (!strcmp(DebugSections[SectIdx].Name, "__debug_aranges"))
- DebugArangesSection = DbgInfoObj->getData(DebugSections[SectIdx].Offset,
- DebugSections[SectIdx].Size);
- else if (!strcmp(DebugSections[SectIdx].Name, "__debug_line"))
- DebugLineSection = DbgInfoObj->getData(DebugSections[SectIdx].Offset,
- DebugSections[SectIdx].Size);
- else if (!strcmp(DebugSections[SectIdx].Name, "__debug_str"))
- DebugStrSection = DbgInfoObj->getData(DebugSections[SectIdx].Offset,
- DebugSections[SectIdx].Size);
+ StringRef SectName;
+ if (!DebugSections[SectIdx].getName(SectName)) {
+ if (SectName.equals("__DWARF,__debug_abbrev"))
+ DebugSections[SectIdx].getContents(DebugAbbrevSection);
+ else if (SectName.equals("__DWARF,__debug_info"))
+ DebugSections[SectIdx].getContents(DebugInfoSection);
+ else if (SectName.equals("__DWARF,__debug_aranges"))
+ DebugSections[SectIdx].getContents(DebugArangesSection);
+ else if (SectName.equals("__DWARF,__debug_line"))
+ DebugSections[SectIdx].getContents(DebugLineSection);
+ else if (SectName.equals("__DWARF,__debug_str"))
+ DebugSections[SectIdx].getContents(DebugStrSection);
+ }
}
// Setup the DIContext.
@@ -401,68 +367,115 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
FunctionListTy Functions;
for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) {
- if (strcmp(Sections[SectIdx].Name, "__text"))
+ StringRef SectName;
+ if (Sections[SectIdx].getName(SectName) ||
+ SectName.compare("__TEXT,__text"))
continue; // Skip non-text sections
// Insert the functions from the function starts segment into our map.
- uint64_t VMAddr = Sections[SectIdx].Address - Sections[SectIdx].Offset;
- for (unsigned i = 0, e = FoundFns.size(); i != e; ++i)
- FunctionMap.insert(std::make_pair(FoundFns[i]+VMAddr, (MCFunction*)0));
+ uint64_t VMAddr;
+ Sections[SectIdx].getAddress(VMAddr);
+ for (unsigned i = 0, e = FoundFns.size(); i != e; ++i) {
+ StringRef SectBegin;
+ Sections[SectIdx].getContents(SectBegin);
+ uint64_t Offset = (uint64_t)SectBegin.data();
+ FunctionMap.insert(std::make_pair(VMAddr + FoundFns[i]-Offset,
+ (MCFunction*)0));
+ }
- StringRef Bytes = MachOObj->getData(Sections[SectIdx].Offset,
- Sections[SectIdx].Size);
+ StringRef Bytes;
+ Sections[SectIdx].getContents(Bytes);
StringRefMemoryObject memoryObject(Bytes);
bool symbolTableWorked = false;
// Parse relocations.
- std::vector<std::pair<uint64_t, uint32_t> > Relocs;
- for (unsigned j = 0; j != Sections[SectIdx].NumRelocs; ++j) {
- InMemoryStruct<macho::RelocationEntry> RE;
- MachOObj->ReadRelocationEntry(Sections[SectIdx].RelocTableOffset, j, RE);
- Relocs.push_back(std::make_pair(RE->Word0, RE->Word1 & 0xffffff));
+ std::vector<std::pair<uint64_t, SymbolRef> > Relocs;
+ error_code ec;
+ for (relocation_iterator RI = Sections[SectIdx].begin_relocations(),
+ RE = Sections[SectIdx].end_relocations(); RI != RE; RI.increment(ec)) {
+ uint64_t RelocOffset, SectionAddress;
+ RI->getAddress(RelocOffset);
+ Sections[SectIdx].getAddress(SectionAddress);
+ RelocOffset -= SectionAddress;
+
+ SymbolRef RelocSym;
+ RI->getSymbol(RelocSym);
+
+ Relocs.push_back(std::make_pair(RelocOffset, RelocSym));
}
array_pod_sort(Relocs.begin(), Relocs.end());
// Disassemble symbol by symbol.
for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) {
+ StringRef SymName;
+ Symbols[SymIdx].getName(SymName);
+
+ SymbolRef::Type ST;
+ Symbols[SymIdx].getType(ST);
+ if (ST != SymbolRef::ST_Function)
+ continue;
+
// Make sure the symbol is defined in this section.
- if ((unsigned)Symbols[SymIdx].SectionIndex - 1 != SectIdx)
+ bool containsSym = false;
+ Sections[SectIdx].containsSymbol(Symbols[SymIdx], containsSym);
+ if (!containsSym)
continue;
// Start at the address of the symbol relative to the section's address.
- uint64_t Start = Symbols[SymIdx].Value - Sections[SectIdx].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.
- uint64_t End = (SymIdx+1 == Symbols.size() ||
- Symbols[SymIdx].SectionIndex != Symbols[SymIdx+1].SectionIndex) ?
- Sections[SectIdx].Size :
- Symbols[SymIdx+1].Value - Sections[SectIdx].Address;
- uint64_t Size;
+ bool containsNextSym = true;
+ uint64_t NextSym = 0;
+ uint64_t NextSymIdx = SymIdx+1;
+ while (Symbols.size() > NextSymIdx) {
+ SymbolRef::Type NextSymType;
+ Symbols[NextSymIdx].getType(NextSymType);
+ if (NextSymType == SymbolRef::ST_Function) {
+ Sections[SectIdx].containsSymbol(Symbols[NextSymIdx],
+ containsNextSym);
+ Symbols[NextSymIdx].getAddress(NextSym);
+ NextSym -= SectionAddress;
+ break;
+ }
+ ++NextSymIdx;
+ }
- if (Start >= End)
- continue;
+ uint64_t SectSize;
+ Sections[SectIdx].getSize(SectSize);
+ uint64_t End = containsNextSym ? NextSym : SectSize;
+ uint64_t Size;
symbolTableWorked = true;
if (!CFG) {
// Normal disassembly, print addresses, bytes and mnemonic form.
- outs() << MachOObj->getStringAtIndex(Symbols[SymIdx].StringIndex)
- << ":\n";
+ StringRef SymName;
+ Symbols[SymIdx].getName(SymName);
+
+ outs() << SymName << ":\n";
DILineInfo lastLine;
for (uint64_t Index = Start; Index < End; Index += Size) {
MCInst Inst;
if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
DebugOut, nulls())) {
- outs() << format("%8llx:\t", Sections[SectIdx].Address + Index);
+ uint64_t SectAddress = 0;
+ Sections[SectIdx].getAddress(SectAddress);
+ outs() << format("%8" PRIx64 ":\t", SectAddress + Index);
+
DumpBytes(StringRef(Bytes.data() + Index, Size));
IP->printInst(&Inst, outs(), "");
// Print debug info.
if (diContext) {
DILineInfo dli =
- diContext->getLineInfoForAddress(Sections[SectIdx].Address +
- Index);
+ diContext->getLineInfoForAddress(SectAddress + Index);
// Print valid line info if it changed.
if (dli != lastLine && dli.getLine() != 0)
outs() << "\t## " << dli.getFileName() << ':'
@@ -478,20 +491,24 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
}
} else {
// Create CFG and use it for disassembly.
+ StringRef SymName;
+ Symbols[SymIdx].getName(SymName);
createMCFunctionAndSaveCalls(
- MachOObj->getStringAtIndex(Symbols[SymIdx].StringIndex),
- DisAsm.get(), memoryObject, Start, End, InstrAnalysis.get(),
- Start, DebugOut, FunctionMap, Functions);
+ SymName, DisAsm.get(), memoryObject, Start, End,
+ InstrAnalysis.get(), Start, DebugOut, FunctionMap, Functions);
}
}
if (CFG) {
if (!symbolTableWorked) {
// Reading the symbol table didn't work, create a big __TEXT symbol.
+ uint64_t SectSize = 0, SectAddress = 0;
+ Sections[SectIdx].getSize(SectSize);
+ Sections[SectIdx].getAddress(SectAddress);
createMCFunctionAndSaveCalls("__TEXT", DisAsm.get(), memoryObject,
- 0, Sections[SectIdx].Size,
+ 0, SectSize,
InstrAnalysis.get(),
- Sections[SectIdx].Offset, DebugOut,
+ SectAddress, DebugOut,
FunctionMap, Functions);
}
for (std::map<uint64_t, MCFunction*>::iterator mi = FunctionMap.begin(),
@@ -499,11 +516,14 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
if (mi->second == 0) {
// Create functions for the remaining callees we have gathered,
// but we didn't find a name for them.
+ uint64_t SectSize = 0;
+ Sections[SectIdx].getSize(SectSize);
+
SmallVector<uint64_t, 16> Calls;
MCFunction f =
MCFunction::createFunctionFromMC("unknown", DisAsm.get(),
memoryObject, mi->first,
- Sections[SectIdx].Size,
+ SectSize,
InstrAnalysis.get(), DebugOut,
Calls);
Functions.push_back(f);
@@ -535,13 +555,17 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
break;
}
+ uint64_t SectSize = 0, SectAddress;
+ Sections[SectIdx].getSize(SectSize);
+ Sections[SectIdx].getAddress(SectAddress);
+
// No predecessors, this is a data block. Print as .byte directives.
if (!hasPreds) {
- uint64_t End = llvm::next(fi) == fe ? Sections[SectIdx].Size :
+ uint64_t End = llvm::next(fi) == fe ? SectSize :
llvm::next(fi)->first;
outs() << "# " << End-fi->first << " bytes of data:\n";
for (unsigned pos = fi->first; pos != End; ++pos) {
- outs() << format("%8x:\t", Sections[SectIdx].Address + pos);
+ outs() << format("%8x:\t", SectAddress + pos);
DumpBytes(StringRef(Bytes.data() + pos, 1));
outs() << format("\t.byte 0x%02x\n", (uint8_t)Bytes[pos]);
}
@@ -558,13 +582,12 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
const MCDecodedInst &Inst = fi->second.getInsts()[ii];
// If there's a symbol at this address, print its name.
- if (FunctionMap.find(Sections[SectIdx].Address + Inst.Address) !=
+ if (FunctionMap.find(SectAddress + Inst.Address) !=
FunctionMap.end())
- outs() << FunctionMap[Sections[SectIdx].Address + Inst.Address]->
- getName() << ":\n";
+ outs() << FunctionMap[SectAddress + Inst.Address]-> getName()
+ << ":\n";
- outs() << format("%8llx:\t", Sections[SectIdx].Address +
- Inst.Address);
+ outs() << format("%8" PRIx64 ":\t", SectAddress + Inst.Address);
DumpBytes(StringRef(Bytes.data() + Inst.Address, Inst.Size));
if (fi->second.contains(fi->first)) // Indent simple loops.
@@ -575,15 +598,15 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
// Look for relocations inside this instructions, if there is one
// print its target and additional information if available.
for (unsigned j = 0; j != Relocs.size(); ++j)
- if (Relocs[j].first >= Sections[SectIdx].Address + Inst.Address &&
- Relocs[j].first < Sections[SectIdx].Address + Inst.Address +
- Inst.Size) {
- outs() << "\t# "
- << MachOObj->getStringAtIndex(
- UnsortedSymbols[Relocs[j].second].StringIndex)
- << ' ';
- DumpAddress(UnsortedSymbols[Relocs[j].second].Value, Sections,
- MachOObj.get(), outs());
+ if (Relocs[j].first >= SectAddress + Inst.Address &&
+ Relocs[j].first < SectAddress + Inst.Address + Inst.Size) {
+ StringRef SymName;
+ uint64_t Addr;
+ Relocs[j].second.getAddress(Addr);
+ Relocs[j].second.getName(SymName);
+
+ outs() << "\t# " << SymName << ' ';
+ DumpAddress(Addr, Sections, MachOObj, outs());
}
// If this instructions contains an address, see if we can evaluate
@@ -592,13 +615,12 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
Inst.Address,
Inst.Size);
if (targ != -1ULL)
- DumpAddress(targ, Sections, MachOObj.get(), outs());
+ DumpAddress(targ, Sections, MachOObj, outs());
// Print debug info.
if (diContext) {
DILineInfo dli =
- diContext->getLineInfoForAddress(Sections[SectIdx].Address +
- Inst.Address);
+ diContext->getLineInfoForAddress(SectAddress + Inst.Address);
// Print valid line info if it changed.
if (dli != lastLine && dli.getLine() != 0)
outs() << "\t## " << dli.getFileName() << ':'
diff --git a/tools/llvm-objdump/Makefile b/tools/llvm-objdump/Makefile
index 703bf6c..4616b78 100644
--- a/tools/llvm-objdump/Makefile
+++ b/tools/llvm-objdump/Makefile
@@ -6,13 +6,12 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = llvm-objdump
-LINK_COMPONENTS = $(TARGETS_TO_BUILD) DebugInfo MC MCParser MCDisassembler \
- Object
+LEVEL := ../..
+TOOLNAME := llvm-objdump
+LINK_COMPONENTS := all-targets DebugInfo MC MCParser MCDisassembler Object
# This tool has no plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
+TOOL_NO_EXPORTS := 1
include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp
index 40c59bd..5a6f94a 100644
--- a/tools/llvm-objdump/llvm-objdump.cpp
+++ b/tools/llvm-objdump/llvm-objdump.cpp
@@ -16,14 +16,18 @@
#include "llvm-objdump.h"
#include "MCFunction.h"
#include "llvm/Object/Archive.h"
+#include "llvm/Object/COFF.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
@@ -43,6 +47,7 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
#include <algorithm>
+#include <cctype>
#include <cstring>
using namespace llvm;
using namespace object;
@@ -61,6 +66,12 @@ static cl::opt<bool>
Relocations("r", cl::desc("Display the relocation entries in the file"));
static cl::opt<bool>
+SectionContents("s", cl::desc("Display the content of each section"));
+
+static cl::opt<bool>
+SymbolTable("t", cl::desc("Display the symbol table"));
+
+static cl::opt<bool>
MachO("macho", cl::desc("Use MachO specific object file parser"));
static cl::alias
MachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachO));
@@ -118,6 +129,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
@@ -158,10 +171,6 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
return;
}
- outs() << '\n';
- outs() << Obj->getFileName()
- << ":\tfile format " << Obj->getFileFormatName() << "\n\n";
-
error_code ec;
for (section_iterator i = Obj->begin_sections(),
e = Obj->end_sections();
@@ -182,7 +191,9 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
bool contains;
if (!error(i->containsSymbol(*si, contains)) && contains) {
uint64_t Address;
- if (error(si->getOffset(Address))) break;
+ if (error(si->getAddress(Address))) break;
+ Address -= SectionAddr;
+
StringRef Name;
if (error(si->getName(Name))) break;
Symbols.push_back(std::make_pair(Address, Name));
@@ -238,9 +249,21 @@ 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;
+ }
+
+ OwningPtr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
+ if (!MII) {
+ errs() << "error: no instruction info for target " << TripleName << "\n";
+ return;
+ }
+
int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
- AsmPrinterVariant, *AsmInfo, *STI));
+ AsmPrinterVariant, *AsmInfo, *MII, *MRI, *STI));
if (!IP) {
errs() << "error: no instruction printer for target " << TripleName
<< '\n';
@@ -285,7 +308,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
DebugOut, nulls())) {
- outs() << format("%8"PRIx64":\t", SectionAddr + Index);
+ outs() << format("%8" PRIx64 ":\t", SectionAddr + Index);
DumpBytes(StringRef(Bytes.data() + Index, Size));
IP->printInst(&Inst, outs(), "");
outs() << "\n";
@@ -297,17 +320,23 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
// Print relocation for instruction.
while (rel_cur != rel_end) {
+ bool hidden = false;
uint64_t addr;
SmallString<16> name;
SmallString<32> val;
+
+ // If this relocation is hidden, skip it.
+ if (error(rel_cur->getHidden(hidden))) goto skip_print_rel;
+ if (hidden) goto skip_print_rel;
+
if (error(rel_cur->getAddress(addr))) goto skip_print_rel;
// Stop when rel_cur's address is past the current instruction.
- if (addr > Index + Size) break;
+ if (addr >= Index + Size) break;
if (error(rel_cur->getTypeName(name))) goto skip_print_rel;
if (error(rel_cur->getValueString(val))) goto skip_print_rel;
- outs() << format("\t\t\t%8"PRIx64": ", SectionAddr + addr) << name << "\t"
- << val << "\n";
+ outs() << format("\t\t\t%8" PRIx64 ": ", SectionAddr + addr) << name
+ << "\t" << val << "\n";
skip_print_rel:
++rel_cur;
@@ -332,9 +361,12 @@ static void PrintRelocations(const ObjectFile *o) {
ri != re; ri.increment(ec)) {
if (error(ec)) return;
+ bool hidden;
uint64_t address;
SmallString<32> relocname;
SmallString<32> valuestr;
+ if (error(ri->getHidden(hidden))) continue;
+ if (hidden) continue;
if (error(ri->getTypeName(relocname))) continue;
if (error(ri->getAddress(address))) continue;
if (error(ri->getValueString(valuestr))) continue;
@@ -364,19 +396,179 @@ static void PrintSectionHeaders(const ObjectFile *o) {
if (error(si->isBSS(BSS))) return;
std::string Type = (std::string(Text ? "TEXT " : "") +
(Data ? "DATA " : "") + (BSS ? "BSS" : ""));
- outs() << format("%3d %-13s %09"PRIx64" %017"PRIx64" %s\n", i, Name.str().c_str(), Size,
- Address, Type.c_str());
+ outs() << format("%3d %-13s %09" PRIx64 " %017" PRIx64 " %s\n",
+ i, Name.str().c_str(), Size, Address, Type.c_str());
++i;
}
}
+static void PrintSectionContents(const ObjectFile *o) {
+ error_code ec;
+ for (section_iterator si = o->begin_sections(),
+ se = o->end_sections();
+ si != se; si.increment(ec)) {
+ if (error(ec)) return;
+ StringRef Name;
+ StringRef Contents;
+ uint64_t BaseAddr;
+ if (error(si->getName(Name))) continue;
+ if (error(si->getContents(Contents))) continue;
+ if (error(si->getAddress(BaseAddr))) continue;
+
+ outs() << "Contents of section " << Name << ":\n";
+
+ // Dump out the content as hex and printable ascii characters.
+ for (std::size_t addr = 0, end = Contents.size(); addr < end; addr += 16) {
+ outs() << format(" %04" PRIx64 " ", BaseAddr + addr);
+ // Dump line of hex.
+ for (std::size_t i = 0; i < 16; ++i) {
+ if (i != 0 && i % 4 == 0)
+ outs() << ' ';
+ if (addr + i < end)
+ outs() << hexdigit((Contents[addr + i] >> 4) & 0xF, true)
+ << hexdigit(Contents[addr + i] & 0xF, true);
+ else
+ outs() << " ";
+ }
+ // Print ascii.
+ outs() << " ";
+ for (std::size_t i = 0; i < 16 && addr + i < end; ++i) {
+ if (std::isprint(Contents[addr + i] & 0xFF))
+ outs() << Contents[addr + i];
+ else
+ outs() << ".";
+ }
+ outs() << "\n";
+ }
+ }
+}
+
+static void PrintCOFFSymbolTable(const COFFObjectFile *coff) {
+ const coff_file_header *header;
+ if (error(coff->getHeader(header))) return;
+ int aux_count = 0;
+ const coff_symbol *symbol = 0;
+ for (int i = 0, e = header->NumberOfSymbols; i != e; ++i) {
+ if (aux_count--) {
+ // Figure out which type of aux this is.
+ if (symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC
+ && symbol->Value == 0) { // Section definition.
+ const coff_aux_section_definition *asd;
+ if (error(coff->getAuxSymbol<coff_aux_section_definition>(i, asd)))
+ return;
+ outs() << "AUX "
+ << format("scnlen 0x%x nreloc %d nlnno %d checksum 0x%x "
+ , unsigned(asd->Length)
+ , unsigned(asd->NumberOfRelocations)
+ , unsigned(asd->NumberOfLinenumbers)
+ , unsigned(asd->CheckSum))
+ << format("assoc %d comdat %d\n"
+ , unsigned(asd->Number)
+ , unsigned(asd->Selection));
+ } else {
+ outs() << "AUX Unknown\n";
+ }
+ } else {
+ StringRef name;
+ if (error(coff->getSymbol(i, symbol))) return;
+ if (error(coff->getSymbolName(symbol, name))) return;
+ outs() << "[" << format("%2d", i) << "]"
+ << "(sec " << format("%2d", int(symbol->SectionNumber)) << ")"
+ << "(fl 0x00)" // Flag bits, which COFF doesn't have.
+ << "(ty " << format("%3x", unsigned(symbol->Type)) << ")"
+ << "(scl " << format("%3x", unsigned(symbol->StorageClass)) << ") "
+ << "(nx " << unsigned(symbol->NumberOfAuxSymbols) << ") "
+ << "0x" << format("%08x", unsigned(symbol->Value)) << " "
+ << name << "\n";
+ aux_count = symbol->NumberOfAuxSymbols;
+ }
+ }
+}
+
+static void PrintSymbolTable(const ObjectFile *o) {
+ outs() << "SYMBOL TABLE:\n";
+
+ if (const COFFObjectFile *coff = dyn_cast<const COFFObjectFile>(o))
+ PrintCOFFSymbolTable(coff);
+ else {
+ error_code ec;
+ for (symbol_iterator si = o->begin_symbols(),
+ se = o->end_symbols(); si != se; si.increment(ec)) {
+ if (error(ec)) return;
+ StringRef Name;
+ uint64_t Address;
+ SymbolRef::Type Type;
+ 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->getFlags(Flags))) continue;
+ if (error(si->getType(Type))) 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_Unknown)
+ GlobLoc = Global ? 'g' : 'l';
+ char Debug = (Type == SymbolRef::ST_Debug || Type == SymbolRef::ST_File)
+ ? 'd' : ' ';
+ char FileFunc = ' ';
+ if (Type == SymbolRef::ST_File)
+ FileFunc = 'f';
+ else if (Type == SymbolRef::ST_Function)
+ FileFunc = 'F';
+
+ outs() << format("%08" PRIx64, Address) << " "
+ << GlobLoc // Local -> 'l', Global -> 'g', Neither -> ' '
+ << (Weak ? 'w' : ' ') // Weak?
+ << ' ' // Constructor. Not supported yet.
+ << ' ' // Warning. Not supported yet.
+ << ' ' // Indirect reference to another symbol.
+ << Debug // Debugging (d) or dynamic (D) symbol.
+ << FileFunc // Name of function (F), file (f) or object (O).
+ << ' ';
+ if (Absolute)
+ outs() << "*ABS*";
+ else if (Section == o->end_sections())
+ outs() << "*UND*";
+ else {
+ StringRef SectionName;
+ if (error(Section->getName(SectionName)))
+ SectionName = "";
+ outs() << SectionName;
+ }
+ outs() << '\t'
+ << format("%08" PRIx64 " ", Size)
+ << Name
+ << '\n';
+ }
+ }
+}
+
static void DumpObject(const ObjectFile *o) {
+ outs() << '\n';
+ outs() << o->getFileName()
+ << ":\tfile format " << o->getFileFormatName() << "\n\n";
+
if (Disassemble)
DisassembleObject(o, Relocations);
if (Relocations && !Disassemble)
PrintRelocations(o);
if (SectionHeaders)
PrintSectionHeaders(o);
+ if (SectionContents)
+ PrintSectionContents(o);
+ if (SymbolTable)
+ PrintSymbolTable(o);
}
/// @brief Dump each object file in \a a;
@@ -385,8 +577,10 @@ static void DumpArchive(const Archive *a) {
e = a->end_children(); i != e; ++i) {
OwningPtr<Binary> child;
if (error_code ec = i->getAsBinary(child)) {
- errs() << ToolName << ": '" << a->getFileName() << "': " << ec.message()
- << ".\n";
+ // Ignore non-object files.
+ if (ec != object_error::invalid_file_type)
+ errs() << ToolName << ": '" << a->getFileName() << "': " << ec.message()
+ << ".\n";
continue;
}
if (ObjectFile *o = dyn_cast<ObjectFile>(child.get()))
@@ -447,7 +641,11 @@ int main(int argc, char **argv) {
if (InputFilenames.size() == 0)
InputFilenames.push_back("a.out");
- if (!Disassemble && !Relocations && !SectionHeaders) {
+ if (!Disassemble
+ && !Relocations
+ && !SectionHeaders
+ && !SectionContents
+ && !SymbolTable) {
cl::PrintHelpMessage();
return 2;
}
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-prof/LLVMBuild.txt b/tools/llvm-prof/LLVMBuild.txt
new file mode 100644
index 0000000..d59127c
--- /dev/null
+++ b/tools/llvm-prof/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-prof/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-prof
+parent = Tools
+required_libraries = Analysis BitReader
diff --git a/tools/llvm-prof/Makefile b/tools/llvm-prof/Makefile
index 86eb54d..f829786 100644
--- a/tools/llvm-prof/Makefile
+++ b/tools/llvm-prof/Makefile
@@ -6,10 +6,10 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = llvm-prof
-LINK_COMPONENTS = bitreader analysis
+LEVEL := ../..
+TOOLNAME := llvm-prof
+LINK_COMPONENTS := bitreader analysis
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
diff --git a/tools/llvm-prof/llvm-prof.cpp b/tools/llvm-prof/llvm-prof.cpp
index 9d0b468..d9b6713 100644
--- a/tools/llvm-prof/llvm-prof.cpp
+++ b/tools/llvm-prof/llvm-prof.cpp
@@ -200,9 +200,9 @@ bool ProfileInfoPrinterPass::runOnModule(Module &M) {
}
outs() << format("%3d", i+1) << ". "
- << format("%5.2g", FunctionCounts[i].second) << "/"
- << format("%g", TotalExecutions) << " "
- << FunctionCounts[i].first->getNameStr() << "\n";
+ << format("%5.2g", FunctionCounts[i].second) << "/"
+ << format("%g", TotalExecutions) << " "
+ << FunctionCounts[i].first->getName() << "\n";
}
std::set<Function*> FunctionsToPrint;
@@ -225,12 +225,12 @@ bool ProfileInfoPrinterPass::runOnModule(Module &M) {
for (unsigned i = 0; i != BlocksToPrint; ++i) {
if (Counts[i].second == 0) break;
Function *F = Counts[i].first->getParent();
- outs() << format("%3d", i+1) << ". "
- << format("%5g", Counts[i].second/(double)TotalExecutions*100) << "% "
- << format("%5.0f", Counts[i].second) << "/"
- << format("%g", TotalExecutions) << "\t"
- << F->getNameStr() << "() - "
- << Counts[i].first->getNameStr() << "\n";
+ outs() << format("%3d", i+1) << ". "
+ << format("%5g", Counts[i].second/(double)TotalExecutions*100)<<"% "
+ << format("%5.0f", Counts[i].second) << "/"
+ << format("%g", TotalExecutions) << "\t"
+ << F->getName() << "() - "
+ << Counts[i].first->getName() << "\n";
FunctionsToPrint.insert(F);
}
diff --git a/tools/llvm-ranlib/LLVMBuild.txt b/tools/llvm-ranlib/LLVMBuild.txt
new file mode 100644
index 0000000..23015c5
--- /dev/null
+++ b/tools/llvm-ranlib/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-ranlib/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-ranlib
+parent = Tools
+required_libraries = Archive
diff --git a/tools/llvm-ranlib/Makefile b/tools/llvm-ranlib/Makefile
index 46a10e6..36195f4 100644
--- a/tools/llvm-ranlib/Makefile
+++ b/tools/llvm-ranlib/Makefile
@@ -7,12 +7,12 @@
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = llvm-ranlib
-LINK_COMPONENTS = archive
+LEVEL := ../..
+TOOLNAME := llvm-ranlib
+LINK_COMPONENTS := archive
REQUIRES_EH := 1
# This tool has no plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
+TOOL_NO_EXPORTS := 1
include $(LEVEL)/Makefile.common
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..3be1289
--- /dev/null
+++ b/tools/llvm-readobj/llvm-readobj.cpp
@@ -0,0 +1,218 @@
+//===- 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/Object/ELF.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, const ObjectFile *obj, bool IsDynamic) {
+ 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);
+ std::string FullName = Name;
+
+ // If this is a dynamic symbol from an ELF object, append
+ // the symbol's version to the name.
+ if (IsDynamic && obj->isELF()) {
+ StringRef Version;
+ bool IsDefault;
+ GetELFSymbolVersion(obj, Sym, Version, IsDefault);
+ if (!Version.empty()) {
+ FullName += (IsDefault ? "@@" : "@");
+ FullName += Version;
+ }
+ }
+
+ // format() can't handle StringRefs
+ outs() << format(" %-32s", FullName.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, obj, false);
+ 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, obj, true);
+ 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/LLVMBuild.txt b/tools/llvm-rtdyld/LLVMBuild.txt
new file mode 100644
index 0000000..b36d13c
--- /dev/null
+++ b/tools/llvm-rtdyld/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-rtdyld/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-rtdyld
+parent = Tools
+required_libraries = JIT MC Object RuntimeDyld Support all-targets
diff --git a/tools/llvm-rtdyld/Makefile b/tools/llvm-rtdyld/Makefile
index 0d57277..30fbee0 100644
--- a/tools/llvm-rtdyld/Makefile
+++ b/tools/llvm-rtdyld/Makefile
@@ -7,17 +7,11 @@
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = llvm-rtdyld
+LEVEL := ../..
+TOOLNAME := llvm-rtdyld
+LINK_COMPONENTS := all-targets support MC object RuntimeDyld JIT
# This tool has no plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
+TOOL_NO_EXPORTS := 1
-# Include this here so we can get the configuration of the targets
-# that have been configured for construction. We have to do this
-# early so we can set up LINK_COMPONENTS before including Makefile.rules
-include $(LEVEL)/Makefile.config
-
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) support MC object RuntimeDyld JIT
-
-include $(LLVM_SRC_ROOT)/Makefile.rules
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp
index ec9d652..01a7d15 100644
--- a/tools/llvm-rtdyld/llvm-rtdyld.cpp
+++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp
@@ -51,22 +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);
+
+ virtual void *getPointerToNamedFunction(const std::string &Name,
+ bool AbortOnFailure = true) {
+ return 0;
+ }
- uint8_t *startFunctionBody(const char *Name, uintptr_t &Size);
- void endFunctionBody(const char *Name, uint8_t *FunctionStart,
- uint8_t *FunctionEnd);
};
-uint8_t *TrivialMemoryManager::startFunctionBody(const char *Name,
- uintptr_t &Size) {
+uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size,
+ unsigned Alignment,
+ unsigned SectionID) {
return (uint8_t*)sys::Memory::AllocateRWX(Size, 0, 0).base();
}
-void TrivialMemoryManager::endFunctionBody(const char *Name,
- uint8_t *FunctionStart,
- uint8_t *FunctionEnd) {
- uintptr_t Size = FunctionEnd - FunctionStart + 1;
- FunctionMemory.push_back(sys::MemoryBlock(FunctionStart, Size));
+uint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size,
+ unsigned Alignment,
+ unsigned SectionID) {
+ return (uint8_t*)sys::Memory::AllocateRWX(Size, 0, 0).base();
}
static const char *ProgramName;
@@ -142,10 +150,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-shlib/Makefile b/tools/llvm-shlib/Makefile
index 0695c00..2d2e2c5 100644
--- a/tools/llvm-shlib/Makefile
+++ b/tools/llvm-shlib/Makefile
@@ -7,13 +7,13 @@
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
+LEVEL := ../..
LIBRARYNAME = LLVM-$(LLVMVersion)
-NO_BUILD_ARCHIVE = 1
-LINK_LIBS_IN_SHARED = 1
-SHARED_LIBRARY = 1
+NO_BUILD_ARCHIVE := 1
+LINK_LIBS_IN_SHARED := 1
+SHARED_LIBRARY := 1
include $(LEVEL)/Makefile.config
@@ -63,13 +63,15 @@ ifeq ($(HOST_OS),Darwin)
endif
endif
-ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux FreeBSD OpenBSD))
+ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux FreeBSD OpenBSD GNU))
# Include everything from the .a's into the shared library.
LLVMLibsOptions := -Wl,--whole-archive $(LLVMLibsOptions) \
-Wl,--no-whole-archive
+ # Add soname to the library.
+ LLVMLibsOptions += -Wl,--soname,lib$(LIBRARYNAME)$(SHLIBEXT)
endif
-ifeq ($(HOST_OS),Linux)
+ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux GNU))
# Don't allow unresolved symbols.
LLVMLibsOptions += -Wl,--no-undefined
endif
diff --git a/tools/llvm-size/LLVMBuild.txt b/tools/llvm-size/LLVMBuild.txt
new file mode 100644
index 0000000..b4c538a
--- /dev/null
+++ b/tools/llvm-size/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-size/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-size
+parent = Tools
+required_libraries = Object
diff --git a/tools/llvm-size/Makefile b/tools/llvm-size/Makefile
index 5d0e27e..0622eb1 100644
--- a/tools/llvm-size/Makefile
+++ b/tools/llvm-size/Makefile
@@ -6,10 +6,10 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = llvm-size
-LINK_COMPONENTS = object
+LEVEL := ../..
+TOOLNAME := llvm-size
+LINK_COMPONENTS := object
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
diff --git a/tools/llvm-size/llvm-size.cpp b/tools/llvm-size/llvm-size.cpp
index 70e5cb9..462da40 100644
--- a/tools/llvm-size/llvm-size.cpp
+++ b/tools/llvm-size/llvm-size.cpp
@@ -96,13 +96,13 @@ static void PrintObjectSectionSizes(ObjectFile *o) {
const char *radix_fmt = 0;
switch (Radix) {
case octal:
- radix_fmt = "llo";
+ radix_fmt = PRIo64;
break;
case decimal:
- radix_fmt = "llu";
+ radix_fmt = PRIu64;
break;
case hexadecimal:
- radix_fmt = "llx";
+ radix_fmt = PRIx64;
break;
}
if (OutputFormat == sysv) {
@@ -223,8 +223,8 @@ static void PrintObjectSectionSizes(ObjectFile *o) {
total_data,
total_bss);
fmtbuf.clear();
- fmt << "%7" << (Radix == octal ? "llo" : "llu") << " "
- << "%7llx ";
+ fmt << "%7" << (Radix == octal ? PRIo64 : PRIu64) << " "
+ << "%7" PRIx64 " ";
outs() << format(fmt.str().c_str(),
total,
total);
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..d284ea5
--- /dev/null
+++ b/tools/llvm-stress/llvm-stress.cpp
@@ -0,0 +1,702 @@
+//===-- 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 a random integer, up to a
+ /// maximum of 2**19 - 1.
+ uint32_t Rand() {
+ uint32_t Val = Seed + 0x000b07a1;
+ Seed = (Val * 0x3c7c0ac1);
+ // Only lowest 19 bits are random-ish.
+ return Seed & 0x7ffff;
+ }
+
+ /// Return a random 32 bit integer.
+ uint32_t Rand32() {
+ uint32_t Val = Rand();
+ Val &= 0xffff;
+ return Val | (Rand() << 16);
+ }
+
+ /// Return a random 64 bit integer.
+ uint64_t Rand64() {
+ uint64_t Val = Rand32();
+ return Val | (uint64_t(Rand32()) << 32);
+ }
+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) {
+ // 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));
+ Type *Ty;
+
+ // Vectors of x86mmx are illegal; keep trying till we get something else.
+ do {
+ Ty = pickScalarType();
+ } while (Ty->isX86_MMXTy());
+
+ 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()) {
+ // Generate 128 random bits, the size of the (currently)
+ // largest floating-point types.
+ uint64_t RandomBits[2];
+ for (unsigned i = 0; i < 2; ++i)
+ RandomBits[i] = Ran->Rand64();
+
+ APInt RandomInt(Ty->getPrimitiveSizeInBits(), makeArrayRef(RandomBits));
+
+ bool isIEEE = !Ty->isX86_FP80Ty() && !Ty->isPPC_FP128Ty();
+ APFloat RandomFloat(RandomInt, isIEEE);
+
+ if (Ran->Rand() & 1)
+ return PT->push_back(ConstantFP::getNullValue(Ty));
+ return PT->push_back(ConstantFP::get(Ty->getContext(), RandomFloat));
+ }
+
+ 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/llvm-stub/LLVMBuild.txt b/tools/llvm-stub/LLVMBuild.txt
new file mode 100644
index 0000000..5c3534c
--- /dev/null
+++ b/tools/llvm-stub/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./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
index 7ffe149..077efa2 100644
--- a/tools/llvm-stub/Makefile
+++ b/tools/llvm-stub/Makefile
@@ -7,7 +7,9 @@
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = llvm-stub
+LEVEL := ../..
+TOOLNAME := llvm-stub
+LINK_COMPONENTS := object
+
include $(LEVEL)/Makefile.common
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 6c8dbad..77c06a6 100644
--- a/tools/lto/LTOCodeGenerator.cpp
+++ b/tools/lto/LTOCodeGenerator.cpp
@@ -4,27 +4,26 @@
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
-// This file implements the Link Time Optimization library. This library is
+// This file implements the Link Time Optimization library. This library is
// intended to be used by linker to optimize code at link time.
//
//===----------------------------------------------------------------------===//
-#include "LTOModule.h"
#include "LTOCodeGenerator.h"
+#include "LTOModule.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Linker.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Config/config.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/SubtargetFeature.h"
@@ -33,67 +32,55 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/Host.h"
-#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/system_error.h"
-#include "llvm/Config/config.h"
-#include "llvm/Transforms/IPO.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
-#include <cstdlib>
-#include <unistd.h>
-#include <fcntl.h>
-
-
+#include "llvm/ADT/StringExtras.h"
using namespace llvm;
-static cl::opt<bool> DisableInline("disable-inlining",
+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),
+ cl::desc("Do not run the GVN load PRE pass"));
-const char* LTOCodeGenerator::getVersionString()
-{
+const char* LTOCodeGenerator::getVersionString() {
#ifdef LLVM_VERSION_INFO
- return PACKAGE_NAME " version " PACKAGE_VERSION ", " LLVM_VERSION_INFO;
+ return PACKAGE_NAME " version " PACKAGE_VERSION ", " LLVM_VERSION_INFO;
#else
- return PACKAGE_NAME " version " PACKAGE_VERSION;
+ return PACKAGE_NAME " version " PACKAGE_VERSION;
#endif
}
-
-LTOCodeGenerator::LTOCodeGenerator()
- : _context(getGlobalContext()),
- _linker("LinkTimeOptimizer", "ld-temp.o", _context), _target(NULL),
- _emitDwarfDebugInfo(false), _scopeRestrictionsDone(false),
- _codeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC),
- _nativeObjectFile(NULL)
-{
- InitializeAllTargets();
- InitializeAllTargetMCs();
- InitializeAllAsmPrinters();
-}
-
-LTOCodeGenerator::~LTOCodeGenerator()
-{
- delete _target;
- delete _nativeObjectFile;
+LTOCodeGenerator::LTOCodeGenerator()
+ : _context(getGlobalContext()),
+ _linker("LinkTimeOptimizer", "ld-temp.o", _context), _target(NULL),
+ _emitDwarfDebugInfo(false), _scopeRestrictionsDone(false),
+ _runInternalizePass(false), _codeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC),
+ _nativeObjectFile(NULL) {
+ InitializeAllTargets();
+ InitializeAllTargetMCs();
+ InitializeAllAsmPrinters();
}
+LTOCodeGenerator::~LTOCodeGenerator() {
+ delete _target;
+ delete _nativeObjectFile;
+ for (std::vector<char*>::iterator I = _codegenOptions.begin(),
+ E = _codegenOptions.end(); I != E; ++I)
+ free(*I);
+}
-bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg)
-{
-
- if(mod->getLLVVMModule()->MaterializeAllPermanently(&errMsg))
- return true;
-
+bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg) {
bool ret = _linker.LinkInModule(mod->getLLVVMModule(), &errMsg);
const std::vector<const char*> &undefs = mod->getAsmUndefinedRefs();
@@ -102,55 +89,39 @@ bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg)
return ret;
}
-
-
-bool LTOCodeGenerator::setDebugInfo(lto_debug_model debug, std::string& errMsg)
-{
- switch (debug) {
- case LTO_DEBUG_MODEL_NONE:
- _emitDwarfDebugInfo = false;
- return false;
-
- case LTO_DEBUG_MODEL_DWARF:
- _emitDwarfDebugInfo = true;
- return false;
- }
- errMsg = "unknown debug format";
- return true;
-}
+bool LTOCodeGenerator::setDebugInfo(lto_debug_model debug,
+ std::string& errMsg) {
+ switch (debug) {
+ case LTO_DEBUG_MODEL_NONE:
+ _emitDwarfDebugInfo = false;
+ return false;
-bool LTOCodeGenerator::setCodePICModel(lto_codegen_model model,
- std::string& errMsg)
-{
- switch (model) {
- case LTO_CODEGEN_PIC_MODEL_STATIC:
- case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
- case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
- _codeModel = model;
- return false;
- }
- errMsg = "unknown pic model";
- return true;
-}
-
-void LTOCodeGenerator::setCpu(const char* mCpu)
-{
- _mCpu = mCpu;
+ case LTO_DEBUG_MODEL_DWARF:
+ _emitDwarfDebugInfo = true;
+ return false;
+ }
+ llvm_unreachable("Unknown debug format!");
}
-void LTOCodeGenerator::addMustPreserveSymbol(const char* sym)
-{
- _mustPreserveSymbols[sym] = 1;
+bool LTOCodeGenerator::setCodePICModel(lto_codegen_model model,
+ std::string& errMsg) {
+ switch (model) {
+ case LTO_CODEGEN_PIC_MODEL_STATIC:
+ case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
+ case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
+ _codeModel = model;
+ return false;
+ }
+ llvm_unreachable("Unknown PIC model!");
}
-
bool LTOCodeGenerator::writeMergedModules(const char *path,
std::string &errMsg) {
if (determineTarget(errMsg))
return true;
- // mark which symbols can not be internalized
+ // mark which symbols can not be internalized
applyScopeRestrictions();
// create output file
@@ -162,7 +133,7 @@ bool LTOCodeGenerator::writeMergedModules(const char *path,
errMsg += path;
return true;
}
-
+
// write bitcode to it
WriteBitcodeToFile(_linker.getModule(), Out.os());
Out.os().close();
@@ -173,14 +144,12 @@ bool LTOCodeGenerator::writeMergedModules(const char *path,
Out.os().clear_error();
return true;
}
-
+
Out.keep();
return false;
}
-
-bool LTOCodeGenerator::compile_to_file(const char** name, std::string& errMsg)
-{
+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) ) {
@@ -194,12 +163,14 @@ bool LTOCodeGenerator::compile_to_file(const char** name, std::string& errMsg)
tool_output_file objFile(uniqueObjPath.c_str(), errMsg);
if (!errMsg.empty())
return true;
+
genResult = this->generateObjectFile(objFile.os(), errMsg);
objFile.os().close();
if (objFile.os().has_error()) {
objFile.os().clear_error();
return true;
}
+
objFile.keep();
if ( genResult ) {
uniqueObjPath.eraseFromDisk();
@@ -211,8 +182,7 @@ bool LTOCodeGenerator::compile_to_file(const char** name, std::string& errMsg)
return false;
}
-const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg)
-{
+const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg) {
const char *name;
if (compile_to_file(&name, errMsg))
return NULL;
@@ -238,47 +208,48 @@ const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg)
return _nativeObjectFile->getBufferStart();
}
-bool LTOCodeGenerator::determineTarget(std::string& errMsg)
-{
- if ( _target == NULL ) {
- std::string Triple = _linker.getModule()->getTargetTriple();
- if (Triple.empty())
- Triple = sys::getHostTriple();
-
- // 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();
- _target = march->createTargetMachine(Triple, _mCpu, FeatureStr,
- RelocModel);
+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;
}
- return false;
+
+ // 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);
+ }
+ return false;
}
-void LTOCodeGenerator::applyRestriction(GlobalValue &GV,
- std::vector<const char*> &mustPreserveList,
- SmallPtrSet<GlobalValue*, 8> &asmUsed,
- Mangler &mangler) {
+void LTOCodeGenerator::
+applyRestriction(GlobalValue &GV,
+ std::vector<const char*> &mustPreserveList,
+ SmallPtrSet<GlobalValue*, 8> &asmUsed,
+ Mangler &mangler) {
SmallString<64> Buffer;
mangler.getNameWithPrefix(Buffer, &GV, false);
@@ -298,8 +269,8 @@ static void findUsedValues(GlobalVariable *LLVMUsed,
if (Inits == 0) return;
for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
- if (GlobalValue *GV =
- dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
+ if (GlobalValue *GV =
+ dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
UsedValues.insert(GV);
}
@@ -311,8 +282,8 @@ void LTOCodeGenerator::applyScopeRestrictions() {
PassManager passes;
passes.add(createVerifierPass());
- // mark which symbols can not be internalized
- MCContext Context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(), NULL);
+ // mark which symbols can not be internalized
+ MCContext Context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(),NULL);
Mangler mangler(Context, *_target->getTargetData());
std::vector<const char*> mustPreserveList;
SmallPtrSet<GlobalValue*, 8> asmUsed;
@@ -320,7 +291,7 @@ void LTOCodeGenerator::applyScopeRestrictions() {
for (Module::iterator f = mergedModule->begin(),
e = mergedModule->end(); f != e; ++f)
applyRestriction(*f, mustPreserveList, asmUsed, mangler);
- for (Module::global_iterator v = mergedModule->global_begin(),
+ for (Module::global_iterator v = mergedModule->global_begin(),
e = mergedModule->global_end(); v != e; ++v)
applyRestriction(*v, mustPreserveList, asmUsed, mangler);
for (Module::alias_iterator a = mergedModule->alias_begin(),
@@ -355,81 +326,82 @@ void LTOCodeGenerator::applyScopeRestrictions() {
// apply scope restrictions
passes.run(*mergedModule);
-
+
_scopeRestrictionsDone = true;
}
/// Optimize merged modules using various IPO passes
bool LTOCodeGenerator::generateObjectFile(raw_ostream &out,
std::string &errMsg) {
- if ( this->determineTarget(errMsg) )
- return true;
+ if ( this->determineTarget(errMsg) )
+ return true;
- // mark which symbols can not be internalized
- this->applyScopeRestrictions();
+ Module* mergedModule = _linker.getModule();
- Module* mergedModule = _linker.getModule();
+ // if options were requested, set them
+ if ( !_codegenOptions.empty() )
+ cl::ParseCommandLineOptions(_codegenOptions.size(),
+ const_cast<char **>(&_codegenOptions[0]));
- // if options were requested, set them
- if ( !_codegenOptions.empty() )
- cl::ParseCommandLineOptions(_codegenOptions.size(),
- const_cast<char **>(&_codegenOptions[0]));
+ // mark which symbols can not be internalized
+ this->applyScopeRestrictions();
- // Instantiate the pass manager to organize the passes.
- PassManager passes;
+ // Instantiate the pass manager to organize the passes.
+ PassManager passes;
- // Start off with a verification pass.
- passes.add(createVerifierPass());
+ // Start off with a verification pass.
+ passes.add(createVerifierPass());
- // Add an appropriate TargetData instance for this module...
- passes.add(new TargetData(*_target->getTargetData()));
-
- PassManagerBuilder().populateLTOPassManager(passes, /*Internalize=*/ false,
- !DisableInline);
+ // Add an appropriate TargetData instance for this module...
+ passes.add(new TargetData(*_target->getTargetData()));
- // Make sure everything is still good.
- passes.add(createVerifierPass());
+ PassManagerBuilder().populateLTOPassManager(passes,
+ _runInternalizePass,
+ !DisableInline,
+ DisableGVNLoadPRE);
- FunctionPassManager *codeGenPasses = new FunctionPassManager(mergedModule);
+ // Make sure everything is still good.
+ passes.add(createVerifierPass());
- codeGenPasses->add(new TargetData(*_target->getTargetData()));
+ FunctionPassManager *codeGenPasses = new FunctionPassManager(mergedModule);
- formatted_raw_ostream Out(out);
+ codeGenPasses->add(new TargetData(*_target->getTargetData()));
- if (_target->addPassesToEmitFile(*codeGenPasses, Out,
- TargetMachine::CGFT_ObjectFile,
- CodeGenOpt::Aggressive)) {
- errMsg = "target file type not supported";
- return true;
- }
+ formatted_raw_ostream Out(out);
- // Run our queue of passes all at once now, efficiently.
- passes.run(*mergedModule);
+ if (_target->addPassesToEmitFile(*codeGenPasses, Out,
+ TargetMachine::CGFT_ObjectFile,
+ CodeGenOpt::Aggressive)) {
+ errMsg = "target file type not supported";
+ return true;
+ }
+
+ // Run our queue of passes all at once now, efficiently.
+ passes.run(*mergedModule);
- // Run the code generator, and write assembly file
- codeGenPasses->doInitialization();
+ // Run the code generator, and write assembly file
+ codeGenPasses->doInitialization();
- for (Module::iterator
- it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it)
- if (!it->isDeclaration())
- codeGenPasses->run(*it);
+ for (Module::iterator
+ it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it)
+ if (!it->isDeclaration())
+ codeGenPasses->run(*it);
- codeGenPasses->doFinalization();
- delete codeGenPasses;
+ codeGenPasses->doFinalization();
+ delete codeGenPasses;
- return false; // success
+ return false; // success
}
-
-/// Optimize merged modules using various IPO passes
-void LTOCodeGenerator::setCodeGenDebugOptions(const char* options)
-{
- for (std::pair<StringRef, StringRef> o = getToken(options);
- !o.first.empty(); o = getToken(o.second)) {
- // ParseCommandLineOptions() expects argv[0] to be program name.
- // Lazily add that.
- if ( _codegenOptions.empty() )
- _codegenOptions.push_back("libLTO");
- _codegenOptions.push_back(strdup(o.first.str().c_str()));
- }
+/// setCodeGenDebugOptions - Set codegen debugging options to aid in debugging
+/// LTO problems.
+void LTOCodeGenerator::setCodeGenDebugOptions(const char *options) {
+ for (std::pair<StringRef, StringRef> o = getToken(options);
+ !o.first.empty(); o = getToken(o.second)) {
+ // ParseCommandLineOptions() expects argv[0] to be program name. Lazily add
+ // that.
+ 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 f8fd357..bac3e6e 100644
--- a/tools/lto/LTOCodeGenerator.h
+++ b/tools/lto/LTOCodeGenerator.h
@@ -4,71 +4,82 @@
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
-// This file declares the LTOCodeGenerator class.
+// This file declares the LTOCodeGenerator class.
//
//===----------------------------------------------------------------------===//
-
#ifndef LTO_CODE_GENERATOR_H
#define LTO_CODE_GENERATOR_H
#include "llvm/Linker.h"
-#include "llvm/LLVMContext.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallPtrSet.h"
-
+#include "llvm-c/lto.h"
#include <string>
+namespace llvm {
+ class LLVMContext;
+ class GlobalValue;
+ class Mangler;
+ class MemoryBuffer;
+ class TargetMachine;
+ class raw_ostream;
+}
-//
-// C++ class which implements the opaque lto_code_gen_t
-//
-
+//===----------------------------------------------------------------------===//
+/// LTOCodeGenerator - C++ class which implements the opaque lto_code_gen_t
+/// type.
+///
struct LTOCodeGenerator {
- static const char* getVersionString();
-
- LTOCodeGenerator();
- ~LTOCodeGenerator();
-
- bool addModule(struct LTOModule*, std::string& errMsg);
- bool setDebugInfo(lto_debug_model, std::string& errMsg);
- bool setCodePICModel(lto_codegen_model, std::string& errMsg);
- void setCpu(const char *cpu);
- void addMustPreserveSymbol(const char* sym);
- bool writeMergedModules(const char* path,
- std::string& errMsg);
- bool compile_to_file(const char** name, std::string& errMsg);
- const void* compile(size_t* length, std::string& errMsg);
- void setCodeGenDebugOptions(const char *opts);
+ static const char *getVersionString();
+
+ LTOCodeGenerator();
+ ~LTOCodeGenerator();
+
+ bool addModule(struct LTOModule*, std::string &errMsg);
+ bool setDebugInfo(lto_debug_model, std::string &errMsg);
+ bool setCodePICModel(lto_codegen_model, std::string &errMsg);
+
+ void setCpu(const char* mCpu) { _mCpu = mCpu; }
+
+ void addMustPreserveSymbol(const char* sym) {
+ _mustPreserveSymbols[sym] = 1;
+ }
+
+ bool writeMergedModules(const char *path, std::string &errMsg);
+ bool compile_to_file(const char **name, std::string &errMsg);
+ const void *compile(size_t *length, std::string &errMsg);
+ void setCodeGenDebugOptions(const char *opts);
+
+ void enableInternalizePass() { _runInternalizePass = true; }
+
private:
- bool generateObjectFile(llvm::raw_ostream& out,
- std::string& errMsg);
- void applyScopeRestrictions();
- void applyRestriction(llvm::GlobalValue &GV,
- std::vector<const char*> &mustPreserveList,
+ bool generateObjectFile(llvm::raw_ostream &out, std::string &errMsg);
+ void applyScopeRestrictions();
+ void applyRestriction(llvm::GlobalValue &GV,
+ std::vector<const char*> &mustPreserveList,
llvm::SmallPtrSet<llvm::GlobalValue*, 8> &asmUsed,
- llvm::Mangler &mangler);
- bool determineTarget(std::string& errMsg);
-
- typedef llvm::StringMap<uint8_t> StringSet;
+ llvm::Mangler &mangler);
+ bool determineTarget(std::string &errMsg);
- llvm::LLVMContext& _context;
- llvm::Linker _linker;
- llvm::TargetMachine* _target;
- bool _emitDwarfDebugInfo;
- bool _scopeRestrictionsDone;
- lto_codegen_model _codeModel;
- StringSet _mustPreserveSymbols;
- StringSet _asmUndefinedRefs;
- llvm::MemoryBuffer* _nativeObjectFile;
- std::vector<const char*> _codegenOptions;
- std::string _mCpu;
- std::string _nativeObjectPath;
+ typedef llvm::StringMap<uint8_t> StringSet;
+
+ llvm::LLVMContext& _context;
+ llvm::Linker _linker;
+ llvm::TargetMachine* _target;
+ bool _emitDwarfDebugInfo;
+ bool _scopeRestrictionsDone;
+ bool _runInternalizePass;
+ lto_codegen_model _codeModel;
+ StringSet _mustPreserveSymbols;
+ StringSet _asmUndefinedRefs;
+ llvm::MemoryBuffer* _nativeObjectFile;
+ std::vector<char*> _codegenOptions;
+ std::string _mCpu;
+ std::string _nativeObjectPath;
};
#endif // LTO_CODE_GENERATOR_H
-
diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp
index 4ba8985..1dbd64b 100644
--- a/tools/lto/LTOModule.cpp
+++ b/tools/lto/LTOModule.cpp
@@ -13,39 +13,37 @@
//===----------------------------------------------------------------------===//
#include "LTOModule.h"
-
#include "llvm/Constants.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Bitcode/ReaderWriter.h"
-#include "llvm/Support/SystemUtils.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/Process.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/TargetRegistry.h"
-#include "llvm/Support/TargetSelect.h"
-#include "llvm/Support/system_error.h"
-#include "llvm/Target/Mangler.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/MC/SubtargetFeature.h"
#include "llvm/MC/MCTargetAsmParser.h"
-#include "llvm/Target/TargetMachine.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/Target/TargetRegisterInfo.h"
-
+#include "llvm/Support/Host.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/system_error.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/Triple.h"
using namespace llvm;
+LTOModule::LTOModule(llvm::Module *m, llvm::TargetMachine *t)
+ : _module(m), _target(t),
+ _context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(), NULL),
+ _mangler(_context, *_target->getTargetData()) {}
+
+/// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM
+/// bitcode.
bool LTOModule::isBitcodeFile(const void *mem, size_t length) {
return llvm::sys::IdentifyFileType((char*)mem, length)
== llvm::sys::Bitcode_FileType;
@@ -55,6 +53,8 @@ bool LTOModule::isBitcodeFile(const char *path) {
return llvm::sys::Path(path).isBitcodeFile();
}
+/// isBitcodeFileForTarget - Returns 'true' if the file (or memory contents) is
+/// LLVM bitcode for the specified triple.
bool LTOModule::isBitcodeFileForTarget(const void *mem, size_t length,
const char *triplePrefix) {
MemoryBuffer *buffer = makeBuffer(mem, length);
@@ -63,7 +63,6 @@ bool LTOModule::isBitcodeFileForTarget(const void *mem, size_t length,
return isTargetMatch(buffer, triplePrefix);
}
-
bool LTOModule::isBitcodeFileForTarget(const char *path,
const char *triplePrefix) {
OwningPtr<MemoryBuffer> buffer;
@@ -72,22 +71,17 @@ bool LTOModule::isBitcodeFileForTarget(const char *path,
return isTargetMatch(buffer.take(), triplePrefix);
}
-// Takes ownership of buffer.
+/// isTargetMatch - Returns 'true' if the memory buffer is for the specified
+/// target triple.
bool LTOModule::isTargetMatch(MemoryBuffer *buffer, const char *triplePrefix) {
std::string Triple = getBitcodeTargetTriple(buffer, getGlobalContext());
delete buffer;
- return (strncmp(Triple.c_str(), triplePrefix,
- strlen(triplePrefix)) == 0);
+ return strncmp(Triple.c_str(), triplePrefix, strlen(triplePrefix)) == 0;
}
-
-LTOModule::LTOModule(Module *m, TargetMachine *t)
- : _module(m), _target(t)
-{
-}
-
-LTOModule *LTOModule::makeLTOModule(const char *path,
- std::string &errMsg) {
+/// makeLTOModule - Create an LTOModule. N.B. These methods take ownership of
+/// the buffer.
+LTOModule *LTOModule::makeLTOModule(const char *path, std::string &errMsg) {
OwningPtr<MemoryBuffer> buffer;
if (error_code ec = MemoryBuffer::getFile(path, buffer)) {
errMsg = ec.message();
@@ -97,8 +91,7 @@ LTOModule *LTOModule::makeLTOModule(const char *path,
}
LTOModule *LTOModule::makeLTOModule(int fd, const char *path,
- size_t size,
- std::string &errMsg) {
+ size_t size, std::string &errMsg) {
return makeLTOModule(fd, path, size, size, 0, errMsg);
}
@@ -116,13 +109,6 @@ LTOModule *LTOModule::makeLTOModule(int fd, const char *path,
return makeLTOModule(buffer.take(), errMsg);
}
-/// makeBuffer - Create a MemoryBuffer from a memory range.
-MemoryBuffer *LTOModule::makeBuffer(const void *mem, size_t length) {
- const char *startPtr = (char*)mem;
- return MemoryBuffer::getMemBuffer(StringRef(startPtr, length), "", false);
-}
-
-
LTOModule *LTOModule::makeLTOModule(const void *mem, size_t length,
std::string &errMsg) {
OwningPtr<MemoryBuffer> buffer(makeBuffer(mem, length));
@@ -151,7 +137,7 @@ LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer,
std::string Triple = m->getTargetTriple();
if (Triple.empty())
- Triple = sys::getHostTriple();
+ Triple = sys::getDefaultTargetTriple();
// find machine architecture for this module
const Target *march = TargetRegistry::lookupTarget(Triple, errMsg);
@@ -163,39 +149,33 @@ LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer,
Features.getDefaultSubtargetFeatures(llvm::Triple(Triple));
std::string FeatureStr = Features.getString();
std::string CPU;
- TargetMachine *target = march->createTargetMachine(Triple, CPU, FeatureStr);
+ TargetOptions Options;
+ TargetMachine *target = march->createTargetMachine(Triple, CPU, FeatureStr,
+ Options);
LTOModule *Ret = new LTOModule(m.take(), target);
- bool Err = Ret->ParseSymbols(errMsg);
- if (Err) {
+ if (Ret->parseSymbols(errMsg)) {
delete Ret;
return NULL;
}
- return Ret;
-}
-
-const char *LTOModule::getTargetTriple() {
- return _module->getTargetTriple().c_str();
-}
-
-void LTOModule::setTargetTriple(const char *triple) {
- _module->setTargetTriple(triple);
+ return Ret;
}
-void LTOModule::addDefinedFunctionSymbol(Function *f, Mangler &mangler) {
- // add to list of defined symbols
- addDefinedSymbol(f, mangler, true);
+/// makeBuffer - Create a MemoryBuffer from a memory range.
+MemoryBuffer *LTOModule::makeBuffer(const void *mem, size_t length) {
+ const char *startPtr = (char*)mem;
+ return MemoryBuffer::getMemBuffer(StringRef(startPtr, length), "", false);
}
-// Get string that data pointer points to.
+/// objcClassNameFromExpression - Get string that the data pointer points to.
bool LTOModule::objcClassNameFromExpression(Constant *c, std::string &name) {
if (ConstantExpr *ce = dyn_cast<ConstantExpr>(c)) {
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;
}
}
@@ -204,85 +184,92 @@ bool LTOModule::objcClassNameFromExpression(Constant *c, std::string &name) {
return false;
}
-// Parse i386/ppc ObjC class data structure.
+/// addObjCClass - Parse i386/ppc ObjC class data structure.
void LTOModule::addObjCClass(GlobalVariable *clgv) {
- if (ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer())) {
- // second slot in __OBJC,__class is pointer to superclass name
- std::string superclassName;
- if (objcClassNameFromExpression(c->getOperand(1), superclassName)) {
- NameAndAttributes info;
- StringMap<NameAndAttributes>::value_type &entry =
- _undefines.GetOrCreateValue(superclassName);
- if (!entry.getValue().name) {
- const char *symbolName = entry.getKey().data();
- info.name = symbolName;
- info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
- entry.setValue(info);
- }
- }
- // third slot in __OBJC,__class is pointer to class name
- std::string className;
- if (objcClassNameFromExpression(c->getOperand(2), className)) {
- StringSet::value_type &entry =
- _defines.GetOrCreateValue(className);
- entry.setValue(1);
- NameAndAttributes info;
- info.name = entry.getKey().data();
- info.attributes = (lto_symbol_attributes)
- (LTO_SYMBOL_PERMISSIONS_DATA |
- LTO_SYMBOL_DEFINITION_REGULAR |
- LTO_SYMBOL_SCOPE_DEFAULT);
- _symbols.push_back(info);
- }
- }
-}
-
-
-// Parse i386/ppc ObjC category data structure.
-void LTOModule::addObjCCategory(GlobalVariable *clgv) {
- if (ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer())) {
- // second slot in __OBJC,__category is pointer to target class name
- std::string targetclassName;
- if (objcClassNameFromExpression(c->getOperand(1), targetclassName)) {
- NameAndAttributes info;
-
- StringMap<NameAndAttributes>::value_type &entry =
- _undefines.GetOrCreateValue(targetclassName);
-
- if (entry.getValue().name)
- return;
+ ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer());
+ if (!c) return;
+ // second slot in __OBJC,__class is pointer to superclass name
+ std::string superclassName;
+ if (objcClassNameFromExpression(c->getOperand(1), superclassName)) {
+ NameAndAttributes info;
+ StringMap<NameAndAttributes>::value_type &entry =
+ _undefines.GetOrCreateValue(superclassName);
+ if (!entry.getValue().name) {
const char *symbolName = entry.getKey().data();
info.name = symbolName;
info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
+ info.isFunction = false;
+ info.symbol = clgv;
entry.setValue(info);
}
}
+
+ // third slot in __OBJC,__class is pointer to class name
+ std::string className;
+ if (objcClassNameFromExpression(c->getOperand(2), className)) {
+ StringSet::value_type &entry = _defines.GetOrCreateValue(className);
+ entry.setValue(1);
+
+ NameAndAttributes info;
+ info.name = entry.getKey().data();
+ info.attributes = LTO_SYMBOL_PERMISSIONS_DATA |
+ LTO_SYMBOL_DEFINITION_REGULAR | LTO_SYMBOL_SCOPE_DEFAULT;
+ info.isFunction = false;
+ info.symbol = clgv;
+ _symbols.push_back(info);
+ }
}
+/// addObjCCategory - Parse i386/ppc ObjC category data structure.
+void LTOModule::addObjCCategory(GlobalVariable *clgv) {
+ ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer());
+ if (!c) return;
-// Parse i386/ppc ObjC class list data structure.
-void LTOModule::addObjCClassRef(GlobalVariable *clgv) {
+ // second slot in __OBJC,__category is pointer to target class name
std::string targetclassName;
- if (objcClassNameFromExpression(clgv->getInitializer(), targetclassName)) {
- NameAndAttributes info;
+ if (!objcClassNameFromExpression(c->getOperand(1), targetclassName))
+ return;
- StringMap<NameAndAttributes>::value_type &entry =
- _undefines.GetOrCreateValue(targetclassName);
- if (entry.getValue().name)
- return;
+ NameAndAttributes info;
+ StringMap<NameAndAttributes>::value_type &entry =
+ _undefines.GetOrCreateValue(targetclassName);
- const char *symbolName = entry.getKey().data();
- info.name = symbolName;
- info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
- entry.setValue(info);
- }
+ if (entry.getValue().name)
+ return;
+
+ const char *symbolName = entry.getKey().data();
+ info.name = symbolName;
+ info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
+ info.isFunction = false;
+ info.symbol = clgv;
+ entry.setValue(info);
}
+/// addObjCClassRef - Parse i386/ppc ObjC class list data structure.
+void LTOModule::addObjCClassRef(GlobalVariable *clgv) {
+ std::string targetclassName;
+ if (!objcClassNameFromExpression(clgv->getInitializer(), targetclassName))
+ return;
+
+ NameAndAttributes info;
+ StringMap<NameAndAttributes>::value_type &entry =
+ _undefines.GetOrCreateValue(targetclassName);
+ if (entry.getValue().name)
+ return;
+
+ const char *symbolName = entry.getKey().data();
+ info.name = symbolName;
+ info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
+ info.isFunction = false;
+ info.symbol = clgv;
+ entry.setValue(info);
+}
-void LTOModule::addDefinedDataSymbol(GlobalValue *v, Mangler &mangler) {
+/// addDefinedDataSymbol - Add a data symbol as defined to the list.
+void LTOModule::addDefinedDataSymbol(GlobalValue *v) {
// Add to list of defined symbols.
- addDefinedSymbol(v, mangler, false);
+ addDefinedSymbol(v, false);
// Special case i386/ppc ObjC data structures in magic sections:
// The issue is that the old ObjC object format did some strange
@@ -327,25 +314,30 @@ void LTOModule::addDefinedDataSymbol(GlobalValue *v, Mangler &mangler) {
}
}
+/// addDefinedFunctionSymbol - Add a function symbol as defined to the list.
+void LTOModule::addDefinedFunctionSymbol(Function *f) {
+ // add to list of defined symbols
+ addDefinedSymbol(f, true);
+}
-void LTOModule::addDefinedSymbol(GlobalValue *def, Mangler &mangler,
- bool isFunction) {
+/// addDefinedSymbol - Add a defined symbol to the list.
+void LTOModule::addDefinedSymbol(GlobalValue *def, bool isFunction) {
// ignore all llvm.* symbols
if (def->getName().startswith("llvm."))
return;
// string is owned by _defines
SmallString<64> Buffer;
- mangler.getNameWithPrefix(Buffer, def, false);
+ _mangler.getNameWithPrefix(Buffer, def, false);
// set alignment part log2() can have rounding errors
uint32_t align = def->getAlignment();
uint32_t attr = align ? CountTrailingZeros_32(def->getAlignment()) : 0;
// set permissions part
- if (isFunction)
+ if (isFunction) {
attr |= LTO_SYMBOL_PERMISSIONS_CODE;
- else {
+ } else {
GlobalVariable *gv = dyn_cast<GlobalVariable>(def);
if (gv && gv->isConstant())
attr |= LTO_SYMBOL_PERMISSIONS_RODATA;
@@ -377,18 +369,24 @@ void LTOModule::addDefinedSymbol(GlobalValue *def, Mangler &mangler,
else
attr |= LTO_SYMBOL_SCOPE_INTERNAL;
- // add to table of symbols
- NameAndAttributes info;
StringSet::value_type &entry = _defines.GetOrCreateValue(Buffer);
entry.setValue(1);
+ // fill information structure
+ NameAndAttributes info;
StringRef Name = entry.getKey();
info.name = Name.data();
assert(info.name[Name.size()] == '\0');
- info.attributes = (lto_symbol_attributes)attr;
+ info.attributes = attr;
+ info.isFunction = isFunction;
+ info.symbol = def;
+
+ // add to table of symbols
_symbols.push_back(info);
}
+/// addAsmGlobalSymbol - Add a global symbol from module-level ASM to the
+/// defined list.
void LTOModule::addAsmGlobalSymbol(const char *name,
lto_symbol_attributes scope) {
StringSet::value_type &entry = _defines.GetOrCreateValue(name);
@@ -398,15 +396,41 @@ void LTOModule::addAsmGlobalSymbol(const char *name,
return;
entry.setValue(1);
- const char *symbolName = entry.getKey().data();
- uint32_t attr = LTO_SYMBOL_DEFINITION_REGULAR;
- attr |= scope;
- NameAndAttributes info;
- info.name = symbolName;
- info.attributes = (lto_symbol_attributes)attr;
- _symbols.push_back(info);
+
+ NameAndAttributes &info = _undefines[entry.getKey().data()];
+
+ if (info.symbol == 0) {
+ // FIXME: This is trying to take care of module ASM like this:
+ //
+ // module asm ".zerofill __FOO, __foo, _bar_baz_qux, 0"
+ //
+ // but is gross and its mother dresses it funny. Have the ASM parser give us
+ // more details for this type of situation so that we're not guessing so
+ // much.
+
+ // fill information structure
+ info.name = name;
+ info.attributes =
+ LTO_SYMBOL_PERMISSIONS_DATA | LTO_SYMBOL_DEFINITION_REGULAR | scope;
+ info.isFunction = false;
+ info.symbol = 0;
+
+ // add to table of symbols
+ _symbols.push_back(info);
+ return;
+ }
+
+ if (info.isFunction)
+ addDefinedFunctionSymbol(cast<Function>(info.symbol));
+ else
+ addDefinedDataSymbol(info.symbol);
+
+ _symbols.back().attributes &= ~LTO_SYMBOL_SCOPE_MASK;
+ _symbols.back().attributes |= scope;
}
+/// addAsmGlobalSymbolUndef - Add a global symbol from module-level ASM to the
+/// undefined list.
void LTOModule::addAsmGlobalSymbolUndef(const char *name) {
StringMap<NameAndAttributes>::value_type &entry =
_undefines.GetOrCreateValue(name);
@@ -421,13 +445,16 @@ void LTOModule::addAsmGlobalSymbolUndef(const char *name) {
attr |= LTO_SYMBOL_SCOPE_DEFAULT;
NameAndAttributes info;
info.name = entry.getKey().data();
- info.attributes = (lto_symbol_attributes)attr;
+ info.attributes = attr;
+ info.isFunction = false;
+ info.symbol = 0;
entry.setValue(info);
}
-void LTOModule::addPotentialUndefinedSymbol(GlobalValue *decl,
- Mangler &mangler) {
+/// addPotentialUndefinedSymbol - Add a symbol which isn't defined just yet to a
+/// list to be resolved later.
+void LTOModule::addPotentialUndefinedSymbol(GlobalValue *decl, bool isFunc) {
// ignore all llvm.* symbols
if (decl->getName().startswith("llvm."))
return;
@@ -437,7 +464,7 @@ void LTOModule::addPotentialUndefinedSymbol(GlobalValue *decl,
return;
SmallString<64> name;
- mangler.getNameWithPrefix(name, decl, false);
+ _mangler.getNameWithPrefix(name, decl, false);
StringMap<NameAndAttributes>::value_type &entry =
_undefines.GetOrCreateValue(name);
@@ -449,19 +476,22 @@ void LTOModule::addPotentialUndefinedSymbol(GlobalValue *decl,
NameAndAttributes info;
info.name = entry.getKey().data();
+
if (decl->hasExternalWeakLinkage())
info.attributes = LTO_SYMBOL_DEFINITION_WEAKUNDEF;
else
info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
+ info.isFunction = isFunc;
+ info.symbol = decl;
+
entry.setValue(info);
}
-
namespace {
class RecordStreamer : public MCStreamer {
public:
- enum State { NeverSeen, Global, Defined, DefinedGlobal, Used};
+ enum State { NeverSeen, Global, Defined, DefinedGlobal, Used };
private:
StringMap<State> Symbols;
@@ -550,14 +580,16 @@ namespace {
RecordStreamer(MCContext &Context) : MCStreamer(Context) {}
- virtual void ChangeSection(const MCSection *Section) {}
- virtual void InitSections() {}
+ virtual void EmitInstruction(const MCInst &Inst) {
+ // Scan for values.
+ for (unsigned i = Inst.getNumOperands(); i--; )
+ if (Inst.getOperand(i).isExpr())
+ AddValueSymbols(Inst.getOperand(i).getExpr());
+ }
virtual void EmitLabel(MCSymbol *Symbol) {
Symbol->setSection(*getCurrentSection());
markDefined(*Symbol);
}
- virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {}
- virtual void EmitThumbFunc(MCSymbol *Func) {}
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
// FIXME: should we handle aliases?
markDefined(*Symbol);
@@ -566,20 +598,26 @@ namespace {
if (Attribute == MCSA_Global)
markGlobal(*Symbol);
}
- virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
- virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
- virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {}
- virtual void EmitCOFFSymbolStorageClass(int StorageClass) {}
virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
unsigned Size , unsigned ByteAlignment) {
markDefined(*Symbol);
}
- virtual void EmitCOFFSymbolType(int Type) {}
- virtual void EndCOFFSymbolDef() {}
virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {
markDefined(*Symbol);
}
+
+ // Noop calls.
+ virtual void ChangeSection(const MCSection *Section) {}
+ virtual void InitSections() {}
+ virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {}
+ virtual void EmitThumbFunc(MCSymbol *Func) {}
+ virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
+ virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
+ virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {}
+ virtual void EmitCOFFSymbolStorageClass(int StorageClass) {}
+ virtual void EmitCOFFSymbolType(int Type) {}
+ virtual void EndCOFFSymbolDef() {}
virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {}
@@ -595,35 +633,30 @@ 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,
const MCSymbol *Label,
unsigned PointerSize) {}
-
- virtual void EmitInstruction(const MCInst &Inst) {
- // Scan for values.
- for (unsigned i = Inst.getNumOperands(); i--; )
- if (Inst.getOperand(i).isExpr())
- AddValueSymbols(Inst.getOperand(i).getExpr());
- }
- virtual void Finish() {}
+ virtual void FinishImpl() {}
};
-}
+} // end anonymous namespace
-bool LTOModule::addAsmGlobalSymbols(MCContext &Context, std::string &errMsg) {
+/// addAsmGlobalSymbols - Add global symbols from module-level ASM to the
+/// defined or undefined lists.
+bool LTOModule::addAsmGlobalSymbols(std::string &errMsg) {
const std::string &inlineAsm = _module->getModuleInlineAsm();
if (inlineAsm.empty())
return false;
- OwningPtr<RecordStreamer> Streamer(new RecordStreamer(Context));
+ OwningPtr<RecordStreamer> Streamer(new RecordStreamer(_context));
MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(inlineAsm);
SourceMgr SrcMgr;
SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr,
- Context, *Streamer,
+ _context, *Streamer,
*_target->getMCAsmInfo()));
OwningPtr<MCSubtargetInfo> STI(_target->getTarget().
createMCSubtargetInfo(_target->getTargetTriple(),
@@ -657,6 +690,7 @@ bool LTOModule::addAsmGlobalSymbols(MCContext &Context, std::string &errMsg) {
return false;
}
+/// isDeclaration - Return 'true' if the global value is a declaration.
static bool isDeclaration(const GlobalValue &V) {
if (V.hasAvailableExternallyLinkage())
return true;
@@ -665,74 +699,49 @@ static bool isDeclaration(const GlobalValue &V) {
return V.isDeclaration();
}
-static bool isAliasToDeclaration(const GlobalAlias &V) {
- return isDeclaration(*V.getAliasedGlobal());
-}
-
-bool LTOModule::ParseSymbols(std::string &errMsg) {
- // Use mangler to add GlobalPrefix to names to match linker names.
- MCContext Context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(),NULL);
- Mangler mangler(Context, *_target->getTargetData());
-
+/// parseSymbols - Parse the symbols from the module and model-level ASM and add
+/// them to either the defined or undefined lists.
+bool LTOModule::parseSymbols(std::string &errMsg) {
// add functions
- for (Module::iterator f = _module->begin(); f != _module->end(); ++f) {
+ for (Module::iterator f = _module->begin(), e = _module->end(); f != e; ++f) {
if (isDeclaration(*f))
- addPotentialUndefinedSymbol(f, mangler);
+ addPotentialUndefinedSymbol(f, true);
else
- addDefinedFunctionSymbol(f, mangler);
+ addDefinedFunctionSymbol(f);
}
// add data
for (Module::global_iterator v = _module->global_begin(),
e = _module->global_end(); v != e; ++v) {
if (isDeclaration(*v))
- addPotentialUndefinedSymbol(v, mangler);
+ addPotentialUndefinedSymbol(v, false);
else
- addDefinedDataSymbol(v, mangler);
+ addDefinedDataSymbol(v);
}
// add asm globals
- if (addAsmGlobalSymbols(Context, errMsg))
+ if (addAsmGlobalSymbols(errMsg))
return true;
// add aliases
- for (Module::alias_iterator i = _module->alias_begin(),
- e = _module->alias_end(); i != e; ++i) {
- if (isAliasToDeclaration(*i))
- addPotentialUndefinedSymbol(i, mangler);
+ for (Module::alias_iterator a = _module->alias_begin(),
+ e = _module->alias_end(); a != e; ++a) {
+ if (isDeclaration(*a->getAliasedGlobal()))
+ // Is an alias to a declaration.
+ addPotentialUndefinedSymbol(a, false);
else
- addDefinedDataSymbol(i, mangler);
+ addDefinedDataSymbol(a);
}
// make symbols for all undefines
- for (StringMap<NameAndAttributes>::iterator it=_undefines.begin();
- it != _undefines.end(); ++it) {
- // if this symbol also has a definition, then don't make an undefine
- // because it is a tentative definition
- if (_defines.count(it->getKey()) == 0) {
- NameAndAttributes info = it->getValue();
- _symbols.push_back(info);
- }
+ for (StringMap<NameAndAttributes>::iterator u =_undefines.begin(),
+ e = _undefines.end(); u != e; ++u) {
+ // If this symbol also has a definition, then don't make an undefine because
+ // it is a tentative definition.
+ if (_defines.count(u->getKey())) continue;
+ NameAndAttributes info = u->getValue();
+ _symbols.push_back(info);
}
- return false;
-}
-
-uint32_t LTOModule::getSymbolCount() {
- return _symbols.size();
-}
-
-
-lto_symbol_attributes LTOModule::getSymbolAttributes(uint32_t index) {
- if (index < _symbols.size())
- return _symbols[index].attributes;
- else
- return lto_symbol_attributes(0);
-}
-
-const char *LTOModule::getSymbolName(uint32_t index) {
- if (index < _symbols.size())
- return _symbols[index].name;
- else
- return NULL;
+ return false;
}
diff --git a/tools/lto/LTOModule.h b/tools/lto/LTOModule.h
index ca08aea..cafb927 100644
--- a/tools/lto/LTOModule.h
+++ b/tools/lto/LTOModule.h
@@ -4,10 +4,10 @@
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
-// This file declares the LTOModule class.
+// This file declares the LTOModule class.
//
//===----------------------------------------------------------------------===//
@@ -15,110 +15,172 @@
#define LTO_MODULE_H
#include "llvm/Module.h"
-#include "llvm/ADT/OwningPtr.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
-
#include "llvm-c/lto.h"
-
#include <vector>
#include <string>
-
-// forward references to llvm classes
+// Forward references to llvm classes.
namespace llvm {
- class Mangler;
- class MemoryBuffer;
- class GlobalValue;
- class Value;
- class Function;
+ class Function;
+ class GlobalValue;
+ class MemoryBuffer;
+ class Value;
}
-
-//
-// C++ class which implements the opaque lto_module_t
-//
+//===----------------------------------------------------------------------===//
+/// LTOModule - C++ class which implements the opaque lto_module_t type.
+///
struct LTOModule {
-
- static bool isBitcodeFile(const void* mem, size_t length);
- static bool isBitcodeFile(const char* path);
-
- static bool isBitcodeFileForTarget(const void* mem,
- size_t length, const char* triplePrefix);
-
- static bool isBitcodeFileForTarget(const char* path,
- const char* triplePrefix);
-
- static LTOModule* makeLTOModule(const char* path,
- std::string& errMsg);
- static LTOModule* makeLTOModule(int fd, const char *path,
- size_t size,
- std::string& errMsg);
- static LTOModule* makeLTOModule(int fd, const char *path,
- size_t file_size,
- size_t map_size,
- off_t offset,
- std::string& errMsg);
- static LTOModule* makeLTOModule(const void* mem, size_t length,
- std::string& errMsg);
-
- const char* getTargetTriple();
- void setTargetTriple(const char*);
- uint32_t getSymbolCount();
- lto_symbol_attributes getSymbolAttributes(uint32_t index);
- const char* getSymbolName(uint32_t index);
-
- llvm::Module * getLLVVMModule() { return _module.get(); }
- const std::vector<const char*> &getAsmUndefinedRefs() {
- return _asm_undefines;
- }
+private:
+ typedef llvm::StringMap<uint8_t> StringSet;
+
+ struct NameAndAttributes {
+ const char *name;
+ uint32_t attributes;
+ bool isFunction;
+ llvm::GlobalValue *symbol;
+ };
+
+ llvm::OwningPtr<llvm::Module> _module;
+ llvm::OwningPtr<llvm::TargetMachine> _target;
+ std::vector<NameAndAttributes> _symbols;
+
+ // _defines and _undefines only needed to disambiguate tentative definitions
+ StringSet _defines;
+ llvm::StringMap<NameAndAttributes> _undefines;
+ std::vector<const char*> _asm_undefines;
+ llvm::MCContext _context;
+
+ // Use mangler to add GlobalPrefix to names to match linker names.
+ llvm::Mangler _mangler;
+
+ LTOModule(llvm::Module *m, llvm::TargetMachine *t);
+public:
+ /// isBitcodeFile - Returns 'true' if the file or memory contents is LLVM
+ /// bitcode.
+ static bool isBitcodeFile(const void *mem, size_t length);
+ static bool isBitcodeFile(const char *path);
+
+ /// isBitcodeFileForTarget - Returns 'true' if the file or memory contents
+ /// is LLVM bitcode for the specified triple.
+ static bool isBitcodeFileForTarget(const void *mem,
+ size_t length,
+ const char *triplePrefix);
+ static bool isBitcodeFileForTarget(const char *path,
+ const char *triplePrefix);
+
+ /// makeLTOModule - Create an LTOModule. N.B. These methods take ownership
+ /// of the buffer.
+ static LTOModule *makeLTOModule(const char* path,
+ std::string &errMsg);
+ static LTOModule *makeLTOModule(int fd, const char *path,
+ size_t size, std::string &errMsg);
+ static LTOModule *makeLTOModule(int fd, const char *path,
+ size_t file_size,
+ size_t map_size,
+ off_t offset,
+ std::string& errMsg);
+ static LTOModule *makeLTOModule(const void *mem, size_t length,
+ std::string &errMsg);
+
+ /// getTargetTriple - Return the Module's target triple.
+ const char *getTargetTriple() {
+ return _module->getTargetTriple().c_str();
+ }
+
+ /// setTargetTriple - Set the Module's target triple.
+ void setTargetTriple(const char *triple) {
+ _module->setTargetTriple(triple);
+ }
+
+ /// getSymbolCount - Get the number of symbols
+ uint32_t getSymbolCount() {
+ return _symbols.size();
+ }
+
+ /// getSymbolAttributes - Get the attributes for a symbol at the specified
+ /// index.
+ lto_symbol_attributes getSymbolAttributes(uint32_t index) {
+ if (index < _symbols.size())
+ return lto_symbol_attributes(_symbols[index].attributes);
+ return lto_symbol_attributes(0);
+ }
+
+ /// getSymbolName - Get the name of the symbol at the specified index.
+ const char *getSymbolName(uint32_t index) {
+ if (index < _symbols.size())
+ return _symbols[index].name;
+ return NULL;
+ }
+
+ /// getLLVVMModule - Return the Module.
+ llvm::Module *getLLVVMModule() { return _module.get(); }
+
+ /// getAsmUndefinedRefs -
+ const std::vector<const char*> &getAsmUndefinedRefs() {
+ return _asm_undefines;
+ }
private:
- LTOModule(llvm::Module* m, llvm::TargetMachine* t);
-
- bool ParseSymbols(std::string &errMsg);
- void addDefinedSymbol(llvm::GlobalValue* def,
- llvm::Mangler& mangler,
- bool isFunction);
- void addPotentialUndefinedSymbol(llvm::GlobalValue* decl,
- llvm::Mangler &mangler);
- void addDefinedFunctionSymbol(llvm::Function* f,
- llvm::Mangler &mangler);
- void addDefinedDataSymbol(llvm::GlobalValue* v,
- llvm::Mangler &mangler);
- bool addAsmGlobalSymbols(llvm::MCContext &Context,
- std::string &errMsg);
- void addAsmGlobalSymbol(const char *,
- lto_symbol_attributes scope);
- void addAsmGlobalSymbolUndef(const char *);
- void addObjCClass(llvm::GlobalVariable* clgv);
- void addObjCCategory(llvm::GlobalVariable* clgv);
- void addObjCClassRef(llvm::GlobalVariable* clgv);
- bool objcClassNameFromExpression(llvm::Constant* c,
- std::string& name);
-
- static bool isTargetMatch(llvm::MemoryBuffer* memBuffer,
- const char* triplePrefix);
-
- static LTOModule* makeLTOModule(llvm::MemoryBuffer* buffer,
- std::string& errMsg);
- static llvm::MemoryBuffer* makeBuffer(const void* mem, size_t length);
-
- typedef llvm::StringMap<uint8_t> StringSet;
-
- struct NameAndAttributes {
- const char* name;
- lto_symbol_attributes attributes;
- };
-
- llvm::OwningPtr<llvm::Module> _module;
- llvm::OwningPtr<llvm::TargetMachine> _target;
- std::vector<NameAndAttributes> _symbols;
- // _defines and _undefines only needed to disambiguate tentative definitions
- StringSet _defines;
- llvm::StringMap<NameAndAttributes> _undefines;
- std::vector<const char*> _asm_undefines;
+ /// parseSymbols - Parse the symbols from the module and model-level ASM and
+ /// add them to either the defined or undefined lists.
+ bool parseSymbols(std::string &errMsg);
+
+ /// addPotentialUndefinedSymbol - Add a symbol which isn't defined just yet
+ /// to a list to be resolved later.
+ void addPotentialUndefinedSymbol(llvm::GlobalValue *dcl, bool isFunc);
+
+ /// addDefinedSymbol - Add a defined symbol to the list.
+ void addDefinedSymbol(llvm::GlobalValue *def, bool isFunction);
+
+ /// addDefinedFunctionSymbol - Add a function symbol as defined to the list.
+ void addDefinedFunctionSymbol(llvm::Function *f);
+
+ /// addDefinedDataSymbol - Add a data symbol as defined to the list.
+ void addDefinedDataSymbol(llvm::GlobalValue *v);
+
+ /// addAsmGlobalSymbols - Add global symbols from module-level ASM to the
+ /// defined or undefined lists.
+ bool addAsmGlobalSymbols(std::string &errMsg);
+
+ /// addAsmGlobalSymbol - Add a global symbol from module-level ASM to the
+ /// defined list.
+ void addAsmGlobalSymbol(const char *, lto_symbol_attributes scope);
+
+ /// addAsmGlobalSymbolUndef - Add a global symbol from module-level ASM to
+ /// the undefined list.
+ void addAsmGlobalSymbolUndef(const char *);
+
+ /// addObjCClass - Parse i386/ppc ObjC class data structure.
+ void addObjCClass(llvm::GlobalVariable *clgv);
+
+ /// addObjCCategory - Parse i386/ppc ObjC category data structure.
+ void addObjCCategory(llvm::GlobalVariable *clgv);
+
+ /// addObjCClassRef - Parse i386/ppc ObjC class list data structure.
+ void addObjCClassRef(llvm::GlobalVariable *clgv);
+
+ /// objcClassNameFromExpression - Get string that the data pointer points
+ /// to.
+ bool objcClassNameFromExpression(llvm::Constant* c, std::string &name);
+
+ /// isTargetMatch - Returns 'true' if the memory buffer is for the specified
+ /// target triple.
+ static bool isTargetMatch(llvm::MemoryBuffer *memBuffer,
+ const char *triplePrefix);
+
+ /// makeLTOModule - Create an LTOModule (private version). N.B. This
+ /// method takes ownership of the buffer.
+ static LTOModule *makeLTOModule(llvm::MemoryBuffer *buffer,
+ std::string &errMsg);
+
+ /// makeBuffer - Create a MemoryBuffer from a memory range.
+ static llvm::MemoryBuffer *makeBuffer(const void *mem, size_t length);
};
#endif // LTO_MODULE_H
-
diff --git a/tools/lto/Makefile b/tools/lto/Makefile
index 46925e7..153fa03 100644
--- a/tools/lto/Makefile
+++ b/tools/lto/Makefile
@@ -7,22 +7,15 @@
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-LIBRARYNAME = LTO
+LEVEL := ../..
+LIBRARYNAME := LTO
+LINK_COMPONENTS := all-targets ipo scalaropts linker bitreader bitwriter \
+ mcdisassembler vectorize
+LINK_LIBS_IN_SHARED := 1
+SHARED_LIBRARY := 1
EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/lto.exports
-# Include this here so we can get the configuration of the targets
-# that have been configured for construction. We have to do this
-# early so we can set up LINK_COMPONENTS before including Makefile.rules
-include $(LEVEL)/Makefile.config
-
-LINK_LIBS_IN_SHARED = 1
-SHARED_LIBRARY = 1
-
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) ipo scalaropts linker bitreader \
- bitwriter mcdisassembler
-
include $(LEVEL)/Makefile.common
ifdef LLVM_VERSION_INFO
diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp
index dd658d1..addf787 100644
--- a/tools/lto/lto.cpp
+++ b/tools/lto/lto.cpp
@@ -4,10 +4,10 @@
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
-// This file implements the Link Time Optimization library. This library is
+// This file implements the Link Time Optimization library. This library is
// intended to be used by linker to optimize code at link time.
//
//===----------------------------------------------------------------------===//
@@ -19,292 +19,202 @@
#include "LTOCodeGenerator.h"
-// holds most recent error string
-// *** not thread safe ***
+// Holds most recent error string.
+// *** Not thread safe ***
static std::string sLastErrorString;
-
-
-//
-// returns a printable string
-//
-extern const char* lto_get_version()
-{
- return LTOCodeGenerator::getVersionString();
+/// lto_get_version - Returns a printable string.
+extern const char* lto_get_version() {
+ return LTOCodeGenerator::getVersionString();
}
-//
-// returns the last error string or NULL if last operation was successful
-//
-const char* lto_get_error_message()
-{
- return sLastErrorString.c_str();
+/// lto_get_error_message - Returns the last error string or NULL if last
+/// operation was successful.
+const char* lto_get_error_message() {
+ return sLastErrorString.c_str();
}
-
-
-//
-// validates if a file is a loadable object file
-//
-bool lto_module_is_object_file(const char* path)
-{
- return LTOModule::isBitcodeFile(path);
+/// lto_module_is_object_file - Validates if a file is a loadable object file.
+bool lto_module_is_object_file(const char* path) {
+ return LTOModule::isBitcodeFile(path);
}
-
-//
-// validates if a file is a loadable object file compilable for requested target
-//
-bool lto_module_is_object_file_for_target(const char* path,
- const char* target_triplet_prefix)
-{
- return LTOModule::isBitcodeFileForTarget(path, target_triplet_prefix);
+/// lto_module_is_object_file_for_target - Validates if a file is a loadable
+/// object file compilable for requested target.
+bool lto_module_is_object_file_for_target(const char* path,
+ const char* target_triplet_prefix) {
+ return LTOModule::isBitcodeFileForTarget(path, target_triplet_prefix);
}
-
-//
-// validates if a buffer is a loadable object file
-//
-bool lto_module_is_object_file_in_memory(const void* mem, size_t length)
-{
- return LTOModule::isBitcodeFile(mem, length);
+/// lto_module_is_object_file_in_memory - Validates if a buffer is a loadable
+/// object file.
+bool lto_module_is_object_file_in_memory(const void* mem, size_t length) {
+ return LTOModule::isBitcodeFile(mem, length);
}
-
-//
-// validates if a buffer is a loadable object file compilable for the target
-//
-bool lto_module_is_object_file_in_memory_for_target(const void* mem,
- size_t length, const char* target_triplet_prefix)
-{
- return LTOModule::isBitcodeFileForTarget(mem, length, target_triplet_prefix);
+/// lto_module_is_object_file_in_memory_for_target - Validates if a buffer is a
+/// loadable object file compilable for the target.
+bool
+lto_module_is_object_file_in_memory_for_target(const void* mem,
+ size_t length,
+ const char* target_triplet_prefix) {
+ return LTOModule::isBitcodeFileForTarget(mem, length, target_triplet_prefix);
}
-
-
-//
-// loads an object file from disk
-// returns NULL on error (check lto_get_error_message() for details)
-//
-lto_module_t lto_module_create(const char* path)
-{
- return LTOModule::makeLTOModule(path, sLastErrorString);
+/// lto_module_create - Loads an object file from disk. Returns NULL on error
+/// (check lto_get_error_message() for details).
+lto_module_t lto_module_create(const char* path) {
+ return LTOModule::makeLTOModule(path, sLastErrorString);
}
-//
-// loads an object file from disk
-// returns NULL on error (check lto_get_error_message() for details)
-//
-lto_module_t lto_module_create_from_fd(int fd, const char *path, size_t size)
-{
- return LTOModule::makeLTOModule(fd, path, size, sLastErrorString);
+/// lto_module_create_from_fd - Loads an object file from disk. Returns NULL on
+/// error (check lto_get_error_message() for details).
+lto_module_t lto_module_create_from_fd(int fd, const char *path, size_t size) {
+ return LTOModule::makeLTOModule(fd, path, size, sLastErrorString);
}
-//
-// loads an object file from disk
-// returns NULL on error (check lto_get_error_message() for details)
-//
+/// lto_module_create_from_fd_at_offset - Loads an object file from disk.
+/// Returns NULL on error (check lto_get_error_message() for details).
lto_module_t lto_module_create_from_fd_at_offset(int fd, const char *path,
size_t file_size,
size_t map_size,
- off_t offset)
-{
- return LTOModule::makeLTOModule(fd, path, file_size, map_size,
- offset, sLastErrorString);
+ off_t offset) {
+ return LTOModule::makeLTOModule(fd, path, file_size, map_size,
+ offset, sLastErrorString);
}
-//
-// loads an object file from memory
-// returns NULL on error (check lto_get_error_message() for details)
-//
-lto_module_t lto_module_create_from_memory(const void* mem, size_t length)
-{
- return LTOModule::makeLTOModule(mem, length, sLastErrorString);
+/// lto_module_create_from_memory - Loads an object file from memory. Returns
+/// NULL on error (check lto_get_error_message() for details).
+lto_module_t lto_module_create_from_memory(const void* mem, size_t length) {
+ return LTOModule::makeLTOModule(mem, length, sLastErrorString);
}
-
-//
-// frees all memory for a module
-// upon return the lto_module_t is no longer valid
-//
-void lto_module_dispose(lto_module_t mod)
-{
- delete mod;
+/// lto_module_dispose - Frees all memory for a module. Upon return the
+/// lto_module_t is no longer valid.
+void lto_module_dispose(lto_module_t mod) {
+ delete mod;
}
-
-//
-// returns triplet string which the object module was compiled under
-//
-const char* lto_module_get_target_triple(lto_module_t mod)
-{
- return mod->getTargetTriple();
+/// lto_module_get_target_triple - Returns triplet string which the object
+/// module was compiled under.
+const char* lto_module_get_target_triple(lto_module_t mod) {
+ return mod->getTargetTriple();
}
-//
-// sets triple string with which the object will be codegened.
-//
-void lto_module_set_target_triple(lto_module_t mod, const char *triple)
-{
- return mod->setTargetTriple(triple);
+/// lto_module_set_target_triple - Sets triple string with which the object will
+/// be codegened.
+void lto_module_set_target_triple(lto_module_t mod, const char *triple) {
+ return mod->setTargetTriple(triple);
}
-
-//
-// returns the number of symbols in the object module
-//
-unsigned int lto_module_get_num_symbols(lto_module_t mod)
-{
- return mod->getSymbolCount();
+/// lto_module_get_num_symbols - Returns the number of symbols in the object
+/// module.
+unsigned int lto_module_get_num_symbols(lto_module_t mod) {
+ return mod->getSymbolCount();
}
-//
-// returns the name of the ith symbol in the object module
-//
-const char* lto_module_get_symbol_name(lto_module_t mod, unsigned int index)
-{
- return mod->getSymbolName(index);
+/// lto_module_get_symbol_name - Returns the name of the ith symbol in the
+/// object module.
+const char* lto_module_get_symbol_name(lto_module_t mod, unsigned int index) {
+ return mod->getSymbolName(index);
}
-
-//
-// returns the attributes of the ith symbol in the object module
-//
-lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod,
- unsigned int index)
-{
- return mod->getSymbolAttributes(index);
+/// lto_module_get_symbol_attribute - Returns the attributes of the ith symbol
+/// in the object module.
+lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod,
+ unsigned int index) {
+ return mod->getSymbolAttributes(index);
}
-
-
-
-
-//
-// instantiates a code generator
-// returns NULL if there is an error
-//
-lto_code_gen_t lto_codegen_create(void)
-{
- return new LTOCodeGenerator();
+/// lto_codegen_create - Instantiates a code generator. Returns NULL if there
+/// is an error.
+lto_code_gen_t lto_codegen_create(void) {
+ return new LTOCodeGenerator();
}
-
-
-//
-// frees all memory for a code generator
-// upon return the lto_code_gen_t is no longer valid
-//
-void lto_codegen_dispose(lto_code_gen_t cg)
-{
- delete cg;
+/// lto_codegen_dispose - Frees all memory for a code generator. Upon return the
+/// lto_code_gen_t is no longer valid.
+void lto_codegen_dispose(lto_code_gen_t cg) {
+ delete cg;
}
-
-
-//
-// add an object module to the set of modules for which code will be generated
-// returns true on error (check lto_get_error_message() for details)
-//
-bool lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod)
-{
- return cg->addModule(mod, sLastErrorString);
+/// lto_codegen_add_module - Add an object module to the set of modules for
+/// which code will be generated. Returns true on error (check
+/// lto_get_error_message() for details).
+bool lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod) {
+ return cg->addModule(mod, sLastErrorString);
}
-
-//
-// sets what if any format of debug info should be generated
-// returns true on error (check lto_get_error_message() for details)
-//
-bool lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model debug)
-{
- return cg->setDebugInfo(debug, sLastErrorString);
+/// lto_codegen_set_debug_model - Sets what if any format of debug info should
+/// be generated. Returns true on error (check lto_get_error_message() for
+/// details).
+bool lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model debug) {
+ return cg->setDebugInfo(debug, sLastErrorString);
}
-
-//
-// sets what code model to generated
-// returns true on error (check lto_get_error_message() for details)
-//
-bool lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model model)
-{
+/// lto_codegen_set_pic_model - Sets what code model to generated. Returns true
+/// on error (check lto_get_error_message() for details).
+bool lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model model) {
return cg->setCodePICModel(model, sLastErrorString);
}
-//
-// sets the cpu to generate code for
-//
-void lto_codegen_set_cpu(lto_code_gen_t cg, const char* cpu)
-{
+/// lto_codegen_set_cpu - Sets the cpu to generate code for.
+void lto_codegen_set_cpu(lto_code_gen_t cg, const char *cpu) {
return cg->setCpu(cpu);
}
-//
-// sets the path to the assembler tool
-//
-void lto_codegen_set_assembler_path(lto_code_gen_t cg, const char* path)
-{
+/// lto_codegen_set_assembler_path - Sets the path to the assembler tool.
+void lto_codegen_set_assembler_path(lto_code_gen_t cg, const char *path) {
// In here only for backwards compatibility. We use MC now.
}
-
-//
-// sets extra arguments that libLTO should pass to the assembler
-//
-void lto_codegen_set_assembler_args(lto_code_gen_t cg, const char** args,
- int nargs)
-{
+/// lto_codegen_set_assembler_args - Sets extra arguments that libLTO should
+/// pass to the assembler.
+void lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args,
+ int nargs) {
// In here only for backwards compatibility. We use MC now.
}
-//
-// adds to a list of all global symbols that must exist in the final
-// generated code. If a function is not listed there, it might be
-// inlined into every usage and optimized away.
-//
-void lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, const char* symbol)
-{
+/// lto_codegen_add_must_preserve_symbol - Adds to a list of all global symbols
+/// that must exist in the final generated code. If a function is not listed
+/// there, it might be inlined into every usage and optimized away.
+void lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg,
+ const char *symbol) {
cg->addMustPreserveSymbol(symbol);
}
+/// lto_codegen_set_whole_program_optimization - Enable the internalize pass
+/// during LTO optimizations.
+void lto_codegen_set_whole_program_optimization(lto_code_gen_t cg) {
+ cg->enableInternalizePass();
+}
-//
-// writes a new file at the specified path that contains the
-// merged contents of all modules added so far.
-// returns true on error (check lto_get_error_message() for details)
-//
-bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char* path)
-{
+/// lto_codegen_write_merged_modules - Writes a new file at the specified path
+/// that contains the merged contents of all modules added so far. Returns true
+/// on error (check lto_get_error_message() for details).
+bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) {
return cg->writeMergedModules(path, sLastErrorString);
}
-
-//
-// Generates code for all added modules into one native object file.
-// On success returns a pointer to a generated mach-o/ELF buffer and
-// length set to the buffer size. The buffer is owned by the
-// lto_code_gen_t and will be freed when lto_codegen_dispose()
-// is called, or lto_codegen_compile() is called again.
-// On failure, returns NULL (check lto_get_error_message() for details).
-//
-extern const void*
-lto_codegen_compile(lto_code_gen_t cg, size_t* length)
-{
+/// lto_codegen_compile - Generates code for all added modules into one native
+/// object file. On success returns a pointer to a generated mach-o/ELF buffer
+/// and length set to the buffer size. The buffer is owned by the lto_code_gen_t
+/// object and will be freed when lto_codegen_dispose() is called, or
+/// lto_codegen_compile() is called again. On failure, returns NULL (check
+/// lto_get_error_message() for details).
+const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) {
return cg->compile(length, sLastErrorString);
}
-extern bool
-lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name)
-{
+/// lto_codegen_compile_to_file - Generates code for all added modules into one
+/// native object file. The name of the file is written to name. Returns true on
+/// error.
+bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) {
return cg->compile_to_file(name, sLastErrorString);
}
-
-//
-// Used to pass extra options to the code generator
-//
-extern void
-lto_codegen_debug_options(lto_code_gen_t cg, const char * opt)
-{
+/// lto_codegen_debug_options - Used to pass extra options to the code
+/// generator.
+void lto_codegen_debug_options(lto_code_gen_t cg, const char *opt) {
cg->setCodeGenDebugOptions(opt);
}
diff --git a/tools/lto/lto.exports b/tools/lto/lto.exports
index b900bfb..f471f1a 100644
--- a/tools/lto/lto.exports
+++ b/tools/lto/lto.exports
@@ -27,6 +27,7 @@ lto_codegen_set_assembler_args
lto_codegen_set_assembler_path
lto_codegen_set_cpu
lto_codegen_compile_to_file
+lto_codegen_set_whole_program_optimization
LLVMCreateDisasm
LLVMDisasmDispose
LLVMDisasmInstruction
diff --git a/tools/macho-dump/LLVMBuild.txt b/tools/macho-dump/LLVMBuild.txt
new file mode 100644
index 0000000..1ad9b84
--- /dev/null
+++ b/tools/macho-dump/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/macho-dump/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 = macho-dump
+parent = Tools
+required_libraries = Object Support
diff --git a/tools/macho-dump/Makefile b/tools/macho-dump/Makefile
index 638015e..0843e98 100644
--- a/tools/macho-dump/Makefile
+++ b/tools/macho-dump/Makefile
@@ -7,17 +7,11 @@
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = macho-dump
+LEVEL := ../..
+TOOLNAME := macho-dump
+LINK_COMPONENTS := support object
# This tool has no plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
-
-# Include this here so we can get the configuration of the targets
-# that have been configured for construction. We have to do this
-# early so we can set up LINK_COMPONENTS before including Makefile.rules
-include $(LEVEL)/Makefile.config
-
-LINK_COMPONENTS := support object
+TOOL_NO_EXPORTS := 1
-include $(LLVM_SRC_ROOT)/Makefile.rules
+include $(LEVEL)/Makefile.common
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/LLVMBuild.txt b/tools/opt/LLVMBuild.txt
new file mode 100644
index 0000000..4de99f5
--- /dev/null
+++ b/tools/opt/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/opt/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 = opt
+parent = Tools
+required_libraries = AsmParser BitReader BitWriter IPO Instrumentation Scalar
diff --git a/tools/opt/Makefile b/tools/opt/Makefile
index 726cad8..16d116d 100644
--- a/tools/opt/Makefile
+++ b/tools/opt/Makefile
@@ -6,9 +6,9 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = opt
-LINK_COMPONENTS := bitreader bitwriter asmparser instrumentation scalaropts ipo
+LEVEL := ../..
+TOOLNAME := opt
+LINK_COMPONENTS := bitreader bitwriter asmparser instrumentation scalaropts ipo vectorize
include $(LEVEL)/Makefile.common
diff --git a/tools/opt/PrintSCC.cpp b/tools/opt/PrintSCC.cpp
index 533f49e..11efdcd 100644
--- a/tools/opt/PrintSCC.cpp
+++ b/tools/opt/PrintSCC.cpp
@@ -101,8 +101,8 @@ bool CallGraphSCC::runOnModule(Module &M) {
errs() << "\nSCC #" << ++sccNum << " : ";
for (std::vector<CallGraphNode*>::const_iterator I = nextSCC.begin(),
E = nextSCC.end(); I != E; ++I)
- errs() << ((*I)->getFunction() ? (*I)->getFunction()->getNameStr()
- : std::string("external node")) << ", ";
+ errs() << ((*I)->getFunction() ? (*I)->getFunction()->getName()
+ : "external node") << ", ";
if (nextSCC.size() == 1 && SCCI.hasLoop())
errs() << " (Has self-loop).";
}
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp
index ffd2c21..30da863 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -291,8 +291,8 @@ struct RegionPassPrinter : public RegionPass {
virtual bool runOnRegion(Region *R, RGPassManager &RGM) {
if (!Quiet) {
Out << "Printing analysis '" << PassToPrint->getPassName() << "' for "
- << "region: '" << R->getNameStr() << "' in function '"
- << R->getEntry()->getParent()->getNameStr() << "':\n";
+ << "region: '" << R->getNameStr() << "' in function '"
+ << R->getEntry()->getParent()->getName() << "':\n";
}
// Get and print pass...
getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out,
@@ -407,6 +407,8 @@ static inline void addPass(PassManagerBase &PM, Pass *P) {
/// OptLevel - Optimization Level
static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM,
unsigned OptLevel) {
+ FPM.add(createVerifierPass()); // Verify that input is correct
+
PassManagerBuilder Builder;
Builder.OptLevel = OptLevel;
@@ -478,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);
@@ -505,7 +508,7 @@ int main(int argc, char **argv) {
M.reset(ParseIRFile(InputFilename, Err, Context));
if (M.get() == 0) {
- Err.Print(argv[0], errs());
+ Err.print(argv[0], errs());
return 1;
}
OpenPOWER on IntegriCloud