From: Chris Lattner Date: Tue, 29 Oct 2002 22:37:54 +0000 (+0000) Subject: Convert backend to use passes, implement X86TargetMachine X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=b4f68ed32ede4cf7d31ce9e516e4074dad0a24ee;p=oota-llvm.git 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 4491fdf792f..4659bea9072 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 namespace { - struct ISel : public InstVisitor { // eventually will be a FunctionPass + struct ISel : public FunctionPass, InstVisitor { + TargetMachine &TM; MachineFunction *F; // The function we are compiling into MachineBasicBlock *BB; // The current MBB we are compiling unsigned CurReg; std::map 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 @@ void ISel::visitAdd(BinaryOperator &B) { } } - - -/// 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 1a42ed86f84..b320e2c1788 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 -/// 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) { +namespace { + struct Printer : public FunctionPass { + TargetMachine &TM; + std::ostream &O; + + 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; +} + + - // This should use the X86InstructionInfo::print method to print assembly for - // each instruction + +/// 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 5c5133ebf5d..d94ec28f3e5 100644 --- a/lib/Target/X86/X86.h +++ b/lib/Target/X86/X86.h @@ -11,34 +11,32 @@ #define TARGET_X86_H #include -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 1a42ed86f84..b320e2c1788 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 -/// 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) { +namespace { + struct Printer : public FunctionPass { + TargetMachine &TM; + std::ostream &O; + + 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; +} + + - // This should use the X86InstructionInfo::print method to print assembly for - // each instruction + +/// 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 4491fdf792f..4659bea9072 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 namespace { - struct ISel : public InstVisitor { // eventually will be a FunctionPass + struct ISel : public FunctionPass, InstVisitor { + TargetMachine &TM; MachineFunction *F; // The function we are compiling into MachineBasicBlock *BB; // The current MBB we are compiling unsigned CurReg; std::map 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 @@ void ISel::visitAdd(BinaryOperator &B) { } } - - -/// 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 00000000000..4273dafefcf --- /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 + +// 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 00000000000..863eb604f53 --- /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