Index: tools/pnacl-llc/pnacl-llc.cpp |
diff --git a/tools/pnacl-llc/pnacl-llc.cpp b/tools/pnacl-llc/pnacl-llc.cpp |
index cc0ee94bd0cad6a3d3fdbfdb36a1e731e9f5f32d..c4379635d5bbc75ccdc493883549bb64ae8a93c8 100644 |
--- a/tools/pnacl-llc/pnacl-llc.cpp |
+++ b/tools/pnacl-llc/pnacl-llc.cpp |
@@ -11,6 +11,7 @@ |
// |
//===----------------------------------------------------------------------===// |
+#include "llvm/ADT/STLExtras.h" |
#include "llvm/ADT/Triple.h" |
#include "llvm/Analysis/NaCl.h" |
#include "llvm/Bitcode/NaCl/NaClReaderWriter.h" |
@@ -24,7 +25,7 @@ |
#include "llvm/IRReader/IRReader.h" |
#include "llvm/MC/SubtargetFeature.h" |
#include "llvm/Pass.h" |
-#include "llvm/PassManager.h" |
+#include "llvm/IR/LegacyPassManager.h" |
#include "llvm/Support/CommandLine.h" |
#include "llvm/Support/DataStream.h" |
#include "llvm/Support/Debug.h" |
@@ -40,7 +41,7 @@ |
#include "llvm/Support/TargetRegistry.h" |
#include "llvm/Support/TargetSelect.h" |
#include "llvm/Support/ToolOutputFile.h" |
-#include "llvm/Target/TargetLibraryInfo.h" |
+#include "llvm/Analysis/TargetLibraryInfo.h" |
#include "llvm/Target/TargetMachine.h" |
#include "llvm/Target/TargetSubtargetInfo.h" |
#include "llvm/Transforms/NaCl.h" |
@@ -86,8 +87,10 @@ InputFileFormat( |
static cl::opt<std::string> |
InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); |
+// Primary output filename. If module splitting is used, the other output files |
+// will have names derived from this one. |
static cl::opt<std::string> |
-OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename")); |
+MainOutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename")); |
// Using bitcode streaming allows compilation of one function at a time. This |
// allows earlier functions to be compiled before later functions are read from |
@@ -161,53 +164,42 @@ SplitModuleSched( |
static int compileModule(StringRef ProgramName); |
#if !defined(PNACL_BROWSER_TRANSLATOR) |
-// GetFileNameRoot - Helper function to get the basename of a filename. |
-static std::string |
-GetFileNameRoot(StringRef InputFilename) { |
- std::string IFN = InputFilename; |
- std::string outputFilename; |
- int Len = IFN.length(); |
- if ((Len > 2) && |
- IFN[Len-3] == '.' && |
- ((IFN[Len-2] == 'b' && IFN[Len-1] == 'c') || |
- (IFN[Len-2] == 'l' && IFN[Len-1] == 'l'))) { |
- outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/ |
- } else { |
- outputFilename = IFN; |
- } |
- return outputFilename; |
-} |
- |
-static tool_output_file *GetOutputStream(const char *TargetName, |
- Triple::OSType OS, |
- std::string Filename) { |
+static std::unique_ptr<tool_output_file> |
+GetOutputStream(const char *TargetName, |
+ Triple::OSType OS, |
+ std::string OutputFilename) { |
// If we don't yet have an output filename, make one. |
- if (Filename.empty()) { |
+ if (OutputFilename.empty()) { |
if (InputFilename == "-") |
- Filename = "-"; |
+ OutputFilename = "-"; |
else { |
- Filename = GetFileNameRoot(InputFilename); |
+ // If InputFilename ends in .bc or .ll, remove it. |
+ StringRef IFN = InputFilename; |
+ if (IFN.endswith(".bc") || IFN.endswith(".ll")) |
+ OutputFilename = IFN.drop_back(3); |
+ else |
+ OutputFilename = IFN; |
switch (FileType) { |
case TargetMachine::CGFT_AssemblyFile: |
if (TargetName[0] == 'c') { |
if (TargetName[1] == 0) |
- Filename += ".cbe.c"; |
+ OutputFilename += ".cbe.c"; |
else if (TargetName[1] == 'p' && TargetName[2] == 'p') |
- Filename += ".cpp"; |
+ OutputFilename += ".cpp"; |
else |
- Filename += ".s"; |
+ OutputFilename += ".s"; |
} else |
- Filename += ".s"; |
+ OutputFilename += ".s"; |
break; |
case TargetMachine::CGFT_ObjectFile: |
if (OS == Triple::Win32) |
- Filename += ".obj"; |
+ OutputFilename += ".obj"; |
else |
- Filename += ".o"; |
+ OutputFilename += ".o"; |
break; |
case TargetMachine::CGFT_Null: |
- Filename += ".null"; |
+ OutputFilename += ".null"; |
break; |
} |
} |
@@ -229,10 +221,10 @@ static tool_output_file *GetOutputStream(const char *TargetName, |
sys::fs::OpenFlags OpenFlags = sys::fs::F_None; |
if (!Binary) |
OpenFlags |= sys::fs::F_Text; |
- tool_output_file *FDOut = new tool_output_file(Filename, EC, OpenFlags); |
+ auto FDOut = llvm::make_unique<tool_output_file>(OutputFilename, EC, |
+ OpenFlags); |
if (EC) { |
errs() << EC.message() << '\n'; |
- delete FDOut; |
return nullptr; |
} |
@@ -327,17 +319,22 @@ static std::unique_ptr<Module> getModule( |
if (LazyBitcode) { |
std::string StrError; |
switch (InputFileFormat) { |
- case PNaClFormat: |
+ case PNaClFormat: { |
+ std::unique_ptr<StreamingMemoryObject> Cache( |
+ new ThreadedStreamingCache(StreamingObject)); |
M.reset(getNaClStreamedBitcodeModule( |
- InputFilename, |
- new ThreadedStreamingCache(StreamingObject), Context, &VerboseStrm, |
- &StrError)); |
+ InputFilename, Cache.release(), Context, &VerboseStrm, &StrError)); |
break; |
- case LLVMFormat: |
- M.reset(getStreamedBitcodeModule( |
- InputFilename, |
- new ThreadedStreamingCache(StreamingObject), Context, &StrError)); |
+ } |
+ case LLVMFormat: { |
+ std::unique_ptr<StreamingMemoryObject> Cache( |
+ new ThreadedStreamingCache(StreamingObject)); |
+ ErrorOr<std::unique_ptr<Module>> MOrErr = |
+ getStreamedBitcodeModule( |
+ InputFilename, Cache.release(), Context); |
+ M = std::move(*MOrErr); |
break; |
+ } |
case AutodetectFileFormat: |
report_fatal_error("Command can't autodetect file format!"); |
} |
@@ -377,7 +374,7 @@ static int runCompilePasses(Module *ModuleRef, |
const Triple &TheTriple, |
TargetMachine &Target, |
StringRef ProgramName, |
- formatted_raw_ostream &FOS){ |
+ raw_pwrite_stream &OS){ |
PNaClABIErrorReporter ABIErrorReporter; |
if (SplitModuleCount > 1 || ExternalizeAll) { |
@@ -430,12 +427,12 @@ static int runCompilePasses(Module *ModuleRef, |
// Build up all of the passes that we want to do to the module. |
// We always use a FunctionPassManager to divide up the functions |
// among threads (instead of a whole-module PassManager). |
- std::unique_ptr<FunctionPassManager> PM(new FunctionPassManager(ModuleRef)); |
+ std::unique_ptr<legacy::FunctionPassManager> PM( |
+ new legacy::FunctionPassManager(ModuleRef)); |
// Add the target data from the target machine, if it exists, or the module. |
- if (const DataLayout *DL = Target.getSubtargetImpl()->getDataLayout()) |
- ModuleRef->setDataLayout(DL); |
- PM->add(new DataLayoutPass()); |
+ if (const DataLayout *DL = Target.getDataLayout()) |
+ ModuleRef->setDataLayout(*DL); |
// For conformance with llc, we let the user disable LLVM IR verification with |
// -disable-verify. Unlike llc, when LLVM IR verification is enabled we only |
@@ -451,22 +448,21 @@ static int runCompilePasses(Module *ModuleRef, |
PM->add(createResolvePNaClIntrinsicsPass()); |
// Add an appropriate TargetLibraryInfo pass for the module's triple. |
- TargetLibraryInfo *TLI = new TargetLibraryInfo(TheTriple); |
+ TargetLibraryInfoImpl TLII(TheTriple); |
+ |
+ // The -disable-simplify-libcalls flag actually disables all builtin optzns. |
if (DisableSimplifyLibCalls) |
- TLI->disableAllFunctions(); |
- PM->add(TLI); |
+ TLII.disableAllFunctions(); |
+ PM->add(new TargetLibraryInfoWrapperPass(TLII)); |
// Allow subsequent passes and the backend to better optimize instructions |
// that were simplified for PNaCl's ABI. This pass uses the TargetLibraryInfo |
// above. |
PM->add(createBackendCanonicalizePass()); |
- // Add internal analysis passes from the target machine. |
- Target.addAnalysisPasses(*PM); |
- |
// Ask the target to add backend passes as necessary. We explicitly ask it |
// not to add the verifier pass because we added it earlier. |
- if (Target.addPassesToEmitFile(*PM, FOS, FileType, |
+ if (Target.addPassesToEmitFile(*PM, OS, FileType, |
/* DisableVerify */ true)) { |
errs() << ProgramName |
<< ": target does not support generation of this file type!\n"; |
@@ -540,8 +536,6 @@ static int compileSplitModule(const TargetOptions &Options, |
RelocModel, CMModel, OLvl)); |
assert(target.get() && "Could not allocate target machine!"); |
TargetMachine &Target = *target.get(); |
- // Override default to generate verbose assembly. |
- Target.setAsmVerbosityDefault(true); |
if (RelaxAll.getNumOccurrences() > 0 && |
FileType != TargetMachine::CGFT_ObjectFile) |
errs() << ProgramName |
@@ -576,28 +570,33 @@ static int compileSplitModule(const TargetOptions &Options, |
{ |
#if !defined(PNACL_BROWSER_TRANSLATOR) |
// Figure out where we are going to send the output. |
- std::string N(OutputFilename); |
+ std::string N(MainOutputFilename); |
raw_string_ostream OutFileName(N); |
if (ModuleIndex > 0) |
OutFileName << ".module" << ModuleIndex; |
- std::unique_ptr<tool_output_file> Out |
- (GetOutputStream(TheTarget->getName(), TheTriple.getOS(), |
- OutFileName.str())); |
+ std::unique_ptr<tool_output_file> Out = |
+ GetOutputStream(TheTarget->getName(), TheTriple.getOS(), |
+ OutFileName.str()); |
if (!Out) return 1; |
- formatted_raw_ostream FOS(Out->os()); |
+ raw_pwrite_stream *OS = &Out->os(); |
+ std::unique_ptr<buffer_ostream> BOS; |
+ if (FileType != TargetMachine::CGFT_AssemblyFile && |
+ !Out->os().supportsSeeking()) { |
+ BOS = make_unique<buffer_ostream>(*OS); |
+ OS = BOS.get(); |
+ } |
#else |
- raw_fd_ostream ROS(getObjectFileFD(ModuleIndex), /* ShouldClose */ true); |
- ROS.SetBufferSize(1 << 20); |
- formatted_raw_ostream FOS(ROS); |
+ auto OS = llvm::make_unique<raw_fd_ostream>( |
+ getObjectFileFD(ModuleIndex), /* ShouldClose */ true); |
+ OS->SetBufferSize(1 << 20); |
#endif |
int ret = runCompilePasses(ModuleRef, ModuleIndex, FuncQueue, |
TheTriple, Target, ProgramName, |
- FOS); |
+ *OS); |
if (ret) |
return ret; |
#if defined(PNACL_BROWSER_TRANSLATOR) |
- FOS.flush(); |
- ROS.flush(); |
+ OS->flush(); |
#else |
// Declare success. |
Out->keep(); |
@@ -705,6 +704,7 @@ static int compileModule(StringRef ProgramName) { |
TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); |
Options.DisableIntegratedAS = NoIntegratedAssembler; |
+ Options.MCOptions.AsmVerbose = true; |
if (GenerateSoftFloatCalls) |
FloatABIForCalls = FloatABI::Soft; |