Convert backend to use passes, implement X86TargetMachine


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4421 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp
index 4491fdf..4659bea 100644
--- a/lib/Target/X86/InstSelectSimple.cpp
+++ b/lib/Target/X86/InstSelectSimple.cpp
@@ -10,28 +10,32 @@
 #include "llvm/iTerminators.h"
 #include "llvm/Type.h"
 #include "llvm/Constants.h"
+#include "llvm/Pass.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/Support/InstVisitor.h"
 #include <map>
 
 namespace {
-  struct ISel : public InstVisitor<ISel> { // eventually will be a FunctionPass
+  struct ISel : public FunctionPass, InstVisitor<ISel> {
+    TargetMachine &TM;
     MachineFunction *F;                    // The function we are compiling into
     MachineBasicBlock *BB;                 // The current MBB we are compiling
 
     unsigned CurReg;
     std::map<Value*, unsigned> RegMap;  // Mapping between Val's and SSA Regs
 
-    ISel(MachineFunction *f)
-      : F(f), BB(0), CurReg(MRegisterInfo::FirstVirtualRegister) {}
+    ISel(TargetMachine &tm)
+      : TM(tm), F(0), BB(0), CurReg(MRegisterInfo::FirstVirtualRegister) {}
 
     /// runOnFunction - Top level implementation of instruction selection for
     /// the entire function.
     ///
-    bool runOnFunction(Function &F) {
-      visit(F);
+    bool runOnFunction(Function &Fn) {
+      F = new MachineFunction(&Fn, TM);
+      visit(Fn);
       RegMap.clear();
+      F = 0;
       return false;  // We never modify the LLVM itself.
     }
 
@@ -161,14 +165,10 @@
   }
 }
 
-
-
-/// X86SimpleInstructionSelection - This function converts an LLVM function into
-/// a machine code representation is a very simple peep-hole fashion.  The
+/// createSimpleX86InstructionSelector - This pass converts an LLVM function
+/// into a machine code representation is a very simple peep-hole fashion.  The
 /// generated code sucks but the implementation is nice and simple.
 ///
-MachineFunction *X86SimpleInstructionSelection(Function &F, TargetMachine &TM) {
-  MachineFunction *Result = new MachineFunction(&F, TM);
-  ISel(Result).runOnFunction(F);
-  return Result;
+Pass *createSimpleX86InstructionSelector(TargetMachine &TM) {
+  return new ISel(TM);
 }
diff --git a/lib/Target/X86/Printer.cpp b/lib/Target/X86/Printer.cpp
index 1a42ed8..b320e2c 100644
--- a/lib/Target/X86/Printer.cpp
+++ b/lib/Target/X86/Printer.cpp
@@ -6,16 +6,37 @@
 //===----------------------------------------------------------------------===//
 
 #include "X86.h"
+#include "llvm/Pass.h"
+#include "llvm/CodeGen/MachineFunction.h"
 #include <iostream>
 
-/// X86PrintCode - Print out the specified machine code function to the
-/// specified stream.  This function should work regardless of whether or not
-/// the function is in SSA form or not, although when in SSA form, we obviously
-/// don't care about being consumable by an assembler.
-///
-void X86PrintCode(const MachineFunction *MF, std::ostream &O) {
-  O << "x86 printing not implemented yet!\n";
+namespace {
+  struct Printer : public FunctionPass {
+    TargetMachine &TM;
+    std::ostream &O;
 
-  // This should use the X86InstructionInfo::print method to print assembly for
-  // each instruction
+    Printer(TargetMachine &tm, std::ostream &o) : TM(tm), O(o) {}
+
+    bool runOnFunction(Function &F);
+  };
+}
+
+bool Printer::runOnFunction(Function &F) {
+  MachineFunction &MF = MachineFunction::get(&F);
+  O << "x86 printing not implemented yet!\n";
+  
+  // This should use the X86InstructionInfo::print method to print assembly
+  // for each instruction
+  return false;
+}
+
+
+
+
+/// createX86CodePrinterPass - Print out the specified machine code function to
+/// the specified stream.  This function should work regardless of whether or
+/// not the function is in SSA form or not.
+///
+Pass *createX86CodePrinterPass(TargetMachine &TM, std::ostream &O) {
+  return new Printer(TM, O);
 }
diff --git a/lib/Target/X86/X86.h b/lib/Target/X86/X86.h
index 5c5133e..d94ec28 100644
--- a/lib/Target/X86/X86.h
+++ b/lib/Target/X86/X86.h
@@ -11,34 +11,32 @@
 #define TARGET_X86_H
 
 #include <iosfwd>
-class MachineFunction;
-class Function;
 class TargetMachine;
+class Pass;
 
-/// X86PrintCode - Print out the specified machine code function to the
-/// specified stream.  This function should work regardless of whether or not
-/// the function is in SSA form or not.
-///
-void X86PrintCode(const MachineFunction *MF, std::ostream &O);
-
-/// X86SimpleInstructionSelection - This function converts an LLVM function into
-/// a machine code representation is a very simple peep-hole fashion.  The
+/// createSimpleX86InstructionSelector - This pass converts an LLVM function
+/// into a machine code representation is a very simple peep-hole fashion.  The
 /// generated code sucks but the implementation is nice and simple.
 ///
-MachineFunction *X86SimpleInstructionSelection(Function &F, TargetMachine &TM);
+Pass *createSimpleX86InstructionSelector(TargetMachine &TM);
 
 /// X86SimpleRegisterAllocation - This function converts the specified machine
 /// code function from SSA form to use explicit registers by spilling every
 /// register.  Wow, great policy huh?
 ///
-inline void X86SimpleRegisterAllocation(MachineFunction *MF) {}
+Pass *createSimpleX86RegisterAllocator(TargetMachine &TM);
+
+/// createX86CodePrinterPass - Print out the specified machine code function to
+/// the specified stream.  This function should work regardless of whether or
+/// not the function is in SSA form or not.
+///
+Pass *createX86CodePrinterPass(TargetMachine &TM, std::ostream &O);
 
 /// X86EmitCodeToMemory - This function converts a register allocated function
 /// into raw machine code in a dynamically allocated chunk of memory.  A pointer
 /// to the start of the function is returned.
 ///
-inline void *X86EmitCodeToMemory(MachineFunction *MF) { return 0; }
-
+Pass *createEmitX86CodeToMemory(TargetMachine &TM);
 
 // Put symbolic names in a namespace to avoid causing these to clash with all
 // kinds of other things...
diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp
index 1a42ed8..b320e2c 100644
--- a/lib/Target/X86/X86AsmPrinter.cpp
+++ b/lib/Target/X86/X86AsmPrinter.cpp
@@ -6,16 +6,37 @@
 //===----------------------------------------------------------------------===//
 
 #include "X86.h"
+#include "llvm/Pass.h"
+#include "llvm/CodeGen/MachineFunction.h"
 #include <iostream>
 
-/// X86PrintCode - Print out the specified machine code function to the
-/// specified stream.  This function should work regardless of whether or not
-/// the function is in SSA form or not, although when in SSA form, we obviously
-/// don't care about being consumable by an assembler.
-///
-void X86PrintCode(const MachineFunction *MF, std::ostream &O) {
-  O << "x86 printing not implemented yet!\n";
+namespace {
+  struct Printer : public FunctionPass {
+    TargetMachine &TM;
+    std::ostream &O;
 
-  // This should use the X86InstructionInfo::print method to print assembly for
-  // each instruction
+    Printer(TargetMachine &tm, std::ostream &o) : TM(tm), O(o) {}
+
+    bool runOnFunction(Function &F);
+  };
+}
+
+bool Printer::runOnFunction(Function &F) {
+  MachineFunction &MF = MachineFunction::get(&F);
+  O << "x86 printing not implemented yet!\n";
+  
+  // This should use the X86InstructionInfo::print method to print assembly
+  // for each instruction
+  return false;
+}
+
+
+
+
+/// createX86CodePrinterPass - Print out the specified machine code function to
+/// the specified stream.  This function should work regardless of whether or
+/// not the function is in SSA form or not.
+///
+Pass *createX86CodePrinterPass(TargetMachine &TM, std::ostream &O) {
+  return new Printer(TM, O);
 }
diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp
index 4491fdf..4659bea 100644
--- a/lib/Target/X86/X86ISelSimple.cpp
+++ b/lib/Target/X86/X86ISelSimple.cpp
@@ -10,28 +10,32 @@
 #include "llvm/iTerminators.h"
 #include "llvm/Type.h"
 #include "llvm/Constants.h"
+#include "llvm/Pass.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/Support/InstVisitor.h"
 #include <map>
 
 namespace {
-  struct ISel : public InstVisitor<ISel> { // eventually will be a FunctionPass
+  struct ISel : public FunctionPass, InstVisitor<ISel> {
+    TargetMachine &TM;
     MachineFunction *F;                    // The function we are compiling into
     MachineBasicBlock *BB;                 // The current MBB we are compiling
 
     unsigned CurReg;
     std::map<Value*, unsigned> RegMap;  // Mapping between Val's and SSA Regs
 
-    ISel(MachineFunction *f)
-      : F(f), BB(0), CurReg(MRegisterInfo::FirstVirtualRegister) {}
+    ISel(TargetMachine &tm)
+      : TM(tm), F(0), BB(0), CurReg(MRegisterInfo::FirstVirtualRegister) {}
 
     /// runOnFunction - Top level implementation of instruction selection for
     /// the entire function.
     ///
-    bool runOnFunction(Function &F) {
-      visit(F);
+    bool runOnFunction(Function &Fn) {
+      F = new MachineFunction(&Fn, TM);
+      visit(Fn);
       RegMap.clear();
+      F = 0;
       return false;  // We never modify the LLVM itself.
     }
 
@@ -161,14 +165,10 @@
   }
 }
 
-
-
-/// X86SimpleInstructionSelection - This function converts an LLVM function into
-/// a machine code representation is a very simple peep-hole fashion.  The
+/// createSimpleX86InstructionSelector - This pass converts an LLVM function
+/// into a machine code representation is a very simple peep-hole fashion.  The
 /// generated code sucks but the implementation is nice and simple.
 ///
-MachineFunction *X86SimpleInstructionSelection(Function &F, TargetMachine &TM) {
-  MachineFunction *Result = new MachineFunction(&F, TM);
-  ISel(Result).runOnFunction(F);
-  return Result;
+Pass *createSimpleX86InstructionSelector(TargetMachine &TM) {
+  return new ISel(TM);
 }
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
new file mode 100644
index 0000000..4273daf
--- /dev/null
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -0,0 +1,43 @@
+//===-- X86TargetMachine.cpp - Define TargetMachine for the X86 -----------===//
+// 
+// This file defines the X86 specific subclass of TargetMachine.
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86TargetMachine.h"
+#include "llvm/Target/TargetMachineImpls.h"
+#include "llvm/PassManager.h"
+#include "X86.h"
+#include <iostream>
+
+// allocateX86TargetMachine - Allocate and return a subclass of TargetMachine
+// that implements the X86 backend.
+//
+TargetMachine *allocateX86TargetMachine() { return new X86TargetMachine(); }
+
+
+/// X86TargetMachine ctor - Create an ILP32 architecture model
+///
+X86TargetMachine::X86TargetMachine() : TargetMachine("X86", 1, 4, 4, 4) {
+}
+
+
+/// addPassesToJITCompile - Add passes to the specified pass manager to
+/// implement a fast dynamic compiler for this target.  Return true if this is
+/// not supported for this target.
+///
+bool X86TargetMachine::addPassesToJITCompile(PassManager &PM) {
+  PM.add(createSimpleX86InstructionSelector(*this));
+
+  // TODO: optional optimizations go here
+
+  // Perform register allocation to convert to a concrete x86 representation
+  //PM.add(createSimpleX86RegisterAllocator(*this));
+
+  PM.add(createX86CodePrinterPass(*this, std::cerr));
+
+  //PM.add(createEmitX86CodeToMemory(*this));
+
+  return false; // success!
+}
+
diff --git a/lib/Target/X86/X86TargetMachine.h b/lib/Target/X86/X86TargetMachine.h
new file mode 100644
index 0000000..863eb60
--- /dev/null
+++ b/lib/Target/X86/X86TargetMachine.h
@@ -0,0 +1,32 @@
+//===-- X86TargetMachine.h - Define TargetMachine for the X86 ---*- C++ -*-===//
+// 
+// This file declares the X86 specific subclass of TargetMachine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef X86TARGETMACHINE_H
+#define X86TARGETMACHINE_H
+
+#include "llvm/Target/TargetMachine.h"
+#include "X86InstrInfo.h"
+
+class X86TargetMachine : public TargetMachine {
+  X86InstrInfo instrInfo;
+public:
+  X86TargetMachine();
+
+  virtual const MachineInstrInfo &getInstrInfo() const { return instrInfo; }
+  virtual const MachineSchedInfo &getSchedInfo() const { abort(); }
+  virtual const MachineRegInfo   &getRegInfo()   const { abort(); }
+  virtual const MachineFrameInfo &getFrameInfo() const { abort(); }
+  virtual const MachineCacheInfo &getCacheInfo() const { abort(); }
+  virtual const MachineOptInfo   &getOptInfo()   const { abort(); }
+
+  /// addPassesToJITCompile - Add passes to the specified pass manager to
+  /// implement a fast dynamic compiler for this target.  Return true if this is
+  /// not supported for this target.
+  ///
+  virtual bool addPassesToJITCompile(PassManager &PM);
+};
+
+#endif