aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorShih-wei Liao <sliao@google.com>2012-04-24 11:26:46 -0700
committerShih-wei Liao <sliao@google.com>2012-04-24 11:26:46 -0700
commitcf5a1461acaace0f3e7d11fbbcfbf635b8c8ea9d (patch)
tree557137810ae9efc96147d672d372e4dabd0a2440 /tools
parent4c8fab82874a29dcd2b242533af3ebe7f66bfd74 (diff)
parentfc728fbdc2631ce8f343cf9b7292d218fde7419f (diff)
downloadexternal_llvm-cf5a1461acaace0f3e7d11fbbcfbf635b8c8ea9d.zip
external_llvm-cf5a1461acaace0f3e7d11fbbcfbf635b8c8ea9d.tar.gz
external_llvm-cf5a1461acaace0f3e7d11fbbcfbf635b8c8ea9d.tar.bz2
Merge with LLVM upstream r155090.
Conflicts: lib/Support/Unix/PathV2.inc Change-Id: I7b89833849f6cbcfa958a33a971d0f7754c9cb2c
Diffstat (limited to 'tools')
-rw-r--r--tools/bugpoint/ExecutionDriver.cpp47
-rw-r--r--tools/bugpoint/ToolRunner.cpp88
-rw-r--r--tools/llc/llc.cpp32
-rw-r--r--tools/lli/lli.cpp28
-rw-r--r--tools/llvm-mc/Disassembler.cpp59
-rw-r--r--tools/llvm-mc/Disassembler.h15
-rw-r--r--tools/llvm-mc/llvm-mc.cpp175
-rw-r--r--tools/llvm-objdump/MachODump.cpp5
-rw-r--r--tools/llvm-objdump/llvm-objdump.cpp10
-rw-r--r--tools/llvm-shlib/Makefile6
-rw-r--r--tools/llvm-stress/llvm-stress.cpp63
-rw-r--r--tools/lto/LTOCodeGenerator.cpp338
-rw-r--r--tools/lto/LTOCodeGenerator.h103
-rw-r--r--tools/lto/LTOModule.cpp279
-rw-r--r--tools/lto/LTOModule.h243
-rw-r--r--tools/lto/lto.cpp344
-rw-r--r--tools/opt/opt.cpp7
17 files changed, 831 insertions, 1011 deletions
diff --git a/tools/bugpoint/ExecutionDriver.cpp b/tools/bugpoint/ExecutionDriver.cpp
index adf5587..218a559 100644
--- a/tools/bugpoint/ExecutionDriver.cpp
+++ b/tools/bugpoint/ExecutionDriver.cpp
@@ -28,8 +28,7 @@ namespace {
// for miscompilation.
//
enum OutputType {
- AutoPick, RunLLI, RunJIT, RunLLC, RunLLCIA, RunCBE, CBE_bug, LLC_Safe,
- CompileCustom, Custom
+ AutoPick, RunLLI, RunJIT, RunLLC, RunLLCIA, LLC_Safe, CompileCustom, Custom
};
cl::opt<double>
@@ -48,8 +47,6 @@ namespace {
clEnumValN(RunLLC, "run-llc", "Compile with LLC"),
clEnumValN(RunLLCIA, "run-llc-ia",
"Compile with LLC with integrated assembler"),
- clEnumValN(RunCBE, "run-cbe", "Compile with CBE"),
- clEnumValN(CBE_bug,"cbe-bug", "Find CBE bugs"),
clEnumValN(LLC_Safe, "llc-safe", "Use LLC for all"),
clEnumValN(CompileCustom, "compile-custom",
"Use -compile-command to define a command to "
@@ -64,7 +61,6 @@ namespace {
SafeInterpreterSel(cl::desc("Specify \"safe\" i.e. known-good backend:"),
cl::values(clEnumValN(AutoPick, "safe-auto", "Use best guess"),
clEnumValN(RunLLC, "safe-run-llc", "Compile with LLC"),
- clEnumValN(RunCBE, "safe-run-cbe", "Compile with CBE"),
clEnumValN(Custom, "safe-run-custom",
"Use -exec-command to define a command to execute "
"the bitcode. Useful for cross-compilation."),
@@ -154,10 +150,6 @@ bool BugDriver::initializeExecutionEnvironment() {
switch (InterpreterSel) {
case AutoPick:
- InterpreterSel = RunCBE;
- Interpreter =
- AbstractInterpreter::createCBE(getToolName(), Message, GCCBinary,
- &ToolArgv, &GCCToolArgv);
if (!Interpreter) {
InterpreterSel = RunJIT;
Interpreter = AbstractInterpreter::createJIT(getToolName(), Message,
@@ -195,12 +187,6 @@ bool BugDriver::initializeExecutionEnvironment() {
Interpreter = AbstractInterpreter::createJIT(getToolName(), Message,
&ToolArgv);
break;
- case RunCBE:
- case CBE_bug:
- Interpreter = AbstractInterpreter::createCBE(getToolName(), Message,
- GCCBinary, &ToolArgv,
- &GCCToolArgv);
- break;
case CompileCustom:
Interpreter =
AbstractInterpreter::createCustomCompiler(Message, CustomCompileCommand);
@@ -221,17 +207,6 @@ bool BugDriver::initializeExecutionEnvironment() {
std::vector<std::string> SafeToolArgs = SafeToolArgv;
switch (SafeInterpreterSel) {
case AutoPick:
- // In "cbe-bug" mode, default to using LLC as the "safe" backend.
- if (!SafeInterpreter &&
- InterpreterSel == CBE_bug) {
- SafeInterpreterSel = RunLLC;
- SafeToolArgs.push_back("--relocation-model=pic");
- SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
- GCCBinary,
- &SafeToolArgs,
- &GCCToolArgv);
- }
-
// In "llc-safe" mode, default to using LLC as the "safe" backend.
if (!SafeInterpreter &&
InterpreterSel == LLC_Safe) {
@@ -243,17 +218,6 @@ bool BugDriver::initializeExecutionEnvironment() {
&GCCToolArgv);
}
- // Pick a backend that's different from the test backend. The JIT and
- // LLC backends share a lot of code, so prefer to use the CBE as the
- // safe back-end when testing them.
- if (!SafeInterpreter &&
- InterpreterSel != RunCBE) {
- SafeInterpreterSel = RunCBE;
- SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message,
- GCCBinary,
- &SafeToolArgs,
- &GCCToolArgv);
- }
if (!SafeInterpreter &&
InterpreterSel != RunLLC &&
InterpreterSel != RunJIT) {
@@ -277,11 +241,6 @@ bool BugDriver::initializeExecutionEnvironment() {
&GCCToolArgv,
SafeInterpreterSel == RunLLCIA);
break;
- case RunCBE:
- SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message,
- GCCBinary, &SafeToolArgs,
- &GCCToolArgv);
- break;
case Custom:
SafeInterpreter =
AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand);
@@ -459,8 +418,8 @@ bool BugDriver::createReferenceFile(Module *M, const std::string &Filename) {
errs() << Error;
if (Interpreter != SafeInterpreter) {
errs() << "*** There is a bug running the \"safe\" backend. Either"
- << " debug it (for example with the -run-cbe bugpoint option,"
- << " if CBE is being used as the \"safe\" backend), or fix the"
+ << " debug it (for example with the -run-jit bugpoint option,"
+ << " if JIT is being used as the \"safe\" backend), or fix the"
<< " error some other way.\n";
}
return false;
diff --git a/tools/bugpoint/ToolRunner.cpp b/tools/bugpoint/ToolRunner.cpp
index b80a5b4..25a2bae 100644
--- a/tools/bugpoint/ToolRunner.cpp
+++ b/tools/bugpoint/ToolRunner.cpp
@@ -623,94 +623,6 @@ AbstractInterpreter *AbstractInterpreter::createJIT(const char *Argv0,
return 0;
}
-GCC::FileType CBE::OutputCode(const std::string &Bitcode,
- sys::Path &OutputCFile, std::string &Error,
- unsigned Timeout, unsigned MemoryLimit) {
- sys::Path uniqueFile(Bitcode+".cbe.c");
- std::string ErrMsg;
- if (uniqueFile.makeUnique(true, &ErrMsg)) {
- errs() << "Error making unique filename: " << ErrMsg << "\n";
- exit(1);
- }
- OutputCFile = uniqueFile;
- std::vector<const char *> LLCArgs;
- LLCArgs.push_back(LLCPath.c_str());
-
- // Add any extra LLC args.
- for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
- LLCArgs.push_back(ToolArgs[i].c_str());
-
- LLCArgs.push_back("-o");
- LLCArgs.push_back(OutputCFile.c_str()); // Output to the C file
- LLCArgs.push_back("-march=c"); // Output C language
- LLCArgs.push_back(Bitcode.c_str()); // This is the input bitcode
- LLCArgs.push_back(0);
-
- outs() << "<cbe>"; outs().flush();
- DEBUG(errs() << "\nAbout to run:\t";
- for (unsigned i = 0, e = LLCArgs.size()-1; i != e; ++i)
- errs() << " " << LLCArgs[i];
- errs() << "\n";
- );
- if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], sys::Path(), sys::Path(),
- sys::Path(), Timeout, MemoryLimit))
- Error = ProcessFailure(LLCPath, &LLCArgs[0], Timeout, MemoryLimit);
- return GCC::CFile;
-}
-
-void CBE::compileProgram(const std::string &Bitcode, std::string *Error,
- unsigned Timeout, unsigned MemoryLimit) {
- sys::Path OutputCFile;
- OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit);
- OutputCFile.eraseFromDisk();
-}
-
-int CBE::ExecuteProgram(const std::string &Bitcode,
- const std::vector<std::string> &Args,
- const std::string &InputFile,
- const std::string &OutputFile,
- std::string *Error,
- const std::vector<std::string> &ArgsForGCC,
- const std::vector<std::string> &SharedLibs,
- unsigned Timeout,
- unsigned MemoryLimit) {
- sys::Path OutputCFile;
- OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit);
-
- FileRemover CFileRemove(OutputCFile.str(), !SaveTemps);
-
- std::vector<std::string> GCCArgs(ArgsForGCC);
- GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end());
-
- return gcc->ExecuteProgram(OutputCFile.str(), Args, GCC::CFile,
- InputFile, OutputFile, Error, GCCArgs,
- Timeout, MemoryLimit);
-}
-
-/// createCBE - Try to find the 'llc' executable
-///
-CBE *AbstractInterpreter::createCBE(const char *Argv0,
- std::string &Message,
- const std::string &GCCBinary,
- const std::vector<std::string> *Args,
- const std::vector<std::string> *GCCArgs) {
- sys::Path LLCPath =
- PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createCBE);
- if (LLCPath.isEmpty()) {
- Message =
- "Cannot find `llc' in executable directory!\n";
- return 0;
- }
-
- Message = "Found llc: " + LLCPath.str() + "\n";
- GCC *gcc = GCC::create(Message, GCCBinary, GCCArgs);
- if (!gcc) {
- errs() << Message << "\n";
- exit(1);
- }
- return new CBE(LLCPath, gcc, Args);
-}
-
//===---------------------------------------------------------------------===//
// GCC abstraction
//
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp
index 191b649..ceff8a6 100644
--- a/tools/llc/llc.cpp
+++ b/tools/llc/llc.cpp
@@ -210,29 +210,6 @@ DontPlaceZerosInBSS("nozero-initialized-in-bss",
cl::init(false));
static cl::opt<bool>
-EnableJITExceptionHandling("jit-enable-eh",
- cl::desc("Emit exception handling information"),
- cl::init(false));
-
-// In debug builds, make this default to true.
-#ifdef NDEBUG
-#define EMIT_DEBUG false
-#else
-#define EMIT_DEBUG true
-#endif
-static cl::opt<bool>
-EmitJitDebugInfo("jit-emit-debug",
- cl::desc("Emit debug information to debugger"),
- cl::init(EMIT_DEBUG));
-#undef EMIT_DEBUG
-
-static cl::opt<bool>
-EmitJitDebugInfoToDisk("jit-emit-debug-to-disk",
- cl::Hidden,
- cl::desc("Emit debug info objfiles to disk"),
- cl::init(false));
-
-static cl::opt<bool>
EnableGuaranteedTailCallOpt("tailcallopt",
cl::desc("Turn fastcc calls into tail calls by (potentially) changing ABI."),
cl::init(false));
@@ -263,6 +240,11 @@ TrapFuncName("trap-func", cl::Hidden,
cl::init(""));
static cl::opt<bool>
+EnablePIE("enable-pie",
+ cl::desc("Assume the creation of a position independent executable."),
+ cl::init(false));
+
+static cl::opt<bool>
SegmentedStacks("segmented-stacks",
cl::desc("Use segmented stacks if possible."),
cl::init(false));
@@ -458,15 +440,13 @@ int main(int argc, char **argv) {
if (FloatABIForCalls != FloatABI::Default)
Options.FloatABIType = FloatABIForCalls;
Options.NoZerosInBSS = DontPlaceZerosInBSS;
- Options.JITExceptionHandling = EnableJITExceptionHandling;
- Options.JITEmitDebugInfo = EmitJitDebugInfo;
- Options.JITEmitDebugInfoToDisk = EmitJitDebugInfoToDisk;
Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt;
Options.DisableTailCalls = DisableTailCalls;
Options.StackAlignmentOverride = OverrideStackAlignment;
Options.RealignStack = EnableRealignStack;
Options.DisableJumpTables = DisableSwitchTables;
Options.TrapFuncName = TrapFuncName;
+ Options.PositionIndependentExecutable = EnablePIE;
Options.EnableSegmentedStacks = SegmentedStacks;
std::auto_ptr<TargetMachine>
diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp
index efcc1f5..2e2bf7d 100644
--- a/tools/lli/lli.cpp
+++ b/tools/lli/lli.cpp
@@ -141,6 +141,28 @@ namespace {
"Large code model"),
clEnumValEnd));
+ cl::opt<bool>
+ EnableJITExceptionHandling("jit-enable-eh",
+ cl::desc("Emit exception handling information"),
+ cl::init(false));
+
+ cl::opt<bool>
+// In debug builds, make this default to true.
+#ifdef NDEBUG
+#define EMIT_DEBUG false
+#else
+#define EMIT_DEBUG true
+#endif
+ EmitJitDebugInfo("jit-emit-debug",
+ cl::desc("Emit debug information to debugger"),
+ cl::init(EMIT_DEBUG));
+#undef EMIT_DEBUG
+
+ static cl::opt<bool>
+ EmitJitDebugInfoToDisk("jit-emit-debug-to-disk",
+ cl::Hidden,
+ cl::desc("Emit debug info objfiles to disk"),
+ cl::init(false));
}
static ExecutionEngine *EE = 0;
@@ -229,6 +251,12 @@ int main(int argc, char **argv, char * const *envp) {
}
builder.setOptLevel(OLvl);
+ TargetOptions Options;
+ Options.JITExceptionHandling = EnableJITExceptionHandling;
+ Options.JITEmitDebugInfo = EmitJitDebugInfo;
+ Options.JITEmitDebugInfoToDisk = EmitJitDebugInfoToDisk;
+ builder.setTargetOptions(Options);
+
EE = builder.create();
if (!EE) {
if (!ErrorMsg.empty())
diff --git a/tools/llvm-mc/Disassembler.cpp b/tools/llvm-mc/Disassembler.cpp
index 6793d7e..5f2fdb8 100644
--- a/tools/llvm-mc/Disassembler.cpp
+++ b/tools/llvm-mc/Disassembler.cpp
@@ -17,20 +17,18 @@
#include "../../lib/MC/MCDisassembler/EDInst.h"
#include "../../lib/MC/MCDisassembler/EDOperand.h"
#include "../../lib/MC/MCDisassembler/EDToken.h"
-#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCInstPrinter.h"
-#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.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/SourceMgr.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
+
using namespace llvm;
typedef std::vector<std::pair<unsigned char, const char*> > ByteArrayTy;
@@ -55,8 +53,9 @@ public:
}
static bool PrintInsts(const MCDisassembler &DisAsm,
- MCInstPrinter &Printer, const ByteArrayTy &Bytes,
- SourceMgr &SM, raw_ostream &Out) {
+ const ByteArrayTy &Bytes,
+ SourceMgr &SM, raw_ostream &Out,
+ MCStreamer &Streamer) {
// Wrap the vector in a MemoryObject.
VectorMemoryObject memoryObject(Bytes);
@@ -86,8 +85,7 @@ static bool PrintInsts(const MCDisassembler &DisAsm,
// Fall through
case MCDisassembler::Success:
- Printer.printInst(&Inst, Out, "");
- Out << "\n";
+ Streamer.EmitInstruction(Inst);
break;
}
}
@@ -144,49 +142,22 @@ static bool ByteArrayFromString(ByteArrayTy &ByteArray,
int Disassembler::disassemble(const Target &T,
const std::string &Triple,
- const std::string &Cpu,
- const std::string &FeaturesStr,
+ MCSubtargetInfo &STI,
+ MCStreamer &Streamer,
MemoryBuffer &Buffer,
+ SourceMgr &SM,
raw_ostream &Out) {
- // Set up disassembler.
- OwningPtr<const MCAsmInfo> AsmInfo(T.createMCAsmInfo(Triple));
-
- if (!AsmInfo) {
- errs() << "error: no assembly info for target " << Triple << "\n";
- return -1;
- }
-
- OwningPtr<const MCSubtargetInfo> STI(T.createMCSubtargetInfo(Triple, Cpu, FeaturesStr));
- if (!STI) {
- errs() << "error: no subtarget info for target " << Triple << "\n";
- return -1;
- }
-
- OwningPtr<const MCDisassembler> DisAsm(T.createMCDisassembler(*STI));
+ OwningPtr<const MCDisassembler> DisAsm(T.createMCDisassembler(STI));
if (!DisAsm) {
errs() << "error: no disassembler for target " << Triple << "\n";
return -1;
}
- OwningPtr<const MCRegisterInfo> MRI(T.createMCRegInfo(Triple));
- if (!MRI) {
- errs() << "error: no register info for target " << Triple << "\n";
- return -1;
- }
-
- int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
- OwningPtr<MCInstPrinter> IP(T.createMCInstPrinter(AsmPrinterVariant,
- *AsmInfo, *MRI, *STI));
- if (!IP) {
- errs() << "error: no instruction printer for target " << Triple << '\n';
- return -1;
- }
+ // Set up initial section manually here
+ Streamer.InitSections();
bool ErrorOccurred = false;
- SourceMgr SM;
- SM.AddNewSourceBuffer(&Buffer, SMLoc());
-
// Convert the input to a vector for disassembly.
ByteArrayTy ByteArray;
StringRef Str = Buffer.getBuffer();
@@ -194,7 +165,7 @@ int Disassembler::disassemble(const Target &T,
ErrorOccurred |= ByteArrayFromString(ByteArray, Str, SM);
if (!ByteArray.empty())
- ErrorOccurred |= PrintInsts(*DisAsm, *IP, ByteArray, SM, Out);
+ ErrorOccurred |= PrintInsts(*DisAsm, ByteArray, SM, Out, Streamer);
return ErrorOccurred;
}
@@ -228,12 +199,10 @@ static int verboseEvaluator(uint64_t *V, unsigned R, void *Arg) {
int Disassembler::disassembleEnhanced(const std::string &TS,
MemoryBuffer &Buffer,
+ SourceMgr &SM,
raw_ostream &Out) {
ByteArrayTy ByteArray;
StringRef Str = Buffer.getBuffer();
- SourceMgr SM;
-
- SM.AddNewSourceBuffer(&Buffer, SMLoc());
if (ByteArrayFromString(ByteArray, Str, SM)) {
return -1;
diff --git a/tools/llvm-mc/Disassembler.h b/tools/llvm-mc/Disassembler.h
index e8cd92d..17d622f 100644
--- a/tools/llvm-mc/Disassembler.h
+++ b/tools/llvm-mc/Disassembler.h
@@ -22,18 +22,23 @@ namespace llvm {
class MemoryBuffer;
class Target;
class raw_ostream;
+class SourceMgr;
+class MCSubtargetInfo;
+class MCStreamer;
class Disassembler {
public:
- static int disassemble(const Target &target,
- const std::string &tripleString,
- const std::string &Cpu,
- const std::string &FeaturesStr,
- MemoryBuffer &buffer,
+ static int disassemble(const Target &T,
+ const std::string &Triple,
+ MCSubtargetInfo &STI,
+ MCStreamer &Streamer,
+ MemoryBuffer &Buffer,
+ SourceMgr &SM,
raw_ostream &Out);
static int disassembleEnhanced(const std::string &tripleString,
MemoryBuffer &buffer,
+ SourceMgr &SM,
raw_ostream &Out);
};
diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp
index ceed2d6..36a482e 100644
--- a/tools/llvm-mc/llvm-mc.cpp
+++ b/tools/llvm-mc/llvm-mc.cpp
@@ -15,6 +15,7 @@
#include "llvm/MC/MCParser/AsmLexer.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCInstPrinter.h"
@@ -242,37 +243,11 @@ static void setDwarfDebugFlags(int argc, char **argv) {
}
}
-static int AsLexInput(const char *ProgName) {
- OwningPtr<MemoryBuffer> BufferPtr;
- if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) {
- errs() << ProgName << ": " << ec.message() << '\n';
- return 1;
- }
- MemoryBuffer *Buffer = BufferPtr.take();
-
- SourceMgr SrcMgr;
-
- // Tell SrcMgr about this buffer, which is what TGParser will pick up.
- SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
-
- // Record the location of the include directories so that the lexer can find
- // it later.
- SrcMgr.setIncludeDirs(IncludeDirs);
-
- const Target *TheTarget = GetTarget(ProgName);
- if (!TheTarget)
- return 1;
-
- llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(TripleName));
- assert(MAI && "Unable to create target asm info!");
+static int AsLexInput(SourceMgr &SrcMgr, MCAsmInfo &MAI, tool_output_file *Out) {
- AsmLexer Lexer(*MAI);
+ AsmLexer Lexer(MAI);
Lexer.setBuffer(SrcMgr.getMemoryBuffer(0));
- OwningPtr<tool_output_file> Out(GetOutputStream());
- if (!Out)
- return 1;
-
bool Error = false;
while (Lexer.Lex().isNot(AsmToken::Eof)) {
AsmToken Tok = Lexer.getTok();
@@ -346,13 +321,49 @@ static int AsLexInput(const char *ProgName) {
Out->os() << "\")\n";
}
- // Keep output if no errors.
- if (Error == 0) Out->keep();
-
return Error;
}
-static int AssembleInput(const char *ProgName) {
+static int AssembleInput(const char *ProgName, const Target *TheTarget,
+ SourceMgr &SrcMgr, MCContext &Ctx, MCStreamer &Str,
+ MCAsmInfo &MAI, MCSubtargetInfo &STI) {
+ OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx,
+ Str, MAI));
+ OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(STI, *Parser));
+ if (!TAP) {
+ errs() << ProgName
+ << ": error: this target does not support assembly parsing.\n";
+ return 1;
+ }
+
+ Parser->setShowParsedOperands(ShowInstOperands);
+ Parser->setTargetParser(*TAP.get());
+
+ int Res = Parser->Run(NoInitialTextSection);
+
+ return Res;
+}
+
+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();
+ llvm::InitializeAllTargetMCs();
+ llvm::InitializeAllAsmParsers();
+ llvm::InitializeAllDisassemblers();
+
+ // Register the target printer for --version.
+ cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
+
+ cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n");
+ TripleName = Triple::normalize(TripleName);
+ setDwarfDebugFlags(argc, argv);
+
+ const char *ProgName = argv[0];
const Target *TheTarget = GetTarget(ProgName);
if (!TheTarget)
return 1;
@@ -413,10 +424,9 @@ static int AssembleInput(const char *ProgName) {
OwningPtr<MCSubtargetInfo>
STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
- // FIXME: There is a bit of code duplication with addPassesToEmitFile.
if (FileType == OFT_AssemblyFile) {
MCInstPrinter *IP =
- TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MRI, *STI);
+ TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MCII, *MRI, *STI);
MCCodeEmitter *CE = 0;
MCAsmBackend *MAB = 0;
if (ShowEncoding) {
@@ -440,93 +450,24 @@ static int AssembleInput(const char *ProgName) {
NoExecStack));
}
- OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx,
- *Str.get(), *MAI));
- OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(*STI, *Parser));
- if (!TAP) {
- errs() << ProgName
- << ": error: this target does not support assembly parsing.\n";
- return 1;
- }
-
- Parser->setShowParsedOperands(ShowInstOperands);
- Parser->setTargetParser(*TAP.get());
-
- int Res = Parser->Run(NoInitialTextSection);
-
- // Keep output if no errors.
- if (Res == 0) Out->keep();
-
- return Res;
-}
-
-static int DisassembleInput(const char *ProgName, bool Enhanced) {
- const Target *TheTarget = GetTarget(ProgName);
- if (!TheTarget)
- return 0;
-
- OwningPtr<MemoryBuffer> Buffer;
- if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, Buffer)) {
- errs() << ProgName << ": " << ec.message() << '\n';
- return 1;
- }
-
- OwningPtr<tool_output_file> Out(GetOutputStream());
- if (!Out)
- return 1;
-
- int Res;
- if (Enhanced) {
- Res =
- Disassembler::disassembleEnhanced(TripleName, *Buffer.take(), Out->os());
- } else {
- // Package up features to be passed to target/subtarget
- std::string FeaturesStr;
- if (MAttrs.size()) {
- SubtargetFeatures Features;
- for (unsigned i = 0; i != MAttrs.size(); ++i)
- Features.AddFeature(MAttrs[i]);
- FeaturesStr = Features.getString();
- }
-
- Res = Disassembler::disassemble(*TheTarget, TripleName, MCPU, FeaturesStr,
- *Buffer.take(), Out->os());
- }
-
- // Keep output if no errors.
- if (Res == 0) Out->keep();
-
- return Res;
-}
-
-
-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();
- llvm::InitializeAllTargetMCs();
- llvm::InitializeAllAsmParsers();
- llvm::InitializeAllDisassemblers();
-
- // Register the target printer for --version.
- cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
-
- cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n");
- TripleName = Triple::normalize(TripleName);
- setDwarfDebugFlags(argc, argv);
-
+ int Res = 1;
switch (Action) {
case AC_AsLex:
- return AsLexInput(argv[0]);
+ Res = AsLexInput(SrcMgr, *MAI, Out.get());
+ break;
case AC_Assemble:
- return AssembleInput(argv[0]);
+ Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI);
+ break;
case AC_Disassemble:
- return DisassembleInput(argv[0], false);
+ Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str,
+ *Buffer, SrcMgr, Out->os());
+ break;
case AC_EDisassemble:
- return DisassembleInput(argv[0], true);
+ Res = Disassembler::disassembleEnhanced(TripleName, *Buffer, SrcMgr, Out->os());
+ break;
}
+
+ // Keep output if no errors.
+ if (Res == 0) Out->keep();
+ return Res;
}
diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp
index b9ea041..0e7f3fd 100644
--- a/tools/llvm-objdump/MachODump.cpp
+++ b/tools/llvm-objdump/MachODump.cpp
@@ -260,8 +260,9 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI));
OwningPtr<const MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
- OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
- AsmPrinterVariant, *AsmInfo, *MRI, *STI));
+ OwningPtr<MCInstPrinter>
+ IP(TheTarget->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *InstrInfo,
+ *MRI, *STI));
if (!InstrAnalysis || !AsmInfo || !STI || !DisAsm || !IP) {
errs() << "error: couldn't initialize disassembler for target "
diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp
index 94becae..5a6f94a 100644
--- a/tools/llvm-objdump/llvm-objdump.cpp
+++ b/tools/llvm-objdump/llvm-objdump.cpp
@@ -26,6 +26,7 @@
#include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/Casting.h"
@@ -46,6 +47,7 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
#include <algorithm>
+#include <cctype>
#include <cstring>
using namespace llvm;
using namespace object;
@@ -253,9 +255,15 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
return;
}
+ OwningPtr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
+ if (!MII) {
+ errs() << "error: no instruction info for target " << TripleName << "\n";
+ return;
+ }
+
int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
- AsmPrinterVariant, *AsmInfo, *MRI, *STI));
+ AsmPrinterVariant, *AsmInfo, *MII, *MRI, *STI));
if (!IP) {
errs() << "error: no instruction printer for target " << TripleName
<< '\n';
diff --git a/tools/llvm-shlib/Makefile b/tools/llvm-shlib/Makefile
index 1d35670..2d2e2c5 100644
--- a/tools/llvm-shlib/Makefile
+++ b/tools/llvm-shlib/Makefile
@@ -63,13 +63,15 @@ ifeq ($(HOST_OS),Darwin)
endif
endif
-ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux FreeBSD OpenBSD))
+ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux FreeBSD OpenBSD GNU))
# Include everything from the .a's into the shared library.
LLVMLibsOptions := -Wl,--whole-archive $(LLVMLibsOptions) \
-Wl,--no-whole-archive
+ # Add soname to the library.
+ LLVMLibsOptions += -Wl,--soname,lib$(LIBRARYNAME)$(SHLIBEXT)
endif
-ifeq ($(HOST_OS),Linux)
+ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux GNU))
# Don't allow unresolved symbols.
LLVMLibsOptions += -Wl,--no-undefined
endif
diff --git a/tools/llvm-stress/llvm-stress.cpp b/tools/llvm-stress/llvm-stress.cpp
index c095059..fb05a58 100644
--- a/tools/llvm-stress/llvm-stress.cpp
+++ b/tools/llvm-stress/llvm-stress.cpp
@@ -60,14 +60,28 @@ class Random {
public:
/// C'tor
Random(unsigned _seed):Seed(_seed) {}
- /// Return the next random value.
- unsigned Rand() {
- unsigned Val = Seed + 0x000b07a1;
+
+ /// Return a random integer, up to a
+ /// maximum of 2**19 - 1.
+ uint32_t Rand() {
+ uint32_t Val = Seed + 0x000b07a1;
Seed = (Val * 0x3c7c0ac1);
// Only lowest 19 bits are random-ish.
return Seed & 0x7ffff;
}
+ /// Return a random 32 bit integer.
+ uint32_t Rand32() {
+ uint32_t Val = Rand();
+ Val &= 0xffff;
+ return Val | (Rand() << 16);
+ }
+
+ /// Return a random 64 bit integer.
+ uint64_t Rand64() {
+ uint64_t Val = Rand32();
+ return Val | (uint64_t(Rand32()) << 32);
+ }
private:
unsigned Seed;
};
@@ -202,11 +216,17 @@ protected:
/// Pick a random vector type.
Type *pickVectorType(unsigned len = (unsigned)-1) {
- Type *Ty = pickScalarType();
// Pick a random vector width in the range 2**0 to 2**4.
// by adding two randoms we are generating a normal-like distribution
// around 2**3.
unsigned width = 1<<((Ran->Rand() % 3) + (Ran->Rand() % 3));
+ Type *Ty;
+
+ // Vectors of x86mmx are illegal; keep trying till we get something else.
+ do {
+ Ty = pickScalarType();
+ } while (Ty->isX86_MMXTy());
+
if (len != (unsigned)-1)
width = len;
return VectorType::get(Ty, width);
@@ -342,10 +362,20 @@ struct ConstModifier: public Modifier {
}
if (Ty->isFloatingPointTy()) {
+ // Generate 128 random bits, the size of the (currently)
+ // largest floating-point types.
+ uint64_t RandomBits[2];
+ for (unsigned i = 0; i < 2; ++i)
+ RandomBits[i] = Ran->Rand64();
+
+ APInt RandomInt(Ty->getPrimitiveSizeInBits(), makeArrayRef(RandomBits));
+
+ bool isIEEE = !Ty->isX86_FP80Ty() && !Ty->isPPC_FP128Ty();
+ APFloat RandomFloat(RandomInt, isIEEE);
+
if (Ran->Rand() & 1)
return PT->push_back(ConstantFP::getNullValue(Ty));
- return PT->push_back(ConstantFP::get(Ty,
- static_cast<double>(1)/Ran->Rand()));
+ return PT->push_back(ConstantFP::get(Ty->getContext(), RandomFloat));
}
if (Ty->isIntegerTy()) {
@@ -382,7 +412,7 @@ struct ExtractElementModifier: public Modifier {
Value *Val0 = getRandomVectorValue();
Value *V = ExtractElementInst::Create(Val0,
ConstantInt::get(Type::getInt32Ty(BB->getContext()),
- Ran->Rand() % cast<VectorType>(Val0->getType())->getNumElements()),
+ Ran->Rand() % cast<VectorType>(Val0->getType())->getNumElements()),
"E", BB->getTerminator());
return PT->push_back(V);
}
@@ -446,7 +476,7 @@ struct CastModifier: public Modifier {
DestTy = pickVectorType(VecTy->getNumElements());
}
- // no need to casr.
+ // no need to cast.
if (VTy == DestTy) return;
// Pointers:
@@ -457,9 +487,11 @@ struct CastModifier: public Modifier {
new BitCastInst(V, DestTy, "PC", BB->getTerminator()));
}
+ unsigned VSize = VTy->getScalarType()->getPrimitiveSizeInBits();
+ unsigned DestSize = DestTy->getScalarType()->getPrimitiveSizeInBits();
+
// Generate lots of bitcasts.
- if ((Ran->Rand() & 1) &&
- VTy->getPrimitiveSizeInBits() == DestTy->getPrimitiveSizeInBits()) {
+ if ((Ran->Rand() & 1) && VSize == DestSize) {
return PT->push_back(
new BitCastInst(V, DestTy, "BC", BB->getTerminator()));
}
@@ -467,11 +499,11 @@ struct CastModifier: public Modifier {
// Both types are integers:
if (VTy->getScalarType()->isIntegerTy() &&
DestTy->getScalarType()->isIntegerTy()) {
- if (VTy->getScalarType()->getPrimitiveSizeInBits() >
- DestTy->getScalarType()->getPrimitiveSizeInBits()) {
+ if (VSize > DestSize) {
return PT->push_back(
new TruncInst(V, DestTy, "Tr", BB->getTerminator()));
} else {
+ assert(VSize < DestSize && "Different int types with the same size?");
if (Ran->Rand() & 1)
return PT->push_back(
new ZExtInst(V, DestTy, "ZE", BB->getTerminator()));
@@ -501,14 +533,15 @@ struct CastModifier: public Modifier {
// Both floats.
if (VTy->getScalarType()->isFloatingPointTy() &&
DestTy->getScalarType()->isFloatingPointTy()) {
- if (VTy->getScalarType()->getPrimitiveSizeInBits() >
- DestTy->getScalarType()->getPrimitiveSizeInBits()) {
+ if (VSize > DestSize) {
return PT->push_back(
new FPTruncInst(V, DestTy, "Tr", BB->getTerminator()));
- } else {
+ } else if (VSize < DestSize) {
return PT->push_back(
new FPExtInst(V, DestTy, "ZE", BB->getTerminator()));
}
+ // If VSize == DestSize, then the two types must be fp128 and ppc_fp128,
+ // for which there is no defined conversion. So do nothing.
}
}
diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp
index 111f8c8..6382a3f 100644
--- a/tools/lto/LTOCodeGenerator.cpp
+++ b/tools/lto/LTOCodeGenerator.cpp
@@ -4,27 +4,26 @@
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
-// This file implements the Link Time Optimization library. This library is
+// This file implements the Link Time Optimization library. This library is
// intended to be used by linker to optimize code at link time.
//
//===----------------------------------------------------------------------===//
-#include "LTOModule.h"
#include "LTOCodeGenerator.h"
+#include "LTOModule.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Linker.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Config/config.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/SubtargetFeature.h"
@@ -33,64 +32,55 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/Host.h"
-#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/system_error.h"
-#include "llvm/Config/config.h"
-#include "llvm/Transforms/IPO.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
-#include <cstdlib>
-#include <unistd.h>
-#include <fcntl.h>
-
-
+#include "llvm/ADT/StringExtras.h"
using namespace llvm;
-static cl::opt<bool> DisableInline("disable-inlining",
+static cl::opt<bool> DisableInline("disable-inlining", cl::init(false),
cl::desc("Do not run the inliner pass"));
+static cl::opt<bool> DisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false),
+ cl::desc("Do not run the GVN load PRE pass"));
-const char* LTOCodeGenerator::getVersionString()
-{
+const char* LTOCodeGenerator::getVersionString() {
#ifdef LLVM_VERSION_INFO
- return PACKAGE_NAME " version " PACKAGE_VERSION ", " LLVM_VERSION_INFO;
+ return PACKAGE_NAME " version " PACKAGE_VERSION ", " LLVM_VERSION_INFO;
#else
- return PACKAGE_NAME " version " PACKAGE_VERSION;
+ return PACKAGE_NAME " version " PACKAGE_VERSION;
#endif
}
-
-LTOCodeGenerator::LTOCodeGenerator()
- : _context(getGlobalContext()),
- _linker("LinkTimeOptimizer", "ld-temp.o", _context), _target(NULL),
- _emitDwarfDebugInfo(false), _scopeRestrictionsDone(false),
- _codeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC),
- _nativeObjectFile(NULL)
-{
- InitializeAllTargets();
- InitializeAllTargetMCs();
- InitializeAllAsmPrinters();
-}
-
-LTOCodeGenerator::~LTOCodeGenerator()
-{
- delete _target;
- delete _nativeObjectFile;
+LTOCodeGenerator::LTOCodeGenerator()
+ : _context(getGlobalContext()),
+ _linker("LinkTimeOptimizer", "ld-temp.o", _context), _target(NULL),
+ _emitDwarfDebugInfo(false), _scopeRestrictionsDone(false),
+ _codeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC),
+ _nativeObjectFile(NULL) {
+ InitializeAllTargets();
+ InitializeAllTargetMCs();
+ InitializeAllAsmPrinters();
}
+LTOCodeGenerator::~LTOCodeGenerator() {
+ delete _target;
+ delete _nativeObjectFile;
+ for (std::vector<char*>::iterator I = _codegenOptions.begin(),
+ E = _codegenOptions.end(); I != E; ++I)
+ free(*I);
+}
-bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg)
-{
+bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg) {
bool ret = _linker.LinkInModule(mod->getLLVVMModule(), &errMsg);
const std::vector<const char*> &undefs = mod->getAsmUndefinedRefs();
@@ -99,53 +89,39 @@ bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg)
return ret;
}
-
-
-bool LTOCodeGenerator::setDebugInfo(lto_debug_model debug, std::string& errMsg)
-{
- switch (debug) {
- case LTO_DEBUG_MODEL_NONE:
- _emitDwarfDebugInfo = false;
- return false;
-
- case LTO_DEBUG_MODEL_DWARF:
- _emitDwarfDebugInfo = true;
- return false;
- }
- llvm_unreachable("Unknown debug format!");
-}
-
-bool LTOCodeGenerator::setCodePICModel(lto_codegen_model model,
- std::string& errMsg)
-{
- switch (model) {
- case LTO_CODEGEN_PIC_MODEL_STATIC:
- case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
- case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
- _codeModel = model;
- return false;
- }
- llvm_unreachable("Unknown PIC model!");
-}
+bool LTOCodeGenerator::setDebugInfo(lto_debug_model debug,
+ std::string& errMsg) {
+ switch (debug) {
+ case LTO_DEBUG_MODEL_NONE:
+ _emitDwarfDebugInfo = false;
+ return false;
-void LTOCodeGenerator::setCpu(const char* mCpu)
-{
- _mCpu = mCpu;
+ case LTO_DEBUG_MODEL_DWARF:
+ _emitDwarfDebugInfo = true;
+ return false;
+ }
+ llvm_unreachable("Unknown debug format!");
}
-void LTOCodeGenerator::addMustPreserveSymbol(const char* sym)
-{
- _mustPreserveSymbols[sym] = 1;
+bool LTOCodeGenerator::setCodePICModel(lto_codegen_model model,
+ std::string& errMsg) {
+ switch (model) {
+ case LTO_CODEGEN_PIC_MODEL_STATIC:
+ case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
+ case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
+ _codeModel = model;
+ return false;
+ }
+ llvm_unreachable("Unknown PIC model!");
}
-
bool LTOCodeGenerator::writeMergedModules(const char *path,
std::string &errMsg) {
if (determineTarget(errMsg))
return true;
- // mark which symbols can not be internalized
+ // mark which symbols can not be internalized
applyScopeRestrictions();
// create output file
@@ -157,7 +133,7 @@ bool LTOCodeGenerator::writeMergedModules(const char *path,
errMsg += path;
return true;
}
-
+
// write bitcode to it
WriteBitcodeToFile(_linker.getModule(), Out.os());
Out.os().close();
@@ -168,14 +144,12 @@ bool LTOCodeGenerator::writeMergedModules(const char *path,
Out.os().clear_error();
return true;
}
-
+
Out.keep();
return false;
}
-
-bool LTOCodeGenerator::compile_to_file(const char** name, std::string& errMsg)
-{
+bool LTOCodeGenerator::compile_to_file(const char** name, std::string& errMsg) {
// make unique temp .o file to put generated object file
sys::PathWithStatus uniqueObjPath("lto-llvm.o");
if ( uniqueObjPath.createTemporaryFileOnDisk(false, &errMsg) ) {
@@ -189,12 +163,14 @@ bool LTOCodeGenerator::compile_to_file(const char** name, std::string& errMsg)
tool_output_file objFile(uniqueObjPath.c_str(), errMsg);
if (!errMsg.empty())
return true;
+
genResult = this->generateObjectFile(objFile.os(), errMsg);
objFile.os().close();
if (objFile.os().has_error()) {
objFile.os().clear_error();
return true;
}
+
objFile.keep();
if ( genResult ) {
uniqueObjPath.eraseFromDisk();
@@ -206,8 +182,7 @@ bool LTOCodeGenerator::compile_to_file(const char** name, std::string& errMsg)
return false;
}
-const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg)
-{
+const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg) {
const char *name;
if (compile_to_file(&name, errMsg))
return NULL;
@@ -233,48 +208,48 @@ const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg)
return _nativeObjectFile->getBufferStart();
}
-bool LTOCodeGenerator::determineTarget(std::string& errMsg)
-{
- if ( _target == NULL ) {
- std::string Triple = _linker.getModule()->getTargetTriple();
- if (Triple.empty())
- Triple = sys::getDefaultTargetTriple();
-
- // create target machine from info for merged modules
- const Target *march = TargetRegistry::lookupTarget(Triple, errMsg);
- if ( march == NULL )
- return true;
-
- // The relocation model is actually a static member of TargetMachine
- // and needs to be set before the TargetMachine is instantiated.
- Reloc::Model RelocModel = Reloc::Default;
- switch( _codeModel ) {
- case LTO_CODEGEN_PIC_MODEL_STATIC:
- RelocModel = Reloc::Static;
- break;
- case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
- RelocModel = Reloc::PIC_;
- break;
- case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
- RelocModel = Reloc::DynamicNoPIC;
- break;
- }
-
- // construct LTOModule, hand over ownership of module and target
- SubtargetFeatures Features;
- Features.getDefaultSubtargetFeatures(llvm::Triple(Triple));
- std::string FeatureStr = Features.getString();
- TargetOptions Options;
- _target = march->createTargetMachine(Triple, _mCpu, FeatureStr, Options,
- RelocModel);
+bool LTOCodeGenerator::determineTarget(std::string& errMsg) {
+ if ( _target == NULL ) {
+ std::string Triple = _linker.getModule()->getTargetTriple();
+ if (Triple.empty())
+ Triple = sys::getDefaultTargetTriple();
+
+ // create target machine from info for merged modules
+ const Target *march = TargetRegistry::lookupTarget(Triple, errMsg);
+ if ( march == NULL )
+ return true;
+
+ // The relocation model is actually a static member of TargetMachine and
+ // needs to be set before the TargetMachine is instantiated.
+ Reloc::Model RelocModel = Reloc::Default;
+ switch( _codeModel ) {
+ case LTO_CODEGEN_PIC_MODEL_STATIC:
+ RelocModel = Reloc::Static;
+ break;
+ case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
+ RelocModel = Reloc::PIC_;
+ break;
+ case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
+ RelocModel = Reloc::DynamicNoPIC;
+ break;
}
- return false;
+
+ // construct LTOModule, hand over ownership of module and target
+ SubtargetFeatures Features;
+ Features.getDefaultSubtargetFeatures(llvm::Triple(Triple));
+ std::string FeatureStr = Features.getString();
+ TargetOptions Options;
+ _target = march->createTargetMachine(Triple, _mCpu, FeatureStr, Options,
+ RelocModel);
+ }
+ return false;
}
-void LTOCodeGenerator::applyRestriction(GlobalValue &GV,
- std::vector<const char*> &mustPreserveList,
- SmallPtrSet<GlobalValue*, 8> &asmUsed,
- Mangler &mangler) {
+void LTOCodeGenerator::
+applyRestriction(GlobalValue &GV,
+ std::vector<const char*> &mustPreserveList,
+ SmallPtrSet<GlobalValue*, 8> &asmUsed,
+ Mangler &mangler) {
SmallString<64> Buffer;
mangler.getNameWithPrefix(Buffer, &GV, false);
@@ -294,8 +269,8 @@ static void findUsedValues(GlobalVariable *LLVMUsed,
if (Inits == 0) return;
for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
- if (GlobalValue *GV =
- dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
+ if (GlobalValue *GV =
+ dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
UsedValues.insert(GV);
}
@@ -307,8 +282,8 @@ void LTOCodeGenerator::applyScopeRestrictions() {
PassManager passes;
passes.add(createVerifierPass());
- // mark which symbols can not be internalized
- MCContext Context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(), NULL);
+ // mark which symbols can not be internalized
+ MCContext Context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(),NULL);
Mangler mangler(Context, *_target->getTargetData());
std::vector<const char*> mustPreserveList;
SmallPtrSet<GlobalValue*, 8> asmUsed;
@@ -316,7 +291,7 @@ void LTOCodeGenerator::applyScopeRestrictions() {
for (Module::iterator f = mergedModule->begin(),
e = mergedModule->end(); f != e; ++f)
applyRestriction(*f, mustPreserveList, asmUsed, mangler);
- for (Module::global_iterator v = mergedModule->global_begin(),
+ for (Module::global_iterator v = mergedModule->global_begin(),
e = mergedModule->global_end(); v != e; ++v)
applyRestriction(*v, mustPreserveList, asmUsed, mangler);
for (Module::alias_iterator a = mergedModule->alias_begin(),
@@ -351,81 +326,84 @@ void LTOCodeGenerator::applyScopeRestrictions() {
// apply scope restrictions
passes.run(*mergedModule);
-
+
_scopeRestrictionsDone = true;
}
/// Optimize merged modules using various IPO passes
bool LTOCodeGenerator::generateObjectFile(raw_ostream &out,
std::string &errMsg) {
- if ( this->determineTarget(errMsg) )
- return true;
+ if ( this->determineTarget(errMsg) )
+ return true;
- // mark which symbols can not be internalized
- this->applyScopeRestrictions();
+ Module* mergedModule = _linker.getModule();
- Module* mergedModule = _linker.getModule();
+ // if options were requested, set them
+ if ( !_codegenOptions.empty() )
+ cl::ParseCommandLineOptions(_codegenOptions.size(),
+ const_cast<char **>(&_codegenOptions[0]));
- // if options were requested, set them
- if ( !_codegenOptions.empty() )
- cl::ParseCommandLineOptions(_codegenOptions.size(),
- const_cast<char **>(&_codegenOptions[0]));
+ // mark which symbols can not be internalized
+ this->applyScopeRestrictions();
- // Instantiate the pass manager to organize the passes.
- PassManager passes;
+ // Instantiate the pass manager to organize the passes.
+ PassManager passes;
- // Start off with a verification pass.
- passes.add(createVerifierPass());
+ // Start off with a verification pass.
+ passes.add(createVerifierPass());
- // Add an appropriate TargetData instance for this module...
- passes.add(new TargetData(*_target->getTargetData()));
-
- PassManagerBuilder().populateLTOPassManager(passes, /*Internalize=*/ false,
- !DisableInline);
+ // Add an appropriate TargetData instance for this module...
+ passes.add(new TargetData(*_target->getTargetData()));
- // Make sure everything is still good.
- passes.add(createVerifierPass());
+ // Enabling internalize here would use its AllButMain variant. It
+ // keeps only main if it exists and does nothing for libraries. Instead
+ // we create the pass ourselves with the symbol list provided by the linker.
+ PassManagerBuilder().populateLTOPassManager(passes, /*Internalize=*/false,
+ !DisableInline,
+ DisableGVNLoadPRE);
- FunctionPassManager *codeGenPasses = new FunctionPassManager(mergedModule);
+ // Make sure everything is still good.
+ passes.add(createVerifierPass());
- codeGenPasses->add(new TargetData(*_target->getTargetData()));
+ FunctionPassManager *codeGenPasses = new FunctionPassManager(mergedModule);
- formatted_raw_ostream Out(out);
+ codeGenPasses->add(new TargetData(*_target->getTargetData()));
- if (_target->addPassesToEmitFile(*codeGenPasses, Out,
- TargetMachine::CGFT_ObjectFile,
- CodeGenOpt::Aggressive)) {
- errMsg = "target file type not supported";
- return true;
- }
+ formatted_raw_ostream Out(out);
+
+ if (_target->addPassesToEmitFile(*codeGenPasses, Out,
+ TargetMachine::CGFT_ObjectFile,
+ CodeGenOpt::Aggressive)) {
+ errMsg = "target file type not supported";
+ return true;
+ }
- // Run our queue of passes all at once now, efficiently.
- passes.run(*mergedModule);
+ // Run our queue of passes all at once now, efficiently.
+ passes.run(*mergedModule);
- // Run the code generator, and write assembly file
- codeGenPasses->doInitialization();
+ // Run the code generator, and write assembly file
+ codeGenPasses->doInitialization();
- for (Module::iterator
- it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it)
- if (!it->isDeclaration())
- codeGenPasses->run(*it);
+ for (Module::iterator
+ it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it)
+ if (!it->isDeclaration())
+ codeGenPasses->run(*it);
- codeGenPasses->doFinalization();
- delete codeGenPasses;
+ codeGenPasses->doFinalization();
+ delete codeGenPasses;
- return false; // success
+ return false; // success
}
-
-/// Optimize merged modules using various IPO passes
-void LTOCodeGenerator::setCodeGenDebugOptions(const char* options)
-{
- for (std::pair<StringRef, StringRef> o = getToken(options);
- !o.first.empty(); o = getToken(o.second)) {
- // ParseCommandLineOptions() expects argv[0] to be program name.
- // Lazily add that.
- if ( _codegenOptions.empty() )
- _codegenOptions.push_back("libLTO");
- _codegenOptions.push_back(strdup(o.first.str().c_str()));
- }
+/// setCodeGenDebugOptions - Set codegen debugging options to aid in debugging
+/// LTO problems.
+void LTOCodeGenerator::setCodeGenDebugOptions(const char *options) {
+ for (std::pair<StringRef, StringRef> o = getToken(options);
+ !o.first.empty(); o = getToken(o.second)) {
+ // ParseCommandLineOptions() expects argv[0] to be program name. Lazily add
+ // that.
+ if ( _codegenOptions.empty() )
+ _codegenOptions.push_back(strdup("libLTO"));
+ _codegenOptions.push_back(strdup(o.first.str().c_str()));
+ }
}
diff --git a/tools/lto/LTOCodeGenerator.h b/tools/lto/LTOCodeGenerator.h
index f8fd357..032dc37 100644
--- a/tools/lto/LTOCodeGenerator.h
+++ b/tools/lto/LTOCodeGenerator.h
@@ -4,71 +4,80 @@
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
-// This file declares the LTOCodeGenerator class.
+// This file declares the LTOCodeGenerator class.
//
//===----------------------------------------------------------------------===//
-
#ifndef LTO_CODE_GENERATOR_H
#define LTO_CODE_GENERATOR_H
#include "llvm/Linker.h"
-#include "llvm/LLVMContext.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallPtrSet.h"
-
+#include "llvm-c/lto.h"
#include <string>
+namespace llvm {
+ class LLVMContext;
+ class GlobalValue;
+ class Mangler;
+ class MemoryBuffer;
+ class TargetMachine;
+ class raw_ostream;
+}
-//
-// C++ class which implements the opaque lto_code_gen_t
-//
-
+//===----------------------------------------------------------------------===//
+/// LTOCodeGenerator - C++ class which implements the opaque lto_code_gen_t
+/// type.
+///
struct LTOCodeGenerator {
- static const char* getVersionString();
-
- LTOCodeGenerator();
- ~LTOCodeGenerator();
-
- bool addModule(struct LTOModule*, std::string& errMsg);
- bool setDebugInfo(lto_debug_model, std::string& errMsg);
- bool setCodePICModel(lto_codegen_model, std::string& errMsg);
- void setCpu(const char *cpu);
- void addMustPreserveSymbol(const char* sym);
- bool writeMergedModules(const char* path,
- std::string& errMsg);
- bool compile_to_file(const char** name, std::string& errMsg);
- const void* compile(size_t* length, std::string& errMsg);
- void setCodeGenDebugOptions(const char *opts);
+ static const char *getVersionString();
+
+ LTOCodeGenerator();
+ ~LTOCodeGenerator();
+
+ bool addModule(struct LTOModule*, std::string &errMsg);
+ bool setDebugInfo(lto_debug_model, std::string &errMsg);
+ bool setCodePICModel(lto_codegen_model, std::string &errMsg);
+
+ void setCpu(const char* mCpu) { _mCpu = mCpu; }
+
+ void addMustPreserveSymbol(const char* sym) {
+ _mustPreserveSymbols[sym] = 1;
+ }
+
+ bool writeMergedModules(const char *path, std::string &errMsg);
+ bool compile_to_file(const char **name, std::string &errMsg);
+ const void *compile(size_t *length, std::string &errMsg);
+ void setCodeGenDebugOptions(const char *opts);
+
private:
- bool generateObjectFile(llvm::raw_ostream& out,
- std::string& errMsg);
- void applyScopeRestrictions();
- void applyRestriction(llvm::GlobalValue &GV,
- std::vector<const char*> &mustPreserveList,
+ bool generateObjectFile(llvm::raw_ostream &out, std::string &errMsg);
+ void applyScopeRestrictions();
+ void applyRestriction(llvm::GlobalValue &GV,
+ std::vector<const char*> &mustPreserveList,
llvm::SmallPtrSet<llvm::GlobalValue*, 8> &asmUsed,
- llvm::Mangler &mangler);
- bool determineTarget(std::string& errMsg);
-
- typedef llvm::StringMap<uint8_t> StringSet;
+ llvm::Mangler &mangler);
+ bool determineTarget(std::string &errMsg);
+
+ typedef llvm::StringMap<uint8_t> StringSet;
- llvm::LLVMContext& _context;
- llvm::Linker _linker;
- llvm::TargetMachine* _target;
- bool _emitDwarfDebugInfo;
- bool _scopeRestrictionsDone;
- lto_codegen_model _codeModel;
- StringSet _mustPreserveSymbols;
- StringSet _asmUndefinedRefs;
- llvm::MemoryBuffer* _nativeObjectFile;
- std::vector<const char*> _codegenOptions;
- std::string _mCpu;
- std::string _nativeObjectPath;
+ llvm::LLVMContext& _context;
+ llvm::Linker _linker;
+ llvm::TargetMachine* _target;
+ bool _emitDwarfDebugInfo;
+ bool _scopeRestrictionsDone;
+ bool _runInternalizePass;
+ lto_codegen_model _codeModel;
+ StringSet _mustPreserveSymbols;
+ StringSet _asmUndefinedRefs;
+ llvm::MemoryBuffer* _nativeObjectFile;
+ std::vector<char*> _codegenOptions;
+ std::string _mCpu;
+ std::string _nativeObjectPath;
};
#endif // LTO_CODE_GENERATOR_H
-
diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp
index 8ce8cd2..1dbd64b 100644
--- a/tools/lto/LTOModule.cpp
+++ b/tools/lto/LTOModule.cpp
@@ -13,37 +13,37 @@
//===----------------------------------------------------------------------===//
#include "LTOModule.h"
-
#include "llvm/Constants.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Bitcode/ReaderWriter.h"
-#include "llvm/Support/SystemUtils.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/Process.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/TargetRegistry.h"
-#include "llvm/Support/TargetSelect.h"
-#include "llvm/Support/system_error.h"
-#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/MC/SubtargetFeature.h"
#include "llvm/MC/MCTargetAsmParser.h"
-#include "llvm/Target/TargetMachine.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/Target/TargetRegisterInfo.h"
-
+#include "llvm/Support/Host.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/system_error.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/Triple.h"
using namespace llvm;
+LTOModule::LTOModule(llvm::Module *m, llvm::TargetMachine *t)
+ : _module(m), _target(t),
+ _context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(), NULL),
+ _mangler(_context, *_target->getTargetData()) {}
+
+/// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM
+/// bitcode.
bool LTOModule::isBitcodeFile(const void *mem, size_t length) {
return llvm::sys::IdentifyFileType((char*)mem, length)
== llvm::sys::Bitcode_FileType;
@@ -53,6 +53,8 @@ bool LTOModule::isBitcodeFile(const char *path) {
return llvm::sys::Path(path).isBitcodeFile();
}
+/// isBitcodeFileForTarget - Returns 'true' if the file (or memory contents) is
+/// LLVM bitcode for the specified triple.
bool LTOModule::isBitcodeFileForTarget(const void *mem, size_t length,
const char *triplePrefix) {
MemoryBuffer *buffer = makeBuffer(mem, length);
@@ -69,23 +71,17 @@ bool LTOModule::isBitcodeFileForTarget(const char *path,
return isTargetMatch(buffer.take(), triplePrefix);
}
-// Takes ownership of buffer.
+/// isTargetMatch - Returns 'true' if the memory buffer is for the specified
+/// target triple.
bool LTOModule::isTargetMatch(MemoryBuffer *buffer, const char *triplePrefix) {
std::string Triple = getBitcodeTargetTriple(buffer, getGlobalContext());
delete buffer;
return strncmp(Triple.c_str(), triplePrefix, strlen(triplePrefix)) == 0;
}
-
-LTOModule::LTOModule(Module *m, TargetMachine *t)
- : _module(m), _target(t),
- _context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(), NULL),
- _mangler(_context, *_target->getTargetData())
-{
-}
-
-LTOModule *LTOModule::makeLTOModule(const char *path,
- std::string &errMsg) {
+/// makeLTOModule - Create an LTOModule. N.B. These methods take ownership of
+/// the buffer.
+LTOModule *LTOModule::makeLTOModule(const char *path, std::string &errMsg) {
OwningPtr<MemoryBuffer> buffer;
if (error_code ec = MemoryBuffer::getFile(path, buffer)) {
errMsg = ec.message();
@@ -113,12 +109,6 @@ LTOModule *LTOModule::makeLTOModule(int fd, const char *path,
return makeLTOModule(buffer.take(), errMsg);
}
-/// makeBuffer - Create a MemoryBuffer from a memory range.
-MemoryBuffer *LTOModule::makeBuffer(const void *mem, size_t length) {
- const char *startPtr = (char*)mem;
- return MemoryBuffer::getMemBuffer(StringRef(startPtr, length), "", false);
-}
-
LTOModule *LTOModule::makeLTOModule(const void *mem, size_t length,
std::string &errMsg) {
OwningPtr<MemoryBuffer> buffer(makeBuffer(mem, length));
@@ -163,7 +153,7 @@ LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer,
TargetMachine *target = march->createTargetMachine(Triple, CPU, FeatureStr,
Options);
LTOModule *Ret = new LTOModule(m.take(), target);
- if (Ret->ParseSymbols(errMsg)) {
+ if (Ret->parseSymbols(errMsg)) {
delete Ret;
return NULL;
}
@@ -171,20 +161,13 @@ LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer,
return Ret;
}
-const char *LTOModule::getTargetTriple() {
- return _module->getTargetTriple().c_str();
-}
-
-void LTOModule::setTargetTriple(const char *triple) {
- _module->setTargetTriple(triple);
-}
-
-void LTOModule::addDefinedFunctionSymbol(Function *f) {
- // add to list of defined symbols
- addDefinedSymbol(f, true);
+/// makeBuffer - Create a MemoryBuffer from a memory range.
+MemoryBuffer *LTOModule::makeBuffer(const void *mem, size_t length) {
+ const char *startPtr = (char*)mem;
+ return MemoryBuffer::getMemBuffer(StringRef(startPtr, length), "", false);
}
-// Get string that data pointer points to.
+/// objcClassNameFromExpression - Get string that the data pointer points to.
bool LTOModule::objcClassNameFromExpression(Constant *c, std::string &name) {
if (ConstantExpr *ce = dyn_cast<ConstantExpr>(c)) {
Constant *op = ce->getOperand(0);
@@ -201,7 +184,7 @@ bool LTOModule::objcClassNameFromExpression(Constant *c, std::string &name) {
return false;
}
-// Parse i386/ppc ObjC class data structure.
+/// addObjCClass - Parse i386/ppc ObjC class data structure.
void LTOModule::addObjCClass(GlobalVariable *clgv) {
ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer());
if (!c) return;
@@ -216,6 +199,8 @@ void LTOModule::addObjCClass(GlobalVariable *clgv) {
const char *symbolName = entry.getKey().data();
info.name = symbolName;
info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
+ info.isFunction = false;
+ info.symbol = clgv;
entry.setValue(info);
}
}
@@ -225,17 +210,18 @@ void LTOModule::addObjCClass(GlobalVariable *clgv) {
if (objcClassNameFromExpression(c->getOperand(2), className)) {
StringSet::value_type &entry = _defines.GetOrCreateValue(className);
entry.setValue(1);
+
NameAndAttributes info;
info.name = entry.getKey().data();
- info.attributes = lto_symbol_attributes(LTO_SYMBOL_PERMISSIONS_DATA |
- LTO_SYMBOL_DEFINITION_REGULAR |
- LTO_SYMBOL_SCOPE_DEFAULT);
+ info.attributes = LTO_SYMBOL_PERMISSIONS_DATA |
+ LTO_SYMBOL_DEFINITION_REGULAR | LTO_SYMBOL_SCOPE_DEFAULT;
+ info.isFunction = false;
+ info.symbol = clgv;
_symbols.push_back(info);
}
}
-
-// Parse i386/ppc ObjC category data structure.
+/// addObjCCategory - Parse i386/ppc ObjC category data structure.
void LTOModule::addObjCCategory(GlobalVariable *clgv) {
ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer());
if (!c) return;
@@ -255,11 +241,12 @@ void LTOModule::addObjCCategory(GlobalVariable *clgv) {
const char *symbolName = entry.getKey().data();
info.name = symbolName;
info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
+ info.isFunction = false;
+ info.symbol = clgv;
entry.setValue(info);
}
-
-// Parse i386/ppc ObjC class list data structure.
+/// addObjCClassRef - Parse i386/ppc ObjC class list data structure.
void LTOModule::addObjCClassRef(GlobalVariable *clgv) {
std::string targetclassName;
if (!objcClassNameFromExpression(clgv->getInitializer(), targetclassName))
@@ -274,10 +261,12 @@ void LTOModule::addObjCClassRef(GlobalVariable *clgv) {
const char *symbolName = entry.getKey().data();
info.name = symbolName;
info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
+ info.isFunction = false;
+ info.symbol = clgv;
entry.setValue(info);
}
-
+/// addDefinedDataSymbol - Add a data symbol as defined to the list.
void LTOModule::addDefinedDataSymbol(GlobalValue *v) {
// Add to list of defined symbols.
addDefinedSymbol(v, false);
@@ -325,6 +314,13 @@ void LTOModule::addDefinedDataSymbol(GlobalValue *v) {
}
}
+/// addDefinedFunctionSymbol - Add a function symbol as defined to the list.
+void LTOModule::addDefinedFunctionSymbol(Function *f) {
+ // add to list of defined symbols
+ addDefinedSymbol(f, true);
+}
+
+/// addDefinedSymbol - Add a defined symbol to the list.
void LTOModule::addDefinedSymbol(GlobalValue *def, bool isFunction) {
// ignore all llvm.* symbols
if (def->getName().startswith("llvm."))
@@ -339,9 +335,9 @@ void LTOModule::addDefinedSymbol(GlobalValue *def, bool isFunction) {
uint32_t attr = align ? CountTrailingZeros_32(def->getAlignment()) : 0;
// set permissions part
- if (isFunction)
+ if (isFunction) {
attr |= LTO_SYMBOL_PERMISSIONS_CODE;
- else {
+ } else {
GlobalVariable *gv = dyn_cast<GlobalVariable>(def);
if (gv && gv->isConstant())
attr |= LTO_SYMBOL_PERMISSIONS_RODATA;
@@ -373,18 +369,24 @@ void LTOModule::addDefinedSymbol(GlobalValue *def, bool isFunction) {
else
attr |= LTO_SYMBOL_SCOPE_INTERNAL;
- // add to table of symbols
- NameAndAttributes info;
StringSet::value_type &entry = _defines.GetOrCreateValue(Buffer);
entry.setValue(1);
+ // fill information structure
+ NameAndAttributes info;
StringRef Name = entry.getKey();
info.name = Name.data();
assert(info.name[Name.size()] == '\0');
- info.attributes = (lto_symbol_attributes)attr;
+ info.attributes = attr;
+ info.isFunction = isFunction;
+ info.symbol = def;
+
+ // add to table of symbols
_symbols.push_back(info);
}
+/// addAsmGlobalSymbol - Add a global symbol from module-level ASM to the
+/// defined list.
void LTOModule::addAsmGlobalSymbol(const char *name,
lto_symbol_attributes scope) {
StringSet::value_type &entry = _defines.GetOrCreateValue(name);
@@ -394,15 +396,41 @@ void LTOModule::addAsmGlobalSymbol(const char *name,
return;
entry.setValue(1);
- const char *symbolName = entry.getKey().data();
- uint32_t attr = LTO_SYMBOL_DEFINITION_REGULAR;
- attr |= scope;
- NameAndAttributes info;
- info.name = symbolName;
- info.attributes = (lto_symbol_attributes)attr;
- _symbols.push_back(info);
+
+ NameAndAttributes &info = _undefines[entry.getKey().data()];
+
+ if (info.symbol == 0) {
+ // FIXME: This is trying to take care of module ASM like this:
+ //
+ // module asm ".zerofill __FOO, __foo, _bar_baz_qux, 0"
+ //
+ // but is gross and its mother dresses it funny. Have the ASM parser give us
+ // more details for this type of situation so that we're not guessing so
+ // much.
+
+ // fill information structure
+ info.name = name;
+ info.attributes =
+ LTO_SYMBOL_PERMISSIONS_DATA | LTO_SYMBOL_DEFINITION_REGULAR | scope;
+ info.isFunction = false;
+ info.symbol = 0;
+
+ // add to table of symbols
+ _symbols.push_back(info);
+ return;
+ }
+
+ if (info.isFunction)
+ addDefinedFunctionSymbol(cast<Function>(info.symbol));
+ else
+ addDefinedDataSymbol(info.symbol);
+
+ _symbols.back().attributes &= ~LTO_SYMBOL_SCOPE_MASK;
+ _symbols.back().attributes |= scope;
}
+/// addAsmGlobalSymbolUndef - Add a global symbol from module-level ASM to the
+/// undefined list.
void LTOModule::addAsmGlobalSymbolUndef(const char *name) {
StringMap<NameAndAttributes>::value_type &entry =
_undefines.GetOrCreateValue(name);
@@ -417,12 +445,16 @@ void LTOModule::addAsmGlobalSymbolUndef(const char *name) {
attr |= LTO_SYMBOL_SCOPE_DEFAULT;
NameAndAttributes info;
info.name = entry.getKey().data();
- info.attributes = (lto_symbol_attributes)attr;
+ info.attributes = attr;
+ info.isFunction = false;
+ info.symbol = 0;
entry.setValue(info);
}
-void LTOModule::addPotentialUndefinedSymbol(GlobalValue *decl) {
+/// addPotentialUndefinedSymbol - Add a symbol which isn't defined just yet to a
+/// list to be resolved later.
+void LTOModule::addPotentialUndefinedSymbol(GlobalValue *decl, bool isFunc) {
// ignore all llvm.* symbols
if (decl->getName().startswith("llvm."))
return;
@@ -444,18 +476,22 @@ void LTOModule::addPotentialUndefinedSymbol(GlobalValue *decl) {
NameAndAttributes info;
info.name = entry.getKey().data();
+
if (decl->hasExternalWeakLinkage())
info.attributes = LTO_SYMBOL_DEFINITION_WEAKUNDEF;
else
info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
+ info.isFunction = isFunc;
+ info.symbol = decl;
+
entry.setValue(info);
}
namespace {
class RecordStreamer : public MCStreamer {
public:
- enum State { NeverSeen, Global, Defined, DefinedGlobal, Used};
+ enum State { NeverSeen, Global, Defined, DefinedGlobal, Used };
private:
StringMap<State> Symbols;
@@ -544,14 +580,16 @@ namespace {
RecordStreamer(MCContext &Context) : MCStreamer(Context) {}
- virtual void ChangeSection(const MCSection *Section) {}
- virtual void InitSections() {}
+ virtual void EmitInstruction(const MCInst &Inst) {
+ // Scan for values.
+ for (unsigned i = Inst.getNumOperands(); i--; )
+ if (Inst.getOperand(i).isExpr())
+ AddValueSymbols(Inst.getOperand(i).getExpr());
+ }
virtual void EmitLabel(MCSymbol *Symbol) {
Symbol->setSection(*getCurrentSection());
markDefined(*Symbol);
}
- virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {}
- virtual void EmitThumbFunc(MCSymbol *Func) {}
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
// FIXME: should we handle aliases?
markDefined(*Symbol);
@@ -560,20 +598,26 @@ namespace {
if (Attribute == MCSA_Global)
markGlobal(*Symbol);
}
- virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
- virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
- virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {}
- virtual void EmitCOFFSymbolStorageClass(int StorageClass) {}
virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
unsigned Size , unsigned ByteAlignment) {
markDefined(*Symbol);
}
- virtual void EmitCOFFSymbolType(int Type) {}
- virtual void EndCOFFSymbolDef() {}
virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {
markDefined(*Symbol);
}
+
+ // Noop calls.
+ virtual void ChangeSection(const MCSection *Section) {}
+ virtual void InitSections() {}
+ virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {}
+ virtual void EmitThumbFunc(MCSymbol *Func) {}
+ virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
+ virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
+ virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {}
+ virtual void EmitCOFFSymbolStorageClass(int StorageClass) {}
+ virtual void EmitCOFFSymbolType(int Type) {}
+ virtual void EndCOFFSymbolDef() {}
virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {}
@@ -596,17 +640,12 @@ namespace {
const MCSymbol *LastLabel,
const MCSymbol *Label,
unsigned PointerSize) {}
-
- virtual void EmitInstruction(const MCInst &Inst) {
- // Scan for values.
- for (unsigned i = Inst.getNumOperands(); i--; )
- if (Inst.getOperand(i).isExpr())
- AddValueSymbols(Inst.getOperand(i).getExpr());
- }
virtual void FinishImpl() {}
};
-}
+} // end anonymous namespace
+/// addAsmGlobalSymbols - Add global symbols from module-level ASM to the
+/// defined or undefined lists.
bool LTOModule::addAsmGlobalSymbols(std::string &errMsg) {
const std::string &inlineAsm = _module->getModuleInlineAsm();
if (inlineAsm.empty())
@@ -651,6 +690,7 @@ bool LTOModule::addAsmGlobalSymbols(std::string &errMsg) {
return false;
}
+/// isDeclaration - Return 'true' if the global value is a declaration.
static bool isDeclaration(const GlobalValue &V) {
if (V.hasAvailableExternallyLinkage())
return true;
@@ -659,15 +699,13 @@ static bool isDeclaration(const GlobalValue &V) {
return V.isDeclaration();
}
-static bool isAliasToDeclaration(const GlobalAlias &V) {
- return isDeclaration(*V.getAliasedGlobal());
-}
-
-bool LTOModule::ParseSymbols(std::string &errMsg) {
+/// parseSymbols - Parse the symbols from the module and model-level ASM and add
+/// them to either the defined or undefined lists.
+bool LTOModule::parseSymbols(std::string &errMsg) {
// add functions
- for (Module::iterator f = _module->begin(); f != _module->end(); ++f) {
+ for (Module::iterator f = _module->begin(), e = _module->end(); f != e; ++f) {
if (isDeclaration(*f))
- addPotentialUndefinedSymbol(f);
+ addPotentialUndefinedSymbol(f, true);
else
addDefinedFunctionSymbol(f);
}
@@ -676,7 +714,7 @@ bool LTOModule::ParseSymbols(std::string &errMsg) {
for (Module::global_iterator v = _module->global_begin(),
e = _module->global_end(); v != e; ++v) {
if (isDeclaration(*v))
- addPotentialUndefinedSymbol(v);
+ addPotentialUndefinedSymbol(v, false);
else
addDefinedDataSymbol(v);
}
@@ -686,41 +724,24 @@ bool LTOModule::ParseSymbols(std::string &errMsg) {
return true;
// add aliases
- for (Module::alias_iterator i = _module->alias_begin(),
- e = _module->alias_end(); i != e; ++i) {
- if (isAliasToDeclaration(*i))
- addPotentialUndefinedSymbol(i);
+ for (Module::alias_iterator a = _module->alias_begin(),
+ e = _module->alias_end(); a != e; ++a) {
+ if (isDeclaration(*a->getAliasedGlobal()))
+ // Is an alias to a declaration.
+ addPotentialUndefinedSymbol(a, false);
else
- addDefinedDataSymbol(i);
+ addDefinedDataSymbol(a);
}
// make symbols for all undefines
- for (StringMap<NameAndAttributes>::iterator it=_undefines.begin();
- it != _undefines.end(); ++it) {
- // if this symbol also has a definition, then don't make an undefine
- // because it is a tentative definition
- if (_defines.count(it->getKey()) == 0) {
- NameAndAttributes info = it->getValue();
- _symbols.push_back(info);
- }
+ for (StringMap<NameAndAttributes>::iterator u =_undefines.begin(),
+ e = _undefines.end(); u != e; ++u) {
+ // If this symbol also has a definition, then don't make an undefine because
+ // it is a tentative definition.
+ if (_defines.count(u->getKey())) continue;
+ NameAndAttributes info = u->getValue();
+ _symbols.push_back(info);
}
- return false;
-}
-uint32_t LTOModule::getSymbolCount() {
- return _symbols.size();
-}
-
-lto_symbol_attributes LTOModule::getSymbolAttributes(uint32_t index) {
- if (index < _symbols.size())
- return _symbols[index].attributes;
- else
- return lto_symbol_attributes(0);
-}
-
-const char *LTOModule::getSymbolName(uint32_t index) {
- if (index < _symbols.size())
- return _symbols[index].name;
- else
- return NULL;
+ return false;
}
diff --git a/tools/lto/LTOModule.h b/tools/lto/LTOModule.h
index 35a0935..cafb927 100644
--- a/tools/lto/LTOModule.h
+++ b/tools/lto/LTOModule.h
@@ -4,10 +4,10 @@
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
-// This file declares the LTOModule class.
+// This file declares the LTOModule class.
//
//===----------------------------------------------------------------------===//
@@ -20,104 +20,167 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
-
#include "llvm-c/lto.h"
-
#include <vector>
#include <string>
-
-// forward references to llvm classes
+// Forward references to llvm classes.
namespace llvm {
- class MemoryBuffer;
- class GlobalValue;
- class Value;
- class Function;
+ class Function;
+ class GlobalValue;
+ class MemoryBuffer;
+ class Value;
}
-
-//
-// C++ class which implements the opaque lto_module_t
-//
+//===----------------------------------------------------------------------===//
+/// LTOModule - C++ class which implements the opaque lto_module_t type.
+///
struct LTOModule {
-
- static bool isBitcodeFile(const void* mem, size_t length);
- static bool isBitcodeFile(const char* path);
-
- static bool isBitcodeFileForTarget(const void* mem,
- size_t length, const char* triplePrefix);
-
- static bool isBitcodeFileForTarget(const char* path,
- const char* triplePrefix);
-
- static LTOModule* makeLTOModule(const char* path,
- std::string& errMsg);
- static LTOModule* makeLTOModule(int fd, const char *path,
- size_t size,
- std::string& errMsg);
- static LTOModule* makeLTOModule(int fd, const char *path,
- size_t file_size,
- size_t map_size,
- off_t offset,
- std::string& errMsg);
- static LTOModule* makeLTOModule(const void* mem, size_t length,
- std::string& errMsg);
-
- const char* getTargetTriple();
- void setTargetTriple(const char*);
- uint32_t getSymbolCount();
- lto_symbol_attributes getSymbolAttributes(uint32_t index);
- const char* getSymbolName(uint32_t index);
-
- llvm::Module * getLLVVMModule() { return _module.get(); }
- const std::vector<const char*> &getAsmUndefinedRefs() {
- return _asm_undefines;
- }
+private:
+ typedef llvm::StringMap<uint8_t> StringSet;
+
+ struct NameAndAttributes {
+ const char *name;
+ uint32_t attributes;
+ bool isFunction;
+ llvm::GlobalValue *symbol;
+ };
+
+ llvm::OwningPtr<llvm::Module> _module;
+ llvm::OwningPtr<llvm::TargetMachine> _target;
+ std::vector<NameAndAttributes> _symbols;
+
+ // _defines and _undefines only needed to disambiguate tentative definitions
+ StringSet _defines;
+ llvm::StringMap<NameAndAttributes> _undefines;
+ std::vector<const char*> _asm_undefines;
+ llvm::MCContext _context;
+
+ // Use mangler to add GlobalPrefix to names to match linker names.
+ llvm::Mangler _mangler;
+
+ LTOModule(llvm::Module *m, llvm::TargetMachine *t);
+public:
+ /// isBitcodeFile - Returns 'true' if the file or memory contents is LLVM
+ /// bitcode.
+ static bool isBitcodeFile(const void *mem, size_t length);
+ static bool isBitcodeFile(const char *path);
+
+ /// isBitcodeFileForTarget - Returns 'true' if the file or memory contents
+ /// is LLVM bitcode for the specified triple.
+ static bool isBitcodeFileForTarget(const void *mem,
+ size_t length,
+ const char *triplePrefix);
+ static bool isBitcodeFileForTarget(const char *path,
+ const char *triplePrefix);
+
+ /// makeLTOModule - Create an LTOModule. N.B. These methods take ownership
+ /// of the buffer.
+ static LTOModule *makeLTOModule(const char* path,
+ std::string &errMsg);
+ static LTOModule *makeLTOModule(int fd, const char *path,
+ size_t size, std::string &errMsg);
+ static LTOModule *makeLTOModule(int fd, const char *path,
+ size_t file_size,
+ size_t map_size,
+ off_t offset,
+ std::string& errMsg);
+ static LTOModule *makeLTOModule(const void *mem, size_t length,
+ std::string &errMsg);
+
+ /// getTargetTriple - Return the Module's target triple.
+ const char *getTargetTriple() {
+ return _module->getTargetTriple().c_str();
+ }
+
+ /// setTargetTriple - Set the Module's target triple.
+ void setTargetTriple(const char *triple) {
+ _module->setTargetTriple(triple);
+ }
+
+ /// getSymbolCount - Get the number of symbols
+ uint32_t getSymbolCount() {
+ return _symbols.size();
+ }
+
+ /// getSymbolAttributes - Get the attributes for a symbol at the specified
+ /// index.
+ lto_symbol_attributes getSymbolAttributes(uint32_t index) {
+ if (index < _symbols.size())
+ return lto_symbol_attributes(_symbols[index].attributes);
+ return lto_symbol_attributes(0);
+ }
+
+ /// getSymbolName - Get the name of the symbol at the specified index.
+ const char *getSymbolName(uint32_t index) {
+ if (index < _symbols.size())
+ return _symbols[index].name;
+ return NULL;
+ }
+
+ /// getLLVVMModule - Return the Module.
+ llvm::Module *getLLVVMModule() { return _module.get(); }
+
+ /// getAsmUndefinedRefs -
+ const std::vector<const char*> &getAsmUndefinedRefs() {
+ return _asm_undefines;
+ }
private:
- LTOModule(llvm::Module* m, llvm::TargetMachine* t);
-
- bool ParseSymbols(std::string &errMsg);
- void addDefinedSymbol(llvm::GlobalValue* def,
- bool isFunction);
- void addPotentialUndefinedSymbol(llvm::GlobalValue* decl);
- void addDefinedFunctionSymbol(llvm::Function* f);
- void addDefinedDataSymbol(llvm::GlobalValue* v);
- bool addAsmGlobalSymbols(std::string &errMsg);
- void addAsmGlobalSymbol(const char *,
- lto_symbol_attributes scope);
- void addAsmGlobalSymbolUndef(const char *);
- void addObjCClass(llvm::GlobalVariable* clgv);
- void addObjCCategory(llvm::GlobalVariable* clgv);
- void addObjCClassRef(llvm::GlobalVariable* clgv);
- bool objcClassNameFromExpression(llvm::Constant* c,
- std::string& name);
-
- static bool isTargetMatch(llvm::MemoryBuffer* memBuffer,
- const char* triplePrefix);
-
- static LTOModule* makeLTOModule(llvm::MemoryBuffer* buffer,
- std::string& errMsg);
- static llvm::MemoryBuffer* makeBuffer(const void* mem, size_t length);
-
- typedef llvm::StringMap<uint8_t> StringSet;
-
- struct NameAndAttributes {
- const char* name;
- lto_symbol_attributes attributes;
- };
-
- llvm::OwningPtr<llvm::Module> _module;
- llvm::OwningPtr<llvm::TargetMachine> _target;
- std::vector<NameAndAttributes> _symbols;
- // _defines and _undefines only needed to disambiguate tentative definitions
- StringSet _defines;
- llvm::StringMap<NameAndAttributes> _undefines;
- std::vector<const char*> _asm_undefines;
- llvm::MCContext _context;
- // Use mangler to add GlobalPrefix to names to match linker names.
- llvm::Mangler _mangler;
+ /// parseSymbols - Parse the symbols from the module and model-level ASM and
+ /// add them to either the defined or undefined lists.
+ bool parseSymbols(std::string &errMsg);
+
+ /// addPotentialUndefinedSymbol - Add a symbol which isn't defined just yet
+ /// to a list to be resolved later.
+ void addPotentialUndefinedSymbol(llvm::GlobalValue *dcl, bool isFunc);
+
+ /// addDefinedSymbol - Add a defined symbol to the list.
+ void addDefinedSymbol(llvm::GlobalValue *def, bool isFunction);
+
+ /// addDefinedFunctionSymbol - Add a function symbol as defined to the list.
+ void addDefinedFunctionSymbol(llvm::Function *f);
+
+ /// addDefinedDataSymbol - Add a data symbol as defined to the list.
+ void addDefinedDataSymbol(llvm::GlobalValue *v);
+
+ /// addAsmGlobalSymbols - Add global symbols from module-level ASM to the
+ /// defined or undefined lists.
+ bool addAsmGlobalSymbols(std::string &errMsg);
+
+ /// addAsmGlobalSymbol - Add a global symbol from module-level ASM to the
+ /// defined list.
+ void addAsmGlobalSymbol(const char *, lto_symbol_attributes scope);
+
+ /// addAsmGlobalSymbolUndef - Add a global symbol from module-level ASM to
+ /// the undefined list.
+ void addAsmGlobalSymbolUndef(const char *);
+
+ /// addObjCClass - Parse i386/ppc ObjC class data structure.
+ void addObjCClass(llvm::GlobalVariable *clgv);
+
+ /// addObjCCategory - Parse i386/ppc ObjC category data structure.
+ void addObjCCategory(llvm::GlobalVariable *clgv);
+
+ /// addObjCClassRef - Parse i386/ppc ObjC class list data structure.
+ void addObjCClassRef(llvm::GlobalVariable *clgv);
+
+ /// objcClassNameFromExpression - Get string that the data pointer points
+ /// to.
+ bool objcClassNameFromExpression(llvm::Constant* c, std::string &name);
+
+ /// isTargetMatch - Returns 'true' if the memory buffer is for the specified
+ /// target triple.
+ static bool isTargetMatch(llvm::MemoryBuffer *memBuffer,
+ const char *triplePrefix);
+
+ /// makeLTOModule - Create an LTOModule (private version). N.B. This
+ /// method takes ownership of the buffer.
+ static LTOModule *makeLTOModule(llvm::MemoryBuffer *buffer,
+ std::string &errMsg);
+
+ /// makeBuffer - Create a MemoryBuffer from a memory range.
+ static llvm::MemoryBuffer *makeBuffer(const void *mem, size_t length);
};
#endif // LTO_MODULE_H
-
diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp
index dd658d1..a7e633d 100644
--- a/tools/lto/lto.cpp
+++ b/tools/lto/lto.cpp
@@ -4,10 +4,10 @@
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
-// This file implements the Link Time Optimization library. This library is
+// This file implements the Link Time Optimization library. This library is
// intended to be used by linker to optimize code at link time.
//
//===----------------------------------------------------------------------===//
@@ -19,292 +19,196 @@
#include "LTOCodeGenerator.h"
-// holds most recent error string
-// *** not thread safe ***
+// Holds most recent error string.
+// *** Not thread safe ***
static std::string sLastErrorString;
-
-
-//
-// returns a printable string
-//
-extern const char* lto_get_version()
-{
- return LTOCodeGenerator::getVersionString();
+/// lto_get_version - Returns a printable string.
+extern const char* lto_get_version() {
+ return LTOCodeGenerator::getVersionString();
}
-//
-// returns the last error string or NULL if last operation was successful
-//
-const char* lto_get_error_message()
-{
- return sLastErrorString.c_str();
+/// lto_get_error_message - Returns the last error string or NULL if last
+/// operation was successful.
+const char* lto_get_error_message() {
+ return sLastErrorString.c_str();
}
-
-
-//
-// validates if a file is a loadable object file
-//
-bool lto_module_is_object_file(const char* path)
-{
- return LTOModule::isBitcodeFile(path);
+/// lto_module_is_object_file - Validates if a file is a loadable object file.
+bool lto_module_is_object_file(const char* path) {
+ return LTOModule::isBitcodeFile(path);
}
-
-//
-// validates if a file is a loadable object file compilable for requested target
-//
-bool lto_module_is_object_file_for_target(const char* path,
- const char* target_triplet_prefix)
-{
- return LTOModule::isBitcodeFileForTarget(path, target_triplet_prefix);
+/// lto_module_is_object_file_for_target - Validates if a file is a loadable
+/// object file compilable for requested target.
+bool lto_module_is_object_file_for_target(const char* path,
+ const char* target_triplet_prefix) {
+ return LTOModule::isBitcodeFileForTarget(path, target_triplet_prefix);
}
-
-//
-// validates if a buffer is a loadable object file
-//
-bool lto_module_is_object_file_in_memory(const void* mem, size_t length)
-{
- return LTOModule::isBitcodeFile(mem, length);
+/// lto_module_is_object_file_in_memory - Validates if a buffer is a loadable
+/// object file.
+bool lto_module_is_object_file_in_memory(const void* mem, size_t length) {
+ return LTOModule::isBitcodeFile(mem, length);
}
-
-//
-// validates if a buffer is a loadable object file compilable for the target
-//
-bool lto_module_is_object_file_in_memory_for_target(const void* mem,
- size_t length, const char* target_triplet_prefix)
-{
- return LTOModule::isBitcodeFileForTarget(mem, length, target_triplet_prefix);
+/// lto_module_is_object_file_in_memory_for_target - Validates if a buffer is a
+/// loadable object file compilable for the target.
+bool
+lto_module_is_object_file_in_memory_for_target(const void* mem,
+ size_t length,
+ const char* target_triplet_prefix) {
+ return LTOModule::isBitcodeFileForTarget(mem, length, target_triplet_prefix);
}
-
-
-//
-// loads an object file from disk
-// returns NULL on error (check lto_get_error_message() for details)
-//
-lto_module_t lto_module_create(const char* path)
-{
- return LTOModule::makeLTOModule(path, sLastErrorString);
+/// lto_module_create - Loads an object file from disk. Returns NULL on error
+/// (check lto_get_error_message() for details).
+lto_module_t lto_module_create(const char* path) {
+ return LTOModule::makeLTOModule(path, sLastErrorString);
}
-//
-// loads an object file from disk
-// returns NULL on error (check lto_get_error_message() for details)
-//
-lto_module_t lto_module_create_from_fd(int fd, const char *path, size_t size)
-{
- return LTOModule::makeLTOModule(fd, path, size, sLastErrorString);
+/// lto_module_create_from_fd - Loads an object file from disk. Returns NULL on
+/// error (check lto_get_error_message() for details).
+lto_module_t lto_module_create_from_fd(int fd, const char *path, size_t size) {
+ return LTOModule::makeLTOModule(fd, path, size, sLastErrorString);
}
-//
-// loads an object file from disk
-// returns NULL on error (check lto_get_error_message() for details)
-//
+/// lto_module_create_from_fd_at_offset - Loads an object file from disk.
+/// Returns NULL on error (check lto_get_error_message() for details).
lto_module_t lto_module_create_from_fd_at_offset(int fd, const char *path,
size_t file_size,
size_t map_size,
- off_t offset)
-{
- return LTOModule::makeLTOModule(fd, path, file_size, map_size,
- offset, sLastErrorString);
+ off_t offset) {
+ return LTOModule::makeLTOModule(fd, path, file_size, map_size,
+ offset, sLastErrorString);
}
-//
-// loads an object file from memory
-// returns NULL on error (check lto_get_error_message() for details)
-//
-lto_module_t lto_module_create_from_memory(const void* mem, size_t length)
-{
- return LTOModule::makeLTOModule(mem, length, sLastErrorString);
+/// lto_module_create_from_memory - Loads an object file from memory. Returns
+/// NULL on error (check lto_get_error_message() for details).
+lto_module_t lto_module_create_from_memory(const void* mem, size_t length) {
+ return LTOModule::makeLTOModule(mem, length, sLastErrorString);
}
-
-//
-// frees all memory for a module
-// upon return the lto_module_t is no longer valid
-//
-void lto_module_dispose(lto_module_t mod)
-{
- delete mod;
+/// lto_module_dispose - Frees all memory for a module. Upon return the
+/// lto_module_t is no longer valid.
+void lto_module_dispose(lto_module_t mod) {
+ delete mod;
}
-
-//
-// returns triplet string which the object module was compiled under
-//
-const char* lto_module_get_target_triple(lto_module_t mod)
-{
- return mod->getTargetTriple();
+/// lto_module_get_target_triple - Returns triplet string which the object
+/// module was compiled under.
+const char* lto_module_get_target_triple(lto_module_t mod) {
+ return mod->getTargetTriple();
}
-//
-// sets triple string with which the object will be codegened.
-//
-void lto_module_set_target_triple(lto_module_t mod, const char *triple)
-{
- return mod->setTargetTriple(triple);
+/// lto_module_set_target_triple - Sets triple string with which the object will
+/// be codegened.
+void lto_module_set_target_triple(lto_module_t mod, const char *triple) {
+ return mod->setTargetTriple(triple);
}
-
-//
-// returns the number of symbols in the object module
-//
-unsigned int lto_module_get_num_symbols(lto_module_t mod)
-{
- return mod->getSymbolCount();
+/// lto_module_get_num_symbols - Returns the number of symbols in the object
+/// module.
+unsigned int lto_module_get_num_symbols(lto_module_t mod) {
+ return mod->getSymbolCount();
}
-//
-// returns the name of the ith symbol in the object module
-//
-const char* lto_module_get_symbol_name(lto_module_t mod, unsigned int index)
-{
- return mod->getSymbolName(index);
+/// lto_module_get_symbol_name - Returns the name of the ith symbol in the
+/// object module.
+const char* lto_module_get_symbol_name(lto_module_t mod, unsigned int index) {
+ return mod->getSymbolName(index);
}
-
-//
-// returns the attributes of the ith symbol in the object module
-//
-lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod,
- unsigned int index)
-{
- return mod->getSymbolAttributes(index);
+/// lto_module_get_symbol_attribute - Returns the attributes of the ith symbol
+/// in the object module.
+lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod,
+ unsigned int index) {
+ return mod->getSymbolAttributes(index);
}
-
-
-
-
-//
-// instantiates a code generator
-// returns NULL if there is an error
-//
-lto_code_gen_t lto_codegen_create(void)
-{
- return new LTOCodeGenerator();
+/// lto_codegen_create - Instantiates a code generator. Returns NULL if there
+/// is an error.
+lto_code_gen_t lto_codegen_create(void) {
+ return new LTOCodeGenerator();
}
-
-
-//
-// frees all memory for a code generator
-// upon return the lto_code_gen_t is no longer valid
-//
-void lto_codegen_dispose(lto_code_gen_t cg)
-{
- delete cg;
+/// lto_codegen_dispose - Frees all memory for a code generator. Upon return the
+/// lto_code_gen_t is no longer valid.
+void lto_codegen_dispose(lto_code_gen_t cg) {
+ delete cg;
}
-
-
-//
-// add an object module to the set of modules for which code will be generated
-// returns true on error (check lto_get_error_message() for details)
-//
-bool lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod)
-{
- return cg->addModule(mod, sLastErrorString);
+/// lto_codegen_add_module - Add an object module to the set of modules for
+/// which code will be generated. Returns true on error (check
+/// lto_get_error_message() for details).
+bool lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod) {
+ return cg->addModule(mod, sLastErrorString);
}
-
-//
-// sets what if any format of debug info should be generated
-// returns true on error (check lto_get_error_message() for details)
-//
-bool lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model debug)
-{
- return cg->setDebugInfo(debug, sLastErrorString);
+/// lto_codegen_set_debug_model - Sets what if any format of debug info should
+/// be generated. Returns true on error (check lto_get_error_message() for
+/// details).
+bool lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model debug) {
+ return cg->setDebugInfo(debug, sLastErrorString);
}
-
-//
-// sets what code model to generated
-// returns true on error (check lto_get_error_message() for details)
-//
-bool lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model model)
-{
+/// lto_codegen_set_pic_model - Sets what code model to generated. Returns true
+/// on error (check lto_get_error_message() for details).
+bool lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model model) {
return cg->setCodePICModel(model, sLastErrorString);
}
-//
-// sets the cpu to generate code for
-//
-void lto_codegen_set_cpu(lto_code_gen_t cg, const char* cpu)
-{
+/// lto_codegen_set_cpu - Sets the cpu to generate code for.
+void lto_codegen_set_cpu(lto_code_gen_t cg, const char *cpu) {
return cg->setCpu(cpu);
}
-//
-// sets the path to the assembler tool
-//
-void lto_codegen_set_assembler_path(lto_code_gen_t cg, const char* path)
-{
+/// lto_codegen_set_assembler_path - Sets the path to the assembler tool.
+void lto_codegen_set_assembler_path(lto_code_gen_t cg, const char *path) {
// In here only for backwards compatibility. We use MC now.
}
-
-//
-// sets extra arguments that libLTO should pass to the assembler
-//
-void lto_codegen_set_assembler_args(lto_code_gen_t cg, const char** args,
- int nargs)
-{
+/// lto_codegen_set_assembler_args - Sets extra arguments that libLTO should
+/// pass to the assembler.
+void lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args,
+ int nargs) {
// In here only for backwards compatibility. We use MC now.
}
-//
-// adds to a list of all global symbols that must exist in the final
-// generated code. If a function is not listed there, it might be
-// inlined into every usage and optimized away.
-//
-void lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, const char* symbol)
-{
+/// lto_codegen_add_must_preserve_symbol - Adds to a list of all global symbols
+/// that must exist in the final generated code. If a function is not listed
+/// there, it might be inlined into every usage and optimized away.
+void lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg,
+ const char *symbol) {
cg->addMustPreserveSymbol(symbol);
}
-
-//
-// writes a new file at the specified path that contains the
-// merged contents of all modules added so far.
-// returns true on error (check lto_get_error_message() for details)
-//
-bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char* path)
-{
+/// lto_codegen_write_merged_modules - Writes a new file at the specified path
+/// that contains the merged contents of all modules added so far. Returns true
+/// on error (check lto_get_error_message() for details).
+bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) {
return cg->writeMergedModules(path, sLastErrorString);
}
-
-//
-// Generates code for all added modules into one native object file.
-// On success returns a pointer to a generated mach-o/ELF buffer and
-// length set to the buffer size. The buffer is owned by the
-// lto_code_gen_t and will be freed when lto_codegen_dispose()
-// is called, or lto_codegen_compile() is called again.
-// On failure, returns NULL (check lto_get_error_message() for details).
-//
-extern const void*
-lto_codegen_compile(lto_code_gen_t cg, size_t* length)
-{
+/// lto_codegen_compile - Generates code for all added modules into one native
+/// object file. On success returns a pointer to a generated mach-o/ELF buffer
+/// and length set to the buffer size. The buffer is owned by the lto_code_gen_t
+/// object and will be freed when lto_codegen_dispose() is called, or
+/// lto_codegen_compile() is called again. On failure, returns NULL (check
+/// lto_get_error_message() for details).
+const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) {
return cg->compile(length, sLastErrorString);
}
-extern bool
-lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name)
-{
+/// lto_codegen_compile_to_file - Generates code for all added modules into one
+/// native object file. The name of the file is written to name. Returns true on
+/// error.
+bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) {
return cg->compile_to_file(name, sLastErrorString);
}
-
-//
-// Used to pass extra options to the code generator
-//
-extern void
-lto_codegen_debug_options(lto_code_gen_t cg, const char * opt)
-{
+/// lto_codegen_debug_options - Used to pass extra options to the code
+/// generator.
+void lto_codegen_debug_options(lto_code_gen_t cg, const char *opt) {
cg->setCodeGenDebugOptions(opt);
}
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp
index 30da863..a5b0511 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -114,6 +114,9 @@ static cl::opt<bool>
OptLevelO3("O3",
cl::desc("Optimization level 3. Similar to llvm-gcc -O3"));
+static cl::opt<std::string>
+TargetTriple("mtriple", cl::desc("Override target triple for module"));
+
static cl::opt<bool>
UnitAtATime("funit-at-a-time",
cl::desc("Enable IPO. This is same as llvm-gcc's -funit-at-a-time"),
@@ -512,6 +515,10 @@ int main(int argc, char **argv) {
return 1;
}
+ // If we are supposed to override the target triple, do so now.
+ if (!TargetTriple.empty())
+ M->setTargetTriple(Triple::normalize(TargetTriple));
+
// Figure out what stream we are supposed to write to...
OwningPtr<tool_output_file> Out;
if (NoOutput) {