Index: tools/llc/llc.cpp |
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp |
index fdc6fec98455e7b954b50293b286ab87dade8f99..306b1420b414b5a2478366580248bd723af42812 100644 |
--- a/tools/llc/llc.cpp |
+++ b/tools/llc/llc.cpp |
@@ -18,6 +18,7 @@ |
#include "llvm/PassManager.h" |
#include "llvm/Pass.h" |
#include "llvm/ADT/Triple.h" |
+#include "llvm/Support/BitcodeStream.h" |
#include "llvm/Support/IRReader.h" |
#include "llvm/CodeGen/LinkAllAsmWriterComponents.h" |
#include "llvm/CodeGen/LinkAllCodegenComponents.h" |
@@ -141,6 +142,16 @@ DisableRedZone("disable-red-zone", |
cl::desc("Do not emit code that uses the red zone."), |
cl::init(false)); |
+// Using bitcode streaming has a couple of ramifications. Primarily it means |
+// that the module in the file will be compiled one function at a time rather |
+// than the whole module. This allows earlier functions to be compiled before |
+// later functions are read from the bitcode but of course means no whole-module |
+// optimizations. For now, streaming is only supported for files and stdin. |
+static cl::opt<bool> |
+LazyBitcode("streaming-bitcode", |
+ cl::desc("Use lazy bitcode streaming for file inputs"), |
+ cl::init(false)); |
+ |
// GetFileNameRoot - Helper function to get the basename of a filename. |
static inline std::string |
GetFileNameRoot(const std::string &InputFilename) { |
@@ -248,7 +259,19 @@ int main(int argc, char **argv) { |
SMDiagnostic Err; |
std::auto_ptr<Module> M; |
- M.reset(ParseIRFile(InputFilename, Err, Context)); |
+ if (LazyBitcode) { |
+ std::string StrError; |
+ BitcodeStreamer *streamer = getBitcodeFileStreamer(InputFilename,&StrError); |
+ if (streamer) { |
+ M.reset(getStreamedBitcodeModule(InputFilename, streamer, Context, |
+ &StrError)); |
+ } |
+ if (!StrError.empty()) { |
+ Err = SMDiagnostic(InputFilename, SourceMgr::DK_Error, StrError); |
+ } |
+ } else { |
+ M.reset(ParseIRFile(InputFilename, Err, Context)); |
+ } |
if (M.get() == 0) { |
Err.print(argv[0], errs()); |
return 1; |
@@ -345,13 +368,18 @@ int main(int argc, char **argv) { |
if (!Out) return 1; |
// Build up all of the passes that we want to do to the module. |
- PassManager PM; |
+ OwningPtr<PassManagerBase> PM; |
+ if (LazyBitcode) |
+ PM.reset(new FunctionPassManager(&mod)); |
+ else |
+ PM.reset(new PassManager()); |
+ |
// Add the target data from the target machine, if it exists, or the module. |
if (const TargetData *TD = Target.getTargetData()) |
- PM.add(new TargetData(*TD)); |
+ PM->add(new TargetData(*TD)); |
else |
- PM.add(new TargetData(&mod)); |
+ PM->add(new TargetData(&mod)); |
// Override default to generate verbose assembly. |
Target.setAsmVerbosityDefault(true); |
@@ -368,7 +396,7 @@ int main(int argc, char **argv) { |
formatted_raw_ostream FOS(Out->os()); |
// Ask the target to add backend passes as necessary. |
- if (Target.addPassesToEmitFile(PM, FOS, FileType, NoVerify)) { |
+ if (Target.addPassesToEmitFile(*PM, FOS, FileType, NoVerify)) { |
errs() << argv[0] << ": target does not support generation of this" |
<< " file type!\n"; |
return 1; |
@@ -377,7 +405,16 @@ int main(int argc, char **argv) { |
// Before executing passes, print the final values of the LLVM options. |
cl::PrintOptionValues(); |
- PM.run(mod); |
+ if (LazyBitcode) { |
+ FunctionPassManager *P = static_cast<FunctionPassManager*>(PM.get()); |
+ P->doInitialization(); |
+ for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I) { |
+ P->run(*I); |
+ } |
+ P->doFinalization(); |
+ } else { |
+ static_cast<PassManager*>(PM.get())->run(mod); |
+ } |
} |
// Declare success. |