lib/Target/Sparc/Sparc.cpp:
authorBrian Gaeke <gaeke@uiuc.edu>
Wed, 18 Jun 2003 21:14:23 +0000 (21:14 +0000)
committerBrian Gaeke <gaeke@uiuc.edu>
Wed, 18 Jun 2003 21:14:23 +0000 (21:14 +0000)
 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
tools/llc/Makefile
tools/llc/llc.cpp

index 8304712bb97f0464dee85d3916f48b41d9f96405..f389f93580e3c82c769ac7d3ac3aaae2507e56cc 100644 (file)
@@ -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<bool> DisableSched("nosched",
 static cl::opt<bool> DisablePeephole("nopeephole",
                                 cl::desc("Disable peephole optimization pass"));
 
+static cl::opt<bool>
+DisableStrip("disable-strip",
+         cl::desc("Do not strip the LLVM bytecode included in the executable"));
+
+static cl::opt<bool>
+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));
 
index 16156f110b5c4897390fc5fd73d579d2fcc4e941..fcce5119ded36de93c583246abf1e67b3e12c7a6 100644 (file)
@@ -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)
index 3bd35f1f746041ad156344dc694ed25c93ec02ab..636779f56d44bbc6d4562f1cb97365ed070458ca 100644 (file)
@@ -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 <memory>
 #include <fstream>
+#include <cstdio>
 
 //------------------------------------------------------------------------------
 // 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<const PassInfo*, bool,
-                FilteredPassNameParser<PassInfo::Optimization> >
-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<bool> Force("f", cl::desc("Overwrite output files"));
 
-static cl::opt<bool>
-DisableStrip("disable-strip",
-          cl::desc("Do not strip the LLVM bytecode included in the executable"));
+enum ArchName { noarch, x86, Sparc };
 
-static cl::opt<bool>
-DumpAsm("d", cl::desc("Print bytecode before native code generation"),
-        cl::Hidden);
+static cl::opt<ArchName>
+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<TargetMachine> 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<Module> 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<TargetMachine> 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());