diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index af6591e7f74..63e28ac30ab 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -199,8 +199,7 @@ public: enum CodeGenFileType { CGFT_AssemblyFile, CGFT_ObjectFile, - CGFT_DynamicLibrary, - CGFT_ErrorOccurred + CGFT_Null // Do not emit any output. }; /// getEnableTailMergeDefault - the default setting for -enable-tail-merge @@ -209,15 +208,13 @@ public: /// addPassesToEmitFile - Add passes to the specified pass manager to get the /// specified file emitted. Typically this will involve several steps of code - /// generation. - /// This method should return InvalidFile if emission of this file type - /// is not supported. - /// - virtual CodeGenFileType addPassesToEmitFile(PassManagerBase &, - formatted_raw_ostream &, - CodeGenFileType Filetype, - CodeGenOpt::Level) { - return CGFT_ErrorOccurred; + /// generation. This method should return true if emission of this file type + /// is not supported, or false on success. + virtual bool addPassesToEmitFile(PassManagerBase &, + formatted_raw_ostream &, + CodeGenFileType Filetype, + CodeGenOpt::Level) { + return true; } /// addPassesToEmitMachineCode - Add passes to the specified pass manager to @@ -264,18 +261,11 @@ public: /// addPassesToEmitFile - Add passes to the specified pass manager to get the /// specified file emitted. Typically this will involve several steps of code /// generation. If OptLevel is None, the code generator should emit code as - /// fast as possible, though the generated code may be less efficient. This - /// method should return CGFT_ErrorOccurred if emission of this file type is - /// not supported. - /// - /// The default implementation of this method adds components from the - /// LLVM retargetable code generator, invoking the methods below to get - /// target-specific passes in standard locations. - /// - virtual CodeGenFileType addPassesToEmitFile(PassManagerBase &PM, - formatted_raw_ostream &Out, - CodeGenFileType FileType, - CodeGenOpt::Level); + /// fast as possible, though the generated code may be less efficient. + virtual bool addPassesToEmitFile(PassManagerBase &PM, + formatted_raw_ostream &Out, + CodeGenFileType FileType, + CodeGenOpt::Level); /// addPassesToEmitMachineCode - Add passes to the specified pass manager to /// get machine code emitted. This uses a JITCodeEmitter object to handle diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp index 2083c0a7cfe..c03e4290cab 100644 --- a/lib/CodeGen/LLVMTargetMachine.cpp +++ b/lib/CodeGen/LLVMTargetMachine.cpp @@ -111,21 +111,20 @@ LLVMTargetMachine::setCodeModelForStatic() { setCodeModel(CodeModel::Small); } -TargetMachine::CodeGenFileType -LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, - formatted_raw_ostream &Out, - CodeGenFileType FileType, - CodeGenOpt::Level OptLevel) { +bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, + formatted_raw_ostream &Out, + CodeGenFileType FileType, + CodeGenOpt::Level OptLevel) { // Add common CodeGen passes. if (addCommonCodeGenPasses(PM, OptLevel)) - return CGFT_ErrorOccurred; + return true; OwningPtr Context(new MCContext()); OwningPtr AsmStreamer; formatted_raw_ostream *LegacyOutput; switch (FileType) { - default: return CGFT_ErrorOccurred; + default: return true; case CGFT_AssemblyFile: { const MCAsmInfo &MAI = *getMCAsmInfo(); MCInstPrinter *InstPrinter = @@ -143,7 +142,7 @@ LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, // emission fails. MCCodeEmitter *MCE = getTarget().createCodeEmitter(*this); if (MCE == 0) - return CGFT_ErrorOccurred; + return true; AsmStreamer.reset(createMachOStreamer(*Context, Out, MCE)); @@ -154,6 +153,16 @@ LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, LegacyOutput = new formatted_raw_ostream(errs()); break; } + case CGFT_Null: + // The Null output is intended for use for performance analysis and testing, + // not real users. + AsmStreamer.reset(createNullStreamer(*Context)); + // Any output to the asmprinter's "O" stream is bad and needs to be fixed, + // force it to come out stderr. + // FIXME: this is horrible and leaks, eventually remove the raw_ostream from + // asmprinter. + LegacyOutput = new formatted_raw_ostream(errs()); + break; } // Create the AsmPrinter, which takes ownership of Context and AsmStreamer @@ -162,7 +171,7 @@ LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, getTarget().createAsmPrinter(*LegacyOutput, *this, *Context, *AsmStreamer, getMCAsmInfo()); if (Printer == 0) - return CGFT_ErrorOccurred; + return true; // If successful, createAsmPrinter took ownership of AsmStreamer and Context. Context.take(); AsmStreamer.take(); @@ -172,7 +181,7 @@ LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, // Make sure the code model is set. setCodeModelForStatic(); PM.add(createGCInfoDeleter()); - return FileType; + return false; } /// addPassesToEmitMachineCode - Add passes to the specified pass manager to diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index c7bd1c67067..fe34bd128ea 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -91,9 +91,8 @@ FileType("filetype", cl::init(TargetMachine::CGFT_AssemblyFile), "Emit an assembly ('.s') file"), clEnumValN(TargetMachine::CGFT_ObjectFile, "obj", "Emit a native object ('.o') file [experimental]"), - clEnumValN(TargetMachine::CGFT_DynamicLibrary, "dynlib", - "Emit a native dynamic library ('.so') file" - " [experimental]"), + clEnumValN(TargetMachine::CGFT_Null, "null", + "Emit nothing, for performance testing"), clEnumValEnd)); cl::opt NoVerify("disable-verify", cl::Hidden, @@ -177,8 +176,8 @@ static formatted_raw_ostream *GetOutputStream(const char *TargetName, OutputFilename += ".o"; Binary = true; break; - case TargetMachine::CGFT_DynamicLibrary: - OutputFilename += LTDL_SHLIB_EXT; + case TargetMachine::CGFT_Null: + OutputFilename += ".null"; Binary = true; break; } @@ -348,20 +347,13 @@ int main(int argc, char **argv) { // Override default to generate verbose assembly. Target.setAsmVerbosityDefault(true); - switch (Target.addPassesToEmitFile(Passes, *Out, FileType, OLvl)) { - default: - assert(0 && "Invalid file model!"); - return 1; - case TargetMachine::CGFT_ErrorOccurred: + if (Target.addPassesToEmitFile(Passes, *Out, FileType, OLvl)) { errs() << argv[0] << ": target does not support generation of this" << " file type!\n"; if (Out != &fouts()) delete Out; // And the Out file is empty and useless, so remove it now. sys::Path(OutputFilename).eraseFromDisk(); return 1; - case TargetMachine::CGFT_AssemblyFile: - case TargetMachine::CGFT_ObjectFile: - break; } Passes.doInitialization(); diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index 7e873abb139..0a58aa7e898 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -393,14 +393,11 @@ bool LTOCodeGenerator::generateAssemblyCode(formatted_raw_ostream& out, codeGenPasses->add(new TargetData(*_target->getTargetData())); - switch (_target->addPassesToEmitFile(*codeGenPasses, out, - TargetMachine::CGFT_AssemblyFile, - CodeGenOpt::Aggressive)) { - case TargetMachine::CGFT_AssemblyFile: - break; - default: - errMsg = "target file type not supported"; - return true; + if (_target->addPassesToEmitFile(*codeGenPasses, out, + TargetMachine::CGFT_AssemblyFile, + CodeGenOpt::Aggressive)) { + errMsg = "target file type not supported"; + return true; } // Run our queue of passes all at once now, efficiently.