From 2e2f2dcd6af454a26838457dbfd61ceca7cef41b Mon Sep 17 00:00:00 2001 From: Brian Gaeke Date: Wed, 18 Jun 2003 21:14:23 +0000 Subject: [PATCH] lib/Target/Sparc/Sparc.cpp: Move LowerAllocations, PrintFunction, and SymbolStripping passes, and the corresponding -disable-strip and -d options, over here to the SPARC target-specific bits of llc. Rename -d to -dump-asm. tools/llc/Makefile: Reindent. Add x86 library so that llc compiles again. tools/llc/llc.cpp: Remove support for running arbitrary optimization passes. Use opt instead. Remove LowerAllocations, PrintFunction, and SymbolStripping passes, as noted above. Allow user to select a backend (x86 or SPARC); default to guessing from the endianness/pointer size of the input bytecode file. Fix typos. Delete empty .s file and exit with error status if target does not support static compilation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6776 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/SparcV9/SparcV9TargetMachine.cpp | 23 ++++- tools/llc/Makefile | 5 +- tools/llc/llc.cpp | 107 +++++++++----------- 3 files changed, 72 insertions(+), 63 deletions(-) diff --git a/lib/Target/SparcV9/SparcV9TargetMachine.cpp b/lib/Target/SparcV9/SparcV9TargetMachine.cpp index 8304712bb97..f389f93580e 100644 --- a/lib/Target/SparcV9/SparcV9TargetMachine.cpp +++ b/lib/Target/SparcV9/SparcV9TargetMachine.cpp @@ -21,6 +21,7 @@ #include "llvm/CodeGen/MachineCodeForInstruction.h" #include "llvm/Reoptimizer/Mapping/MappingInfo.h" #include "Support/CommandLine.h" +#include "llvm/Assembly/PrintModulePass.h" static const unsigned ImplicitRegUseList[] = { 0 }; /* not used yet */ // Build the MachineInstruction Description Array... @@ -46,6 +47,14 @@ static cl::opt DisableSched("nosched", static cl::opt DisablePeephole("nopeephole", cl::desc("Disable peephole optimization pass")); +static cl::opt +DisableStrip("disable-strip", + cl::desc("Do not strip the LLVM bytecode included in the executable")); + +static cl::opt +DumpAsm("dump-asm", cl::desc("Print bytecode before native code generation"), + cl::Hidden); + //---------------------------------------------------------------------------- // allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine // that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface) @@ -141,9 +150,21 @@ UltraSparc::UltraSparc() // bool UltraSparc::addPassesToEmitAssembly(PassManager &PM, std::ostream &Out) { + // The following 3 passes used to be inserted specially by llc. + // Replace malloc and free instructions with library calls. + PM.add(createLowerAllocationsPass()); + + // If LLVM dumping after transformations is requested, add it to the pipeline + if (DumpAsm) + PM.add(new PrintFunctionPass("Code after xformations: \n", &std::cerr)); + + // Strip all of the symbols from the bytecode so that it will be smaller... + if (!DisableStrip) + PM.add(createSymbolStrippingPass()); + // FIXME: implement the switch instruction in the instruction selector. PM.add(createLowerSwitchPass()); - + // Construct and initialize the MachineFunction object for this fn. PM.add(createMachineCodeConstructionPass(*this)); diff --git a/tools/llc/Makefile b/tools/llc/Makefile index 16156f110b5..fcce5119ded 100644 --- a/tools/llc/Makefile +++ b/tools/llc/Makefile @@ -2,6 +2,7 @@ LEVEL = ../.. TOOLNAME = llc USEDLIBS = mapping \ sparc \ + x86 \ regalloc \ sched \ select \ @@ -11,11 +12,11 @@ USEDLIBS = mapping \ target.a \ livevar \ transforms.a \ - scalaropts.a \ + scalaropts.a \ analysis.a \ transformutils.a \ bcreader \ - bcwriter \ + bcwriter \ vmcore \ support TOOLLINKOPTS = $(PLATFORMLIBDL) diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index 3bd35f1f746..636779f56d4 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -8,31 +8,19 @@ #include "llvm/Target/TargetMachineImpls.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/Scalar.h" -#include "llvm/Assembly/PrintModulePass.h" #include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/Pass.h" -#include "llvm/Support/PassNameParser.h" #include "Support/CommandLine.h" #include "Support/Signals.h" #include #include +#include //------------------------------------------------------------------------------ // Option declarations for LLC. //------------------------------------------------------------------------------ -// Make all registered optimization passes available to llc. These passes -// will all be run before the simplification and lowering steps used by the -// back-end code generator, and will be run in the order specified on the -// command line. The OptimizationList is automatically populated with -// registered Passes by the PassNameParser. -// -static cl::list > -OptimizationList(cl::desc("Optimizations available:")); - - // General options for llc. Other pass-specific options are specified // within the corresponding llc passes, and target-specific options // and back-end code generation options are specified with the target machine. @@ -45,13 +33,14 @@ OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename")); static cl::opt Force("f", cl::desc("Overwrite output files")); -static cl::opt -DisableStrip("disable-strip", - cl::desc("Do not strip the LLVM bytecode included in the executable")); +enum ArchName { noarch, x86, Sparc }; -static cl::opt -DumpAsm("d", cl::desc("Print bytecode before native code generation"), - cl::Hidden); +static cl::opt +Arch("march", cl::desc("Architecture to generate assembly for:"), cl::Prefix, + cl::values(clEnumVal(x86, " IA-32 (Pentium and above)"), + clEnumValN(Sparc, "sparc", " SPARC V9"), + 0), + cl::init(noarch)); // GetFileNameRoot - Helper function to get the basename of a filename... static inline std::string @@ -80,14 +69,6 @@ main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n"); - // Allocate a target... in the future this will be controllable on the - // command line. - std::auto_ptr target(allocateSparcTargetMachine()); - assert(target.get() && "Could not allocate target machine!"); - - TargetMachine &Target = *target.get(); - const TargetData &TD = Target.getTargetData(); - // Load the module to be compiled... std::auto_ptr M(ParseBytecodeFile(InputFilename)); if (M.get() == 0) @@ -95,6 +76,38 @@ main(int argc, char **argv) std::cerr << argv[0] << ": bytecode didn't read correctly.\n"; return 1; } + Module &mod = *M.get(); + + // Allocate target machine. First, check whether the user has + // explicitly specified an architecture to compile for. + unsigned Config = (mod.isLittleEndian() ? TM::LittleEndian : TM::BigEndian) | + (mod.has32BitPointers() ? TM::PtrSize32 : TM::PtrSize64); + TargetMachine* (*TargetMachineAllocator)(unsigned) = 0; + switch (Arch) { + case x86: + TargetMachineAllocator = allocateX86TargetMachine; + break; + case Sparc: + TargetMachineAllocator = allocateSparcTargetMachine; + break; + default: + // Decide what the default target machine should be, by looking at + // the module. This heuristic (ILP32, LE -> IA32; LP64, BE -> + // SPARCV9) is kind of gross, but it will work until we have more + // sophisticated target information to work from. + if (mod.isLittleEndian() && mod.has32BitPointers()) { + TargetMachineAllocator = allocateX86TargetMachine; + } else if (mod.isBigEndian() && mod.has64BitPointers()) { + TargetMachineAllocator = allocateSparcTargetMachine; + } else { + assert(0 && "You must specify -march; I could not guess the default"); + } + break; + } + std::auto_ptr target((*TargetMachineAllocator)(Config)); + assert(target.get() && "Could not allocate target machine!"); + TargetMachine &Target = *target.get(); + const TargetData &TD = Target.getTargetData(); // Build up all of the passes that we want to do to the module... PassManager Passes; @@ -102,36 +115,6 @@ main(int argc, char **argv) Passes.add(new TargetData("llc", TD.isLittleEndian(), TD.getPointerSize(), TD.getPointerAlignment(), TD.getDoubleAlignment())); - // Create a new optimization pass for each one specified on the command line - // Deal specially with tracing passes, which must be run differently than opt. - // - for (unsigned i = 0; i < OptimizationList.size(); ++i) { - const PassInfo *Opt = OptimizationList[i]; - - // handle other passes as normal optimization passes - if (Opt->getNormalCtor()) - Passes.add(Opt->getNormalCtor()()); - else if (Opt->getTargetCtor()) - Passes.add(Opt->getTargetCtor()(Target)); - else - std::cerr << argv[0] << ": cannot create pass: " - << Opt->getPassName() << "\n"; - } - - // Replace malloc and free instructions with library calls. - // Do this after tracing until lli implements these lib calls. - // For now, it will emulate malloc and free internally. - // FIXME: This is sparc specific! - Passes.add(createLowerAllocationsPass()); - - // If LLVM dumping after transformations is requested, add it to the pipeline - if (DumpAsm) - Passes.add(new PrintFunctionPass("Code after xformations: \n", &std::cerr)); - - // Strip all of the symbols from the bytecode so that it will be smaller... - if (!DisableStrip) - Passes.add(createSymbolStrippingPass()); - // Figure out where we are going to send the output... std::ostream *Out = 0; if (OutputFilename != "") { @@ -153,7 +136,7 @@ main(int argc, char **argv) OutputFilename = "-"; Out = &std::cout; } else { - std::string OutputFilename = GetFileNameRoot(InputFilename); + OutputFilename = GetFileNameRoot(InputFilename); OutputFilename += ".s"; if (!Force && std::ifstream(OutputFilename.c_str())) { @@ -177,10 +160,14 @@ main(int argc, char **argv) } } - // Ask the target to add backend passes as neccesary + // Ask the target to add backend passes as necessary if (Target.addPassesToEmitAssembly(Passes, *Out)) { std::cerr << argv[0] << ": target '" << Target.getName() - << " does not support static compilation!\n"; + << "' does not support static compilation!\n"; + if (Out != &std::cout) delete Out; + // And the Out file is empty and useless, so remove it now. + std::remove(OutputFilename.c_str()); + return 1; } else { // Run our queue of passes all at once now, efficiently. Passes.run(*M.get());