summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2011-02-20 12:57:14 +0000
committerdim <dim@FreeBSD.org>2011-02-20 12:57:14 +0000
commitcbb70ce070d220642b038ea101d9c0f9fbf860d6 (patch)
treed2b61ce94e654cb01a254d2195259db5f9cc3f3c /tools
parent4ace901e87dac5bbbac78ed325e75462e48e386e (diff)
downloadFreeBSD-src-cbb70ce070d220642b038ea101d9c0f9fbf860d6.zip
FreeBSD-src-cbb70ce070d220642b038ea101d9c0f9fbf860d6.tar.gz
Vendor import of llvm trunk r126079:
http://llvm.org/svn/llvm-project/llvm/trunk@126079
Diffstat (limited to 'tools')
-rw-r--r--tools/CMakeLists.txt16
-rw-r--r--tools/Makefile48
-rw-r--r--tools/bugpoint-passes/CMakeLists.txt2
-rw-r--r--tools/bugpoint/BugDriver.cpp2
-rw-r--r--tools/bugpoint/BugDriver.h3
-rw-r--r--tools/bugpoint/CrashDebugger.cpp8
-rw-r--r--tools/bugpoint/ExecutionDriver.cpp44
-rw-r--r--tools/bugpoint/ExtractFunction.cpp12
-rw-r--r--tools/bugpoint/Miscompilation.cpp12
-rw-r--r--tools/bugpoint/OptimizerDriver.cpp28
-rw-r--r--tools/bugpoint/ToolRunner.cpp206
-rw-r--r--tools/bugpoint/ToolRunner.h13
-rw-r--r--tools/bugpoint/bugpoint.cpp31
-rw-r--r--tools/edis/CMakeLists.txt2
-rw-r--r--tools/edis/Makefile4
-rw-r--r--tools/gold/Makefile3
-rw-r--r--tools/gold/gold-plugin.cpp139
-rw-r--r--tools/llc/llc.cpp22
-rw-r--r--tools/lli/CMakeLists.txt2
-rw-r--r--tools/lli/Makefile2
-rw-r--r--tools/lli/lli.cpp40
-rw-r--r--tools/llvm-ar/llvm-ar.cpp78
-rw-r--r--tools/llvm-as/llvm-as.cpp4
-rw-r--r--tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp30
-rw-r--r--tools/llvm-config/CMakeLists.txt19
-rw-r--r--tools/llvm-config/llvm-config.in.in5
-rw-r--r--tools/llvm-diff/llvm-diff.cpp75
-rw-r--r--tools/llvm-dis/llvm-dis.cpp37
-rw-r--r--tools/llvm-extract/llvm-extract.cpp45
-rw-r--r--tools/llvm-ld/CMakeLists.txt2
-rw-r--r--tools/llvm-ld/Optimize.cpp2
-rw-r--r--tools/llvm-ld/llvm-ld.cpp62
-rw-r--r--tools/llvm-link/llvm-link.cpp6
-rw-r--r--tools/llvm-mc/Disassembler.cpp3
-rw-r--r--tools/llvm-mc/llvm-mc.cpp193
-rw-r--r--tools/llvm-nm/CMakeLists.txt2
-rw-r--r--tools/llvm-nm/Makefile2
-rw-r--r--tools/llvm-nm/llvm-nm.cpp228
-rw-r--r--tools/llvm-objdump/CMakeLists.txt11
-rw-r--r--tools/llvm-objdump/Makefile17
-rw-r--r--tools/llvm-objdump/llvm-objdump.cpp255
-rw-r--r--tools/llvm-prof/llvm-prof.cpp14
-rw-r--r--tools/llvm-ranlib/llvm-ranlib.cpp14
-rw-r--r--tools/llvm-shlib/Makefile15
-rw-r--r--tools/llvm-stub/llvm-stub.c10
-rw-r--r--tools/llvmc/doc/LLVMC-Reference.rst71
-rw-r--r--tools/llvmc/examples/mcc16/Hooks.cpp2
-rw-r--r--tools/llvmc/examples/mcc16/Main.cpp2
-rw-r--r--tools/llvmc/src/Base.td.in227
-rw-r--r--tools/llvmc/src/Clang.td6
-rw-r--r--tools/llvmc/src/Hooks.cpp181
-rw-r--r--tools/lto/LTOCodeGenerator.cpp38
-rw-r--r--tools/lto/LTOModule.cpp83
-rw-r--r--tools/lto/LTOModule.h3
-rw-r--r--tools/lto/Makefile4
-rw-r--r--tools/lto/lto.cpp14
-rw-r--r--tools/lto/lto.exports1
-rw-r--r--tools/macho-dump/CMakeLists.txt5
-rw-r--r--tools/macho-dump/Makefile23
-rw-r--r--tools/macho-dump/macho-dump.cpp391
-rw-r--r--tools/opt/GraphPrinters.cpp13
-rw-r--r--tools/opt/opt.cpp223
62 files changed, 2346 insertions, 709 deletions
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 7ed10e9..2f37911 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -1,6 +1,14 @@
-# NOTE: The tools are organized into five groups of four consisting of one
-# large and three small executables. This is done to minimize memory load
-# in parallel builds. Please retain this ordering.
+# NOTE: The tools are organized into groups of four consisting of one large and
+# three small executables. This is done to minimize memory load in parallel
+# builds. Please retain this ordering.
+
+# If polly exists and is not disabled compile it and add it to the LLVM tools.
+option(LLVM_BUILD_POLLY "Compile polly" ON)
+if( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/polly/CMakeLists.txt )
+ if (LLVM_BUILD_POLLY)
+ add_subdirectory( ${CMAKE_CURRENT_SOURCE_DIR}/polly)
+ endif (LLVM_BUILD_POLLY)
+endif( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/polly/CMakeLists.txt )
if( NOT WIN32 OR MSYS OR CYGWIN )
# It is useful to build llvm-config before the other tools, so we
@@ -28,6 +36,8 @@ add_subdirectory(lli)
add_subdirectory(llvm-extract)
add_subdirectory(llvm-diff)
+add_subdirectory(macho-dump)
+add_subdirectory(llvm-objdump)
add_subdirectory(bugpoint)
add_subdirectory(bugpoint-passes)
diff --git a/tools/Makefile b/tools/Makefile
index aa07a2b..7310247 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -12,6 +12,10 @@ LEVEL := ..
# Build clang if present.
OPTIONAL_PARALLEL_DIRS := clang
+# Build LLDB if present. Note LLDB must be built last as it depends on the
+# wider LLVM infrastructure (including Clang).
+OPTIONAL_DIRS := lldb
+
# NOTE: The tools are organized into five groups of four consisting of one
# large and three small executables. This is done to minimize memory load
# in parallel builds. Please retain this ordering.
@@ -21,12 +25,13 @@ PARALLEL_DIRS := opt llvm-as llvm-dis \
llvm-ld llvm-prof llvm-link \
lli llvm-extract llvm-mc \
bugpoint llvm-bcanalyzer llvm-stub \
- llvmc llvm-diff
+ llvmc llvm-diff macho-dump llvm-objdump
# Let users override the set of tools to build from the command line.
ifdef ONLY_TOOLS
OPTIONAL_PARALLEL_DIRS :=
- PARALLEL_DIRS := $(ONLY_TOOLS)
+ OPTIONAL_DIRS := $(findstring lldb,$(ONLY_TOOLS))
+ PARALLEL_DIRS := $(filter-out lldb,$(ONLY_TOOLS))
endif
include $(LEVEL)/Makefile.config
@@ -34,26 +39,37 @@ 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
ifeq ($(ENABLE_PIC),1)
- # No support for dynamic libraries on windows targets.
- ifneq ($(TARGET_OS), $(filter $(TARGET_OS), Cygwin MingW))
- # gold only builds if binutils is around. It requires "lto" to build before
- # it so it is added to DIRS.
- ifdef BINUTILS_INCDIR
- DIRS += lto gold
- else
- PARALLEL_DIRS += lto
- endif
+ # gold only builds if binutils is around. It requires "lto" to build before
+ # it so it is added to DIRS.
+ ifdef BINUTILS_INCDIR
+ DIRS += lto gold
+ else
+ PARALLEL_DIRS += lto
+ endif
- PARALLEL_DIRS += bugpoint-passes
+ 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)
+ # 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
+endif
+
+ifdef LLVM_HAS_POLLY
+ PARALLEL_DIRS += polly
+endif
+endif
+
+# On Win32, loadable modules can be built with ENABLE_SHARED.
+ifneq ($(ENABLE_SHARED),1)
+ ifneq (,$(filter $(HOST_OS), Cygwin MingW))
+ PARALLEL_DIRS := $(filter-out bugpoint-passes, \
+ $(PARALLEL_DIRS))
endif
endif
diff --git a/tools/bugpoint-passes/CMakeLists.txt b/tools/bugpoint-passes/CMakeLists.txt
index 50109a5..b2f1bb5 100644
--- a/tools/bugpoint-passes/CMakeLists.txt
+++ b/tools/bugpoint-passes/CMakeLists.txt
@@ -1,3 +1,5 @@
add_llvm_loadable_module( BugpointPasses
TestPasses.cpp
)
+
+add_dependencies(BugpointPasses bugpoint)
diff --git a/tools/bugpoint/BugDriver.cpp b/tools/bugpoint/BugDriver.cpp
index 6966671..1cbf632 100644
--- a/tools/bugpoint/BugDriver.cpp
+++ b/tools/bugpoint/BugDriver.cpp
@@ -23,7 +23,7 @@
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Host.h"
+#include "llvm/Support/Host.h"
#include <memory>
using namespace llvm;
diff --git a/tools/bugpoint/BugDriver.h b/tools/bugpoint/BugDriver.h
index e48806a..cc78489 100644
--- a/tools/bugpoint/BugDriver.h
+++ b/tools/bugpoint/BugDriver.h
@@ -17,6 +17,7 @@
#define BUGDRIVER_H
#include "llvm/ADT/ValueMap.h"
+#include "llvm/Transforms/Utils/ValueMapper.h"
#include <vector>
#include <string>
@@ -322,7 +323,7 @@ void DeleteFunctionBody(Function *F);
/// module, split the functions OUT of the specified module, and place them in
/// the new module.
Module *SplitFunctionsOutOfModule(Module *M, const std::vector<Function*> &F,
- ValueMap<const Value*, Value*> &VMap);
+ ValueToValueMapTy &VMap);
} // End llvm namespace
diff --git a/tools/bugpoint/CrashDebugger.cpp b/tools/bugpoint/CrashDebugger.cpp
index 57dc1c8..f19ef62 100644
--- a/tools/bugpoint/CrashDebugger.cpp
+++ b/tools/bugpoint/CrashDebugger.cpp
@@ -130,7 +130,7 @@ bool
ReduceCrashingGlobalVariables::TestGlobalVariables(
std::vector<GlobalVariable*> &GVs) {
// Clone the program to try hacking it apart...
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *M = CloneModule(BD.getProgram(), VMap);
// Convert list to set for fast lookup...
@@ -204,7 +204,7 @@ bool ReduceCrashingFunctions::TestFuncs(std::vector<Function*> &Funcs) {
return false;
// Clone the program to try hacking it apart...
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *M = CloneModule(BD.getProgram(), VMap);
// Convert list to set for fast lookup...
@@ -271,7 +271,7 @@ namespace {
bool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock*> &BBs) {
// Clone the program to try hacking it apart...
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *M = CloneModule(BD.getProgram(), VMap);
// Convert list to set for fast lookup...
@@ -381,7 +381,7 @@ namespace {
bool ReduceCrashingInstructions::TestInsts(std::vector<const Instruction*>
&Insts) {
// Clone the program to try hacking it apart...
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *M = CloneModule(BD.getProgram(), VMap);
// Convert list to set for fast lookup...
diff --git a/tools/bugpoint/ExecutionDriver.cpp b/tools/bugpoint/ExecutionDriver.cpp
index 7312484..f1601cd 100644
--- a/tools/bugpoint/ExecutionDriver.cpp
+++ b/tools/bugpoint/ExecutionDriver.cpp
@@ -28,7 +28,8 @@ namespace {
// for miscompilation.
//
enum OutputType {
- AutoPick, RunLLI, RunJIT, RunLLC, RunLLCIA, RunCBE, CBE_bug, LLC_Safe,Custom
+ AutoPick, RunLLI, RunJIT, RunLLC, RunLLCIA, RunCBE, CBE_bug, LLC_Safe,
+ CompileCustom, Custom
};
cl::opt<double>
@@ -50,6 +51,9 @@ namespace {
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 "
+ "compile the bitcode. Useful to avoid linking."),
clEnumValN(Custom, "run-custom",
"Use -exec-command to define a command to execute "
"the bitcode. Useful for cross-compilation."),
@@ -87,10 +91,15 @@ namespace {
"into executing programs"));
cl::list<std::string>
- AdditionalLinkerArgs("Xlinker",
+ AdditionalLinkerArgs("Xlinker",
cl::desc("Additional arguments to pass to the linker"));
cl::opt<std::string>
+ CustomCompileCommand("compile-command", cl::init("llc"),
+ cl::desc("Command to compile the bitcode (use with -compile-custom) "
+ "(default: llc)"));
+
+ cl::opt<std::string>
CustomExecCommand("exec-command", cl::init("simulate"),
cl::desc("Command to execute the bitcode (use with -run-custom) "
"(default: simulate)"));
@@ -119,7 +128,7 @@ namespace {
cl::ZeroOrMore, cl::PositionalEatsArgs);
cl::opt<std::string>
- GCCBinary("gcc", cl::init("gcc"),
+ GCCBinary("gcc", cl::init("gcc"),
cl::desc("The gcc binary to use. (default 'gcc')"));
cl::list<std::string>
@@ -157,7 +166,7 @@ bool BugDriver::initializeExecutionEnvironment() {
if (!Interpreter) {
InterpreterSel = RunLLC;
Interpreter = AbstractInterpreter::createLLC(getToolName(), Message,
- GCCBinary, &ToolArgv,
+ GCCBinary, &ToolArgv,
&GCCToolArgv);
}
if (!Interpreter) {
@@ -178,7 +187,7 @@ bool BugDriver::initializeExecutionEnvironment() {
case RunLLCIA:
case LLC_Safe:
Interpreter = AbstractInterpreter::createLLC(getToolName(), Message,
- GCCBinary, &ToolArgv,
+ GCCBinary, &ToolArgv,
&GCCToolArgv,
InterpreterSel == RunLLCIA);
break;
@@ -189,11 +198,16 @@ bool BugDriver::initializeExecutionEnvironment() {
case RunCBE:
case CBE_bug:
Interpreter = AbstractInterpreter::createCBE(getToolName(), Message,
- GCCBinary, &ToolArgv,
+ GCCBinary, &ToolArgv,
&GCCToolArgv);
break;
+ case CompileCustom:
+ Interpreter =
+ AbstractInterpreter::createCustomCompiler(Message, CustomCompileCommand);
+ break;
case Custom:
- Interpreter = AbstractInterpreter::createCustom(Message, CustomExecCommand);
+ Interpreter =
+ AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand);
break;
default:
Message = "Sorry, this back-end is not supported by bugpoint right now!\n";
@@ -216,7 +230,7 @@ bool BugDriver::initializeExecutionEnvironment() {
SafeInterpreterSel = RunLLC;
SafeToolArgs.push_back("--relocation-model=pic");
SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
- GCCBinary,
+ GCCBinary,
&SafeToolArgs,
&GCCToolArgv);
}
@@ -227,7 +241,7 @@ bool BugDriver::initializeExecutionEnvironment() {
SafeInterpreterSel = RunLLC;
SafeToolArgs.push_back("--relocation-model=pic");
SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
- GCCBinary,
+ GCCBinary,
&SafeToolArgs,
&GCCToolArgv);
}
@@ -249,7 +263,7 @@ bool BugDriver::initializeExecutionEnvironment() {
SafeInterpreterSel = RunLLC;
SafeToolArgs.push_back("--relocation-model=pic");
SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
- GCCBinary,
+ GCCBinary,
&SafeToolArgs,
&GCCToolArgv);
}
@@ -272,8 +286,8 @@ bool BugDriver::initializeExecutionEnvironment() {
&GCCToolArgv);
break;
case Custom:
- SafeInterpreter = AbstractInterpreter::createCustom(Message,
- CustomExecCommand);
+ SafeInterpreter =
+ AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand);
break;
default:
Message = "Sorry, this back-end is not supported by bugpoint as the "
@@ -281,7 +295,7 @@ bool BugDriver::initializeExecutionEnvironment() {
break;
}
if (!SafeInterpreter) { outs() << Message << "\nExiting.\n"; exit(1); }
-
+
gcc = GCC::create(Message, GCCBinary, &GCCToolArgv);
if (!gcc) { outs() << Message << "\nExiting.\n"; exit(1); }
@@ -298,7 +312,7 @@ void BugDriver::compileProgram(Module *M, std::string *Error) const {
sys::Path BitcodeFile (OutputPrefix + "-test-program.bc");
std::string ErrMsg;
if (BitcodeFile.makeUnique(true, &ErrMsg)) {
- errs() << ToolName << ": Error making unique filename: " << ErrMsg
+ errs() << ToolName << ": Error making unique filename: " << ErrMsg
<< "\n";
exit(1);
}
@@ -432,7 +446,7 @@ std::string BugDriver::compileSharedObject(const std::string &BitcodeFile,
}
/// createReferenceFile - calls compileProgram and then records the output
-/// into ReferenceOutputFile. Returns true if reference file created, false
+/// into ReferenceOutputFile. Returns true if reference file created, false
/// otherwise. Note: initializeExecutionEnvironment should be called BEFORE
/// this function.
///
diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp
index 524f130..593765c 100644
--- a/tools/bugpoint/ExtractFunction.cpp
+++ b/tools/bugpoint/ExtractFunction.cpp
@@ -29,9 +29,9 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileUtilities.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Path.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Signals.h"
#include <set>
using namespace llvm;
@@ -193,7 +193,7 @@ static Constant *GetTorInit(std::vector<std::pair<Function*, int> > &TorList) {
/// static ctors/dtors, we need to add an llvm.global_[cd]tors global to M2, and
/// prune appropriate entries out of M1s list.
static void SplitStaticCtorDtor(const char *GlobalName, Module *M1, Module *M2,
- ValueMap<const Value*, Value*> &VMap) {
+ ValueToValueMapTy &VMap) {
GlobalVariable *GV = M1->getNamedGlobal(GlobalName);
if (!GV || GV->isDeclaration() || GV->hasLocalLinkage() ||
!GV->use_empty()) return;
@@ -256,7 +256,7 @@ static void SplitStaticCtorDtor(const char *GlobalName, Module *M1, Module *M2,
Module *
llvm::SplitFunctionsOutOfModule(Module *M,
const std::vector<Function*> &F,
- ValueMap<const Value*, Value*> &VMap) {
+ ValueToValueMapTy &VMap) {
// Make sure functions & globals are all external so that linkage
// between the two modules will work.
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
@@ -268,7 +268,7 @@ llvm::SplitFunctionsOutOfModule(Module *M,
I->setLinkage(GlobalValue::ExternalLinkage);
}
- ValueMap<const Value*, Value*> NewVMap;
+ ValueToValueMapTy NewVMap;
Module *New = CloneModule(M, NewVMap);
// Make sure global initializers exist only in the safe module (CBE->.so)
diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp
index 3f2b696..3a5f143 100644
--- a/tools/bugpoint/Miscompilation.cpp
+++ b/tools/bugpoint/Miscompilation.cpp
@@ -261,7 +261,7 @@ bool ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function*> &Funcs,
// a function, we want to continue with the original function. Otherwise
// we can conclude that a function triggers the bug when in fact one
// needs a larger set of original functions to do so.
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *Clone = CloneModule(BD.getProgram(), VMap);
Module *Orig = BD.swapProgramIn(Clone);
@@ -310,7 +310,7 @@ static bool ExtractLoops(BugDriver &BD,
while (1) {
if (BugpointIsInterrupted) return MadeChange;
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap);
Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize,
MiscompiledFunctions,
@@ -476,7 +476,7 @@ bool ReduceMiscompiledBlocks::TestFuncs(const std::vector<BasicBlock*> &BBs,
outs() << '\n';
// Split the module into the two halves of the program we want.
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *Clone = CloneModule(BD.getProgram(), VMap);
Module *Orig = BD.swapProgramIn(Clone);
std::vector<Function*> FuncsOnClone;
@@ -551,7 +551,7 @@ static bool ExtractBlocks(BugDriver &BD,
return false;
}
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *ProgClone = CloneModule(BD.getProgram(), VMap);
Module *ToExtract = SplitFunctionsOutOfModule(ProgClone,
MiscompiledFunctions,
@@ -738,7 +738,7 @@ void BugDriver::debugMiscompilation(std::string *Error) {
// Output a bunch of bitcode files for the user...
outs() << "Outputting reduced bitcode files which expose the problem:\n";
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *ToNotOptimize = CloneModule(getProgram(), VMap);
Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize,
MiscompiledFunctions,
@@ -1011,7 +1011,7 @@ bool BugDriver::debugCodeGenerator(std::string *Error) {
return true;
// Split the module into the two halves of the program we want.
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *ToNotCodeGen = CloneModule(getProgram(), VMap);
Module *ToCodeGen = SplitFunctionsOutOfModule(ToNotCodeGen, Funcs, VMap);
diff --git a/tools/bugpoint/OptimizerDriver.cpp b/tools/bugpoint/OptimizerDriver.cpp
index 3600ca6..2471cc1 100644
--- a/tools/bugpoint/OptimizerDriver.cpp
+++ b/tools/bugpoint/OptimizerDriver.cpp
@@ -15,10 +15,6 @@
//
//===----------------------------------------------------------------------===//
-// Note: as a short term hack, the old Unix-specific code and platform-
-// independent code co-exist via conditional compilation until it is verified
-// that the new code works correctly on Unix.
-
#include "BugDriver.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
@@ -29,9 +25,9 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Path.h"
-#include "llvm/System/Program.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
#define DONT_GET_PLUGIN_LOADER_OPTION
#include "llvm/Support/PluginLoader.h"
@@ -130,12 +126,12 @@ bool BugDriver::runPasses(Module *Program,
<< ErrMsg << "\n";
return(1);
}
-
+
std::string ErrInfo;
tool_output_file InFile(inputFilename.c_str(), ErrInfo,
raw_fd_ostream::F_Binary);
-
-
+
+
if (!ErrInfo.empty()) {
errs() << "Error opening bitcode file: " << inputFilename.str() << "\n";
return 1;
@@ -147,11 +143,19 @@ bool BugDriver::runPasses(Module *Program,
InFile.os().clear_error();
return 1;
}
+
+ sys::Path tool = PrependMainExecutablePath("opt", getToolName(),
+ (void*)"opt");
+ if (tool.empty()) {
+ errs() << "Cannot find `opt' in executable directory!\n";
+ return 1;
+ }
+
+ // Ok, everything that could go wrong before running opt is done.
InFile.keep();
// setup the child process' arguments
SmallVector<const char*, 8> Args;
- sys::Path tool = FindExecutable("opt", getToolName(), (void*)"opt");
std::string Opt = tool.str();
if (UseValgrind) {
Args.push_back("valgrind");
@@ -192,7 +196,7 @@ bool BugDriver::runPasses(Module *Program,
prog = sys::Program::FindProgramByName("valgrind");
else
prog = tool;
-
+
// Redirect stdout and stderr to nowhere if SilencePasses is given
sys::Path Nowhere;
const sys::Path *Redirects[3] = {0, &Nowhere, &Nowhere};
diff --git a/tools/bugpoint/ToolRunner.cpp b/tools/bugpoint/ToolRunner.cpp
index 36dbe14..37cc902 100644
--- a/tools/bugpoint/ToolRunner.cpp
+++ b/tools/bugpoint/ToolRunner.cpp
@@ -13,7 +13,7 @@
#define DEBUG_TYPE "toolrunner"
#include "ToolRunner.h"
-#include "llvm/System/Program.h"
+#include "llvm/Support/Program.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileUtilities.h"
@@ -59,7 +59,8 @@ static int RunProgramWithTimeout(const sys::Path &ProgramPath,
const sys::Path &StdOutFile,
const sys::Path &StdErrFile,
unsigned NumSeconds = 0,
- unsigned MemoryLimit = 0) {
+ unsigned MemoryLimit = 0,
+ std::string *ErrMsg = 0) {
const sys::Path* redirects[3];
redirects[0] = &StdInFile;
redirects[1] = &StdOutFile;
@@ -76,7 +77,7 @@ static int RunProgramWithTimeout(const sys::Path &ProgramPath,
return
sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects,
- NumSeconds, MemoryLimit);
+ NumSeconds, MemoryLimit, ErrMsg);
}
/// RunProgramRemotelyWithTimeout - This function runs the given program
@@ -141,7 +142,7 @@ static std::string ProcessFailure(sys::Path ProgPath, const char** Args,
for (const char **Arg = Args; *Arg; ++Arg)
OS << " " << *Arg;
OS << "\n";
-
+
// Rerun the compiler, capturing any error messages to print them.
sys::Path ErrorFilename("bugpoint.program_error_messages");
std::string ErrMsg;
@@ -206,7 +207,8 @@ int LLI::ExecuteProgram(const std::string &Bitcode,
LLIArgs.push_back(LLIPath.c_str());
LLIArgs.push_back("-force-interpreter=true");
- for (std::vector<std::string>::const_iterator i = SharedLibs.begin(), e = SharedLibs.end(); i != e; ++i) {
+ for (std::vector<std::string>::const_iterator i = SharedLibs.begin(),
+ e = SharedLibs.end(); i != e; ++i) {
LLIArgs.push_back("-load");
LLIArgs.push_back((*i).c_str());
}
@@ -229,7 +231,7 @@ int LLI::ExecuteProgram(const std::string &Bitcode,
);
return RunProgramWithTimeout(sys::Path(LLIPath), &LLIArgs[0],
sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
- Timeout, MemoryLimit);
+ Timeout, MemoryLimit, Error);
}
// LLI create method - Try to find the LLI executable
@@ -237,21 +239,82 @@ AbstractInterpreter *AbstractInterpreter::createLLI(const char *Argv0,
std::string &Message,
const std::vector<std::string> *ToolArgs) {
std::string LLIPath =
- FindExecutable("lli", Argv0, (void *)(intptr_t)&createLLI).str();
+ PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createLLI).str();
if (!LLIPath.empty()) {
Message = "Found lli: " + LLIPath + "\n";
return new LLI(LLIPath, ToolArgs);
}
- Message = "Cannot find `lli' in executable directory or PATH!\n";
+ Message = "Cannot find `lli' in executable directory!\n";
return 0;
}
//===---------------------------------------------------------------------===//
+// Custom compiler command implementation of AbstractIntepreter interface
+//
+// Allows using a custom command for compiling the bitcode, thus allows, for
+// example, to compile a bitcode fragment without linking or executing, then
+// using a custom wrapper script to check for compiler errors.
+namespace {
+ class CustomCompiler : public AbstractInterpreter {
+ std::string CompilerCommand;
+ std::vector<std::string> CompilerArgs;
+ public:
+ CustomCompiler(
+ const std::string &CompilerCmd, std::vector<std::string> CompArgs) :
+ CompilerCommand(CompilerCmd), CompilerArgs(CompArgs) {}
+
+ virtual void compileProgram(const std::string &Bitcode,
+ std::string *Error,
+ unsigned Timeout = 0,
+ unsigned MemoryLimit = 0);
+
+ virtual int 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> &GCCArgs =
+ std::vector<std::string>(),
+ const std::vector<std::string> &SharedLibs =
+ std::vector<std::string>(),
+ unsigned Timeout = 0,
+ unsigned MemoryLimit = 0) {
+ *Error = "Execution not supported with -compile-custom";
+ return -1;
+ }
+ };
+}
+
+void CustomCompiler::compileProgram(const std::string &Bitcode,
+ std::string *Error,
+ unsigned Timeout,
+ unsigned MemoryLimit) {
+
+ std::vector<const char*> ProgramArgs;
+ ProgramArgs.push_back(CompilerCommand.c_str());
+
+ for (std::size_t i = 0; i < CompilerArgs.size(); ++i)
+ ProgramArgs.push_back(CompilerArgs.at(i).c_str());
+ ProgramArgs.push_back(Bitcode.c_str());
+ ProgramArgs.push_back(0);
+
+ // Add optional parameters to the running program from Argv
+ for (unsigned i = 0, e = CompilerArgs.size(); i != e; ++i)
+ ProgramArgs.push_back(CompilerArgs[i].c_str());
+
+ if (RunProgramWithTimeout( sys::Path(CompilerCommand), &ProgramArgs[0],
+ sys::Path(), sys::Path(), sys::Path(),
+ Timeout, MemoryLimit, Error))
+ *Error = ProcessFailure(sys::Path(CompilerCommand), &ProgramArgs[0],
+ Timeout, MemoryLimit);
+}
+
+//===---------------------------------------------------------------------===//
// Custom execution command implementation of AbstractIntepreter interface
//
// Allows using a custom command for executing the bitcode, thus allows,
-// for example, to invoke a cross compiler for code generation followed by
+// for example, to invoke a cross compiler for code generation followed by
// a simulator that executes the generated binary.
namespace {
class CustomExecutor : public AbstractInterpreter {
@@ -299,55 +362,78 @@ int CustomExecutor::ExecuteProgram(const std::string &Bitcode,
return RunProgramWithTimeout(
sys::Path(ExecutionCommand),
- &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile),
- sys::Path(OutputFile), Timeout, MemoryLimit);
+ &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile),
+ sys::Path(OutputFile), Timeout, MemoryLimit, Error);
}
-// Custom execution environment create method, takes the execution command
-// as arguments
-AbstractInterpreter *AbstractInterpreter::createCustom(
- std::string &Message,
- const std::string &ExecCommandLine) {
+// Tokenize the CommandLine to the command and the args to allow
+// defining a full command line as the command instead of just the
+// executed program. We cannot just pass the whole string after the command
+// as a single argument because then program sees only a single
+// command line argument (with spaces in it: "foo bar" instead
+// of "foo" and "bar").
+//
+// code borrowed from:
+// http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html
+static void lexCommand(std::string &Message, const std::string &CommandLine,
+ std::string &CmdPath, std::vector<std::string> Args) {
std::string Command = "";
- std::vector<std::string> Args;
std::string delimiters = " ";
- // Tokenize the ExecCommandLine to the command and the args to allow
- // defining a full command line as the command instead of just the
- // executed program. We cannot just pass the whole string after the command
- // as a single argument because then program sees only a single
- // command line argument (with spaces in it: "foo bar" instead
- // of "foo" and "bar").
-
- // code borrowed from:
- // http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html
- std::string::size_type lastPos =
- ExecCommandLine.find_first_not_of(delimiters, 0);
- std::string::size_type pos =
- ExecCommandLine.find_first_of(delimiters, lastPos);
+ std::string::size_type lastPos = CommandLine.find_first_not_of(delimiters, 0);
+ std::string::size_type pos = CommandLine.find_first_of(delimiters, lastPos);
while (std::string::npos != pos || std::string::npos != lastPos) {
- std::string token = ExecCommandLine.substr(lastPos, pos - lastPos);
+ std::string token = CommandLine.substr(lastPos, pos - lastPos);
if (Command == "")
Command = token;
else
Args.push_back(token);
// Skip delimiters. Note the "not_of"
- lastPos = ExecCommandLine.find_first_not_of(delimiters, pos);
+ lastPos = CommandLine.find_first_not_of(delimiters, pos);
// Find next "non-delimiter"
- pos = ExecCommandLine.find_first_of(delimiters, lastPos);
+ pos = CommandLine.find_first_of(delimiters, lastPos);
}
- std::string CmdPath = sys::Program::FindProgramByName(Command).str();
+ CmdPath = sys::Program::FindProgramByName(Command).str();
if (CmdPath.empty()) {
- Message =
- std::string("Cannot find '") + Command +
- "' in executable directory or PATH!\n";
- return 0;
+ Message =
+ std::string("Cannot find '") + Command +
+ "' in PATH!\n";
+ return;
}
Message = "Found command in: " + CmdPath + "\n";
+}
+
+// Custom execution environment create method, takes the execution command
+// as arguments
+AbstractInterpreter *AbstractInterpreter::createCustomCompiler(
+ std::string &Message,
+ const std::string &CompileCommandLine) {
+
+ std::string CmdPath;
+ std::vector<std::string> Args;
+ lexCommand(Message, CompileCommandLine, CmdPath, Args);
+ if (CmdPath.empty())
+ return 0;
+
+ return new CustomCompiler(CmdPath, Args);
+}
+
+// Custom execution environment create method, takes the execution command
+// as arguments
+AbstractInterpreter *AbstractInterpreter::createCustomExecutor(
+ std::string &Message,
+ const std::string &ExecCommandLine) {
+
+
+ std::string CmdPath;
+ std::vector<std::string> Args;
+ lexCommand(Message, ExecCommandLine, CmdPath, Args);
+ if (CmdPath.empty())
+ return 0;
return new CustomExecutor(CmdPath, Args);
}
@@ -355,7 +441,7 @@ AbstractInterpreter *AbstractInterpreter::createCustom(
//===----------------------------------------------------------------------===//
// LLC Implementation of AbstractIntepreter interface
//
-GCC::FileType LLC::OutputCode(const std::string &Bitcode,
+GCC::FileType LLC::OutputCode(const std::string &Bitcode,
sys::Path &OutputAsmFile, std::string &Error,
unsigned Timeout, unsigned MemoryLimit) {
const char *Suffix = (UseIntegratedAssembler ? ".llc.o" : ".llc.s");
@@ -376,10 +462,10 @@ GCC::FileType LLC::OutputCode(const std::string &Bitcode,
LLCArgs.push_back("-o");
LLCArgs.push_back(OutputAsmFile.c_str()); // Output to the Asm file
LLCArgs.push_back(Bitcode.c_str()); // This is the input bitcode
-
+
if (UseIntegratedAssembler)
LLCArgs.push_back("-filetype=obj");
-
+
LLCArgs.push_back (0);
outs() << (UseIntegratedAssembler ? "<llc-ia>" : "<llc>");
@@ -394,7 +480,7 @@ GCC::FileType LLC::OutputCode(const std::string &Bitcode,
Timeout, MemoryLimit))
Error = ProcessFailure(sys::Path(LLCPath), &LLCArgs[0],
Timeout, MemoryLimit);
- return UseIntegratedAssembler ? GCC::ObjectFile : GCC::AsmFile;
+ return UseIntegratedAssembler ? GCC::ObjectFile : GCC::AsmFile;
}
void LLC::compileProgram(const std::string &Bitcode, std::string *Error,
@@ -437,9 +523,9 @@ LLC *AbstractInterpreter::createLLC(const char *Argv0,
const std::vector<std::string> *GCCArgs,
bool UseIntegratedAssembler) {
std::string LLCPath =
- FindExecutable("llc", Argv0, (void *)(intptr_t)&createLLC).str();
+ PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createLLC).str();
if (LLCPath.empty()) {
- Message = "Cannot find `llc' in executable directory or PATH!\n";
+ Message = "Cannot find `llc' in executable directory!\n";
return 0;
}
@@ -474,7 +560,7 @@ namespace {
const std::vector<std::string> &GCCArgs =
std::vector<std::string>(),
const std::vector<std::string> &SharedLibs =
- std::vector<std::string>(),
+ std::vector<std::string>(),
unsigned Timeout = 0,
unsigned MemoryLimit = 0);
};
@@ -517,7 +603,7 @@ int JIT::ExecuteProgram(const std::string &Bitcode,
DEBUG(errs() << "\nSending output to " << OutputFile << "\n");
return RunProgramWithTimeout(sys::Path(LLIPath), &JITArgs[0],
sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
- Timeout, MemoryLimit);
+ Timeout, MemoryLimit, Error);
}
/// createJIT - Try to find the LLI executable
@@ -525,13 +611,13 @@ int JIT::ExecuteProgram(const std::string &Bitcode,
AbstractInterpreter *AbstractInterpreter::createJIT(const char *Argv0,
std::string &Message, const std::vector<std::string> *Args) {
std::string LLIPath =
- FindExecutable("lli", Argv0, (void *)(intptr_t)&createJIT).str();
+ PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createJIT).str();
if (!LLIPath.empty()) {
Message = "Found lli: " + LLIPath + "\n";
return new JIT(LLIPath, Args);
}
- Message = "Cannot find `lli' in executable directory or PATH!\n";
+ Message = "Cannot find `lli' in executable directory!\n";
return 0;
}
@@ -603,14 +689,14 @@ int CBE::ExecuteProgram(const std::string &Bitcode,
///
CBE *AbstractInterpreter::createCBE(const char *Argv0,
std::string &Message,
- const std::string &GCCBinary,
+ const std::string &GCCBinary,
const std::vector<std::string> *Args,
const std::vector<std::string> *GCCArgs) {
sys::Path LLCPath =
- FindExecutable("llc", Argv0, (void *)(intptr_t)&createCBE);
+ PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createCBE);
if (LLCPath.isEmpty()) {
Message =
- "Cannot find `llc' in executable directory or PATH!\n";
+ "Cannot find `llc' in executable directory!\n";
return 0;
}
@@ -677,9 +763,9 @@ int GCC::ExecuteProgram(const std::string &ProgramFile,
GCCArgs.push_back("-force_cpusubtype_ALL");
}
}
-
+
GCCArgs.push_back(ProgramFile.c_str()); // Specify the input filename.
-
+
GCCArgs.push_back("-x");
GCCArgs.push_back("none");
GCCArgs.push_back("-o");
@@ -771,7 +857,7 @@ int GCC::ExecuteProgram(const std::string &ProgramFile,
DEBUG(errs() << "<run locally>");
return RunProgramWithTimeout(OutputBinary, &ProgramArgs[0],
sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
- Timeout, MemoryLimit);
+ Timeout, MemoryLimit, Error);
} else {
outs() << "<run remotely>"; outs().flush();
return RunProgramRemotelyWithTimeout(sys::Path(RemoteClientPath),
@@ -793,7 +879,7 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
OutputFile = uniqueFilename.str();
std::vector<const char*> GCCArgs;
-
+
GCCArgs.push_back(GCCPath.c_str());
if (TargetTriple.getArch() == Triple::x86)
@@ -816,7 +902,7 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
GCCArgs.push_back("-G"); // Compile a shared library, `-G' for Sparc
else if (TargetTriple.getOS() == Triple::Darwin) {
// link all source files into a single module in data segment, rather than
- // generating blocks. dynamic_lookup requires that you set
+ // generating blocks. dynamic_lookup requires that you set
// MACOSX_DEPLOYMENT_TARGET=10.3 in your env. FIXME: it would be better for
// bugpoint to just pass that in the environment of GCC.
GCCArgs.push_back("-single_module");
@@ -837,8 +923,8 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
GCCArgs.push_back(OutputFile.c_str()); // Output to the right filename.
GCCArgs.push_back("-O2"); // Optimize the program a bit.
-
-
+
+
// Add any arguments intended for GCC. We locate them here because this is
// most likely -L and -l options that need to come before other libraries but
// after the source. Other options won't be sensitive to placement on the
@@ -847,7 +933,7 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
GCCArgs.push_back(ArgsForGCC[i].c_str());
GCCArgs.push_back(0); // NULL terminator
-
+
outs() << "<gcc>"; outs().flush();
DEBUG(errs() << "\nAbout to run:\t";
@@ -870,7 +956,7 @@ GCC *GCC::create(std::string &Message,
const std::vector<std::string> *Args) {
sys::Path GCCPath = sys::Program::FindProgramByName(GCCBinary);
if (GCCPath.isEmpty()) {
- Message = "Cannot find `"+ GCCBinary +"' in executable directory or PATH!\n";
+ Message = "Cannot find `"+ GCCBinary +"' in PATH!\n";
return 0;
}
diff --git a/tools/bugpoint/ToolRunner.h b/tools/bugpoint/ToolRunner.h
index cda0ddf..cfa8acf 100644
--- a/tools/bugpoint/ToolRunner.h
+++ b/tools/bugpoint/ToolRunner.h
@@ -21,7 +21,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SystemUtils.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
#include <exception>
#include <vector>
@@ -66,7 +66,7 @@ public:
const std::string &OutputFile,
std::string *Error = 0,
const std::vector<std::string> &GCCArgs =
- std::vector<std::string>(),
+ std::vector<std::string>(),
unsigned Timeout = 0,
unsigned MemoryLimit = 0);
@@ -103,8 +103,13 @@ public:
static AbstractInterpreter* createJIT(const char *Argv0, std::string &Message,
const std::vector<std::string> *Args=0);
- static AbstractInterpreter* createCustom(std::string &Message,
- const std::string &ExecCommandLine);
+ static AbstractInterpreter*
+ createCustomCompiler(std::string &Message,
+ const std::string &CompileCommandLine);
+
+ static AbstractInterpreter*
+ createCustomExecutor(std::string &Message,
+ const std::string &ExecCommandLine);
virtual ~AbstractInterpreter() {}
diff --git a/tools/bugpoint/bugpoint.cpp b/tools/bugpoint/bugpoint.cpp
index 79cf563..f9c9e18 100644
--- a/tools/bugpoint/bugpoint.cpp
+++ b/tools/bugpoint/bugpoint.cpp
@@ -23,10 +23,14 @@
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/StandardPasses.h"
-#include "llvm/System/Process.h"
-#include "llvm/System/Signals.h"
-#include "llvm/System/Valgrind.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/Valgrind.h"
#include "llvm/LinkAllVMCore.h"
+
+//Enable this macro to debug bugpoint itself.
+//#define DEBUG_BUGPOINT 1
+
using namespace llvm;
static cl::opt<bool>
@@ -71,9 +75,11 @@ OverrideTriple("mtriple", cl::desc("Override target triple for module"));
/// BugpointIsInterrupted - Set to true when the user presses ctrl-c.
bool llvm::BugpointIsInterrupted = false;
+#ifndef DEBUG_BUGPOINT
static void BugpointInterruptFunction() {
BugpointIsInterrupted = true;
}
+#endif
// Hack to capture a pass list.
namespace {
@@ -91,14 +97,31 @@ namespace {
}
int main(int argc, char **argv) {
+#ifndef DEBUG_BUGPOINT
llvm::sys::PrintStackTraceOnErrorSignal();
llvm::PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
+#endif
+
+ // Initialize passes
+ PassRegistry &Registry = *PassRegistry::getPassRegistry();
+ initializeCore(Registry);
+ initializeScalarOpts(Registry);
+ initializeIPO(Registry);
+ initializeAnalysis(Registry);
+ initializeIPA(Registry);
+ initializeTransformUtils(Registry);
+ initializeInstCombine(Registry);
+ initializeInstrumentation(Registry);
+ initializeTarget(Registry);
+
cl::ParseCommandLineOptions(argc, argv,
"LLVM automatic testcase reducer. See\nhttp://"
"llvm.org/cmds/bugpoint.html"
" for more information.\n");
+#ifndef DEBUG_BUGPOINT
sys::SetInterruptFunction(BugpointInterruptFunction);
+#endif
LLVMContext& Context = getGlobalContext();
// If we have an override, set it and then track the triple we want Modules
@@ -147,7 +170,9 @@ int main(int argc, char **argv) {
// Bugpoint has the ability of generating a plethora of core files, so to
// avoid filling up the disk, we prevent it
+#ifndef DEBUG_BUGPOINT
sys::Process::PreventCoreFiles();
+#endif
std::string Error;
bool Failure = D.run(Error);
diff --git a/tools/edis/CMakeLists.txt b/tools/edis/CMakeLists.txt
index 2019995..5037f9f 100644
--- a/tools/edis/CMakeLists.txt
+++ b/tools/edis/CMakeLists.txt
@@ -1,5 +1,3 @@
-set(LLVM_NO_RTTI 1)
-
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_llvm_library(EnhancedDisassembly
diff --git a/tools/edis/Makefile b/tools/edis/Makefile
index 92484bf..b5557fc 100644
--- a/tools/edis/Makefile
+++ b/tools/edis/Makefile
@@ -1,4 +1,4 @@
-##===- tools/ed/Makefile -----------------------------------*- Makefile -*-===##
+##===- tools/edis/Makefile -----------------------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
@@ -26,7 +26,7 @@ ifneq ($(filter $(TARGETS_TO_BUILD), X86),)
LINK_COMPONENTS += x86asmprinter x86disassembler
endif
-# If the X86 target is enabled, link in the asmprinter and disassembler.
+# If the ARM target is enabled, link in the asmprinter and disassembler.
ifneq ($(filter $(TARGETS_TO_BUILD), ARM),)
LINK_COMPONENTS += armasmprinter armdisassembler
endif
diff --git a/tools/gold/Makefile b/tools/gold/Makefile
index 1627346..66a0271 100644
--- a/tools/gold/Makefile
+++ b/tools/gold/Makefile
@@ -19,10 +19,9 @@ include $(LEVEL)/Makefile.config
LINK_LIBS_IN_SHARED=1
SHARED_LIBRARY = 1
-BUILD_ARCHIVE = 0
LOADABLE_MODULE = 1
-LINK_COMPONENTS := support system
+LINK_COMPONENTS := support
LIBS += -llto
# Because off_t is used in the public API, the largefile parts are required for
diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp
index 4b58fae..ad2774a 100644
--- a/tools/gold/gold-plugin.cpp
+++ b/tools/gold/gold-plugin.cpp
@@ -17,10 +17,10 @@
#include "llvm-c/lto.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Errno.h"
-#include "llvm/System/Path.h"
-#include "llvm/System/Program.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/Errno.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
#include <cerrno>
#include <cstdlib>
@@ -29,6 +29,13 @@
#include <list>
#include <vector>
+// Support Windows/MinGW crazyness.
+#ifdef _WIN32
+# include <io.h>
+# define lseek _lseek
+# define read _read
+#endif
+
using namespace llvm;
namespace {
@@ -49,7 +56,6 @@ namespace {
int gold_version = 0;
struct claimed_file {
- lto_module_t M;
void *handle;
std::vector<ld_plugin_symbol> syms;
};
@@ -58,6 +64,7 @@ namespace {
std::string output_name = "";
std::list<claimed_file> Modules;
std::vector<sys::Path> Cleanup;
+ lto_code_gen_t code_gen;
}
namespace options {
@@ -65,6 +72,7 @@ namespace options {
static bool generate_api_file = false;
static generate_bc generate_bc_file = BC_NO;
static std::string bc_path;
+ static std::string obj_path;
static std::string as_path;
static std::vector<std::string> as_args;
static std::vector<std::string> pass_through;
@@ -105,6 +113,8 @@ namespace options {
pass_through.push_back(item.str());
} else if (opt.startswith("mtriple=")) {
triple = opt.substr(strlen("mtriple="));
+ } else if (opt.startswith("obj-path=")) {
+ obj_path = opt.substr(strlen("obj-path="));
} else if (opt == "emit-llvm") {
generate_bc_file = BC_ONLY;
} else if (opt == "also-emit-llvm") {
@@ -226,6 +236,8 @@ ld_plugin_status onload(ld_plugin_tv *tv) {
return LDPS_ERR;
}
+ code_gen = lto_codegen_create();
+
return LDPS_OK;
}
@@ -234,7 +246,8 @@ ld_plugin_status onload(ld_plugin_tv *tv) {
/// with add_symbol if possible.
static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
int *claimed) {
- void *buf = NULL;
+ lto_module_t M;
+
if (file->offset) {
// Gold has found what might be IR part-way inside of a file, such as
// an .a archive.
@@ -245,7 +258,7 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
file->offset, sys::StrError(errno).c_str());
return LDPS_ERR;
}
- buf = malloc(file->filesize);
+ void *buf = malloc(file->filesize);
if (!buf) {
(*message)(LDPL_ERROR,
"Failed to allocate buffer for archive member of size: %d\n",
@@ -265,37 +278,50 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
free(buf);
return LDPS_OK;
}
- } else if (!lto_module_is_object_file(file->name))
- return LDPS_OK;
+ M = lto_module_create_from_memory(buf, file->filesize);
+ if (!M) {
+ (*message)(LDPL_ERROR, "Failed to create LLVM module: %s",
+ lto_get_error_message());
+ return LDPS_ERR;
+ }
+ free(buf);
+ } else {
+ // FIXME: We should not need to pass -1 as the file size, but there
+ // is a bug in BFD that causes it to pass 0 to us. Remove this once
+ // that is fixed.
+ off_t size = file->filesize ? file->filesize : -1;
+
+ // FIXME: We should not need to reset the position in the file, but there
+ // is a bug in BFD. Remove this once that is fixed.
+ off_t old_pos = lseek(file->fd, 0, SEEK_CUR);
+
+ lseek(file->fd, 0, SEEK_SET);
+ M = lto_module_create_from_fd(file->fd, file->name, size);
+
+ lseek(file->fd, old_pos, SEEK_SET);
+ if (!M)
+ return LDPS_OK;
+ }
*claimed = 1;
Modules.resize(Modules.size() + 1);
claimed_file &cf = Modules.back();
- cf.M = buf ? lto_module_create_from_memory(buf, file->filesize) :
- lto_module_create(file->name);
- free(buf);
- if (!cf.M) {
- (*message)(LDPL_ERROR, "Failed to create LLVM module: %s",
- lto_get_error_message());
- return LDPS_ERR;
- }
-
if (!options::triple.empty())
- lto_module_set_target_triple(cf.M, options::triple.c_str());
+ lto_module_set_target_triple(M, options::triple.c_str());
cf.handle = file->handle;
- unsigned sym_count = lto_module_get_num_symbols(cf.M);
+ unsigned sym_count = lto_module_get_num_symbols(M);
cf.syms.reserve(sym_count);
for (unsigned i = 0; i != sym_count; ++i) {
- lto_symbol_attributes attrs = lto_module_get_symbol_attribute(cf.M, i);
+ lto_symbol_attributes attrs = lto_module_get_symbol_attribute(M, i);
if ((attrs & LTO_SYMBOL_SCOPE_MASK) == LTO_SYMBOL_SCOPE_INTERNAL)
continue;
cf.syms.push_back(ld_plugin_symbol());
ld_plugin_symbol &sym = cf.syms.back();
- sym.name = const_cast<char *>(lto_module_get_symbol_name(cf.M, i));
+ sym.name = const_cast<char *>(lto_module_get_symbol_name(M, i));
sym.version = NULL;
int scope = attrs & LTO_SYMBOL_SCOPE_MASK;
@@ -316,6 +342,7 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
}
int definition = attrs & LTO_SYMBOL_DEFINITION_MASK;
+ sym.comdat_key = NULL;
switch (definition) {
case LTO_SYMBOL_DEFINITION_REGULAR:
sym.def = LDPK_DEF;
@@ -327,6 +354,7 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
sym.def = LDPK_COMMON;
break;
case LTO_SYMBOL_DEFINITION_WEAK:
+ sym.comdat_key = sym.name;
sym.def = LDPK_WEAKDEF;
break;
case LTO_SYMBOL_DEFINITION_WEAKUNDEF:
@@ -337,9 +365,7 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
return LDPS_ERR;
}
- // LLVM never emits COMDAT.
sym.size = 0;
- sym.comdat_key = NULL;
sym.resolution = LDPR_UNKNOWN;
}
@@ -353,6 +379,7 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
}
}
+ lto_codegen_add_module(code_gen, M);
return LDPS_OK;
}
@@ -361,12 +388,6 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
/// been overridden by a native object file. Then, perform optimization and
/// codegen.
static ld_plugin_status all_symbols_read_hook(void) {
- lto_code_gen_t cg = lto_codegen_create();
-
- for (std::list<claimed_file>::iterator I = Modules.begin(),
- E = Modules.end(); I != E; ++I)
- lto_codegen_add_module(cg, I->M);
-
std::ofstream api_file;
if (options::generate_api_file) {
api_file.open("apifile.txt", std::ofstream::out | std::ofstream::trunc);
@@ -384,7 +405,7 @@ static ld_plugin_status all_symbols_read_hook(void) {
(*get_symbols)(I->handle, I->syms.size(), &I->syms[0]);
for (unsigned i = 0, e = I->syms.size(); i != e; i++) {
if (I->syms[i].resolution == LDPR_PREVAILING_DEF) {
- lto_codegen_add_must_preserve_symbol(cg, I->syms[i].name);
+ lto_codegen_add_must_preserve_symbol(code_gen, I->syms[i].name);
anySymbolsPreserved = true;
if (options::generate_api_file)
@@ -398,15 +419,15 @@ static ld_plugin_status all_symbols_read_hook(void) {
if (!anySymbolsPreserved) {
// All of the IL is unnecessary!
- lto_codegen_dispose(cg);
+ lto_codegen_dispose(code_gen);
return LDPS_OK;
}
- lto_codegen_set_pic_model(cg, output_type);
- lto_codegen_set_debug_model(cg, LTO_DEBUG_MODEL_DWARF);
+ lto_codegen_set_pic_model(code_gen, output_type);
+ lto_codegen_set_debug_model(code_gen, LTO_DEBUG_MODEL_DWARF);
if (!options::as_path.empty()) {
sys::Path p = sys::Program::FindProgramByName(options::as_path);
- lto_codegen_set_assembler_path(cg, p.c_str());
+ lto_codegen_set_assembler_path(code_gen, p.c_str());
}
if (!options::as_args.empty()) {
std::vector<const char *> as_args_p;
@@ -414,20 +435,19 @@ static ld_plugin_status all_symbols_read_hook(void) {
E = options::as_args.end(); I != E; ++I) {
as_args_p.push_back(I->c_str());
}
- lto_codegen_set_assembler_args(cg, &as_args_p[0], as_args_p.size());
+ lto_codegen_set_assembler_args(code_gen, &as_args_p[0], as_args_p.size());
}
if (!options::mcpu.empty())
- lto_codegen_set_cpu(cg, options::mcpu.c_str());
+ lto_codegen_set_cpu(code_gen, options::mcpu.c_str());
// Pass through extra options to the code generator.
if (!options::extra.empty()) {
for (std::vector<std::string>::iterator it = options::extra.begin();
it != options::extra.end(); ++it) {
- lto_codegen_debug_options(cg, (*it).c_str());
+ lto_codegen_debug_options(code_gen, (*it).c_str());
}
}
-
if (options::generate_bc_file != options::BC_NO) {
std::string path;
if (options::generate_bc_file == options::BC_ONLY)
@@ -436,45 +456,51 @@ static ld_plugin_status all_symbols_read_hook(void) {
path = options::bc_path;
else
path = output_name + ".bc";
- bool err = lto_codegen_write_merged_modules(cg, path.c_str());
+ bool err = lto_codegen_write_merged_modules(code_gen, path.c_str());
if (err)
(*message)(LDPL_FATAL, "Failed to write the output file.");
if (options::generate_bc_file == options::BC_ONLY)
exit(0);
}
size_t bufsize = 0;
- const char *buffer = static_cast<const char *>(lto_codegen_compile(cg,
+ const char *buffer = static_cast<const char *>(lto_codegen_compile(code_gen,
&bufsize));
std::string ErrMsg;
- sys::Path uniqueObjPath("/tmp/llvmgold.o");
- if (uniqueObjPath.createTemporaryFileOnDisk(true, &ErrMsg)) {
- (*message)(LDPL_ERROR, "%s", ErrMsg.c_str());
- return LDPS_ERR;
- }
- tool_output_file objFile(uniqueObjPath.c_str(), ErrMsg,
- raw_fd_ostream::F_Binary);
- if (!ErrMsg.empty()) {
- (*message)(LDPL_ERROR, "%s", ErrMsg.c_str());
- return LDPS_ERR;
+ const char *objPath;
+ if (!options::obj_path.empty()) {
+ objPath = options::obj_path.c_str();
+ } else {
+ sys::Path uniqueObjPath("/tmp/llvmgold.o");
+ if (uniqueObjPath.createTemporaryFileOnDisk(true, &ErrMsg)) {
+ (*message)(LDPL_ERROR, "%s", ErrMsg.c_str());
+ return LDPS_ERR;
+ }
+ objPath = uniqueObjPath.c_str();
}
+ tool_output_file objFile(objPath, ErrMsg,
+ raw_fd_ostream::F_Binary);
+ if (!ErrMsg.empty()) {
+ (*message)(LDPL_ERROR, "%s", ErrMsg.c_str());
+ return LDPS_ERR;
+ }
objFile.os().write(buffer, bufsize);
objFile.os().close();
if (objFile.os().has_error()) {
(*message)(LDPL_ERROR, "Error writing output file '%s'",
- uniqueObjPath.c_str());
+ objPath);
objFile.os().clear_error();
return LDPS_ERR;
}
objFile.keep();
- lto_codegen_dispose(cg);
+ lto_codegen_dispose(code_gen);
- if ((*add_input_file)(uniqueObjPath.c_str()) != LDPS_OK) {
+ if ((*add_input_file)(objPath) != LDPS_OK) {
(*message)(LDPL_ERROR, "Unable to add .o file to the link.");
- (*message)(LDPL_ERROR, "File left behind in: %s", uniqueObjPath.c_str());
+ (*message)(LDPL_ERROR, "File left behind in: %s", objPath);
return LDPS_ERR;
}
@@ -502,7 +528,8 @@ static ld_plugin_status all_symbols_read_hook(void) {
}
}
- Cleanup.push_back(uniqueObjPath);
+ if (options::obj_path.empty())
+ Cleanup.push_back(sys::Path(objPath));
return LDPS_OK;
}
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp
index 8bcc2d8..bb426a9 100644
--- a/tools/llc/llc.cpp
+++ b/tools/llc/llc.cpp
@@ -28,8 +28,9 @@
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/System/Host.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/Signals.h"
#include "llvm/Target/SubtargetFeature.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
@@ -95,6 +96,8 @@ FileType("filetype", cl::init(TargetMachine::CGFT_AssemblyFile),
cl::opt<bool> NoVerify("disable-verify", cl::Hidden,
cl::desc("Do not verify input module"));
+cl::opt<bool> DisableDotLoc("disable-dot-loc", cl::Hidden,
+ cl::desc("Do not use .loc entries"));
static cl::opt<bool>
DisableRedZone("disable-red-zone",
@@ -273,6 +276,21 @@ int main(int argc, char **argv) {
assert(target.get() && "Could not allocate target machine!");
TargetMachine &Target = *target.get();
+ if (DisableDotLoc)
+ Target.setMCUseLoc(false);
+ if (TheTriple.getOS() == Triple::Darwin) {
+ switch (TheTriple.getDarwinMajorNumber()) {
+ case 7:
+ case 8:
+ case 9:
+ // disable .loc support for older darwin OS.
+ Target.setMCUseLoc(false);
+ break;
+ default:
+ break;
+ }
+ }
+
// Figure out where we are going to send the output...
OwningPtr<tool_output_file> Out
(GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]));
diff --git a/tools/lli/CMakeLists.txt b/tools/lli/CMakeLists.txt
index ce70d46e..9378ef2 100644
--- a/tools/lli/CMakeLists.txt
+++ b/tools/lli/CMakeLists.txt
@@ -1,4 +1,4 @@
-set(LLVM_LINK_COMPONENTS jit interpreter nativecodegen bitreader selectiondag)
+set(LLVM_LINK_COMPONENTS mcjit jit interpreter nativecodegen bitreader asmparser selectiondag)
add_llvm_tool(lli
lli.cpp
diff --git a/tools/lli/Makefile b/tools/lli/Makefile
index 8f6eeed..80aa82b 100644
--- a/tools/lli/Makefile
+++ b/tools/lli/Makefile
@@ -9,7 +9,7 @@
LEVEL := ../..
TOOLNAME := lli
-LINK_COMPONENTS := jit interpreter nativecodegen bitreader selectiondag
+LINK_COMPONENTS := mcjit jit interpreter nativecodegen bitreader asmparser selectiondag
# Enable JIT support
include $(LEVEL)/Makefile.common
diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp
index 4c37780..a756459 100644
--- a/tools/lli/lli.cpp
+++ b/tools/lli/lli.cpp
@@ -23,16 +23,26 @@
#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
+#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/IRReader.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Process.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Signals.h"
#include "llvm/Target/TargetSelect.h"
#include <cerrno>
+
+#ifdef __CYGWIN__
+#include <cygwin/version.h>
+#if defined(CYGWIN_VERSION_DLL_MAJOR) && CYGWIN_VERSION_DLL_MAJOR<1007
+#define DO_NOTHING_ATEXIT 1
+#endif
+#endif
+
using namespace llvm;
namespace {
@@ -46,6 +56,10 @@ namespace {
cl::desc("Force interpretation: disable JIT"),
cl::init(false));
+ cl::opt<bool> UseMCJIT(
+ "use-mcjit", cl::desc("Enable use of the MC-based JIT (if available)"),
+ cl::init(false));
+
// Determine optimization level.
cl::opt<char>
OptLevel("O",
@@ -99,8 +113,11 @@ namespace {
static ExecutionEngine *EE = 0;
static void do_shutdown() {
+ // Cygwin-1.5 invokes DLL's dtors before atexit handler.
+#ifndef DO_NOTHING_ATEXIT
delete EE;
llvm_shutdown();
+#endif
}
//===----------------------------------------------------------------------===//
@@ -125,20 +142,15 @@ int main(int argc, char **argv, char * const *envp) {
sys::Process::PreventCoreFiles();
// Load the bitcode...
- std::string ErrorMsg;
- Module *Mod = NULL;
- if (MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFile,&ErrorMsg)){
- Mod = getLazyBitcodeModule(Buffer, Context, &ErrorMsg);
- if (!Mod) delete Buffer;
- }
-
+ SMDiagnostic Err;
+ Module *Mod = ParseIRFile(InputFile, Err, Context);
if (!Mod) {
- errs() << argv[0] << ": error loading program '" << InputFile << "': "
- << ErrorMsg << "\n";
- exit(1);
+ Err.Print(argv[0], errs());
+ return 1;
}
// If not jitting lazily, load the whole bitcode file eagerly too.
+ std::string ErrorMsg;
if (NoLazyCompilation) {
if (Mod->MaterializeAllPermanently(&ErrorMsg)) {
errs() << argv[0] << ": bitcode didn't read correctly.\n";
@@ -160,6 +172,10 @@ int main(int argc, char **argv, char * const *envp) {
if (!TargetTriple.empty())
Mod->setTargetTriple(Triple::normalize(TargetTriple));
+ // Enable MCJIT, if desired.
+ if (UseMCJIT)
+ builder.setUseMCJIT(true);
+
CodeGenOpt::Level OLvl = CodeGenOpt::Default;
switch (OptLevel) {
default:
diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp
index 021a369..c1c8b24 100644
--- a/tools/llvm-ar/llvm-ar.cpp
+++ b/tools/llvm-ar/llvm-ar.cpp
@@ -16,13 +16,13 @@
#include "llvm/Module.h"
#include "llvm/Bitcode/Archive.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Signals.h"
-#include <iostream>
+#include "llvm/Support/Signals.h"
#include <algorithm>
-#include <iomanip>
#include <memory>
#include <fstream>
using namespace llvm;
@@ -274,7 +274,7 @@ ArchiveOperation parseCommandLine() {
// finds with all the files in that directory (recursively). It uses the
// sys::Path::getDirectoryContent method to perform the actual directory scans.
bool
-recurseDirectories(const sys::Path& path,
+recurseDirectories(const sys::Path& path,
std::set<sys::Path>& result, std::string* ErrMsg) {
result.clear();
if (RecurseDirectories) {
@@ -311,7 +311,8 @@ bool buildPaths(bool checkExistence, std::string* ErrMsg) {
if (!aPath.set(Members[i]))
throw std::string("File member name invalid: ") + Members[i];
if (checkExistence) {
- if (!aPath.exists())
+ bool Exists;
+ if (sys::fs::exists(aPath.str(), Exists) || !Exists)
throw std::string("File does not exist: ") + Members[i];
std::string Err;
sys::PathWithStatus PwS(aPath);
@@ -335,12 +336,12 @@ bool buildPaths(bool checkExistence, std::string* ErrMsg) {
// printSymbolTable - print out the archive's symbol table.
void printSymbolTable() {
- std::cout << "\nArchive Symbol Table:\n";
+ outs() << "\nArchive Symbol Table:\n";
const Archive::SymTabType& symtab = TheArchive->getSymbolTable();
for (Archive::SymTabType::const_iterator I=symtab.begin(), E=symtab.end();
I != E; ++I ) {
unsigned offset = TheArchive->getFirstFileOffset() + I->second;
- std::cout << " " << std::setw(9) << offset << "\t" << I->first <<"\n";
+ outs() << " " << format("%9u", offset) << "\t" << I->first <<"\n";
}
}
@@ -365,10 +366,10 @@ bool doPrint(std::string* ErrMsg) {
continue;
if (Verbose)
- std::cout << "Printing " << I->getPath().str() << "\n";
+ outs() << "Printing " << I->getPath().str() << "\n";
unsigned len = I->getSize();
- std::cout.write(data, len);
+ outs().write(data, len);
} else {
countDown--;
}
@@ -379,27 +380,27 @@ bool doPrint(std::string* ErrMsg) {
// putMode - utility function for printing out the file mode when the 't'
// operation is in verbose mode.
-void
+void
printMode(unsigned mode) {
if (mode & 004)
- std::cout << "r";
+ outs() << "r";
else
- std::cout << "-";
+ outs() << "-";
if (mode & 002)
- std::cout << "w";
+ outs() << "w";
else
- std::cout << "-";
+ outs() << "-";
if (mode & 001)
- std::cout << "x";
+ outs() << "x";
else
- std::cout << "-";
+ outs() << "-";
}
// doDisplayTable - Implement the 't' operation. This function prints out just
// the file names of each of the members. However, if verbose mode is requested
// ('v' modifier) then the file type, permission mode, user, group, size, and
// modification time are also printed.
-bool
+bool
doDisplayTable(std::string* ErrMsg) {
if (buildPaths(false, ErrMsg))
return true;
@@ -411,22 +412,22 @@ doDisplayTable(std::string* ErrMsg) {
// FIXME: Output should be this format:
// Zrw-r--r-- 500/ 500 525 Nov 8 17:42 2004 Makefile
if (I->isBitcode())
- std::cout << "b";
+ outs() << "b";
else if (I->isCompressed())
- std::cout << "Z";
+ outs() << "Z";
else
- std::cout << " ";
+ outs() << " ";
unsigned mode = I->getMode();
printMode((mode >> 6) & 007);
printMode((mode >> 3) & 007);
printMode(mode & 007);
- std::cout << " " << std::setw(4) << I->getUser();
- std::cout << "/" << std::setw(4) << I->getGroup();
- std::cout << " " << std::setw(8) << I->getSize();
- std::cout << " " << std::setw(20) << I->getModTime().str().substr(4);
- std::cout << " " << I->getPath().str() << "\n";
+ outs() << " " << format("%4u", I->getUser());
+ outs() << "/" << format("%4u", I->getGroup());
+ outs() << " " << format("%8u", I->getSize());
+ outs() << " " << format("%20s", I->getModTime().str().substr(4).c_str());
+ outs() << " " << I->getPath().str() << "\n";
} else {
- std::cout << I->getPath().str() << "\n";
+ outs() << I->getPath().str() << "\n";
}
}
}
@@ -437,7 +438,7 @@ doDisplayTable(std::string* ErrMsg) {
// doExtract - Implement the 'x' operation. This function extracts files back to
// the file system, making sure to uncompress any that were compressed
-bool
+bool
doExtract(std::string* ErrMsg) {
if (buildPaths(false, ErrMsg))
return true;
@@ -450,7 +451,7 @@ doExtract(std::string* ErrMsg) {
if (I->hasPath()) {
sys::Path dirs(I->getPath());
dirs.eraseComponent();
- if (dirs.createDirectoryOnDisk(/*create_parents=*/true, ErrMsg))
+ if (dirs.createDirectoryOnDisk(/*create_parents=*/true, ErrMsg))
return true;
}
@@ -480,11 +481,11 @@ doExtract(std::string* ErrMsg) {
// members from the archive. Note that if the count is specified, there should
// be no more than one path in the Paths list or else this algorithm breaks.
// That check is enforced in parseCommandLine (above).
-bool
+bool
doDelete(std::string* ErrMsg) {
if (buildPaths(false, ErrMsg))
return true;
- if (Paths.empty())
+ if (Paths.empty())
return false;
unsigned countDown = Count;
for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end();
@@ -513,9 +514,9 @@ doDelete(std::string* ErrMsg) {
// order of the archive members so that when the archive is written the move
// of the members is accomplished. Note the use of the RelPos variable to
// determine where the items should be moved to.
-bool
+bool
doMove(std::string* ErrMsg) {
- if (buildPaths(false, ErrMsg))
+ if (buildPaths(false, ErrMsg))
return true;
// By default and convention the place to move members to is the end of the
@@ -566,12 +567,12 @@ doMove(std::string* ErrMsg) {
// doQuickAppend - Implements the 'q' operation. This function just
// indiscriminantly adds the members to the archive and rebuilds it.
-bool
+bool
doQuickAppend(std::string* ErrMsg) {
// Get the list of paths to append.
if (buildPaths(true, ErrMsg))
return true;
- if (Paths.empty())
+ if (Paths.empty())
return false;
// Append them quickly.
@@ -591,13 +592,13 @@ doQuickAppend(std::string* ErrMsg) {
// doReplaceOrInsert - Implements the 'r' operation. This function will replace
// any existing files or insert new ones into the archive.
-bool
+bool
doReplaceOrInsert(std::string* ErrMsg) {
// Build the list of files to be added/replaced.
if (buildPaths(true, ErrMsg))
return true;
- if (Paths.empty())
+ if (Paths.empty())
return false;
// Keep track of the paths that remain to be inserted.
@@ -637,7 +638,7 @@ doReplaceOrInsert(std::string* ErrMsg) {
if (found != remaining.end()) {
std::string Err;
- sys::PathWithStatus PwS(*found);
+ sys::PathWithStatus PwS(*found);
const sys::FileStatus *si = PwS.getFileStatus(false, &Err);
if (!si)
return true;
@@ -716,7 +717,8 @@ int main(int argc, char **argv) {
throw std::string("Archive name invalid: ") + ArchiveName;
// Create or open the archive object.
- if (!ArchivePath.exists()) {
+ bool Exists;
+ if (llvm::sys::fs::exists(ArchivePath.str(), Exists) || !Exists) {
// Produce a warning if we should and we're creating the archive
if (!Create)
errs() << argv[0] << ": creating " << ArchivePath.str() << "\n";
diff --git a/tools/llvm-as/llvm-as.cpp b/tools/llvm-as/llvm-as.cpp
index 1eaa4b3..c1661cd 100644
--- a/tools/llvm-as/llvm-as.cpp
+++ b/tools/llvm-as/llvm-as.cpp
@@ -25,8 +25,8 @@
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/SystemUtils.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/Signals.h"
#include <memory>
using namespace llvm;
diff --git a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
index 9c0d675..980f278 100644
--- a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
+++ b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
@@ -27,6 +27,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/Bitcode/LLVMBitCodes.h"
@@ -37,7 +38,8 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/system_error.h"
#include <cstdio>
#include <map>
#include <algorithm>
@@ -57,15 +59,22 @@ static cl::opt<bool> NoHistogram("disable-histogram",
static cl::opt<bool>
NonSymbolic("non-symbolic",
- cl::desc("Emit numberic info in dump even if"
+ cl::desc("Emit numeric info in dump even if"
" symbolic info is available"));
-/// CurStreamType - If we can sniff the flavor of this stream, we can produce
-/// better dump info.
-static enum {
+namespace {
+
+/// CurStreamTypeType - A type for CurStreamType
+enum CurStreamTypeType {
UnknownBitstream,
LLVMIRBitstream
-} CurStreamType;
+};
+
+}
+
+/// CurStreamType - If we can sniff the flavor of this stream, we can produce
+/// better dump info.
+static CurStreamTypeType CurStreamType;
/// GetBlockName - Return a symbolic block name if known, otherwise return
@@ -254,6 +263,7 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
switch(CodeID) {
default:return 0;
case bitc::METADATA_ATTACHMENT: return "METADATA_ATTACHMENT";
+ case bitc::METADATA_ATTACHMENT2: return "METADATA_ATTACHMENT2";
}
case bitc::METADATA_BLOCK_ID:
switch(CodeID) {
@@ -268,7 +278,6 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
case bitc::METADATA_NODE2: return "METADATA_NODE2";
case bitc::METADATA_FN_NODE2: return "METADATA_FN_NODE2";
case bitc::METADATA_NAMED_NODE2: return "METADATA_NAMED_NODE2";
- case bitc::METADATA_ATTACHMENT2: return "METADATA_ATTACHMENT2";
}
}
}
@@ -473,10 +482,11 @@ static void PrintSize(uint64_t Bits) {
/// AnalyzeBitcode - Analyze the bitcode file specified by InputFilename.
static int AnalyzeBitcode() {
// Read the input file.
- MemoryBuffer *MemBuf = MemoryBuffer::getFileOrSTDIN(InputFilename.c_str());
+ OwningPtr<MemoryBuffer> MemBuf;
- if (MemBuf == 0)
- return Error("Error reading '" + InputFilename + "'.");
+ if (error_code ec =
+ MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), MemBuf))
+ return Error("Error reading '" + InputFilename + "': " + ec.message());
if (MemBuf->getBufferSize() & 3)
return Error("Bitcode stream should be a multiple of 4 bytes in length");
diff --git a/tools/llvm-config/CMakeLists.txt b/tools/llvm-config/CMakeLists.txt
index 663cae5..d33ff0d 100644
--- a/tools/llvm-config/CMakeLists.txt
+++ b/tools/llvm-config/CMakeLists.txt
@@ -70,6 +70,8 @@ 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}
@@ -80,8 +82,11 @@ add_custom_command(OUTPUT ${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 ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/find-cycles.pl < ${LIBDEPS} > ${FINAL_LIBDEPS} || ${CMAKE_COMMAND} -E remove -f ${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.")
@@ -89,6 +94,17 @@ set(C_FLGS "${CMAKE_C_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}")
set(CXX_FLGS "${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}")
set(CPP_FLGS "${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
@@ -108,6 +124,7 @@ add_custom_command(OUTPUT ${LLVM_CONFIG}
add_custom_target(llvm-config.target ALL
DEPENDS ${LLVM_CONFIG})
+get_property(llvm_lib_targets GLOBAL PROPERTY LLVM_LIB_TARGETS)
add_dependencies(llvm-config.target ${llvm_lib_targets})
# Make sure that llvm-config builds before the llvm tools, so we have
diff --git a/tools/llvm-config/llvm-config.in.in b/tools/llvm-config/llvm-config.in.in
index d435d57..840a10e 100644
--- a/tools/llvm-config/llvm-config.in.in
+++ b/tools/llvm-config/llvm-config.in.in
@@ -197,7 +197,7 @@ Options:
Typical components:
all All LLVM libraries (default).
backend Either a native backend or the C backend.
- engine Either a native JIT or a bytecode interpreter.
+ engine Either a native JIT or a bitcode interpreter.
__EOD__
exit(1);
}
@@ -320,6 +320,9 @@ sub build_name_map {
$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]]
diff --git a/tools/llvm-diff/llvm-diff.cpp b/tools/llvm-diff/llvm-diff.cpp
index 16a990f..b932ccc 100644
--- a/tools/llvm-diff/llvm-diff.cpp
+++ b/tools/llvm-diff/llvm-diff.cpp
@@ -17,13 +17,12 @@
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Type.h"
-#include "llvm/Assembly/Parser.h"
-#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/IRReader.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/SourceMgr.h"
@@ -34,47 +33,30 @@
using namespace llvm;
-/// Reads a module from a file. If the filename ends in .ll, it is
-/// interpreted as an assembly file; otherwise, it is interpreted as
-/// bitcode. On error, messages are written to stderr and null is
-/// returned.
+/// Reads a module from a file. On error, messages are written to stderr
+/// and null is returned.
static Module *ReadModule(LLVMContext &Context, StringRef Name) {
- // LLVM assembly path.
- if (Name.endswith(".ll")) {
- SMDiagnostic Diag;
- Module *M = ParseAssemblyFile(Name, Diag, Context);
- if (M) return M;
-
+ SMDiagnostic Diag;
+ Module *M = ParseIRFile(Name, Diag, Context);
+ if (!M)
Diag.Print("llvmdiff", errs());
- return 0;
- }
-
- // Bitcode path.
- MemoryBuffer *Buffer = MemoryBuffer::getFile(Name);
-
- // ParseBitcodeFile takes ownership of the buffer if it succeeds.
- std::string Error;
- Module *M = ParseBitcodeFile(Buffer, Context, &Error);
- if (M) return M;
-
- errs() << "error parsing " << Name << ": " << Error;
- delete Buffer;
- return 0;
+ return M;
}
namespace {
-struct DiffContext {
- DiffContext(Value *L, Value *R)
- : L(L), R(R), Differences(false), IsFunction(isa<Function>(L)) {}
- Value *L;
- Value *R;
- bool Differences;
- bool IsFunction;
- DenseMap<Value*,unsigned> LNumbering;
- DenseMap<Value*,unsigned> RNumbering;
-};
+ struct DiffContext {
+ DiffContext(Value *L, Value *R)
+ : L(L), R(R), Differences(false), IsFunction(isa<Function>(L)) {}
+ Value *L;
+ Value *R;
+ bool Differences;
+ bool IsFunction;
+ DenseMap<Value*,unsigned> LNumbering;
+ DenseMap<Value*,unsigned> RNumbering;
+ };
+}
-void ComputeNumbering(Function *F, DenseMap<Value*,unsigned> &Numbering) {
+static void ComputeNumbering(Function *F, DenseMap<Value*,unsigned> &Numbering){
unsigned IN = 0;
// Arguments get the first numbers.
@@ -98,6 +80,7 @@ void ComputeNumbering(Function *F, DenseMap<Value*,unsigned> &Numbering) {
assert(!Numbering.empty() && "asked for numbering but numbering was no-op");
}
+namespace {
class DiffConsumer : public DifferenceEngine::Consumer {
private:
raw_ostream &out;
@@ -273,7 +256,7 @@ public:
}
};
-}
+} // end anonymous namespace
static void diffGlobal(DifferenceEngine &Engine, Module *L, Module *R,
StringRef Name) {
@@ -292,14 +275,14 @@ static void diffGlobal(DifferenceEngine &Engine, Module *L, Module *R,
errs() << "No function named @" << Name << " in right module\n";
}
-cl::opt<std::string> LeftFilename(cl::Positional,
- cl::desc("<first file>"),
- cl::Required);
-cl::opt<std::string> RightFilename(cl::Positional,
- cl::desc("<second file>"),
- cl::Required);
-cl::list<std::string> GlobalsToCompare(cl::Positional,
- cl::desc("<globals to compare>"));
+static cl::opt<std::string> LeftFilename(cl::Positional,
+ cl::desc("<first file>"),
+ cl::Required);
+static cl::opt<std::string> RightFilename(cl::Positional,
+ cl::desc("<second file>"),
+ cl::Required);
+static cl::list<std::string> GlobalsToCompare(cl::Positional,
+ cl::desc("<globals to compare>"));
int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv);
diff --git a/tools/llvm-dis/llvm-dis.cpp b/tools/llvm-dis/llvm-dis.cpp
index 9d2d31d..b4977ce 100644
--- a/tools/llvm-dis/llvm-dis.cpp
+++ b/tools/llvm-dis/llvm-dis.cpp
@@ -26,8 +26,9 @@
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/system_error.h"
using namespace llvm;
static cl::opt<std::string>
@@ -48,7 +49,7 @@ ShowAnnotations("show-annotations",
cl::desc("Add informational comments to the .ll file"));
namespace {
-
+
class CommentWriter : public AssemblyAnnotationWriter {
public:
void emitFunctionAnnot(const Function *F,
@@ -58,32 +59,34 @@ public:
}
void printInfoComment(const Value &V, formatted_raw_ostream &OS) {
if (V.getType()->isVoidTy()) return;
-
+
OS.PadToColumn(50);
OS << "; [#uses=" << V.getNumUses() << ']'; // Output # uses
}
};
-
+
} // end anon namespace
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
PrettyStackTraceProgram X(argc, argv);
-
+
LLVMContext &Context = getGlobalContext();
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
-
-
+
+
cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n");
std::string ErrorMessage;
std::auto_ptr<Module> M;
-
- if (MemoryBuffer *Buffer
- = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) {
- M.reset(ParseBitcodeFile(Buffer, Context, &ErrorMessage));
- delete Buffer;
+
+ {
+ OwningPtr<MemoryBuffer> BufferPtr;
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr))
+ ErrorMessage = ec.message();
+ else
+ M.reset(ParseBitcodeFile(BufferPtr.get(), Context, &ErrorMessage));
}
if (M.get() == 0) {
@@ -94,11 +97,11 @@ int main(int argc, char **argv) {
errs() << "bitcode didn't read correctly.\n";
return 1;
}
-
+
// Just use stdout. We won't actually print anything on it.
if (DontPrint)
OutputFilename = "-";
-
+
if (OutputFilename.empty()) { // Unspecified output, infer it.
if (InputFilename == "-") {
OutputFilename = "-";
@@ -114,7 +117,7 @@ int main(int argc, char **argv) {
}
std::string ErrorInfo;
- OwningPtr<tool_output_file>
+ OwningPtr<tool_output_file>
Out(new tool_output_file(OutputFilename.c_str(), ErrorInfo,
raw_fd_ostream::F_Binary));
if (!ErrorInfo.empty()) {
@@ -125,7 +128,7 @@ int main(int argc, char **argv) {
OwningPtr<AssemblyAnnotationWriter> Annotator;
if (ShowAnnotations)
Annotator.reset(new CommentWriter());
-
+
// All that llvm-dis does is write the assembly to a file.
if (!DontPrint)
M->print(Out->os(), Annotator.get());
diff --git a/tools/llvm-extract/llvm-extract.cpp b/tools/llvm-extract/llvm-extract.cpp
index 91a59e5..8c2f43a 100644
--- a/tools/llvm-extract/llvm-extract.cpp
+++ b/tools/llvm-extract/llvm-extract.cpp
@@ -23,9 +23,10 @@
#include "llvm/Support/IRReader.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/SystemUtils.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include <memory>
using namespace llvm;
@@ -102,13 +103,39 @@ int main(int argc, char **argv) {
}
// Materialize requisite global values.
- for (size_t i = 0, e = GVs.size(); i != e; ++i) {
- GlobalValue *GV = GVs[i];
- if (GV->isMaterializable()) {
- std::string ErrInfo;
- if (GV->Materialize(&ErrInfo)) {
- errs() << argv[0] << ": error reading input: " << ErrInfo << "\n";
- return 1;
+ if (!DeleteFn)
+ for (size_t i = 0, e = GVs.size(); i != e; ++i) {
+ GlobalValue *GV = GVs[i];
+ if (GV->isMaterializable()) {
+ std::string ErrInfo;
+ if (GV->Materialize(&ErrInfo)) {
+ errs() << argv[0] << ": error reading input: " << ErrInfo << "\n";
+ return 1;
+ }
+ }
+ }
+ else {
+ // Deleting. Materialize every GV that's *not* in GVs.
+ SmallPtrSet<GlobalValue *, 8> GVSet(GVs.begin(), GVs.end());
+ for (Module::global_iterator I = M->global_begin(), E = M->global_end();
+ I != E; ++I) {
+ GlobalVariable *G = I;
+ if (!GVSet.count(G) && G->isMaterializable()) {
+ std::string ErrInfo;
+ if (G->Materialize(&ErrInfo)) {
+ errs() << argv[0] << ": error reading input: " << ErrInfo << "\n";
+ return 1;
+ }
+ }
+ }
+ for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) {
+ Function *F = I;
+ if (!GVSet.count(F) && F->isMaterializable()) {
+ std::string ErrInfo;
+ if (F->Materialize(&ErrInfo)) {
+ errs() << argv[0] << ": error reading input: " << ErrInfo << "\n";
+ return 1;
+ }
}
}
}
diff --git a/tools/llvm-ld/CMakeLists.txt b/tools/llvm-ld/CMakeLists.txt
index 2ae4a1d..370bcb4 100644
--- a/tools/llvm-ld/CMakeLists.txt
+++ b/tools/llvm-ld/CMakeLists.txt
@@ -4,3 +4,5 @@ add_llvm_tool(llvm-ld
Optimize.cpp
llvm-ld.cpp
)
+
+add_dependencies(llvm-ld llvm-stub)
diff --git a/tools/llvm-ld/Optimize.cpp b/tools/llvm-ld/Optimize.cpp
index 3fb0079..ef4502b 100644
--- a/tools/llvm-ld/Optimize.cpp
+++ b/tools/llvm-ld/Optimize.cpp
@@ -16,7 +16,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/StandardPasses.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/DynamicLibrary.h"
+#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/PassNameParser.h"
diff --git a/tools/llvm-ld/llvm-ld.cpp b/tools/llvm-ld/llvm-ld.cpp
index 3bbea9d..cd6ce25 100644
--- a/tools/llvm-ld/llvm-ld.cpp
+++ b/tools/llvm-ld/llvm-ld.cpp
@@ -23,7 +23,7 @@
#include "llvm/LinkAllVMCore.h"
#include "llvm/Linker.h"
#include "llvm/LLVMContext.h"
-#include "llvm/System/Program.h"
+#include "llvm/Support/Program.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Bitcode/ReaderWriter.h"
@@ -35,8 +35,8 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/SystemUtils.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/Signals.h"
#include "llvm/Config/config.h"
#include <memory>
#include <cstring>
@@ -98,7 +98,7 @@ static cl::list<std::string> PostLinkOpts("post-link-opts",
static cl::list<std::string> XLinker("Xlinker", cl::value_desc("option"),
cl::desc("Pass options to the system linker"));
-// Compatibility options that llvm-ld ignores but are supported for
+// Compatibility options that llvm-ld ignores but are supported for
// compatibility with LD
static cl::opt<std::string> CO3("soname", cl::Hidden,
cl::desc("Compatibility option: ignored"));
@@ -112,13 +112,13 @@ static cl::opt<bool> CO5("eh-frame-hdr", cl::Hidden,
static cl::opt<std::string> CO6("h", cl::Hidden,
cl::desc("Compatibility option: ignored"));
-static cl::opt<bool> CO7("start-group", cl::Hidden,
+static cl::opt<bool> CO7("start-group", cl::Hidden,
cl::desc("Compatibility option: ignored"));
-static cl::opt<bool> CO8("end-group", cl::Hidden,
+static cl::opt<bool> CO8("end-group", cl::Hidden,
cl::desc("Compatibility option: ignored"));
-static cl::opt<std::string> CO9("m", cl::Hidden,
+static cl::opt<std::string> CO9("m", cl::Hidden,
cl::desc("Compatibility option: ignored"));
/// This is just for convenience so it doesn't have to be passed around
@@ -142,7 +142,7 @@ static void PrintAndExit(const std::string &Message, Module *M, int errcode = 1)
}
static void PrintCommand(const std::vector<const char*> &args) {
- std::vector<const char*>::const_iterator I = args.begin(), E = args.end();
+ std::vector<const char*>::const_iterator I = args.begin(), E = args.end();
for (; I != E; ++I)
if (*I)
errs() << "'" << *I << "'" << " ";
@@ -178,7 +178,7 @@ static char ** CopyEnv(char ** const envp) {
// Allocate a new environment list.
char **newenv = new char* [entries];
- if ((newenv = new char* [entries]) == NULL)
+ if (newenv == NULL)
return NULL;
// Make a copy of the list. Don't forget the NULL that ends the list.
@@ -384,7 +384,7 @@ static int GenerateNative(const std::string &OutputFilename,
args.push_back("-framework");
args.push_back(Frameworks[index]);
}
-
+
// Now that "args" owns all the std::strings for the arguments, call the c_str
// method to get the underlying string array. We do this game so that the
// std::string array is guaranteed to outlive the const char* array.
@@ -410,13 +410,13 @@ static int GenerateNative(const std::string &OutputFilename,
static void EmitShellScript(char **argv, Module *M) {
if (Verbose)
errs() << "Emitting Shell Script\n";
-#if defined(_WIN32) || defined(__CYGWIN__)
+#if defined(_WIN32)
// Windows doesn't support #!/bin/sh style shell scripts in .exe files. To
// support windows systems, we copy the llvm-stub.exe executable from the
// build tree to the destination file.
- std::string ErrMsg;
- sys::Path llvmstub = FindExecutable("llvm-stub.exe", argv[0],
- (void *)(intptr_t)&Optimize);
+ std::string ErrMsg;
+ sys::Path llvmstub = PrependMainExecutablePath("llvm-stub", argv[0],
+ (void *)(intptr_t)&Optimize);
if (llvmstub.isEmpty())
PrintAndExit("Could not find llvm-stub.exe executable!", M);
@@ -455,7 +455,7 @@ static void EmitShellScript(char **argv, Module *M) {
E = LibPaths.end(); P != E; ++P) {
FullLibraryPath = *P;
FullLibraryPath.appendComponent("lib" + *i);
- FullLibraryPath.appendSuffix(&(LTDL_SHLIB_EXT[1]));
+ FullLibraryPath.appendSuffix(sys::Path::GetDLLSuffix());
if (!FullLibraryPath.isEmpty()) {
if (!FullLibraryPath.isDynamicLibrary()) {
// Not a native shared library; mark as invalid
@@ -513,9 +513,20 @@ int main(int argc, char **argv, char **envp) {
LLVMContext &Context = getGlobalContext();
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
-
+
+ // Initialize passes
+ PassRegistry &Registry = *PassRegistry::getPassRegistry();
+ initializeCore(Registry);
+ initializeScalarOpts(Registry);
+ initializeIPO(Registry);
+ initializeAnalysis(Registry);
+ initializeIPA(Registry);
+ initializeTransformUtils(Registry);
+ initializeInstCombine(Registry);
+ initializeTarget(Registry);
+
// Initial global variable above for convenience printing of program name.
- progname = sys::Path(argv[0]).getBasename();
+ progname = sys::path::stem(argv[0]);
// Parse the command line options
cl::ParseCommandLineOptions(argc, argv, "llvm linker\n");
@@ -527,11 +538,8 @@ int main(int argc, char **argv, char **envp) {
OutputFilename = "a.exe";
// If there is no suffix add an "exe" one.
- sys::Path ExeFile( OutputFilename );
- if (ExeFile.getSuffix() == "") {
- ExeFile.appendSuffix("exe");
- OutputFilename = ExeFile.str();
- }
+ if (sys::path::extension(OutputFilename).empty())
+ OutputFilename.append(".exe");
}
#endif
@@ -653,8 +661,8 @@ int main(int argc, char **argv, char **envp) {
sys::RemoveFileOnSignal(AssemblyFile);
// Determine the locations of the llc and gcc programs.
- sys::Path llc = FindExecutable("llc", argv[0],
- (void *)(intptr_t)&Optimize);
+ sys::Path llc = PrependMainExecutablePath("llc", argv[0],
+ (void *)(intptr_t)&Optimize);
if (llc.isEmpty())
PrintAndExit("Failed to find llc", Composite.get());
@@ -680,8 +688,8 @@ int main(int argc, char **argv, char **envp) {
sys::RemoveFileOnSignal(CFile);
// Determine the locations of the llc and gcc programs.
- sys::Path llc = FindExecutable("llc", argv[0],
- (void *)(intptr_t)&Optimize);
+ sys::Path llc = PrependMainExecutablePath("llc", argv[0],
+ (void *)(intptr_t)&Optimize);
if (llc.isEmpty())
PrintAndExit("Failed to find llc", Composite.get());
@@ -694,7 +702,7 @@ int main(int argc, char **argv, char **envp) {
if (GenerateCFile(CFile.str(), BitcodeOutputFilename, llc, ErrMsg))
PrintAndExit(ErrMsg, Composite.get());
- if (GenerateNative(OutputFilename, CFile.str(),
+ if (GenerateNative(OutputFilename, CFile.str(),
NativeLinkItems, gcc, envp, ErrMsg))
PrintAndExit(ErrMsg, Composite.get());
} else {
diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp
index e55d0de..3fb7ba4 100644
--- a/tools/llvm-link/llvm-link.cpp
+++ b/tools/llvm-link/llvm-link.cpp
@@ -20,11 +20,11 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/IRReader.h"
-#include "llvm/System/Signals.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/Path.h"
#include <memory>
using namespace llvm;
diff --git a/tools/llvm-mc/Disassembler.cpp b/tools/llvm-mc/Disassembler.cpp
index 13080b4..c29d82a 100644
--- a/tools/llvm-mc/Disassembler.cpp
+++ b/tools/llvm-mc/Disassembler.cpp
@@ -24,6 +24,7 @@
#include "llvm/Target/TargetRegistry.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/raw_ostream.h"
@@ -43,7 +44,7 @@ public:
uint64_t getExtent() const { return Bytes.size(); }
int readByte(uint64_t Addr, uint8_t *Byte) const {
- if (Addr > getExtent())
+ if (Addr >= getExtent())
return -1;
*Byte = Bytes[Addr].first;
return 0;
diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp
index aef0a3d..2c22bed 100644
--- a/tools/llvm-mc/llvm-mc.cpp
+++ b/tools/llvm-mc/llvm-mc.cpp
@@ -23,6 +23,10 @@
#include "llvm/Target/TargetAsmParser.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetRegistry.h"
+#include "llvm/Target/SubtargetFeature.h" // FIXME.
+#include "llvm/Target/TargetAsmInfo.h" // FIXME.
+#include "llvm/Target/TargetLowering.h" // FIXME.
+#include "llvm/Target/TargetLoweringObjectFile.h" // FIXME.
#include "llvm/Target/TargetMachine.h" // FIXME.
#include "llvm/Target/TargetSelect.h"
#include "llvm/ADT/OwningPtr.h"
@@ -33,9 +37,10 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Host.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/system_error.h"
#include "Disassembler.h"
using namespace llvm;
@@ -64,6 +69,9 @@ static cl::opt<bool>
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 {
@@ -95,6 +103,12 @@ static cl::opt<std::string>
TripleName("triple", cl::desc("Target triple to assemble for, "
"see -version for available targets"));
+static cl::opt<std::string>
+MCPU("mcpu",
+ cl::desc("Target a specific cpu type (-mcpu=help for details)"),
+ cl::value_desc("cpu-name"),
+ cl::init(""));
+
static cl::opt<bool>
NoInitialTextSection("n", cl::desc(
"Don't assume assembly file starts in the text section"));
@@ -157,17 +171,12 @@ static tool_output_file *GetOutputStream() {
}
static int AsLexInput(const char *ProgName) {
- std::string ErrorMessage;
- MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename,
- &ErrorMessage);
- if (Buffer == 0) {
- errs() << ProgName << ": ";
- if (ErrorMessage.size())
- errs() << ErrorMessage << "\n";
- else
- errs() << "input file didn't read correctly.\n";
+ OwningPtr<MemoryBuffer> BufferPtr;
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) {
+ errs() << ProgName << ": " << ec.message() << '\n';
return 1;
}
+ MemoryBuffer *Buffer = BufferPtr.take();
SourceMgr SrcMgr;
@@ -194,7 +203,9 @@ static int AsLexInput(const char *ProgName) {
bool Error = false;
while (Lexer.Lex().isNot(AsmToken::Eof)) {
- switch (Lexer.getKind()) {
+ AsmToken Tok = Lexer.getTok();
+
+ switch (Tok.getKind()) {
default:
SrcMgr.PrintMessage(Lexer.getLoc(), "unknown token", "warning");
Error = true;
@@ -203,45 +214,63 @@ static int AsLexInput(const char *ProgName) {
Error = true; // error already printed.
break;
case AsmToken::Identifier:
- Out->os() << "identifier: " << Lexer.getTok().getString() << '\n';
- break;
- case AsmToken::String:
- Out->os() << "string: " << Lexer.getTok().getString() << '\n';
+ Out->os() << "identifier: " << Lexer.getTok().getString();
break;
case AsmToken::Integer:
- Out->os() << "int: " << Lexer.getTok().getString() << '\n';
+ Out->os() << "int: " << Lexer.getTok().getString();
+ break;
+ case AsmToken::Real:
+ Out->os() << "real: " << Lexer.getTok().getString();
+ break;
+ case AsmToken::Register:
+ Out->os() << "register: " << Lexer.getTok().getRegVal();
+ break;
+ case AsmToken::String:
+ Out->os() << "string: " << Lexer.getTok().getString();
break;
- case AsmToken::Amp: Out->os() << "Amp\n"; break;
- case AsmToken::AmpAmp: Out->os() << "AmpAmp\n"; break;
- case AsmToken::Caret: Out->os() << "Caret\n"; break;
- case AsmToken::Colon: Out->os() << "Colon\n"; break;
- case AsmToken::Comma: Out->os() << "Comma\n"; break;
- case AsmToken::Dollar: Out->os() << "Dollar\n"; break;
- case AsmToken::EndOfStatement: Out->os() << "EndOfStatement\n"; break;
- case AsmToken::Eof: Out->os() << "Eof\n"; break;
- case AsmToken::Equal: Out->os() << "Equal\n"; break;
- case AsmToken::EqualEqual: Out->os() << "EqualEqual\n"; break;
- case AsmToken::Exclaim: Out->os() << "Exclaim\n"; break;
- case AsmToken::ExclaimEqual: Out->os() << "ExclaimEqual\n"; break;
- case AsmToken::Greater: Out->os() << "Greater\n"; break;
- case AsmToken::GreaterEqual: Out->os() << "GreaterEqual\n"; break;
- case AsmToken::GreaterGreater: Out->os() << "GreaterGreater\n"; break;
- case AsmToken::LParen: Out->os() << "LParen\n"; break;
- case AsmToken::Less: Out->os() << "Less\n"; break;
- case AsmToken::LessEqual: Out->os() << "LessEqual\n"; break;
- case AsmToken::LessGreater: Out->os() << "LessGreater\n"; break;
- case AsmToken::LessLess: Out->os() << "LessLess\n"; break;
- case AsmToken::Minus: Out->os() << "Minus\n"; break;
- case AsmToken::Percent: Out->os() << "Percent\n"; break;
- case AsmToken::Pipe: Out->os() << "Pipe\n"; break;
- case AsmToken::PipePipe: Out->os() << "PipePipe\n"; break;
- case AsmToken::Plus: Out->os() << "Plus\n"; break;
- case AsmToken::RParen: Out->os() << "RParen\n"; break;
- case AsmToken::Slash: Out->os() << "Slash\n"; break;
- case AsmToken::Star: Out->os() << "Star\n"; break;
- case AsmToken::Tilde: Out->os() << "Tilde\n"; break;
+ case AsmToken::Amp: Out->os() << "Amp"; break;
+ case AsmToken::AmpAmp: Out->os() << "AmpAmp"; break;
+ case AsmToken::At: Out->os() << "At"; break;
+ case AsmToken::Caret: Out->os() << "Caret"; break;
+ case AsmToken::Colon: Out->os() << "Colon"; break;
+ case AsmToken::Comma: Out->os() << "Comma"; break;
+ case AsmToken::Dollar: Out->os() << "Dollar"; break;
+ case AsmToken::Dot: Out->os() << "Dot"; break;
+ case AsmToken::EndOfStatement: Out->os() << "EndOfStatement"; break;
+ case AsmToken::Eof: Out->os() << "Eof"; break;
+ case AsmToken::Equal: Out->os() << "Equal"; break;
+ case AsmToken::EqualEqual: Out->os() << "EqualEqual"; break;
+ case AsmToken::Exclaim: Out->os() << "Exclaim"; break;
+ case AsmToken::ExclaimEqual: Out->os() << "ExclaimEqual"; break;
+ case AsmToken::Greater: Out->os() << "Greater"; break;
+ case AsmToken::GreaterEqual: Out->os() << "GreaterEqual"; break;
+ case AsmToken::GreaterGreater: Out->os() << "GreaterGreater"; break;
+ case AsmToken::Hash: Out->os() << "Hash"; break;
+ case AsmToken::LBrac: Out->os() << "LBrac"; break;
+ case AsmToken::LCurly: Out->os() << "LCurly"; break;
+ case AsmToken::LParen: Out->os() << "LParen"; break;
+ case AsmToken::Less: Out->os() << "Less"; break;
+ case AsmToken::LessEqual: Out->os() << "LessEqual"; break;
+ case AsmToken::LessGreater: Out->os() << "LessGreater"; break;
+ case AsmToken::LessLess: Out->os() << "LessLess"; break;
+ case AsmToken::Minus: Out->os() << "Minus"; break;
+ case AsmToken::Percent: Out->os() << "Percent"; break;
+ case AsmToken::Pipe: Out->os() << "Pipe"; break;
+ case AsmToken::PipePipe: Out->os() << "PipePipe"; break;
+ case AsmToken::Plus: Out->os() << "Plus"; break;
+ case AsmToken::RBrac: Out->os() << "RBrac"; break;
+ case AsmToken::RCurly: Out->os() << "RCurly"; break;
+ case AsmToken::RParen: Out->os() << "RParen"; break;
+ case AsmToken::Slash: Out->os() << "Slash"; break;
+ case AsmToken::Star: Out->os() << "Star"; break;
+ case AsmToken::Tilde: Out->os() << "Tilde"; break;
}
+
+ // Print the token string.
+ Out->os() << " (\"";
+ Out->os().write_escaped(Tok.getString());
+ Out->os() << "\")\n";
}
// Keep output if no errors.
@@ -255,16 +284,12 @@ static int AssembleInput(const char *ProgName) {
if (!TheTarget)
return 1;
- std::string Error;
- MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, &Error);
- if (Buffer == 0) {
- errs() << ProgName << ": ";
- if (Error.size())
- errs() << Error << "\n";
- else
- errs() << "input file didn't read correctly.\n";
+ OwningPtr<MemoryBuffer> BufferPtr;
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) {
+ errs() << ProgName << ": " << ec.message() << '\n';
return 1;
}
+ MemoryBuffer *Buffer = BufferPtr.take();
SourceMgr SrcMgr;
@@ -279,10 +304,20 @@ static int AssembleInput(const char *ProgName) {
llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createAsmInfo(TripleName));
assert(MAI && "Unable to create target asm info!");
- MCContext Ctx(*MAI);
+ // Package up features to be passed to target/subtarget
+ std::string FeaturesStr;
+ if (MCPU.size()) {
+ SubtargetFeatures Features;
+ Features.setCPU(MCPU);
+ FeaturesStr = Features.getString();
+ }
// FIXME: We shouldn't need to do this (and link in codegen).
- OwningPtr<TargetMachine> TM(TheTarget->createTargetMachine(TripleName, ""));
+ // When we split this out, we should do it in a way that makes
+ // it straightforward to switch subtargets on the fly (.e.g,
+ // the .cpu and .code16 directives).
+ OwningPtr<TargetMachine> TM(TheTarget->createTargetMachine(TripleName,
+ FeaturesStr));
if (!TM) {
errs() << ProgName << ": error: could not create target for triple '"
@@ -290,6 +325,9 @@ static int AssembleInput(const char *ProgName) {
return 1;
}
+ const TargetAsmInfo *tai = new TargetAsmInfo(*TM);
+ MCContext Ctx(*MAI, tai);
+
OwningPtr<tool_output_file> Out(GetOutputStream());
if (!Out)
return 1;
@@ -297,15 +335,23 @@ static int AssembleInput(const char *ProgName) {
formatted_raw_ostream FOS(Out->os());
OwningPtr<MCStreamer> Str;
+ const TargetLoweringObjectFile &TLOF =
+ TM->getTargetLowering()->getObjFileLowering();
+ const_cast<TargetLoweringObjectFile&>(TLOF).Initialize(Ctx, *TM);
+
+ // FIXME: There is a bit of code duplication with addPassesToEmitFile.
if (FileType == OFT_AssemblyFile) {
MCInstPrinter *IP =
TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI);
MCCodeEmitter *CE = 0;
- if (ShowEncoding)
+ TargetAsmBackend *TAB = 0;
+ if (ShowEncoding) {
CE = TheTarget->createCodeEmitter(*TM, Ctx);
- Str.reset(createAsmStreamer(Ctx, FOS,
- TM->getTargetData()->isLittleEndian(),
- /*asmverbose*/true, IP, CE, ShowInst));
+ TAB = TheTarget->createAsmBackend(TripleName);
+ }
+ Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/true,
+ /*useLoc*/ true, IP, CE, TAB,
+ ShowInst));
} else if (FileType == OFT_Null) {
Str.reset(createNullStreamer(Ctx));
} else {
@@ -313,7 +359,8 @@ static int AssembleInput(const char *ProgName) {
MCCodeEmitter *CE = TheTarget->createCodeEmitter(*TM, Ctx);
TargetAsmBackend *TAB = TheTarget->createAsmBackend(TripleName);
Str.reset(TheTarget->createObjectStreamer(TripleName, Ctx, *TAB,
- FOS, CE, RelaxAll));
+ FOS, CE, RelaxAll,
+ NoExecStack));
}
if (EnableLogging) {
@@ -344,18 +391,10 @@ static int DisassembleInput(const char *ProgName, bool Enhanced) {
const Target *TheTarget = GetTarget(ProgName);
if (!TheTarget)
return 0;
-
- std::string ErrorMessage;
-
- MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename,
- &ErrorMessage);
-
- if (Buffer == 0) {
- errs() << ProgName << ": ";
- if (ErrorMessage.size())
- errs() << ErrorMessage << "\n";
- else
- errs() << "input file didn't read correctly.\n";
+
+ OwningPtr<MemoryBuffer> Buffer;
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, Buffer)) {
+ errs() << ProgName << ": " << ec.message() << '\n';
return 1;
}
@@ -365,9 +404,11 @@ static int DisassembleInput(const char *ProgName, bool Enhanced) {
int Res;
if (Enhanced)
- Res = Disassembler::disassembleEnhanced(TripleName, *Buffer, Out->os());
+ Res =
+ Disassembler::disassembleEnhanced(TripleName, *Buffer.take(), Out->os());
else
- Res = Disassembler::disassemble(*TheTarget, TripleName, *Buffer, Out->os());
+ Res = Disassembler::disassemble(*TheTarget, TripleName,
+ *Buffer.take(), Out->os());
// Keep output if no errors.
if (Res == 0) Out->keep();
diff --git a/tools/llvm-nm/CMakeLists.txt b/tools/llvm-nm/CMakeLists.txt
index 45cf1b6..b6cd80b 100644
--- a/tools/llvm-nm/CMakeLists.txt
+++ b/tools/llvm-nm/CMakeLists.txt
@@ -1,4 +1,4 @@
-set(LLVM_LINK_COMPONENTS archive bitreader)
+set(LLVM_LINK_COMPONENTS archive bitreader object)
add_llvm_tool(llvm-nm
llvm-nm.cpp
diff --git a/tools/llvm-nm/Makefile b/tools/llvm-nm/Makefile
index ecf5f8c..6bb4cd4 100644
--- a/tools/llvm-nm/Makefile
+++ b/tools/llvm-nm/Makefile
@@ -9,7 +9,7 @@
LEVEL = ../..
TOOLNAME = llvm-nm
-LINK_COMPONENTS = archive bitreader
+LINK_COMPONENTS = archive bitreader object
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp
index daa8571..1afa503 100644
--- a/tools/llvm-nm/llvm-nm.cpp
+++ b/tools/llvm-nm/llvm-nm.cpp
@@ -20,17 +20,23 @@
#include "llvm/Module.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Bitcode/Archive.h"
+#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/system_error.h"
#include <algorithm>
#include <cctype>
#include <cerrno>
#include <cstring>
+#include <vector>
using namespace llvm;
+using namespace object;
namespace {
enum OutputFormatTy { bsd, sysv, posix };
@@ -64,11 +70,148 @@ namespace {
cl::opt<bool> BSDFormat("B", cl::desc("Alias for --format=bsd"));
cl::opt<bool> POSIXFormat("P", cl::desc("Alias for --format=posix"));
+ cl::opt<bool> PrintFileName("print-file-name",
+ cl::desc("Precede each symbol with the object file it came from"));
+
+ cl::alias PrintFileNameA("A", cl::desc("Alias for --print-file-name"),
+ cl::aliasopt(PrintFileName));
+ cl::alias PrintFileNameo("o", cl::desc("Alias for --print-file-name"),
+ cl::aliasopt(PrintFileName));
+
+ cl::opt<bool> DebugSyms("debug-syms",
+ cl::desc("Show all symbols, even debugger only"));
+ cl::alias DebugSymsa("a", cl::desc("Alias for --debug-syms"),
+ cl::aliasopt(DebugSyms));
+
+ cl::opt<bool> NumericSort("numeric-sort",
+ cl::desc("Sort symbols by address"));
+ cl::alias NumericSortn("n", cl::desc("Alias for --numeric-sort"),
+ cl::aliasopt(NumericSort));
+ cl::alias NumericSortv("v", cl::desc("Alias for --numeric-sort"),
+ cl::aliasopt(NumericSort));
+
+ cl::opt<bool> NoSort("no-sort",
+ cl::desc("Show symbols in order encountered"));
+ cl::alias NoSortp("p", cl::desc("Alias for --no-sort"),
+ cl::aliasopt(NoSort));
+
+ cl::opt<bool> PrintSize("print-size",
+ cl::desc("Show symbol size instead of address"));
+ cl::alias PrintSizeS("S", cl::desc("Alias for --print-size"),
+ cl::aliasopt(PrintSize));
+
+ cl::opt<bool> SizeSort("size-sort", cl::desc("Sort symbols by size"));
+
+ bool PrintAddress = true;
+
bool MultipleFiles = false;
std::string ToolName;
}
+namespace {
+ struct NMSymbol {
+ uint64_t Address;
+ uint64_t Size;
+ char TypeChar;
+ StringRef Name;
+ };
+
+ static bool CompareSymbolAddress(const NMSymbol &a, const NMSymbol &b) {
+ if (a.Address < b.Address)
+ return true;
+ else if (a.Address == b.Address && a.Name < b.Name)
+ return true;
+ else
+ return false;
+
+ }
+
+ static bool CompareSymbolSize(const NMSymbol &a, const NMSymbol &b) {
+ if (a.Size < b.Size)
+ return true;
+ else if (a.Size == b.Size && a.Name < b.Name)
+ return true;
+ else
+ return false;
+ }
+
+ static bool CompareSymbolName(const NMSymbol &a, const NMSymbol &b) {
+ return a.Name < b.Name;
+ }
+
+ StringRef CurrentFilename;
+ typedef std::vector<NMSymbol> SymbolListT;
+ SymbolListT SymbolList;
+}
+
+static void SortAndPrintSymbolList() {
+ if (!NoSort) {
+ if (NumericSort)
+ std::sort(SymbolList.begin(), SymbolList.end(), CompareSymbolAddress);
+ else if (SizeSort)
+ std::sort(SymbolList.begin(), SymbolList.end(), CompareSymbolSize);
+ else
+ std::sort(SymbolList.begin(), SymbolList.end(), CompareSymbolName);
+ }
+
+ if (OutputFormat == posix && MultipleFiles) {
+ outs() << '\n' << CurrentFilename << ":\n";
+ } else if (OutputFormat == bsd && MultipleFiles) {
+ outs() << "\n" << CurrentFilename << ":\n";
+ } else if (OutputFormat == sysv) {
+ outs() << "\n\nSymbols from " << CurrentFilename << ":\n\n"
+ << "Name Value Class Type"
+ << " Size Line Section\n";
+ }
+
+ for (SymbolListT::iterator i = SymbolList.begin(),
+ e = SymbolList.end(); i != e; ++i) {
+ if ((i->TypeChar != 'U') && UndefinedOnly)
+ continue;
+ if ((i->TypeChar == 'U') && DefinedOnly)
+ continue;
+ if (SizeSort && !PrintAddress && i->Size == UnknownAddressOrSize)
+ continue;
+
+ char SymbolAddrStr[10] = "";
+ char SymbolSizeStr[10] = "";
+
+ if (OutputFormat == sysv || i->Address == object::UnknownAddressOrSize)
+ strcpy(SymbolAddrStr, " ");
+ if (OutputFormat == sysv)
+ strcpy(SymbolSizeStr, " ");
+
+ if (i->Address != object::UnknownAddressOrSize)
+ format("%08x", i->Address).print(SymbolAddrStr, sizeof(SymbolAddrStr));
+ if (i->Size != object::UnknownAddressOrSize)
+ format("%08x", i->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr));
+
+ if (OutputFormat == posix) {
+ outs() << i->Name << " " << i->TypeChar << " "
+ << SymbolAddrStr << SymbolSizeStr << "\n";
+ } else if (OutputFormat == bsd) {
+ if (PrintAddress)
+ outs() << SymbolAddrStr << ' ';
+ if (PrintSize) {
+ outs() << SymbolSizeStr;
+ if (i->Size != object::UnknownAddressOrSize)
+ outs() << ' ';
+ }
+ outs() << i->TypeChar << " " << i->Name << "\n";
+ } else if (OutputFormat == sysv) {
+ std::string PaddedName (i->Name);
+ while (PaddedName.length () < 20)
+ PaddedName += " ";
+ outs() << PaddedName << "|" << SymbolAddrStr << "| "
+ << i->TypeChar
+ << " | |" << SymbolSizeStr << "| |\n";
+ }
+ }
+
+ SymbolList.clear();
+}
+
static char TypeCharForSymbol(GlobalValue &GV) {
if (GV.isDeclaration()) return 'U';
if (GV.hasLinkOnceLinkage()) return 'C';
@@ -94,57 +237,62 @@ static void DumpSymbolNameForGlobalValue(GlobalValue &GV) {
GV.hasLinkerPrivateWeakDefAutoLinkage() ||
GV.hasAvailableExternallyLinkage())
return;
-
- const std::string SymbolAddrStr = " "; // Not used yet...
char TypeChar = TypeCharForSymbol(GV);
- if ((TypeChar != 'U') && UndefinedOnly)
- return;
- if ((TypeChar == 'U') && DefinedOnly)
- return;
if (GV.hasLocalLinkage () && ExternalOnly)
return;
- if (OutputFormat == posix) {
- outs() << GV.getName () << " " << TypeCharForSymbol(GV) << " "
- << SymbolAddrStr << "\n";
- } else if (OutputFormat == bsd) {
- outs() << SymbolAddrStr << " " << TypeCharForSymbol(GV) << " "
- << GV.getName () << "\n";
- } else if (OutputFormat == sysv) {
- std::string PaddedName (GV.getName ());
- while (PaddedName.length () < 20)
- PaddedName += " ";
- outs() << PaddedName << "|" << SymbolAddrStr << "| "
- << TypeCharForSymbol(GV)
- << " | | | |\n";
- }
+
+ NMSymbol s;
+ s.Address = object::UnknownAddressOrSize;
+ s.Size = object::UnknownAddressOrSize;
+ s.TypeChar = TypeChar;
+ s.Name = GV.getName();
+ SymbolList.push_back(s);
}
static void DumpSymbolNamesFromModule(Module *M) {
- const std::string &Filename = M->getModuleIdentifier ();
- if (OutputFormat == posix && MultipleFiles) {
- outs() << Filename << ":\n";
- } else if (OutputFormat == bsd && MultipleFiles) {
- outs() << "\n" << Filename << ":\n";
- } else if (OutputFormat == sysv) {
- outs() << "\n\nSymbols from " << Filename << ":\n\n"
- << "Name Value Class Type"
- << " Size Line Section\n";
- }
+ CurrentFilename = M->getModuleIdentifier();
std::for_each (M->begin(), M->end(), DumpSymbolNameForGlobalValue);
std::for_each (M->global_begin(), M->global_end(),
DumpSymbolNameForGlobalValue);
std::for_each (M->alias_begin(), M->alias_end(),
DumpSymbolNameForGlobalValue);
+
+ SortAndPrintSymbolList();
+}
+
+static void DumpSymbolNamesFromObject(ObjectFile *obj) {
+ for (ObjectFile::symbol_iterator i = obj->begin_symbols(),
+ e = obj->end_symbols(); i != e; ++i) {
+ if (!DebugSyms && i->isInternal())
+ continue;
+ NMSymbol s;
+ s.Size = object::UnknownAddressOrSize;
+ s.Address = object::UnknownAddressOrSize;
+ if (PrintSize || SizeSort)
+ s.Size = i->getSize();
+ if (PrintAddress)
+ s.Address = i->getAddress();
+ s.TypeChar = i->getNMTypeChar();
+ s.Name = i->getName();
+ SymbolList.push_back(s);
+ }
+
+ CurrentFilename = obj->getFilename();
+ SortAndPrintSymbolList();
}
static void DumpSymbolNamesFromFile(std::string &Filename) {
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()) {
- std::auto_ptr<MemoryBuffer> Buffer(
- MemoryBuffer::getFileOrSTDIN(Filename, &ErrorMessage));
+ OwningPtr<MemoryBuffer> Buffer;
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buffer))
+ ErrorMessage = ec.message();
Module *Result = 0;
if (Buffer.get())
Result = ParseBitcodeFile(Buffer.get(), Context, &ErrorMessage);
@@ -168,6 +316,14 @@ static void DumpSymbolNamesFromFile(std::string &Filename) {
}
MultipleFiles = true;
std::for_each (Modules.begin(), Modules.end(), DumpSymbolNamesFromModule);
+ } else if (aPath.isObjectFile()) {
+ std::auto_ptr<ObjectFile> obj(ObjectFile::createObjectFile(aPath.str()));
+ if (!obj.get()) {
+ errs() << ToolName << ": " << Filename << ": "
+ << "Failed to open object file\n";
+ return;
+ }
+ DumpSymbolNamesFromObject(obj.get());
} else {
errs() << ToolName << ": " << Filename << ": "
<< "unrecognizable file type\n";
@@ -187,6 +343,12 @@ int main(int argc, char **argv) {
if (BSDFormat) OutputFormat = bsd;
if (POSIXFormat) OutputFormat = posix;
+ // The relative order of these is important. If you pass --size-sort it should
+ // only print out the size. However, if you pass -S --size-sort, it should
+ // print out both the size and address.
+ if (SizeSort && !PrintSize) PrintAddress = false;
+ if (OutputFormat == sysv || SizeSort) PrintSize = true;
+
switch (InputFilenames.size()) {
case 0: InputFilenames.push_back("-");
case 1: break;
diff --git a/tools/llvm-objdump/CMakeLists.txt b/tools/llvm-objdump/CMakeLists.txt
new file mode 100644
index 0000000..4181b32
--- /dev/null
+++ b/tools/llvm-objdump/CMakeLists.txt
@@ -0,0 +1,11 @@
+set(LLVM_LINK_COMPONENTS
+ ${LLVM_TARGETS_TO_BUILD}
+ MC
+ MCParser
+ MCDisassembler
+ Object
+ )
+
+add_llvm_tool(llvm-objdump
+ llvm-objdump.cpp
+ )
diff --git a/tools/llvm-objdump/Makefile b/tools/llvm-objdump/Makefile
new file mode 100644
index 0000000..4d7cd34
--- /dev/null
+++ b/tools/llvm-objdump/Makefile
@@ -0,0 +1,17 @@
+##===- tools/llvm-objdump/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-objdump
+LINK_COMPONENTS = $(TARGETS_TO_BUILD) MC MCParser MCDisassembler Object
+
+# This tool has no plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp
new file mode 100644
index 0000000..1fef8b6
--- /dev/null
+++ b/tools/llvm-objdump/llvm-objdump.cpp
@@ -0,0 +1,255 @@
+//===-- llvm-objdump.cpp - Object file dumping utility for 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 works like binutils "objdump", that is, it
+// dumps out a plethora of information about an object file depending on the
+// flags.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Object/ObjectFile.h"
+// This config must be included before llvm-config.h.
+#include "llvm/Config/config.h"
+#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/ADT/OwningPtr.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/MemoryObject.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/system_error.h"
+#include "llvm/Target/TargetRegistry.h"
+#include "llvm/Target/TargetSelect.h"
+#include <algorithm>
+#include <cctype>
+#include <cerrno>
+#include <cstring>
+#include <vector>
+using namespace llvm;
+using namespace object;
+
+namespace {
+ cl::list<std::string>
+ InputFilenames(cl::Positional, cl::desc("<input object files>"),
+ cl::ZeroOrMore);
+
+ cl::opt<bool>
+ Disassemble("disassemble",
+ cl::desc("Display assembler mnemonics for the machine instructions"));
+ cl::alias
+ Disassembled("d", cl::desc("Alias for --disassemble"),
+ cl::aliasopt(Disassemble));
+
+ cl::opt<std::string>
+ TripleName("triple", cl::desc("Target triple to disassemble for, "
+ "see -version for available targets"));
+
+ cl::opt<std::string>
+ ArchName("arch", cl::desc("Target arch to disassemble for, "
+ "see -version for available targets"));
+
+ StringRef ToolName;
+}
+
+static const Target *GetTarget(const ObjectFile *Obj = NULL) {
+ // Figure out the target triple.
+ llvm::Triple TT("unknown-unknown-unknown");
+ if (TripleName.empty()) {
+ if (Obj)
+ TT.setArch(Triple::ArchType(Obj->getArch()));
+ } else
+ TT.setTriple(Triple::normalize(TripleName));
+
+ if (!ArchName.empty())
+ TT.setArchName(ArchName);
+
+ TripleName = TT.str();
+
+ // Get the target specific parser.
+ std::string Error;
+ const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
+ if (TheTarget)
+ return TheTarget;
+
+ errs() << ToolName << ": error: unable to get target for '" << TripleName
+ << "', see --version and --triple.\n";
+ return 0;
+}
+
+namespace {
+class StringRefMemoryObject : public MemoryObject {
+private:
+ StringRef Bytes;
+public:
+ StringRefMemoryObject(StringRef bytes) : Bytes(bytes) {}
+
+ uint64_t getBase() const { return 0; }
+ uint64_t getExtent() const { return Bytes.size(); }
+
+ int readByte(uint64_t Addr, uint8_t *Byte) const {
+ if (Addr > getExtent())
+ return -1;
+ *Byte = Bytes[Addr];
+ return 0;
+ }
+};
+}
+
+static void DumpBytes(StringRef bytes) {
+ static char hex_rep[] = "0123456789abcdef";
+ // FIXME: The real way to do this is to figure out the longest instruction
+ // and align to that size before printing. I'll fix this when I get
+ // around to outputting relocations.
+ // 15 is the longest x86 instruction
+ // 3 is for the hex rep of a byte + a space.
+ // 1 is for the null terminator.
+ enum { OutputSize = (15 * 3) + 1 };
+ char output[OutputSize];
+
+ assert(bytes.size() <= 15
+ && "DumpBytes only supports instructions of up to 15 bytes");
+ memset(output, ' ', sizeof(output));
+ unsigned index = 0;
+ for (StringRef::iterator i = bytes.begin(),
+ e = bytes.end(); i != e; ++i) {
+ output[index] = hex_rep[(*i & 0xF0) >> 4];
+ output[index + 1] = hex_rep[*i & 0xF];
+ index += 3;
+ }
+
+ output[sizeof(output) - 1] = 0;
+ outs() << output;
+}
+
+static void DisassembleInput(const StringRef &Filename) {
+ OwningPtr<MemoryBuffer> Buff;
+
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
+ errs() << ToolName << ": " << Filename << ": " << ec.message() << "\n";
+ return;
+ }
+
+ OwningPtr<ObjectFile> Obj(ObjectFile::createObjectFile(Buff.take()));
+
+ const Target *TheTarget = GetTarget(Obj.get());
+ if (!TheTarget) {
+ // GetTarget prints out stuff.
+ return;
+ }
+
+ outs() << '\n';
+ outs() << Filename
+ << ":\tfile format " << Obj->getFileFormatName() << "\n\n\n";
+
+ for (ObjectFile::section_iterator i = Obj->begin_sections(),
+ e = Obj->end_sections();
+ i != e; ++i) {
+ if (!i->isText())
+ continue;
+ outs() << "Disassembly of section " << i->getName() << ":\n\n";
+
+ // Set up disassembler.
+ OwningPtr<const MCAsmInfo> AsmInfo(TheTarget->createAsmInfo(TripleName));
+
+ if (!AsmInfo) {
+ errs() << "error: no assembly info for target " << TripleName << "\n";
+ return;
+ }
+
+ OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler());
+ if (!DisAsm) {
+ errs() << "error: no disassembler for target " << TripleName << "\n";
+ return;
+ }
+
+ int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
+ OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
+ AsmPrinterVariant, *AsmInfo));
+ if (!IP) {
+ errs() << "error: no instruction printer for target " << TripleName << '\n';
+ return;
+ }
+
+ StringRef Bytes = i->getContents();
+ StringRefMemoryObject memoryObject(Bytes);
+ uint64_t Size;
+ uint64_t Index;
+
+ for (Index = 0; Index < Bytes.size(); Index += Size) {
+ MCInst Inst;
+
+# ifndef NDEBUG
+ raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
+# else
+ raw_ostream &DebugOut = nulls();
+# endif
+
+ if (DisAsm->getInstruction(Inst, Size, memoryObject, Index, DebugOut)) {
+ outs() << format("%8x:\t", i->getAddress() + Index);
+ DumpBytes(StringRef(Bytes.data() + Index, Size));
+ IP->printInst(&Inst, outs());
+ outs() << "\n";
+ } else {
+ errs() << ToolName << ": warning: invalid instruction encoding\n";
+ if (Size == 0)
+ Size = 1; // skip illegible bytes
+ }
+ }
+ }
+}
+
+int main(int argc, char **argv) {
+ // Print a stack trace if we signal out.
+ sys::PrintStackTraceOnErrorSignal();
+ PrettyStackTraceProgram X(argc, argv);
+ llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
+
+ // Initialize targets and assembly printers/parsers.
+ llvm::InitializeAllTargetInfos();
+ // FIXME: We shouldn't need to initialize the Target(Machine)s.
+ llvm::InitializeAllTargets();
+ llvm::InitializeAllAsmPrinters();
+ llvm::InitializeAllAsmParsers();
+ llvm::InitializeAllDisassemblers();
+
+ cl::ParseCommandLineOptions(argc, argv, "llvm object file dumper\n");
+ TripleName = Triple::normalize(TripleName);
+
+ ToolName = argv[0];
+
+ // Defaults to a.out if no filenames specified.
+ if (InputFilenames.size() == 0)
+ InputFilenames.push_back("a.out");
+
+ // -d is the only flag that is currently implemented, so just print help if
+ // it is not set.
+ if (!Disassemble) {
+ cl::PrintHelpMessage();
+ return 2;
+ }
+
+ std::for_each(InputFilenames.begin(), InputFilenames.end(),
+ DisassembleInput);
+
+ return 0;
+}
diff --git a/tools/llvm-prof/llvm-prof.cpp b/tools/llvm-prof/llvm-prof.cpp
index 1c63d97..9d0b468 100644
--- a/tools/llvm-prof/llvm-prof.cpp
+++ b/tools/llvm-prof/llvm-prof.cpp
@@ -29,7 +29,8 @@
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Format.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/system_error.h"
#include <algorithm>
#include <iomanip>
#include <map>
@@ -263,12 +264,13 @@ int main(int argc, char **argv) {
// Read in the bitcode file...
std::string ErrorMessage;
+ OwningPtr<MemoryBuffer> Buffer;
+ error_code ec;
Module *M = 0;
- if (MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(BitcodeFile,
- &ErrorMessage)) {
- M = ParseBitcodeFile(Buffer, Context, &ErrorMessage);
- delete Buffer;
- }
+ if (!(ec = MemoryBuffer::getFileOrSTDIN(BitcodeFile, Buffer))) {
+ M = ParseBitcodeFile(Buffer.get(), Context, &ErrorMessage);
+ } else
+ ErrorMessage = ec.message();
if (M == 0) {
errs() << argv[0] << ": " << BitcodeFile << ": "
<< ErrorMessage << "\n";
diff --git a/tools/llvm-ranlib/llvm-ranlib.cpp b/tools/llvm-ranlib/llvm-ranlib.cpp
index dffe3ad..64f795f 100644
--- a/tools/llvm-ranlib/llvm-ranlib.cpp
+++ b/tools/llvm-ranlib/llvm-ranlib.cpp
@@ -15,14 +15,13 @@
#include "llvm/Module.h"
#include "llvm/Bitcode/Archive.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Signals.h"
-#include <iostream>
-#include <iomanip>
+#include "llvm/Support/Signals.h"
#include <memory>
-
using namespace llvm;
// llvm-ar operation code and modifier flags
@@ -35,12 +34,12 @@ Verbose("verbose",cl::Optional,cl::init(false),
// printSymbolTable - print out the archive's symbol table.
void printSymbolTable(Archive* TheArchive) {
- std::cout << "\nArchive Symbol Table:\n";
+ outs() << "\nArchive Symbol Table:\n";
const Archive::SymTabType& symtab = TheArchive->getSymbolTable();
for (Archive::SymTabType::const_iterator I=symtab.begin(), E=symtab.end();
I != E; ++I ) {
unsigned offset = TheArchive->getFirstFileOffset() + I->second;
- std::cout << " " << std::setw(9) << offset << "\t" << I->first <<"\n";
+ outs() << " " << format("%9u", offset) << "\t" << I->first <<"\n";
}
}
@@ -71,7 +70,8 @@ int main(int argc, char **argv) {
throw std::string("Archive name invalid: ") + ArchiveName;
// Make sure it exists, we don't create empty archives
- if (!ArchivePath.exists())
+ bool Exists;
+ if (llvm::sys::fs::exists(ArchivePath.str(), Exists) || !Exists)
throw std::string("Archive file does not exist");
std::string err_msg;
diff --git a/tools/llvm-shlib/Makefile b/tools/llvm-shlib/Makefile
index 5238130..9e6faca 100644
--- a/tools/llvm-shlib/Makefile
+++ b/tools/llvm-shlib/Makefile
@@ -18,11 +18,12 @@ SHARED_LIBRARY = 1
include $(LEVEL)/Makefile.config
ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
- EXPORTED_SYMBOL_FILE = $(ObjDir)/$(LIBRARYNAME).exports
+ EXPORTED_SYMBOL_FILE = $(ObjDir)/$(LIBRARYNAME).exports
+ ifeq (1,$(ENABLE_EMBED_STDCXX))
# It is needed to force static-stdc++.a linked.
- # FIXME: It should be omitted when configure detects system's stdc++.dll.
SHLIB_FRAG_NAMES += stdc++.a.o
+ endif
endif
@@ -61,14 +62,22 @@ ifeq ($(HOST_OS),Darwin)
endif
endif
-ifeq ($(HOST_OS), Linux)
+ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux FreeBSD OpenBSD))
# Include everything from the .a's into the shared library.
LLVMLibsOptions := -Wl,--whole-archive $(LLVMLibsOptions) \
-Wl,--no-whole-archive
+endif
+
+ifeq ($(HOST_OS),Linux)
# Don't allow unresolved symbols.
LLVMLibsOptions += -Wl,--no-undefined
endif
+ifeq ($(HOST_OS),SunOS)
+ # add -z allextract ahead of other libraries on Solaris
+ LLVMLibsOptions := -Wl,-z -Wl,allextract $(LLVMLibsOptions)
+endif
+
ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
SHLIB_STUBS := $(addprefix $(ObjDir)/, $(SHLIB_FRAG_NAMES))
diff --git a/tools/llvm-stub/llvm-stub.c b/tools/llvm-stub/llvm-stub.c
index f2e478e..31c2d09 100644
--- a/tools/llvm-stub/llvm-stub.c
+++ b/tools/llvm-stub/llvm-stub.c
@@ -1,10 +1,10 @@
/*===- llvm-stub.c - Stub executable to run llvm bitcode files ------------===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This tool is used by the gccld program to enable transparent execution of
@@ -64,7 +64,11 @@ int main(int argc, char** argv) {
memcpy((char **)Args+2, argv+1, sizeof(char*)*argc);
/* Run the JIT. */
- execvp(Interp, (char **)Args);
+#ifndef _WIN32
+ execvp(Interp, (char **)Args); /* POSIX execvp takes a char *const[]. */
+#else
+ execvp(Interp, Args); /* windows execvp takes a const char *const *. */
+#endif
/* if _execv returns, the JIT could not be started. */
fprintf(stderr, "Could not execute the LLVM JIT. Either add 'lli' to your"
" path, or set the\ninterpreter you want to use in the LLVMINTERP "
diff --git a/tools/llvmc/doc/LLVMC-Reference.rst b/tools/llvmc/doc/LLVMC-Reference.rst
index d160e75..ec9098b 100644
--- a/tools/llvmc/doc/LLVMC-Reference.rst
+++ b/tools/llvmc/doc/LLVMC-Reference.rst
@@ -319,7 +319,8 @@ separate option groups syntactically.
- ``alias_option`` - a special option type for creating aliases. Unlike other
option types, aliases are not allowed to have any properties besides the
- aliased option name. Usage example: ``(alias_option "preprocess", "E")``
+ aliased option name.
+ Usage example: ``(alias_option "preprocess", "E")``
- ``switch_list_option`` - like ``switch_option`` with the ``zero_or_more``
property, but remembers how many times the switch was turned on. Useful
@@ -456,22 +457,22 @@ use TableGen inheritance instead.
* Possible tests are:
- ``switch_on`` - Returns true if a given command-line switch is provided by
- the user. Can be given a list as argument, in that case ``(switch_on ["foo",
- "bar", "baz"])`` is equivalent to ``(and (switch_on "foo"), (switch_on
+ the user. Can be given multiple arguments, in that case ``(switch_on "foo",
+ "bar", "baz")`` is equivalent to ``(and (switch_on "foo"), (switch_on
"bar"), (switch_on "baz"))``.
Example: ``(switch_on "opt")``.
- - ``any_switch_on`` - Given a list of switch options, returns true if any of
+ - ``any_switch_on`` - Given a number of switch options, returns true if any of
the switches is turned on.
- Example: ``(any_switch_on ["foo", "bar", "baz"])`` is equivalent to ``(or
+ Example: ``(any_switch_on "foo", "bar", "baz")`` is equivalent to ``(or
(switch_on "foo"), (switch_on "bar"), (switch_on "baz"))``.
- - ``parameter_equals`` - Returns true if a command-line parameter equals
- a given value.
+ - ``parameter_equals`` - Returns true if a command-line parameter (first
+ argument) equals a given value (second argument).
Example: ``(parameter_equals "W", "all")``.
- - ``element_in_list`` - Returns true if a command-line parameter
- list contains a given value.
+ - ``element_in_list`` - Returns true if a command-line parameter list (first
+ argument) contains a given value (second argument).
Example: ``(element_in_list "l", "pthread")``.
- ``input_languages_contain`` - Returns true if a given language
@@ -479,27 +480,27 @@ use TableGen inheritance instead.
Example: ``(input_languages_contain "c++")``.
- ``in_language`` - Evaluates to true if the input file language is equal to
- the argument. At the moment works only with ``cmd_line`` and ``actions`` (on
+ the argument. At the moment works only with ``command`` and ``actions`` (on
non-join nodes).
Example: ``(in_language "c++")``.
- ``not_empty`` - Returns true if a given option (which should be either a
parameter or a parameter list) is set by the user. Like ``switch_on``, can
- be also given a list as argument.
- Example: ``(not_empty "o")``.
+ be also given multiple arguments.
+ Examples: ``(not_empty "o")``, ``(not_empty "o", "l")``.
- ``any_not_empty`` - Returns true if ``not_empty`` returns true for any of
- the options in the list.
- Example: ``(any_not_empty ["foo", "bar", "baz"])`` is equivalent to ``(or
+ the provided options.
+ Example: ``(any_not_empty "foo", "bar", "baz")`` is equivalent to ``(or
(not_empty "foo"), (not_empty "bar"), (not_empty "baz"))``.
- ``empty`` - The opposite of ``not_empty``. Equivalent to ``(not (not_empty
- X))``. Provided for convenience. Can be given a list as argument.
+ X))``. Can be given multiple arguments.
- ``any_not_empty`` - Returns true if ``not_empty`` returns true for any of
- the options in the list.
- Example: ``(any_empty ["foo", "bar", "baz"])`` is equivalent to ``(not (and
- (not_empty "foo"), (not_empty "bar"), (not_empty "baz")))``.
+ the provided options.
+ Example: ``(any_empty "foo", "bar", "baz")`` is equivalent to ``(or
+ (not_empty "foo"), (not_empty "bar"), (not_empty "baz"))``.
- ``single_input_file`` - Returns true if there was only one input file
provided on the command-line. Used without arguments:
@@ -511,16 +512,18 @@ use TableGen inheritance instead.
- ``default`` - Always evaluates to true. Should always be the last
test in the ``case`` expression.
- - ``and`` - A standard binary logical combinator that returns true iff all of
+ - ``and`` - A standard logical combinator that returns true iff all of
its arguments return true. Used like this: ``(and (test1), (test2),
... (testN))``. Nesting of ``and`` and ``or`` is allowed, but not
encouraged.
- - ``or`` - A binary logical combinator that returns true iff any of its
- arguments returns true. Example: ``(or (test1), (test2), ... (testN))``.
+ - ``or`` - A logical combinator that returns true iff any of its arguments
+ return true.
+ Example: ``(or (test1), (test2), ... (testN))``.
- ``not`` - Standard unary logical combinator that negates its
- argument. Example: ``(not (or (test1), (test2), ... (testN)))``.
+ argument.
+ Example: ``(not (or (test1), (test2), ... (testN)))``.
@@ -549,10 +552,10 @@ The complete list of all currently implemented tool properties follows.
* Possible tool properties:
- - ``in_language`` - input language name. Can be either a string or a
- list, in case the tool supports multiple input languages.
+ - ``in_language`` - input language name. Can be given multiple arguments, in
+ case the tool supports multiple input languages.
- - ``out_language`` - output language name. Multiple output languages are not
+ - ``out_language`` - output language name. Multiple output languages are
allowed.
- ``output_suffix`` - output file suffix. Can also be changed
@@ -687,12 +690,12 @@ occasions. Example (adapted from the built-in Base plugin)::
def Preprocess : OptionPreprocessor<
- (case (not (any_switch_on ["O0", "O1", "O2", "O3"])),
+ (case (not (any_switch_on "O0", "O1", "O2", "O3")),
(set_option "O2"),
- (and (switch_on "O3"), (any_switch_on ["O0", "O1", "O2"])),
- (unset_option ["O0", "O1", "O2"]),
- (and (switch_on "O2"), (any_switch_on ["O0", "O1"])),
- (unset_option ["O0", "O1"]),
+ (and (switch_on "O3"), (any_switch_on "O0", "O1", "O2")),
+ (unset_option "O0", "O1", "O2"),
+ (and (switch_on "O2"), (any_switch_on "O0", "O1")),
+ (unset_option "O0", "O1"),
(and (switch_on "O1"), (switch_on "O0")),
(unset_option "O0"))
>;
@@ -709,10 +712,10 @@ set or unset a given option. To set an option with ``set_option``, use the
two-argument form: ``(set_option "parameter", VALUE)``. Here, ``VALUE`` can be
either a string, a string list, or a boolean constant.
-For convenience, ``set_option`` and ``unset_option`` also work on lists. That
-is, instead of ``[(unset_option "A"), (unset_option "B")]`` you can use
-``(unset_option ["A", "B"])``. Obviously, ``(set_option ["A", "B"])`` is valid
-only if both ``A`` and ``B`` are switches.
+For convenience, ``set_option`` and ``unset_option`` also work with multiple
+arguments. That is, instead of ``[(unset_option "A"), (unset_option "B")]`` you
+can use ``(unset_option "A", "B")``. Obviously, ``(set_option "A", "B")`` is
+only valid if both ``A`` and ``B`` are switches.
More advanced topics
diff --git a/tools/llvmc/examples/mcc16/Hooks.cpp b/tools/llvmc/examples/mcc16/Hooks.cpp
index edb91e1..95158ef 100644
--- a/tools/llvmc/examples/mcc16/Hooks.cpp
+++ b/tools/llvmc/examples/mcc16/Hooks.cpp
@@ -1,4 +1,4 @@
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"
diff --git a/tools/llvmc/examples/mcc16/Main.cpp b/tools/llvmc/examples/mcc16/Main.cpp
index 55ae912..5d4992d 100644
--- a/tools/llvmc/examples/mcc16/Main.cpp
+++ b/tools/llvmc/examples/mcc16/Main.cpp
@@ -16,7 +16,7 @@
#include "llvm/CompilerDriver/BuiltinOptions.h"
#include "llvm/CompilerDriver/Main.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
#include "llvm/Config/config.h"
#include <iostream>
diff --git a/tools/llvmc/src/Base.td.in b/tools/llvmc/src/Base.td.in
index 0c4de4c..50533f1 100644
--- a/tools/llvmc/src/Base.td.in
+++ b/tools/llvmc/src/Base.td.in
@@ -11,7 +11,6 @@
//
//===----------------------------------------------------------------------===//
-
// Options
def OptList : OptionList<[
@@ -35,8 +34,6 @@ def OptList : OptionList<[
(help "Stop after compilation, do not assemble")),
(switch_option "c",
(help "Compile and assemble, but do not link")),
- (switch_option "pthread",
- (help "Enable threads")),
(switch_option "m32",
(help "Generate code for a 32-bit environment"), (hidden)),
(switch_option "m64",
@@ -45,22 +42,21 @@ def OptList : OptionList<[
(help "Relocation model: PIC"), (hidden)),
(switch_option "mdynamic-no-pic",
(help "Relocation model: dynamic-no-pic"), (hidden)),
- (switch_option "shared",
- (help "Create a DLL instead of the regular executable")),
(parameter_option "linker",
(help "Choose linker (possible values: gcc, g++)")),
(parameter_option "mtune",
- (help "Target a specific CPU type"), (hidden), (forward_not_split)),
-
- // TODO: Add a conditional compilation mechanism to make Darwin-only options
- // like '-arch' really Darwin-only.
-
- (parameter_option "arch",
- (help "Compile for the specified target architecture"), (hidden)),
- (parameter_option "march",
- (help "A synonym for -mtune"), (hidden), (forward_not_split)),
+ (help "Target a specific CPU type"), (forward_not_split)),
+ (parameter_list_option "march",
+ (help "Generate code for the specified machine type")),
(parameter_option "mcpu",
(help "A deprecated synonym for -mtune"), (hidden), (forward_not_split)),
+ (parameter_option "mfpu",
+ (help "Specify type of floating point unit"),
+ (hidden), (forward_not_split)),
+ (parameter_option "mabi",
+ (help "Generate code for the specified ABI"), (hidden)),
+ (parameter_option "mfloat-abi",
+ (help "Specifies which floating-point ABI to use"), (hidden)),
(switch_option "mfix-and-continue",
(help "Needed by gdb to load .o files dynamically"), (hidden)),
(parameter_option "MF",
@@ -73,14 +69,6 @@ def OptList : OptionList<[
(parameter_list_option "iquote",
(help "Search dir only for files requested with #inlcude \"file\""),
(hidden)),
- (parameter_list_option "framework",
- (help "Specifies a framework to link against")),
- (parameter_list_option "weak_framework",
- (help "Specifies a framework to weakly link against"), (hidden)),
- (parameter_option "filelist", (hidden),
- (help "Link the files listed in file")),
- (prefix_list_option "F",
- (help "Add a directory to framework search path")),
(prefix_list_option "I",
(help "Add a directory to include path")),
(prefix_list_option "D",
@@ -93,10 +81,6 @@ def OptList : OptionList<[
(help "Pass options to assembler")),
(prefix_list_option "Wllc,", (comma_separated),
(help "Pass options to llc")),
- (prefix_list_option "L",
- (help "Add a directory to link path")),
- (prefix_list_option "l",
- (help "Search a library when linking")),
(prefix_list_option "Wl,",
(help "Pass options to linker")),
(parameter_list_option "Xlinker", (hidden),
@@ -105,7 +89,56 @@ def OptList : OptionList<[
(help "Pass options to opt")),
(prefix_list_option "m",
(help "Enable or disable various extensions (-mmmx, -msse, etc.)"),
- (hidden)),
+ (hidden))
+]>;
+
+def LinkerOptList : OptionList<[
+ (prefix_list_option "L",
+ (help "Add a directory to link path")),
+ (prefix_list_option "l",
+ (help "Search a library when linking")),
+ (parameter_option "filelist", (hidden),
+ (help "Link the files listed in file")),
+ (switch_option "nostartfiles",
+ (help "Do not use the standard system startup files when linking"),
+ (hidden)),
+ (switch_option "nodefaultlibs",
+ (help "Do not use the standard system libraries when linking"), (hidden)),
+ (switch_option "nostdlib",
+ (help
+ "Do not use the standard system startup files or libraries when linking"),
+ (hidden)),
+ (switch_option "pie",
+ (help "Produce a position independent executable"), (hidden)),
+ (switch_option "rdynamic",
+ (help "Add all symbols to the dynamic export table"), (hidden)),
+ (switch_option "s",
+ (help "Strip all symbols"), (hidden)),
+ (switch_option "static",
+ (help "Do not link against shared libraries"), (hidden)),
+ (switch_option "static-libgcc",
+ (help "Use static libgcc"), (hidden)),
+ (switch_option "shared",
+ (help "Create a DLL instead of the regular executable")),
+ (switch_option "shared-libgcc",
+ (help "Use shared libgcc"), (hidden)),
+ (parameter_option "T",
+ (help "Read linker script"), (hidden)),
+ (parameter_option "u",
+ (help "Start with undefined reference to SYMBOL"), (hidden)),
+ (switch_option "pthread",
+ (help "Enable threads")),
+
+ // TODO: Add a conditional compilation mechanism to make Darwin-only options
+ // like '-arch' really Darwin-only.
+ (parameter_option "arch",
+ (help "Compile for the specified target architecture"), (hidden)),
+ (prefix_list_option "F",
+ (help "Add a directory to framework search path")),
+ (parameter_list_option "framework",
+ (help "Specifies a framework to link against")),
+ (parameter_list_option "weak_framework",
+ (help "Specifies a framework to weakly link against"), (hidden)),
(switch_option "dynamiclib", (hidden),
(help "Produce a dynamic library")),
(switch_option "prebind", (hidden),
@@ -125,24 +158,24 @@ def OptList : OptionList<[
// Option preprocessor.
def Preprocess : OptionPreprocessor<
-(case (not (any_switch_on ["O0", "O1", "O2", "O3"])),
+(case (not (any_switch_on "O0", "O1", "O2", "O3")),
(set_option "O2"),
- (and (switch_on "O3"), (any_switch_on ["O0", "O1", "O2"])),
- (unset_option ["O0", "O1", "O2"]),
- (and (switch_on "O2"), (any_switch_on ["O0", "O1"])),
- (unset_option ["O0", "O1"]),
- (switch_on ["O1", "O0"]),
+ (and (switch_on "O3"), (any_switch_on "O0", "O1", "O2")),
+ (unset_option "O0", "O1", "O2"),
+ (and (switch_on "O2"), (any_switch_on "O0", "O1")),
+ (unset_option "O0", "O1"),
+ (switch_on "O1", "O0"),
(unset_option "O0"))
>;
// Tools
-class llvm_gcc_based <string cmd_prefix, string in_lang,
- string E_ext, string out_lang> : Tool<
+class llvm_gcc_based <string cmd, string in_lang, string E_ext, dag out_lang,
+ string out_ext> : Tool<
[(in_language in_lang),
- (out_language "llvm-bitcode"),
- (output_suffix out_lang),
- (command cmd_prefix),
+ out_lang,
+ (output_suffix out_ext),
+ (command cmd),
(actions
(case
(and (not_empty "o"),
@@ -151,14 +184,20 @@ class llvm_gcc_based <string cmd_prefix, string in_lang,
(switch_on "E"),
[(forward "E"), (stop_compilation), (output_suffix E_ext)],
(and (switch_on "E"), (empty "o")), (no_out_file),
- (switch_on ["emit-llvm", "S"]),
- [(output_suffix "ll"), (stop_compilation)],
- (switch_on ["emit-llvm", "c"]), (stop_compilation),
+
+ // ('-emit-llvm') && !('opt') -> stop compilation
+ (and (switch_on "emit-llvm"), (not (switch_on "opt"))),
+ (stop_compilation),
+ // ('-S' && '-emit-llvm') && !('opt') -> output .ll
+ (and (switch_on "emit-llvm", "S"), (not (switch_on "opt"))),
+ [(forward "S"), (output_suffix "ll")],
+ // Ususally just output .bc
+ (not (switch_on "fsyntax-only")),
+ [(append_cmd "-c"), (append_cmd "-emit-llvm")],
+
+ // -fsyntax-only
(switch_on "fsyntax-only"), [(forward "fsyntax-only"),
(no_out_file), (stop_compilation)],
- (switch_on ["S", "emit-llvm"]), [(forward "S"), (forward "emit-llvm")],
- (not (or (switch_on ["S", "emit-llvm"]), (switch_on "fsyntax-only"))),
- [(append_cmd "-c"), (append_cmd "-emit-llvm")],
// Forwards
(not_empty "Xpreprocessor"), (forward "Xpreprocessor"),
@@ -170,8 +209,11 @@ class llvm_gcc_based <string cmd_prefix, string in_lang,
(not_empty "D"), (forward "D"),
(not_empty "arch"), (forward "arch"),
(not_empty "march"), (forward "march"),
- (not_empty "mtune"), (forward "mtune"),
(not_empty "mcpu"), (forward "mcpu"),
+ (not_empty "mtune"), (forward "mtune"),
+ (not_empty "mfpu"), (forward "mfpu"),
+ (not_empty "mabi"), (forward "mabi"),
+ (not_empty "mfloat-abi"), (forward "mfloat-abi"),
(not_empty "m"), (forward "m"),
(switch_on "mfix-and-continue"), (forward "mfix-and-continue"),
(switch_on "m32"), (forward "m32"),
@@ -187,30 +229,40 @@ class llvm_gcc_based <string cmd_prefix, string in_lang,
(sink)
]>;
-def llvm_gcc_c : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x c", "c", "i", "bc">;
-def llvm_gcc_cpp : llvm_gcc_based<"@LLVMGXXCOMMAND@ -x c++", "c++", "i", "bc">;
-def llvm_gcc_m : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x objective-c",
- "objective-c", "mi", "bc">;
-def llvm_gcc_mxx : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x objective-c++",
- "objective-c++", "mi", "bc">;
+class llvm_gcc_comp_based <string cmd, string in_lang, string E_ext>
+: llvm_gcc_based<cmd, in_lang, E_ext,
+ (out_language "llvm-bitcode", "object-code"), "bc">;
+
+class llvm_gcc_pch_based <string cmd, string in_lang, string E_ext>
+: llvm_gcc_based<cmd, in_lang, E_ext,
+ (out_language "precompiled-header"), "gch">;
-def llvm_gcc_c_pch : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x c-header",
- "c-header", "i", "gch">;
-def llvm_gcc_cpp_pch : llvm_gcc_based<"@LLVMGXXCOMMAND@ -x c++-header",
- "c++-header",
- "i", "gch">;
-def llvm_gcc_m_pch : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x objective-c-header",
- "objective-c-header",
- "mi", "gch">;
-def llvm_gcc_mxx_pch
- : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x objective-c++-header",
- "objective-c++-header", "mi", "gch">;
+def llvm_gcc_c : llvm_gcc_comp_based
+ <"@LLVMGCCCOMMAND@ -x c", "c", "i">;
+def llvm_gcc_cpp : llvm_gcc_comp_based
+ <"@LLVMGXXCOMMAND@ -x c++", "c++", "i">;
+def llvm_gcc_m : llvm_gcc_comp_based
+ <"@LLVMGCCCOMMAND@ -x objective-c", "objective-c", "mi">;
+def llvm_gcc_mxx : llvm_gcc_comp_based
+ <"@LLVMGCCCOMMAND@ -x objective-c++", "objective-c++", "mi">;
+
+def llvm_gcc_c_pch : llvm_gcc_pch_based
+ <"@LLVMGCCCOMMAND@ -x c-header", "c-header", "i">;
+def llvm_gcc_cpp_pch : llvm_gcc_pch_based
+ <"@LLVMGXXCOMMAND@ -x c++-header", "c++-header", "i">;
+def llvm_gcc_m_pch : llvm_gcc_pch_based
+ <"@LLVMGCCCOMMAND@ -x objective-c-header", "objective-c-header", "mi">;
+def llvm_gcc_mxx_pch : llvm_gcc_pch_based
+ <"@LLVMGCCCOMMAND@ -x objective-c++-header", "objective-c++-header", "mi">;
def opt : Tool<
[(in_language "llvm-bitcode"),
(out_language "llvm-bitcode"),
- (output_suffix "bc"),
- (actions (case (not_empty "Wo,"), (forward_value "Wo,"),
+ (output_suffix "opt.bc"),
+ (actions (case (switch_on "emit-llvm"), (stop_compilation),
+ (switch_on "emit-llvm", "S"),
+ [(append_cmd "-S"), (output_suffix "ll")],
+ (not_empty "Wo,"), (forward_value "Wo,"),
(switch_on "O1"), (forward "O1"),
(switch_on "O2"), (forward "O2"),
(switch_on "O3"), (forward "O3"))),
@@ -222,7 +274,8 @@ def llvm_as : Tool<
(out_language "llvm-bitcode"),
(output_suffix "bc"),
(command "llvm-as"),
- (actions (case (switch_on "emit-llvm"), (stop_compilation)))
+ (actions (case (and (switch_on "emit-llvm"), (not (switch_on "opt"))),
+ (stop_compilation)))
]>;
def llvm_gcc_assembler : Tool<
@@ -234,13 +287,18 @@ def llvm_gcc_assembler : Tool<
(switch_on "c"), (stop_compilation),
(not_empty "arch"), (forward "arch"),
(not_empty "Xassembler"), (forward "Xassembler"),
+ (not_empty "march"), (forward "march"),
+ (not_empty "mcpu"), (forward "mcpu"),
+ (not_empty "mtune"), (forward "mtune"),
+ (not_empty "mabi"), (forward "mabi"),
+ (not_empty "mfloat-abi"), (forward "mfloat-abi"),
(switch_on "m32"), (forward "m32"),
(switch_on "m64"), (forward "m64"),
(not_empty "Wa,"), (forward "Wa,")))
]>;
def llc : Tool<
-[(in_language ["llvm-bitcode", "llvm-assembler"]),
+[(in_language "llvm-bitcode", "llvm-assembler"),
(out_language "assembler"),
(output_suffix "s"),
(command "llc"),
@@ -253,19 +311,22 @@ def llc : Tool<
(switch_on "fPIC"), (append_cmd "-relocation-model=pic"),
(switch_on "mdynamic-no-pic"),
(append_cmd "-relocation-model=dynamic-no-pic"),
- (not_empty "march"), (forward_as "mtune", "-mcpu"),
- (not_empty "mtune"), (forward_as "mtune", "-mcpu"),
- (not_empty "mcpu"), (forward "mcpu"),
+ (not_empty "march"), (forward_transformed_value
+ "march", "ConvertMArchToMAttr"),
+ (not_empty "mcpu"), (forward_transformed_value "mcpu", "ConvertMCpu"),
+ (and (not_empty "mtune"), (empty "mcpu")),
+ (forward_as "mtune", "-mcpu"),
+ (not_empty "mfpu"), (forward_transformed_value "mfpu", "ConvertMFpu"),
(not_empty "m"), (forward_transformed_value "m", "ConvertToMAttr"),
(not_empty "Wllc,"), (forward_value "Wllc,")))
]>;
// Base class for linkers
-class llvm_gcc_based_linker <string cmd_prefix, dag on_empty> : Tool<
-[(in_language ["object-code", "static-library", "dynamic-library"]),
+class llvm_gcc_based_linker <string cmd, dag on_empty> : Tool<
+[(in_language "object-code", "static-library", "dynamic-library"),
(out_language "executable"),
(output_suffix "out"),
- (command cmd_prefix),
+ (command cmd),
(works_on_empty (case (and (not_empty "filelist"), on_empty), true,
(default), false)),
(join),
@@ -277,12 +338,28 @@ class llvm_gcc_based_linker <string cmd_prefix, dag on_empty> : Tool<
(not_empty "framework"), (forward "framework"),
(not_empty "weak_framework"), (forward "weak_framework"),
(not_empty "filelist"), (forward "filelist"),
+ (not_empty "march"), (forward "march"),
+ (not_empty "mcpu"), (forward "mcpu"),
+ (not_empty "mtune"), (forward "mtune"),
+ (not_empty "mabi"), (forward "mabi"),
+ (not_empty "mfloat-abi"), (forward "mfloat-abi"),
(switch_on "m32"), (forward "m32"),
(switch_on "m64"), (forward "m64"),
(not_empty "l"), (forward "l"),
(not_empty "Xlinker"), (forward "Xlinker"),
(not_empty "Wl,"), (forward "Wl,"),
+ (switch_on "nostartfiles"), (forward "nostartfiles"),
+ (switch_on "nodefaultlibs"), (forward "nodefaultlibs"),
+ (switch_on "nostdlib"), (forward "nostdlib"),
+ (switch_on "pie"), (forward "pie"),
+ (switch_on "rdynamic"), (forward "rdynamic"),
+ (switch_on "s"), (forward "s"),
+ (switch_on "static"), (forward "static"),
+ (switch_on "static-libgcc"), (forward "static-libgcc"),
(switch_on "shared"), (forward "shared"),
+ (switch_on "shared-libgcc"), (forward "shared-libgcc"),
+ (not_empty "T"), (forward "T"),
+ (not_empty "u"), (forward "u"),
(switch_on "dynamiclib"), (forward "dynamiclib"),
(switch_on "prebind"), (forward "prebind"),
(switch_on "dead_strip"), (forward "dead_strip"),
@@ -305,6 +382,7 @@ def llvm_gcc_cpp_linker : llvm_gcc_based_linker<"@LLVMGXXCOMMAND@",
// Language map
def LanguageMap : LanguageMap<[
+ (lang_to_suffixes "precompiled-header", ["gch", "pch"]),
(lang_to_suffixes "c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]),
(lang_to_suffixes "c++-header", "hpp"),
(lang_to_suffixes "c", "c"),
@@ -322,7 +400,7 @@ def LanguageMap : LanguageMap<[
(lang_to_suffixes "object-code", ["o", "*empty*"]),
(lang_to_suffixes "static-library", ["a", "lib"]),
(lang_to_suffixes "dynamic-library", ["so", "dylib", "dll"]),
- (lang_to_suffixes "executable", ["out"])
+ (lang_to_suffixes "executable", "out")
]>;
// Compilation graph
@@ -347,7 +425,8 @@ def CompilationGraph : CompilationGraph<[
(edge "llvm_as", "llc"),
(optional_edge "root", "llvm_as",
- (case (switch_on "emit-llvm"), (inc_weight))),
+ (case (or (switch_on "emit-llvm"),
+ (switch_on "opt")), (inc_weight))),
(optional_edge "llvm_gcc_c", "opt",
(case (switch_on "opt"), (inc_weight))),
(optional_edge "llvm_gcc_cpp", "opt",
diff --git a/tools/llvmc/src/Clang.td b/tools/llvmc/src/Clang.td
index 1d75743..e2d32e8 100644
--- a/tools/llvmc/src/Clang.td
+++ b/tools/llvmc/src/Clang.td
@@ -25,12 +25,12 @@ class clang_based<string language, string cmd, string ext_E> : Tool<
[(forward "E"), (stop_compilation), (output_suffix ext_E)],
(and (switch_on "E"), (empty "o")), (no_out_file),
(switch_on "fsyntax-only"), (stop_compilation),
- (switch_on ["S", "emit-llvm"]),
+ (switch_on "S", "emit-llvm"),
[(append_cmd "-emit-llvm"),
(stop_compilation), (output_suffix "ll")],
- (not (switch_on ["S", "emit-llvm"])),
+ (not (switch_on "S", "emit-llvm")),
(append_cmd "-emit-llvm-bc"),
- (switch_on ["c", "emit-llvm"]),
+ (switch_on "c", "emit-llvm"),
(stop_compilation),
(not_empty "include"), (forward "include"),
(not_empty "I"), (forward "I"))),
diff --git a/tools/llvmc/src/Hooks.cpp b/tools/llvmc/src/Hooks.cpp
index 661a914..5aa250e 100644
--- a/tools/llvmc/src/Hooks.cpp
+++ b/tools/llvmc/src/Hooks.cpp
@@ -1,14 +1,182 @@
+#include "llvm/ADT/StringMap.h"
+
#include <string>
#include <vector>
namespace hooks {
+
+/// NUM_KEYS - Calculate the size of a const char* array.
+#define NUM_KEYS(Keys) sizeof(Keys) / sizeof(const char*)
+
+// See http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
+inline unsigned NextHighestPowerOf2 (unsigned i) {
+ --i;
+ i |= i >> 1;
+ i |= i >> 2;
+ i |= i >> 4;
+ i |= i >> 8;
+ i |= i >> 16;
+ ++i;
+ return i;
+}
+
typedef std::vector<std::string> StrVec;
+typedef llvm::StringMap<const char*> ArgMap;
+
+/// AddPlusOrMinus - Convert 'no-foo' to '-foo' and 'foo' to '+foo'.
+void AddPlusOrMinus (const std::string& Arg, std::string& out) {
+ if (Arg.find("no-") == 0 && Arg[3] != 0) {
+ out += '-';
+ out += Arg.c_str() + 3;
+ }
+ else {
+ out += '+';
+ out += Arg;
+ }
+}
+
+// -march values that need to be special-cased.
+const char* MArchKeysARM[] = { "armv4t", "armv5t", "armv5te", "armv6",
+ "armv6-m", "armv6t2", "armv7-a", "armv7-m" };
+const char* MArchValuesARM[] = { "v4t", "v5t", "v5te", "v6", "v6m", "v6t2",
+ "v7a", "v7m" };
+const unsigned MArchNumKeysARM = NUM_KEYS(MArchKeysARM);
+const unsigned MArchMapSize = NextHighestPowerOf2(MArchNumKeysARM);
+
+// -march values that should be forwarded as -mcpu
+const char* MArchMCpuKeysARM[] = { "iwmmxt", "ep9312" };
+const char* MArchMCpuValuesARM[] = { "iwmmxt", "ep9312"};
+const unsigned MArchMCpuNumKeysARM = NUM_KEYS(MArchMCpuKeysARM);
+const unsigned MArchMCpuMapSize = NextHighestPowerOf2(MArchMCpuNumKeysARM);
+
+
+void FillInArgMap(ArgMap& Args, const char* Keys[],
+ const char* Values[], unsigned NumKeys)
+{
+ for (unsigned i = 0; i < NumKeys; ++i) {
+ // Explicit cast to StringRef here is necessary to pick up the right
+ // overload.
+ Args.GetOrCreateValue(llvm::StringRef(Keys[i]), Values[i]);
+ }
+}
+
+/// ConvertMArchToMAttr - Convert -march from the gcc dialect to
+/// something llc can understand.
+std::string ConvertMArchToMAttr(const StrVec& Opts) {
+ static ArgMap MArchMap(MArchMapSize);
+ static ArgMap MArchMCpuMap(MArchMapSize);
+ static bool StaticDataInitialized = false;
+
+ if (!StaticDataInitialized) {
+ FillInArgMap(MArchMap, MArchKeysARM, MArchValuesARM, MArchNumKeysARM);
+ FillInArgMap(MArchMCpuMap, MArchMCpuKeysARM,
+ MArchMCpuValuesARM, MArchMCpuNumKeysARM);
+ StaticDataInitialized = true;
+ }
+
+ std::string mattr("-mattr=");
+ std::string mcpu("-mcpu=");
+ bool mattrTouched = false;
+ bool mcpuTouched = false;
+
+ for (StrVec::const_iterator B = Opts.begin(), E = Opts.end(); B!=E; ++B) {
+ const std::string& Arg = *B;
+
+ // Check if the argument should be forwarded to -mcpu instead of -mattr.
+ {
+ ArgMap::const_iterator I = MArchMCpuMap.find(Arg);
+
+ if (I != MArchMCpuMap.end()) {
+ mcpuTouched = true;
+ mcpu += I->getValue();
+ continue;
+ }
+ }
+
+ if (mattrTouched)
+ mattr += ",";
+
+ // Check if the argument is a special case.
+ {
+ ArgMap::const_iterator I = MArchMap.find(Arg);
-/// ConvertToMAttr - Convert -m* and -mno-* to -mattr=+*,-*
+ if (I != MArchMap.end()) {
+ mattrTouched = true;
+ mattr += '+';
+ mattr += I->getValue();
+ continue;
+ }
+ }
+
+ AddPlusOrMinus(Arg, mattr);
+ }
+
+ std::string out;
+ if (mattrTouched)
+ out += mattr;
+ if (mcpuTouched)
+ out += (mattrTouched ? " " : "") + mcpu;
+
+ return out;
+}
+
+// -mcpu values that need to be special-cased.
+const char* MCpuKeysPPC[] = { "G3", "G4", "G5", "powerpc", "powerpc64"};
+const char* MCpuValuesPPC[] = { "g3", "g4", "g5", "ppc", "ppc64"};
+const unsigned MCpuNumKeysPPC = NUM_KEYS(MCpuKeysPPC);
+const unsigned MCpuMapSize = NextHighestPowerOf2(MCpuNumKeysPPC);
+
+/// ConvertMCpu - Convert -mcpu value from the gcc to the llc dialect.
+std::string ConvertMCpu(const char* Val) {
+ static ArgMap MCpuMap(MCpuMapSize);
+ static bool StaticDataInitialized = false;
+
+ if (!StaticDataInitialized) {
+ FillInArgMap(MCpuMap, MCpuKeysPPC, MCpuValuesPPC, MCpuNumKeysPPC);
+ StaticDataInitialized = true;
+ }
+
+ std::string ret = "-mcpu=";
+ ArgMap::const_iterator I = MCpuMap.find(Val);
+ if (I != MCpuMap.end()) {
+ return ret + I->getValue();
+ }
+ return ret + Val;
+}
+
+// -mfpu values that need to be special-cased.
+const char* MFpuKeysARM[] = { "vfp", "vfpv3",
+ "vfpv3-fp16", "vfpv3-d16", "vfpv3-d16-fp16",
+ "neon", "neon-fp16" };
+const char* MFpuValuesARM[] = { "vfp2", "vfp3",
+ "+vfp3,+fp16", "+vfp3,+d16", "+vfp3,+d16,+fp16",
+ "+neon", "+neon,+neonfp" };
+const unsigned MFpuNumKeysARM = NUM_KEYS(MFpuKeysARM);
+const unsigned MFpuMapSize = NextHighestPowerOf2(MFpuNumKeysARM);
+
+/// ConvertMFpu - Convert -mfpu value from the gcc to the llc dialect.
+std::string ConvertMFpu(const char* Val) {
+ static ArgMap MFpuMap(MFpuMapSize);
+ static bool StaticDataInitialized = false;
+
+ if (!StaticDataInitialized) {
+ FillInArgMap(MFpuMap, MFpuKeysARM, MFpuValuesARM, MFpuNumKeysARM);
+ StaticDataInitialized = true;
+ }
+
+ std::string ret = "-mattr=";
+ ArgMap::const_iterator I = MFpuMap.find(Val);
+ if (I != MFpuMap.end()) {
+ return ret + I->getValue();
+ }
+ return ret + '+' + Val;
+}
+
+/// ConvertToMAttr - Convert '-mfoo' and '-mno-bar' to '-mattr=+foo,-bar'.
std::string ConvertToMAttr(const StrVec& Opts) {
std::string out("-mattr=");
-
bool firstIter = true;
+
for (StrVec::const_iterator B = Opts.begin(), E = Opts.end(); B!=E; ++B) {
const std::string& Arg = *B;
@@ -17,14 +185,7 @@ std::string ConvertToMAttr(const StrVec& Opts) {
else
out += ",";
- if (Arg.find("no-") == 0 && Arg[3] != 0) {
- out += '-';
- out += Arg.c_str() + 3;
- }
- else {
- out += '+';
- out += Arg;
- }
+ AddPlusOrMinus(Arg, out);
}
return out;
diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp
index 671348c..adb7102 100644
--- a/tools/lto/LTOCodeGenerator.cpp
+++ b/tools/lto/LTOCodeGenerator.cpp
@@ -39,9 +39,11 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/StandardPasses.h"
#include "llvm/Support/SystemUtils.h"
-#include "llvm/System/Host.h"
-#include "llvm/System/Program.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/system_error.h"
#include "llvm/Config/config.h"
#include <cstdlib>
#include <unistd.h>
@@ -183,7 +185,7 @@ const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg)
{
// make unique temp .s file to put generated assembly code
sys::Path uniqueAsmPath("lto-llvm.s");
- if ( uniqueAsmPath.createTemporaryFileOnDisk(true, &errMsg) )
+ if ( uniqueAsmPath.createTemporaryFileOnDisk(false, &errMsg) )
return NULL;
sys::RemoveFileOnSignal(uniqueAsmPath);
@@ -208,7 +210,7 @@ const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg)
// make unique temp .o file to put generated object file
sys::PathWithStatus uniqueObjPath("lto-llvm.o");
- if ( uniqueObjPath.createTemporaryFileOnDisk(true, &errMsg) ) {
+ if ( uniqueObjPath.createTemporaryFileOnDisk(false, &errMsg) ) {
uniqueAsmPath.eraseFromDisk();
return NULL;
}
@@ -220,9 +222,12 @@ const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg)
if ( !asmResult ) {
// remove old buffer if compile() called twice
delete _nativeObjectFile;
-
+
// read .o file into memory buffer
- _nativeObjectFile = MemoryBuffer::getFile(uniqueObjStr.c_str(),&errMsg);
+ OwningPtr<MemoryBuffer> BuffPtr;
+ if (error_code ec = MemoryBuffer::getFile(uniqueObjStr.c_str(),BuffPtr))
+ errMsg = ec.message();
+ _nativeObjectFile = BuffPtr.take();
}
// remove temp files
@@ -342,21 +347,34 @@ void LTOCodeGenerator::applyScopeRestrictions() {
// mark which symbols can not be internalized
if (!_mustPreserveSymbols.empty()) {
- MCContext Context(*_target->getMCAsmInfo());
+ MCContext Context(*_target->getMCAsmInfo(), NULL);
Mangler mangler(Context, *_target->getTargetData());
std::vector<const char*> mustPreserveList;
+ SmallString<64> Buffer;
for (Module::iterator f = mergedModule->begin(),
e = mergedModule->end(); f != e; ++f) {
+ Buffer.clear();
+ mangler.getNameWithPrefix(Buffer, f, false);
if (!f->isDeclaration() &&
- _mustPreserveSymbols.count(mangler.getNameWithPrefix(f)))
+ _mustPreserveSymbols.count(Buffer))
mustPreserveList.push_back(::strdup(f->getNameStr().c_str()));
}
for (Module::global_iterator v = mergedModule->global_begin(),
e = mergedModule->global_end(); v != e; ++v) {
+ Buffer.clear();
+ mangler.getNameWithPrefix(Buffer, v, false);
if (!v->isDeclaration() &&
- _mustPreserveSymbols.count(mangler.getNameWithPrefix(v)))
+ _mustPreserveSymbols.count(Buffer))
mustPreserveList.push_back(::strdup(v->getNameStr().c_str()));
}
+ for (Module::alias_iterator a = mergedModule->alias_begin(),
+ e = mergedModule->alias_end(); a != e; ++a) {
+ Buffer.clear();
+ mangler.getNameWithPrefix(Buffer, a, false);
+ if (!a->isDeclaration() &&
+ _mustPreserveSymbols.count(Buffer))
+ mustPreserveList.push_back(::strdup(a->getNameStr().c_str()));
+ }
passes.add(createInternalizePass(mustPreserveList));
}
diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp
index c7cd585..8562f74 100644
--- a/tools/lto/LTOModule.cpp
+++ b/tools/lto/LTOModule.cpp
@@ -23,9 +23,10 @@
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/System/Host.h"
-#include "llvm/System/Path.h"
-#include "llvm/System/Process.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/system_error.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/SubtargetFeature.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -56,23 +57,18 @@ bool LTOModule::isBitcodeFileForTarget(const void *mem, size_t length,
bool LTOModule::isBitcodeFileForTarget(const char *path,
const char *triplePrefix) {
- MemoryBuffer *buffer = MemoryBuffer::getFile(path);
- if (buffer == NULL)
+ OwningPtr<MemoryBuffer> buffer;
+ if (MemoryBuffer::getFile(path, buffer))
return false;
- return isTargetMatch(buffer, triplePrefix);
+ return isTargetMatch(buffer.take(), triplePrefix);
}
// Takes ownership of buffer.
bool LTOModule::isTargetMatch(MemoryBuffer *buffer, const char *triplePrefix) {
- OwningPtr<Module> m(getLazyBitcodeModule(buffer, getGlobalContext()));
- // On success, m owns buffer and both are deleted at end of this method.
- if (!m) {
- delete buffer;
- return false;
- }
- std::string actualTarget = m->getTargetTriple();
- return (strncmp(actualTarget.c_str(), triplePrefix,
- strlen(triplePrefix)) == 0);
+ std::string Triple = getBitcodeTargetTriple(buffer, getGlobalContext());
+ delete buffer;
+ return (strncmp(Triple.c_str(), triplePrefix,
+ strlen(triplePrefix)) == 0);
}
@@ -83,9 +79,22 @@ LTOModule::LTOModule(Module *m, TargetMachine *t)
LTOModule *LTOModule::makeLTOModule(const char *path,
std::string &errMsg) {
- OwningPtr<MemoryBuffer> buffer(MemoryBuffer::getFile(path, &errMsg));
- if (!buffer)
+ OwningPtr<MemoryBuffer> buffer;
+ if (error_code ec = MemoryBuffer::getFile(path, buffer)) {
+ errMsg = ec.message();
return NULL;
+ }
+ return makeLTOModule(buffer.get(), errMsg);
+}
+
+LTOModule *LTOModule::makeLTOModule(int fd, const char *path,
+ off_t size,
+ std::string &errMsg) {
+ OwningPtr<MemoryBuffer> buffer;
+ if (error_code ec = MemoryBuffer::getOpenFile(fd, path, buffer, size)) {
+ errMsg = ec.message();
+ return NULL;
+ }
return makeLTOModule(buffer.get(), errMsg);
}
@@ -306,8 +315,14 @@ void LTOModule::addDefinedSymbol(GlobalValue *def, Mangler &mangler,
if (def->getName().startswith("llvm."))
return;
+ // ignore available_externally
+ if (def->hasAvailableExternallyLinkage())
+ return;
+
// string is owned by _defines
- const char *symbolName = ::strdup(mangler.getNameWithPrefix(def).c_str());
+ SmallString<64> Buffer;
+ mangler.getNameWithPrefix(Buffer, def, false);
+ const char *symbolName = ::strdup(Buffer.c_str());
// set alignment part log2() can have rounding errors
uint32_t align = def->getAlignment();
@@ -325,24 +340,26 @@ void LTOModule::addDefinedSymbol(GlobalValue *def, Mangler &mangler,
}
// set definition part
- if (def->hasWeakLinkage() || def->hasLinkOnceLinkage()) {
+ if (def->hasWeakLinkage() || def->hasLinkOnceLinkage() ||
+ def->hasLinkerPrivateWeakLinkage() ||
+ def->hasLinkerPrivateWeakDefAutoLinkage())
attr |= LTO_SYMBOL_DEFINITION_WEAK;
- }
- else if (def->hasCommonLinkage()) {
+ else if (def->hasCommonLinkage())
attr |= LTO_SYMBOL_DEFINITION_TENTATIVE;
- }
- else {
+ else
attr |= LTO_SYMBOL_DEFINITION_REGULAR;
- }
// set scope part
if (def->hasHiddenVisibility())
attr |= LTO_SYMBOL_SCOPE_HIDDEN;
else if (def->hasProtectedVisibility())
attr |= LTO_SYMBOL_SCOPE_PROTECTED;
- else if (def->hasExternalLinkage() || def->hasWeakLinkage()
- || def->hasLinkOnceLinkage() || def->hasCommonLinkage())
+ else if (def->hasExternalLinkage() || def->hasWeakLinkage() ||
+ def->hasLinkOnceLinkage() || def->hasCommonLinkage() ||
+ def->hasLinkerPrivateWeakLinkage())
attr |= LTO_SYMBOL_SCOPE_DEFAULT;
+ else if (def->hasLinkerPrivateWeakDefAutoLinkage())
+ attr |= LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN;
else
attr |= LTO_SYMBOL_SCOPE_INTERNAL;
@@ -380,7 +397,8 @@ void LTOModule::addPotentialUndefinedSymbol(GlobalValue *decl,
if (isa<GlobalAlias>(decl))
return;
- std::string name = mangler.getNameWithPrefix(decl);
+ SmallString<64> name;
+ mangler.getNameWithPrefix(name, decl, false);
// we already have the symbol
if (_undefines.find(name) != _undefines.end())
@@ -426,7 +444,7 @@ void LTOModule::lazyParseSymbols() {
_symbolsParsed = true;
// Use mangler to add GlobalPrefix to names to match linker names.
- MCContext Context(*_target->getMCAsmInfo());
+ MCContext Context(*_target->getMCAsmInfo(), NULL);
Mangler mangler(Context, *_target->getTargetData());
// add functions
@@ -472,6 +490,15 @@ void LTOModule::lazyParseSymbols() {
pos = inlineAsm.find(glbl, pend);
}
+ // add aliases
+ for (Module::alias_iterator i = _module->alias_begin(),
+ e = _module->alias_end(); i != e; ++i) {
+ if (i->isDeclaration())
+ addPotentialUndefinedSymbol(i, mangler);
+ else
+ addDefinedDataSymbol(i, mangler);
+ }
+
// make symbols for all undefines
for (StringMap<NameAndAttributes>::iterator it=_undefines.begin();
it != _undefines.end(); ++it) {
diff --git a/tools/lto/LTOModule.h b/tools/lto/LTOModule.h
index a19acc0..1794d81 100644
--- a/tools/lto/LTOModule.h
+++ b/tools/lto/LTOModule.h
@@ -51,6 +51,9 @@ struct LTOModule {
static LTOModule* makeLTOModule(const char* path,
std::string& errMsg);
+ static LTOModule* makeLTOModule(int fd, const char *path,
+ off_t size,
+ std::string& errMsg);
static LTOModule* makeLTOModule(const void* mem, size_t length,
std::string& errMsg);
diff --git a/tools/lto/Makefile b/tools/lto/Makefile
index e157a4c..294c81b 100644
--- a/tools/lto/Makefile
+++ b/tools/lto/Makefile
@@ -24,6 +24,10 @@ LINK_COMPONENTS := $(TARGETS_TO_BUILD) ipo scalaropts linker bitreader bitwriter
include $(LEVEL)/Makefile.common
+ifdef LLVM_VERSION_INFO
+CXX.Flags += -DLLVM_VERSION_INFO='"$(LLVM_VERSION_INFO)"'
+endif
+
ifeq ($(HOST_OS),Darwin)
# Special hack to allow libLTO to have an offset version number.
ifdef LLVM_LTO_VERSION_OFFSET
diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp
index 3d7ef0a..7d4871d 100644
--- a/tools/lto/lto.cpp
+++ b/tools/lto/lto.cpp
@@ -91,6 +91,14 @@ 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, off_t size)
+{
+ return LTOModule::makeLTOModule(fd, path, size, sLastErrorString);
+}
//
// loads an object file from memory
@@ -132,7 +140,7 @@ void lto_module_set_target_triple(lto_module_t mod, const char *triple)
//
// returns the number of symbols in the object module
//
-uint32_t lto_module_get_num_symbols(lto_module_t mod)
+unsigned int lto_module_get_num_symbols(lto_module_t mod)
{
return mod->getSymbolCount();
}
@@ -140,7 +148,7 @@ uint32_t lto_module_get_num_symbols(lto_module_t mod)
//
// returns the name of the ith symbol in the object module
//
-const char* lto_module_get_symbol_name(lto_module_t mod, uint32_t index)
+const char* lto_module_get_symbol_name(lto_module_t mod, unsigned int index)
{
return mod->getSymbolName(index);
}
@@ -150,7 +158,7 @@ const char* lto_module_get_symbol_name(lto_module_t mod, uint32_t index)
// returns the attributes of the ith symbol in the object module
//
lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod,
- uint32_t index)
+ unsigned int index)
{
return mod->getSymbolAttributes(index);
}
diff --git a/tools/lto/lto.exports b/tools/lto/lto.exports
index 4dbf760..a374091 100644
--- a/tools/lto/lto.exports
+++ b/tools/lto/lto.exports
@@ -1,6 +1,7 @@
lto_get_error_message
lto_get_version
lto_module_create
+lto_module_create_from_fd
lto_module_create_from_memory
lto_module_get_num_symbols
lto_module_get_symbol_attribute
diff --git a/tools/macho-dump/CMakeLists.txt b/tools/macho-dump/CMakeLists.txt
new file mode 100644
index 0000000..d55e1d5
--- /dev/null
+++ b/tools/macho-dump/CMakeLists.txt
@@ -0,0 +1,5 @@
+set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support object)
+
+add_llvm_tool(macho-dump
+ macho-dump.cpp
+ )
diff --git a/tools/macho-dump/Makefile b/tools/macho-dump/Makefile
new file mode 100644
index 0000000..638015e
--- /dev/null
+++ b/tools/macho-dump/Makefile
@@ -0,0 +1,23 @@
+##===- tools/macho-dump/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 = macho-dump
+
+# 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
+
+include $(LLVM_SRC_ROOT)/Makefile.rules
diff --git a/tools/macho-dump/macho-dump.cpp b/tools/macho-dump/macho-dump.cpp
new file mode 100644
index 0000000..c4c558d
--- /dev/null
+++ b/tools/macho-dump/macho-dump.cpp
@@ -0,0 +1,391 @@
+//===-- macho-dump.cpp - Mach Object Dumping Tool -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a testing tool for use with the MC/Mach-O LLVM components.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Object/MachOObject.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/system_error.h"
+using namespace llvm;
+using namespace llvm::object;
+
+static cl::opt<std::string>
+InputFile(cl::Positional, cl::desc("<input file>"), cl::init("-"));
+
+static cl::opt<bool>
+ShowSectionData("dump-section-data", cl::desc("Dump the contents of sections"),
+ cl::init(false));
+
+///
+
+static const char *ProgramName;
+
+static void Message(const char *Type, const Twine &Msg) {
+ errs() << ProgramName << ": " << Type << ": " << Msg << "\n";
+}
+
+static int Error(const Twine &Msg) {
+ Message("error", Msg);
+ return 1;
+}
+
+static void Warning(const Twine &Msg) {
+ Message("warning", Msg);
+}
+
+///
+
+static int DumpHeader(MachOObject &Obj) {
+ // Read the header.
+ const macho::Header &Hdr = Obj.getHeader();
+ outs() << "('cputype', " << Hdr.CPUType << ")\n";
+ outs() << "('cpusubtype', " << Hdr.CPUSubtype << ")\n";
+ outs() << "('filetype', " << Hdr.FileType << ")\n";
+ outs() << "('num_load_commands', " << Hdr.NumLoadCommands << ")\n";
+ outs() << "('load_commands_size', " << Hdr.SizeOfLoadCommands << ")\n";
+ outs() << "('flag', " << Hdr.Flags << ")\n";
+
+ // Print extended header if 64-bit.
+ if (Obj.is64Bit()) {
+ const macho::Header64Ext &Hdr64 = Obj.getHeader64Ext();
+ outs() << "('reserved', " << Hdr64.Reserved << ")\n";
+ }
+
+ return 0;
+}
+
+static void DumpSegmentCommandData(StringRef Name,
+ uint64_t VMAddr, uint64_t VMSize,
+ uint64_t FileOffset, uint64_t FileSize,
+ uint32_t MaxProt, uint32_t InitProt,
+ uint32_t NumSections, uint32_t Flags) {
+ outs() << " ('segment_name', '";
+ outs().write_escaped(Name, /*UseHexEscapes=*/true) << "')\n";
+ outs() << " ('vm_addr', " << VMAddr << ")\n";
+ outs() << " ('vm_size', " << VMSize << ")\n";
+ outs() << " ('file_offset', " << FileOffset << ")\n";
+ outs() << " ('file_size', " << FileSize << ")\n";
+ outs() << " ('maxprot', " << MaxProt << ")\n";
+ outs() << " ('initprot', " << InitProt << ")\n";
+ outs() << " ('num_sections', " << NumSections << ")\n";
+ outs() << " ('flags', " << Flags << ")\n";
+}
+
+static int DumpSectionData(MachOObject &Obj, unsigned Index, StringRef Name,
+ StringRef SegmentName, uint64_t Address,
+ uint64_t Size, uint32_t Offset,
+ uint32_t Align, uint32_t RelocationTableOffset,
+ uint32_t NumRelocationTableEntries,
+ uint32_t Flags, uint32_t Reserved1,
+ uint32_t Reserved2, uint64_t Reserved3 = ~0ULL) {
+ outs() << " # Section " << Index << "\n";
+ outs() << " (('section_name', '";
+ outs().write_escaped(Name, /*UseHexEscapes=*/true) << "')\n";
+ outs() << " ('segment_name', '";
+ outs().write_escaped(SegmentName, /*UseHexEscapes=*/true) << "')\n";
+ outs() << " ('address', " << Address << ")\n";
+ outs() << " ('size', " << Size << ")\n";
+ outs() << " ('offset', " << Offset << ")\n";
+ outs() << " ('alignment', " << Align << ")\n";
+ outs() << " ('reloc_offset', " << RelocationTableOffset << ")\n";
+ outs() << " ('num_reloc', " << NumRelocationTableEntries << ")\n";
+ outs() << " ('flags', " << format("0x%x", Flags) << ")\n";
+ outs() << " ('reserved1', " << Reserved1 << ")\n";
+ outs() << " ('reserved2', " << Reserved2 << ")\n";
+ if (Reserved3 != ~0ULL)
+ outs() << " ('reserved3', " << Reserved3 << ")\n";
+ outs() << " ),\n";
+
+ // Dump the relocation entries.
+ int Res = 0;
+ outs() << " ('_relocations', [\n";
+ for (unsigned i = 0; i != NumRelocationTableEntries; ++i) {
+ InMemoryStruct<macho::RelocationEntry> RE;
+ Obj.ReadRelocationEntry(RelocationTableOffset, i, RE);
+ if (!RE) {
+ Res = Error("unable to read relocation table entry '" + Twine(i) + "'");
+ break;
+ }
+
+ outs() << " # Relocation " << i << "\n";
+ outs() << " (('word-0', " << format("0x%x", RE->Word0) << "),\n";
+ outs() << " ('word-1', " << format("0x%x", RE->Word1) << ")),\n";
+ }
+ outs() << " ])\n";
+
+ // Dump the section data, if requested.
+ if (ShowSectionData) {
+ outs() << " ('_section_data', '";
+ StringRef Data = Obj.getData(Offset, Size);
+ for (unsigned i = 0; i != Data.size(); ++i) {
+ if (i && (i % 4) == 0)
+ outs() << ' ';
+ outs() << hexdigit((Data[i] >> 4) & 0xF, /*LowerCase=*/true);
+ outs() << hexdigit((Data[i] >> 0) & 0xF, /*LowerCase=*/true);
+ }
+ outs() << "')\n";
+ }
+
+ return Res;
+}
+
+static int DumpSegmentCommand(MachOObject &Obj,
+ const MachOObject::LoadCommandInfo &LCI) {
+ InMemoryStruct<macho::SegmentLoadCommand> SLC;
+ Obj.ReadSegmentLoadCommand(LCI, SLC);
+ if (!SLC)
+ return Error("unable to read segment load command");
+
+ DumpSegmentCommandData(StringRef(SLC->Name, 16), SLC->VMAddress,
+ SLC->VMSize, SLC->FileOffset, SLC->FileSize,
+ SLC->MaxVMProtection, SLC->InitialVMProtection,
+ SLC->NumSections, SLC->Flags);
+
+ // Dump the sections.
+ int Res = 0;
+ outs() << " ('sections', [\n";
+ for (unsigned i = 0; i != SLC->NumSections; ++i) {
+ InMemoryStruct<macho::Section> Sect;
+ Obj.ReadSection(LCI, i, Sect);
+ if (!SLC) {
+ Res = Error("unable to read section '" + Twine(i) + "'");
+ break;
+ }
+
+ if ((Res = DumpSectionData(Obj, i, StringRef(Sect->Name, 16),
+ StringRef(Sect->SegmentName, 16), Sect->Address,
+ Sect->Size, Sect->Offset, Sect->Align,
+ Sect->RelocationTableOffset,
+ Sect->NumRelocationTableEntries, Sect->Flags,
+ Sect->Reserved1, Sect->Reserved2)))
+ break;
+ }
+ outs() << " ])\n";
+
+ return Res;
+}
+
+static int DumpSegment64Command(MachOObject &Obj,
+ const MachOObject::LoadCommandInfo &LCI) {
+ InMemoryStruct<macho::Segment64LoadCommand> SLC;
+ Obj.ReadSegment64LoadCommand(LCI, SLC);
+ if (!SLC)
+ return Error("unable to read segment load command");
+
+ DumpSegmentCommandData(StringRef(SLC->Name, 16), SLC->VMAddress,
+ SLC->VMSize, SLC->FileOffset, SLC->FileSize,
+ SLC->MaxVMProtection, SLC->InitialVMProtection,
+ SLC->NumSections, SLC->Flags);
+
+ // Dump the sections.
+ int Res = 0;
+ outs() << " ('sections', [\n";
+ for (unsigned i = 0; i != SLC->NumSections; ++i) {
+ InMemoryStruct<macho::Section64> Sect;
+ Obj.ReadSection64(LCI, i, Sect);
+ if (!SLC) {
+ Res = Error("unable to read section '" + Twine(i) + "'");
+ break;
+ }
+
+ if ((Res = DumpSectionData(Obj, i, StringRef(Sect->Name, 16),
+ StringRef(Sect->SegmentName, 16), Sect->Address,
+ Sect->Size, Sect->Offset, Sect->Align,
+ Sect->RelocationTableOffset,
+ Sect->NumRelocationTableEntries, Sect->Flags,
+ Sect->Reserved1, Sect->Reserved2,
+ Sect->Reserved3)))
+ break;
+ }
+ outs() << " ])\n";
+
+ return 0;
+}
+
+static void DumpSymbolTableEntryData(MachOObject &Obj,
+ unsigned Index, uint32_t StringIndex,
+ uint8_t Type, uint8_t SectionIndex,
+ uint16_t Flags, uint64_t Value) {
+ outs() << " # Symbol " << Index << "\n";
+ outs() << " (('n_strx', " << StringIndex << ")\n";
+ outs() << " ('n_type', " << format("0x%x", Type) << ")\n";
+ outs() << " ('n_sect', " << uint32_t(SectionIndex) << ")\n";
+ outs() << " ('n_desc', " << Flags << ")\n";
+ outs() << " ('n_value', " << Value << ")\n";
+ outs() << " ('_string', '" << Obj.getStringAtIndex(StringIndex) << "')\n";
+ outs() << " ),\n";
+}
+
+static int DumpSymtabCommand(MachOObject &Obj,
+ const MachOObject::LoadCommandInfo &LCI) {
+ InMemoryStruct<macho::SymtabLoadCommand> SLC;
+ Obj.ReadSymtabLoadCommand(LCI, SLC);
+ if (!SLC)
+ return Error("unable to read segment load command");
+
+ outs() << " ('symoff', " << SLC->SymbolTableOffset << ")\n";
+ outs() << " ('nsyms', " << SLC->NumSymbolTableEntries << ")\n";
+ outs() << " ('stroff', " << SLC->StringTableOffset << ")\n";
+ outs() << " ('strsize', " << SLC->StringTableSize << ")\n";
+
+ // Cache the string table data.
+ Obj.RegisterStringTable(*SLC);
+
+ // Dump the string data.
+ outs() << " ('_string_data', '";
+ outs().write_escaped(Obj.getStringTableData(),
+ /*UseHexEscapes=*/true) << "')\n";
+
+ // Dump the symbol table.
+ int Res = 0;
+ outs() << " ('_symbols', [\n";
+ for (unsigned i = 0; i != SLC->NumSymbolTableEntries; ++i) {
+ if (Obj.is64Bit()) {
+ InMemoryStruct<macho::Symbol64TableEntry> STE;
+ Obj.ReadSymbol64TableEntry(SLC->SymbolTableOffset, i, STE);
+ if (!STE) {
+ Res = Error("unable to read symbol: '" + Twine(i) + "'");
+ break;
+ }
+
+ DumpSymbolTableEntryData(Obj, i, STE->StringIndex, STE->Type,
+ STE->SectionIndex, STE->Flags, STE->Value);
+ } else {
+ InMemoryStruct<macho::SymbolTableEntry> STE;
+ Obj.ReadSymbolTableEntry(SLC->SymbolTableOffset, i, STE);
+ if (!SLC) {
+ Res = Error("unable to read symbol: '" + Twine(i) + "'");
+ break;
+ }
+
+ DumpSymbolTableEntryData(Obj, i, STE->StringIndex, STE->Type,
+ STE->SectionIndex, STE->Flags, STE->Value);
+ }
+ }
+ outs() << " ])\n";
+
+ return Res;
+}
+
+static int DumpDysymtabCommand(MachOObject &Obj,
+ const MachOObject::LoadCommandInfo &LCI) {
+ InMemoryStruct<macho::DysymtabLoadCommand> DLC;
+ Obj.ReadDysymtabLoadCommand(LCI, DLC);
+ if (!DLC)
+ return Error("unable to read segment load command");
+
+ outs() << " ('ilocalsym', " << DLC->LocalSymbolsIndex << ")\n";
+ outs() << " ('nlocalsym', " << DLC->NumLocalSymbols << ")\n";
+ outs() << " ('iextdefsym', " << DLC->ExternalSymbolsIndex << ")\n";
+ outs() << " ('nextdefsym', " << DLC->NumExternalSymbols << ")\n";
+ outs() << " ('iundefsym', " << DLC->UndefinedSymbolsIndex << ")\n";
+ outs() << " ('nundefsym', " << DLC->NumUndefinedSymbols << ")\n";
+ outs() << " ('tocoff', " << DLC->TOCOffset << ")\n";
+ outs() << " ('ntoc', " << DLC->NumTOCEntries << ")\n";
+ outs() << " ('modtaboff', " << DLC->ModuleTableOffset << ")\n";
+ outs() << " ('nmodtab', " << DLC->NumModuleTableEntries << ")\n";
+ outs() << " ('extrefsymoff', " << DLC->ReferenceSymbolTableOffset << ")\n";
+ outs() << " ('nextrefsyms', "
+ << DLC->NumReferencedSymbolTableEntries << ")\n";
+ outs() << " ('indirectsymoff', " << DLC->IndirectSymbolTableOffset << ")\n";
+ outs() << " ('nindirectsyms', "
+ << DLC->NumIndirectSymbolTableEntries << ")\n";
+ outs() << " ('extreloff', " << DLC->ExternalRelocationTableOffset << ")\n";
+ outs() << " ('nextrel', " << DLC->NumExternalRelocationTableEntries << ")\n";
+ outs() << " ('locreloff', " << DLC->LocalRelocationTableOffset << ")\n";
+ outs() << " ('nlocrel', " << DLC->NumLocalRelocationTableEntries << ")\n";
+
+ // Dump the indirect symbol table.
+ int Res = 0;
+ outs() << " ('_indirect_symbols', [\n";
+ for (unsigned i = 0; i != DLC->NumIndirectSymbolTableEntries; ++i) {
+ InMemoryStruct<macho::IndirectSymbolTableEntry> ISTE;
+ Obj.ReadIndirectSymbolTableEntry(*DLC, i, ISTE);
+ if (!ISTE) {
+ Res = Error("unable to read segment load command");
+ break;
+ }
+
+ outs() << " # Indirect Symbol " << i << "\n";
+ outs() << " (('symbol_index', "
+ << format("0x%x", ISTE->Index) << "),),\n";
+ }
+ outs() << " ])\n";
+
+ return Res;
+}
+
+static int DumpLoadCommand(MachOObject &Obj, unsigned Index) {
+ const MachOObject::LoadCommandInfo &LCI = Obj.getLoadCommandInfo(Index);
+ int Res = 0;
+
+ outs() << " # Load Command " << Index << "\n"
+ << " (('command', " << LCI.Command.Type << ")\n"
+ << " ('size', " << LCI.Command.Size << ")\n";
+ switch (LCI.Command.Type) {
+ case macho::LCT_Segment:
+ Res = DumpSegmentCommand(Obj, LCI);
+ break;
+ case macho::LCT_Segment64:
+ Res = DumpSegment64Command(Obj, LCI);
+ break;
+ case macho::LCT_Symtab:
+ Res = DumpSymtabCommand(Obj, LCI);
+ break;
+ case macho::LCT_Dysymtab:
+ Res = DumpDysymtabCommand(Obj, LCI);
+ break;
+ default:
+ Warning("unknown load command: " + Twine(LCI.Command.Type));
+ break;
+ }
+ outs() << " ),\n";
+
+ return Res;
+}
+
+int main(int argc, char **argv) {
+ ProgramName = argv[0];
+ llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
+
+ cl::ParseCommandLineOptions(argc, argv, "llvm Mach-O dumping tool\n");
+
+ // Load the input file.
+ std::string ErrorStr;
+ OwningPtr<MemoryBuffer> InputBuffer;
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFile, InputBuffer))
+ return Error("unable to read input: '" + ec.message() + "'");
+
+ // Construct the Mach-O wrapper object.
+ OwningPtr<MachOObject> InputObject(
+ MachOObject::LoadFromBuffer(InputBuffer.take(), &ErrorStr));
+ if (!InputObject)
+ return Error("unable to load object: '" + ErrorStr + "'");
+
+ if (int Res = DumpHeader(*InputObject))
+ return Res;
+
+ // Print the load commands.
+ int Res = 0;
+ outs() << "('load_commands', [\n";
+ for (unsigned i = 0; i != InputObject->getHeader().NumLoadCommands; ++i)
+ if ((Res = DumpLoadCommand(*InputObject, i)))
+ break;
+ outs() << "])\n";
+
+ return Res;
+}
diff --git a/tools/opt/GraphPrinters.cpp b/tools/opt/GraphPrinters.cpp
index 9de7d6a..791caf5 100644
--- a/tools/opt/GraphPrinters.cpp
+++ b/tools/opt/GraphPrinters.cpp
@@ -18,8 +18,8 @@
#include "llvm/Pass.h"
#include "llvm/Value.h"
#include "llvm/Analysis/CallGraph.h"
-#include "llvm/Analysis/Dominators.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Analysis/DominanceFrontier.h"
+#include "llvm/Support/ToolOutputFile.h"
using namespace llvm;
template<typename GraphType>
@@ -61,8 +61,7 @@ namespace llvm {
static std::string getNodeLabel(CallGraphNode *Node, CallGraph *Graph) {
if (Node->getFunction())
return ((Value*)Node->getFunction())->getName();
- else
- return "external node";
+ return "external node";
}
};
}
@@ -109,10 +108,8 @@ namespace {
}
virtual bool runOnFunction(Function &F) {
- DominatorTree &DT = getAnalysis<DominatorTree>();
- DT.dump();
- DominanceFrontier &DF = getAnalysis<DominanceFrontier>();
- DF.dump();
+ getAnalysis<DominatorTree>().dump();
+ getAnalysis<DominanceFrontier>().dump();
return false;
}
};
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp
index d837185..e55b4b3 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -18,13 +18,17 @@
#include "llvm/CallGraphSCCPass.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Assembly/PrintModulePass.h"
+#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/LoopPass.h"
+#include "llvm/Analysis/RegionPass.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/Support/PassNameParser.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/IRReader.h"
#include "llvm/Support/ManagedStatic.h"
@@ -32,7 +36,7 @@
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/StandardPasses.h"
#include "llvm/Support/SystemUtils.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/ToolOutputFile.h"
#include "llvm/LinkAllPasses.h"
#include "llvm/LinkAllVMCore.h"
#include <memory>
@@ -127,6 +131,10 @@ QuietA("quiet", cl::desc("Alias for -q"), cl::aliasopt(Quiet));
static cl::opt<bool>
AnalyzeOnly("analyze", cl::desc("Only perform analysis, no optimization"));
+static cl::opt<bool>
+PrintBreakpoints("print-breakpoints-for-testing",
+ cl::desc("Print select breakpoints location for testing"));
+
static cl::opt<std::string>
DefaultDataLayout("default-data-layout",
cl::desc("data layout string to use if not specified by module"),
@@ -139,25 +147,29 @@ struct CallGraphSCCPassPrinter : public CallGraphSCCPass {
static char ID;
const PassInfo *PassToPrint;
raw_ostream &Out;
+ std::string PassName;
+
CallGraphSCCPassPrinter(const PassInfo *PI, raw_ostream &out) :
- CallGraphSCCPass(ID), PassToPrint(PI), Out(out) {}
+ CallGraphSCCPass(ID), PassToPrint(PI), Out(out) {
+ std::string PassToPrintName = PassToPrint->getPassName();
+ PassName = "CallGraphSCCPass Printer: " + PassToPrintName;
+ }
virtual bool runOnSCC(CallGraphSCC &SCC) {
- if (!Quiet) {
+ if (!Quiet)
Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
- for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
- Function *F = (*I)->getFunction();
- if (F)
- getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out,
- F->getParent());
- }
- }
// Get and print pass...
+ for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
+ Function *F = (*I)->getFunction();
+ if (F)
+ getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out,
+ F->getParent());
+ }
return false;
}
- virtual const char *getPassName() const { return "'Pass' Printer"; }
+ virtual const char *getPassName() const { return PassName.c_str(); }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequiredID(PassToPrint->getTypeInfo());
@@ -171,20 +183,24 @@ struct ModulePassPrinter : public ModulePass {
static char ID;
const PassInfo *PassToPrint;
raw_ostream &Out;
+ std::string PassName;
+
ModulePassPrinter(const PassInfo *PI, raw_ostream &out)
- : ModulePass(ID), PassToPrint(PI), Out(out) {}
+ : ModulePass(ID), PassToPrint(PI), Out(out) {
+ std::string PassToPrintName = PassToPrint->getPassName();
+ PassName = "ModulePass Printer: " + PassToPrintName;
+ }
virtual bool runOnModule(Module &M) {
- if (!Quiet) {
+ if (!Quiet)
Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
- getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out, &M);
- }
// Get and print pass...
+ getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out, &M);
return false;
}
- virtual const char *getPassName() const { return "'Pass' Printer"; }
+ virtual const char *getPassName() const { return PassName.c_str(); }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequiredID(PassToPrint->getTypeInfo());
@@ -197,21 +213,26 @@ struct FunctionPassPrinter : public FunctionPass {
const PassInfo *PassToPrint;
raw_ostream &Out;
static char ID;
+ std::string PassName;
+
FunctionPassPrinter(const PassInfo *PI, raw_ostream &out)
- : FunctionPass(ID), PassToPrint(PI), Out(out) {}
+ : FunctionPass(ID), PassToPrint(PI), Out(out) {
+ std::string PassToPrintName = PassToPrint->getPassName();
+ PassName = "FunctionPass Printer: " + PassToPrintName;
+ }
virtual bool runOnFunction(Function &F) {
- if (!Quiet) {
+ if (!Quiet)
Out << "Printing analysis '" << PassToPrint->getPassName()
<< "' for function '" << F.getName() << "':\n";
- }
+
// Get and print pass...
getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out,
F.getParent());
return false;
}
- virtual const char *getPassName() const { return "FunctionPass Printer"; }
+ virtual const char *getPassName() const { return PassName.c_str(); }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequiredID(PassToPrint->getTypeInfo());
@@ -225,20 +246,26 @@ struct LoopPassPrinter : public LoopPass {
static char ID;
const PassInfo *PassToPrint;
raw_ostream &Out;
+ std::string PassName;
+
LoopPassPrinter(const PassInfo *PI, raw_ostream &out) :
- LoopPass(ID), PassToPrint(PI), Out(out) {}
+ LoopPass(ID), PassToPrint(PI), Out(out) {
+ std::string PassToPrintName = PassToPrint->getPassName();
+ PassName = "LoopPass Printer: " + PassToPrintName;
+ }
+
virtual bool runOnLoop(Loop *L, LPPassManager &LPM) {
- if (!Quiet) {
+ if (!Quiet)
Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
- getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out,
- L->getHeader()->getParent()->getParent());
- }
+
// Get and print pass...
+ getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out,
+ L->getHeader()->getParent()->getParent());
return false;
}
- virtual const char *getPassName() const { return "'Pass' Printer"; }
+ virtual const char *getPassName() const { return PassName.c_str(); }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequiredID(PassToPrint->getTypeInfo());
@@ -248,18 +275,56 @@ struct LoopPassPrinter : public LoopPass {
char LoopPassPrinter::ID = 0;
+struct RegionPassPrinter : public RegionPass {
+ static char ID;
+ const PassInfo *PassToPrint;
+ raw_ostream &Out;
+ std::string PassName;
+
+ RegionPassPrinter(const PassInfo *PI, raw_ostream &out) : RegionPass(ID),
+ PassToPrint(PI), Out(out) {
+ std::string PassToPrintName = PassToPrint->getPassName();
+ PassName = "RegionPass Printer: " + PassToPrintName;
+ }
+
+ 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";
+ }
+ // Get and print pass...
+ getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out,
+ R->getEntry()->getParent()->getParent());
+ return false;
+ }
+
+ virtual const char *getPassName() const { return PassName.c_str(); }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequiredID(PassToPrint->getTypeInfo());
+ AU.setPreservesAll();
+ }
+};
+
+char RegionPassPrinter::ID = 0;
+
struct BasicBlockPassPrinter : public BasicBlockPass {
const PassInfo *PassToPrint;
raw_ostream &Out;
static char ID;
+ std::string PassName;
+
BasicBlockPassPrinter(const PassInfo *PI, raw_ostream &out)
- : BasicBlockPass(ID), PassToPrint(PI), Out(out) {}
+ : BasicBlockPass(ID), PassToPrint(PI), Out(out) {
+ std::string PassToPrintName = PassToPrint->getPassName();
+ PassName = "BasicBlockPass Printer: " + PassToPrintName;
+ }
virtual bool runOnBasicBlock(BasicBlock &BB) {
- if (!Quiet) {
+ if (!Quiet)
Out << "Printing Analysis info for BasicBlock '" << BB.getName()
<< "': Pass " << PassToPrint->getPassName() << ":\n";
- }
// Get and print pass...
getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out,
@@ -267,7 +332,7 @@ struct BasicBlockPassPrinter : public BasicBlockPass {
return false;
}
- virtual const char *getPassName() const { return "BasicBlockPass Printer"; }
+ virtual const char *getPassName() const { return PassName.c_str(); }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequiredID(PassToPrint->getTypeInfo());
@@ -276,6 +341,39 @@ struct BasicBlockPassPrinter : public BasicBlockPass {
};
char BasicBlockPassPrinter::ID = 0;
+
+struct BreakpointPrinter : public FunctionPass {
+ raw_ostream &Out;
+ static char ID;
+
+ BreakpointPrinter(raw_ostream &out)
+ : FunctionPass(ID), Out(out) {
+ }
+
+ virtual bool runOnFunction(Function &F) {
+ BasicBlock &EntryBB = F.getEntryBlock();
+ BasicBlock::const_iterator BI = EntryBB.end();
+ --BI;
+ do {
+ const Instruction *In = BI;
+ const DebugLoc DL = In->getDebugLoc();
+ if (!DL.isUnknown()) {
+ DIScope S(DL.getScope(getGlobalContext()));
+ Out << S.getFilename() << " " << DL.getLine() << "\n";
+ break;
+ }
+ --BI;
+ } while (BI != EntryBB.begin());
+ return false;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+};
+
+char BreakpointPrinter::ID = 0;
+
inline void addPass(PassManagerBase &PM, Pass *P) {
// Add the pass to the pass manager...
PM.add(P);
@@ -297,9 +395,9 @@ void AddOptimizationPasses(PassManagerBase &MPM, PassManagerBase &FPM,
if (DisableInline) {
// No inlining pass
} else if (OptLevel) {
- unsigned Threshold = 200;
+ unsigned Threshold = 225;
if (OptLevel > 2)
- Threshold = 250;
+ Threshold = 275;
InliningPass = createFunctionInliningPass(Threshold);
} else {
InliningPass = createAlwaysInlinerPass();
@@ -331,7 +429,7 @@ void AddStandardCompilePasses(PassManagerBase &PM) {
/*OptimizeSize=*/ false,
/*UnitAtATime=*/ true,
/*UnrollLoops=*/ true,
- /*SimplifyLibCalls=*/ true,
+ !DisableSimplifyLibCalls,
/*HaveExceptions=*/ true,
InliningPass);
}
@@ -360,20 +458,32 @@ int main(int argc, char **argv) {
sys::PrintStackTraceOnErrorSignal();
llvm::PrettyStackTraceProgram X(argc, argv);
- if (AnalyzeOnly && NoOutput) {
- errs() << argv[0] << ": analyze mode conflicts with no-output mode.\n";
- return 1;
- }
-
// Enable debug stream buffering.
EnableDebugBuffering = true;
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
LLVMContext &Context = getGlobalContext();
+ // Initialize passes
+ PassRegistry &Registry = *PassRegistry::getPassRegistry();
+ initializeCore(Registry);
+ initializeScalarOpts(Registry);
+ initializeIPO(Registry);
+ initializeAnalysis(Registry);
+ initializeIPA(Registry);
+ initializeTransformUtils(Registry);
+ initializeInstCombine(Registry);
+ initializeInstrumentation(Registry);
+ initializeTarget(Registry);
+
cl::ParseCommandLineOptions(argc, argv,
"llvm .bc -> .bc modular optimizer and analysis printer\n");
+ if (AnalyzeOnly && NoOutput) {
+ errs() << argv[0] << ": analyze mode conflicts with no-output mode.\n";
+ return 1;
+ }
+
// Allocate a full target machine description only if necessary.
// FIXME: The choice of target should be controllable on the command line.
std::auto_ptr<TargetMachine> target;
@@ -417,11 +527,19 @@ int main(int argc, char **argv) {
NoOutput = true;
// Create a PassManager to hold and optimize the collection of passes we are
- // about to build...
+ // about to build.
//
PassManager Passes;
- // Add an appropriate TargetData instance for this module...
+ // Add an appropriate TargetLibraryInfo pass for the module's triple.
+ TargetLibraryInfo *TLI = new TargetLibraryInfo(Triple(M->getTargetTriple()));
+
+ // The -disable-simplify-libcalls flag actually disables all builtin optzns.
+ if (DisableSimplifyLibCalls)
+ TLI->disableAllFunctions();
+ Passes.add(TLI);
+
+ // Add an appropriate TargetData instance for this module.
TargetData *TD = 0;
const std::string &ModuleDataLayout = M.get()->getDataLayout();
if (!ModuleDataLayout.empty())
@@ -439,6 +557,24 @@ int main(int argc, char **argv) {
FPasses->add(new TargetData(*TD));
}
+ if (PrintBreakpoints) {
+ // Default to standard output.
+ if (!Out) {
+ 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;
+ }
+ }
+ Passes.add(new BreakpointPrinter(Out->os()));
+ NoOutput = true;
+ }
+
// If the -strip-debug command line option was specified, add it. If
// -std-compile-opts was also specified, it will handle StripDebug.
if (StripDebug && !StandardCompileOpts)
@@ -491,6 +627,9 @@ int main(int argc, char **argv) {
case PT_BasicBlock:
Passes.add(new BasicBlockPassPrinter(PassInf, Out->os()));
break;
+ case PT_Region:
+ Passes.add(new RegionPassPrinter(PassInf, Out->os()));
+ break;
case PT_Loop:
Passes.add(new LoopPassPrinter(PassInf, Out->os()));
break;
@@ -550,7 +689,7 @@ int main(int argc, char **argv) {
Passes.run(*M.get());
// Declare success.
- if (!NoOutput)
+ if (!NoOutput || PrintBreakpoints)
Out->keep();
return 0;
OpenPOWER on IntegriCloud