From 6c18b10ad4873ad7e1b1c1d589bcf844c46f4120 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 17 Dec 2005 07:47:01 +0000 Subject: [PATCH] Add the framework for a dag-dag isel git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24769 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Sparc/Makefile | 3 +- lib/Target/Sparc/Sparc.h | 2 + lib/Target/Sparc/SparcISelDAGToDAG.cpp | 172 ++++++++++++++++++++ lib/Target/Sparc/SparcTargetMachine.cpp | 10 +- lib/Target/SparcV8/Makefile | 3 +- lib/Target/SparcV8/SparcV8.h | 2 + lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp | 172 ++++++++++++++++++++ lib/Target/SparcV8/SparcV8TargetMachine.cpp | 10 +- 8 files changed, 370 insertions(+), 4 deletions(-) create mode 100644 lib/Target/Sparc/SparcISelDAGToDAG.cpp create mode 100644 lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp diff --git a/lib/Target/Sparc/Makefile b/lib/Target/Sparc/Makefile index c49eb412027..497d1a52f26 100644 --- a/lib/Target/Sparc/Makefile +++ b/lib/Target/Sparc/Makefile @@ -13,7 +13,8 @@ TARGET = SparcV8 # Make sure that tblgen is run, first thing. BUILT_SOURCES = SparcV8GenRegisterInfo.h.inc SparcV8GenRegisterNames.inc \ SparcV8GenRegisterInfo.inc SparcV8GenInstrNames.inc \ - SparcV8GenInstrInfo.inc SparcV8GenAsmWriter.inc + SparcV8GenInstrInfo.inc SparcV8GenAsmWriter.inc \ + SparcV8GenDAGISel.inc include $(LEVEL)/Makefile.common diff --git a/lib/Target/Sparc/Sparc.h b/lib/Target/Sparc/Sparc.h index 8c58dbfd3cf..33bfdabd12d 100644 --- a/lib/Target/Sparc/Sparc.h +++ b/lib/Target/Sparc/Sparc.h @@ -23,6 +23,8 @@ namespace llvm { class TargetMachine; FunctionPass *createSparcV8SimpleInstructionSelector(TargetMachine &TM); + FunctionPass *createSparcV8ISelDag(TargetMachine &TM); + FunctionPass *createSparcV8CodePrinterPass(std::ostream &OS, TargetMachine &TM); FunctionPass *createSparcV8DelaySlotFillerPass(TargetMachine &TM); diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp new file mode 100644 index 00000000000..7b7383e991b --- /dev/null +++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -0,0 +1,172 @@ +//===-- SparcV8ISelDAGToDAG.cpp - A dag to dag inst selector for SparcV8 --===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Chris Lattner and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines an instruction selector for the V8 target +// +//===----------------------------------------------------------------------===// + +#include "SparcV8.h" +#include "SparcV8TargetMachine.h" +#include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/CodeGen/SelectionDAGISel.h" +#include "llvm/Target/TargetLowering.h" +#include "llvm/Support/Debug.h" +#include +using namespace llvm; + +//===----------------------------------------------------------------------===// +// TargetLowering Implementation +//===----------------------------------------------------------------------===// + +namespace { + class SparcV8TargetLowering : public TargetLowering { + public: + SparcV8TargetLowering(TargetMachine &TM); + + virtual std::vector + LowerArguments(Function &F, SelectionDAG &DAG); + virtual std::pair + LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, + unsigned CC, + bool isTailCall, SDOperand Callee, ArgListTy &Args, + SelectionDAG &DAG); + + virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op, + SelectionDAG &DAG); + virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG); + virtual std::pair + LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG); + virtual std::pair + LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, + SelectionDAG &DAG); + }; +} + +SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM) + : TargetLowering(TM) { + + // Set up the register classes. + addRegisterClass(MVT::i32, V8::IntRegsRegisterClass); + addRegisterClass(MVT::f32, V8::FPRegsRegisterClass); + addRegisterClass(MVT::f64, V8::DFPRegsRegisterClass); + + computeRegisterProperties(); +} + +std::vector +SparcV8TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { + assert(0 && "Unimp"); + abort(); +} + +std::pair +SparcV8TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, + bool isVarArg, unsigned CC, + bool isTailCall, SDOperand Callee, + ArgListTy &Args, SelectionDAG &DAG) { + assert(0 && "Unimp"); + abort(); +} + +SDOperand SparcV8TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op, + SelectionDAG &DAG) { + assert(0 && "Unimp"); + abort(); +} + +SDOperand SparcV8TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG) { + assert(0 && "Unimp"); + abort(); +} + +std::pair +SparcV8TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG) { + assert(0 && "Unimp"); + abort(); +} + +std::pair +SparcV8TargetLowering::LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, + SelectionDAG &DAG) { + assert(0 && "Unimp"); + abort(); +} + +//===----------------------------------------------------------------------===// +// Instruction Selector Implementation +//===----------------------------------------------------------------------===// + +//===--------------------------------------------------------------------===// +/// SparcV8DAGToDAGISel - PPC specific code to select Sparc V8 machine +/// instructions for SelectionDAG operations. +/// +namespace { +class SparcV8DAGToDAGISel : public SelectionDAGISel { + SparcV8TargetLowering V8Lowering; +public: + SparcV8DAGToDAGISel(TargetMachine &TM) + : SelectionDAGISel(V8Lowering), V8Lowering(TM) {} + + SDOperand Select(SDOperand Op); + + /// InstructionSelectBasicBlock - This callback is invoked by + /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. + virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); + + virtual const char *getPassName() const { + return "PowerPC DAG->DAG Pattern Instruction Selection"; + } + + // Include the pieces autogenerated from the target description. +#include "SparcV8GenDAGISel.inc" +}; +} // end anonymous namespace + +/// InstructionSelectBasicBlock - This callback is invoked by +/// SelectionDAGISel when it has created a SelectionDAG for us to codegen. +void SparcV8DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { + DEBUG(BB->dump()); + + // Select target instructions for the DAG. + DAG.setRoot(Select(DAG.getRoot())); + CodeGenMap.clear(); + DAG.RemoveDeadNodes(); + + // Emit machine code to BB. + ScheduleAndEmitDAG(DAG); +} + + +SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) { + SDNode *N = Op.Val; + if (N->getOpcode() >= ISD::BUILTIN_OP_END/* && + N->getOpcode() < V8ISD::FIRST_NUMBER*/) + return Op; // Already selected. + // If this has already been converted, use it. + std::map::iterator CGMI = CodeGenMap.find(Op); + if (CGMI != CodeGenMap.end()) return CGMI->second; + + switch (N->getOpcode()) { + default: break; + } + + return SelectCode(Op); +} + + +/// createPPCISelDag - This pass converts a legalized DAG into a +/// PowerPC-specific DAG, ready for instruction scheduling. +/// +FunctionPass *llvm::createSparcV8ISelDag(TargetMachine &TM) { + return new SparcV8DAGToDAGISel(TM); +} diff --git a/lib/Target/Sparc/SparcTargetMachine.cpp b/lib/Target/Sparc/SparcTargetMachine.cpp index ce9768ea00b..65e97aa678f 100644 --- a/lib/Target/Sparc/SparcTargetMachine.cpp +++ b/lib/Target/Sparc/SparcTargetMachine.cpp @@ -20,12 +20,17 @@ #include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetMachineRegistry.h" #include "llvm/Transforms/Scalar.h" +#include "llvm/Support/CommandLine.h" #include using namespace llvm; namespace { // Register the target. RegisterTarget X("sparcv8"," SPARC V8 (experimental)"); + + cl::opt DisableV8DAGDAG("disable-v8-dag-isel", cl::Hidden, + cl::desc("Disable DAG-to-DAG isel for V8"), + cl::init(1)); } /// SparcV8TargetMachine ctor - Create an ILP32 architecture model @@ -87,7 +92,10 @@ bool SparcV8TargetMachine::addPassesToEmitFile(PassManager &PM, if (PrintMachineCode) PM.add(new PrintFunctionPass()); - PM.add(createSparcV8SimpleInstructionSelector(*this)); + if (DisableV8DAGDAG) + PM.add(createSparcV8SimpleInstructionSelector(*this)); + else + PM.add(createSparcV8ISelDag(*this)); // Print machine instructions as they were initially generated. if (PrintMachineCode) diff --git a/lib/Target/SparcV8/Makefile b/lib/Target/SparcV8/Makefile index c49eb412027..497d1a52f26 100644 --- a/lib/Target/SparcV8/Makefile +++ b/lib/Target/SparcV8/Makefile @@ -13,7 +13,8 @@ TARGET = SparcV8 # Make sure that tblgen is run, first thing. BUILT_SOURCES = SparcV8GenRegisterInfo.h.inc SparcV8GenRegisterNames.inc \ SparcV8GenRegisterInfo.inc SparcV8GenInstrNames.inc \ - SparcV8GenInstrInfo.inc SparcV8GenAsmWriter.inc + SparcV8GenInstrInfo.inc SparcV8GenAsmWriter.inc \ + SparcV8GenDAGISel.inc include $(LEVEL)/Makefile.common diff --git a/lib/Target/SparcV8/SparcV8.h b/lib/Target/SparcV8/SparcV8.h index 8c58dbfd3cf..33bfdabd12d 100644 --- a/lib/Target/SparcV8/SparcV8.h +++ b/lib/Target/SparcV8/SparcV8.h @@ -23,6 +23,8 @@ namespace llvm { class TargetMachine; FunctionPass *createSparcV8SimpleInstructionSelector(TargetMachine &TM); + FunctionPass *createSparcV8ISelDag(TargetMachine &TM); + FunctionPass *createSparcV8CodePrinterPass(std::ostream &OS, TargetMachine &TM); FunctionPass *createSparcV8DelaySlotFillerPass(TargetMachine &TM); diff --git a/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp b/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp new file mode 100644 index 00000000000..7b7383e991b --- /dev/null +++ b/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp @@ -0,0 +1,172 @@ +//===-- SparcV8ISelDAGToDAG.cpp - A dag to dag inst selector for SparcV8 --===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Chris Lattner and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines an instruction selector for the V8 target +// +//===----------------------------------------------------------------------===// + +#include "SparcV8.h" +#include "SparcV8TargetMachine.h" +#include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/CodeGen/SelectionDAGISel.h" +#include "llvm/Target/TargetLowering.h" +#include "llvm/Support/Debug.h" +#include +using namespace llvm; + +//===----------------------------------------------------------------------===// +// TargetLowering Implementation +//===----------------------------------------------------------------------===// + +namespace { + class SparcV8TargetLowering : public TargetLowering { + public: + SparcV8TargetLowering(TargetMachine &TM); + + virtual std::vector + LowerArguments(Function &F, SelectionDAG &DAG); + virtual std::pair + LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, + unsigned CC, + bool isTailCall, SDOperand Callee, ArgListTy &Args, + SelectionDAG &DAG); + + virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op, + SelectionDAG &DAG); + virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG); + virtual std::pair + LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG); + virtual std::pair + LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, + SelectionDAG &DAG); + }; +} + +SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM) + : TargetLowering(TM) { + + // Set up the register classes. + addRegisterClass(MVT::i32, V8::IntRegsRegisterClass); + addRegisterClass(MVT::f32, V8::FPRegsRegisterClass); + addRegisterClass(MVT::f64, V8::DFPRegsRegisterClass); + + computeRegisterProperties(); +} + +std::vector +SparcV8TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { + assert(0 && "Unimp"); + abort(); +} + +std::pair +SparcV8TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, + bool isVarArg, unsigned CC, + bool isTailCall, SDOperand Callee, + ArgListTy &Args, SelectionDAG &DAG) { + assert(0 && "Unimp"); + abort(); +} + +SDOperand SparcV8TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op, + SelectionDAG &DAG) { + assert(0 && "Unimp"); + abort(); +} + +SDOperand SparcV8TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG) { + assert(0 && "Unimp"); + abort(); +} + +std::pair +SparcV8TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG) { + assert(0 && "Unimp"); + abort(); +} + +std::pair +SparcV8TargetLowering::LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, + SelectionDAG &DAG) { + assert(0 && "Unimp"); + abort(); +} + +//===----------------------------------------------------------------------===// +// Instruction Selector Implementation +//===----------------------------------------------------------------------===// + +//===--------------------------------------------------------------------===// +/// SparcV8DAGToDAGISel - PPC specific code to select Sparc V8 machine +/// instructions for SelectionDAG operations. +/// +namespace { +class SparcV8DAGToDAGISel : public SelectionDAGISel { + SparcV8TargetLowering V8Lowering; +public: + SparcV8DAGToDAGISel(TargetMachine &TM) + : SelectionDAGISel(V8Lowering), V8Lowering(TM) {} + + SDOperand Select(SDOperand Op); + + /// InstructionSelectBasicBlock - This callback is invoked by + /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. + virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); + + virtual const char *getPassName() const { + return "PowerPC DAG->DAG Pattern Instruction Selection"; + } + + // Include the pieces autogenerated from the target description. +#include "SparcV8GenDAGISel.inc" +}; +} // end anonymous namespace + +/// InstructionSelectBasicBlock - This callback is invoked by +/// SelectionDAGISel when it has created a SelectionDAG for us to codegen. +void SparcV8DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { + DEBUG(BB->dump()); + + // Select target instructions for the DAG. + DAG.setRoot(Select(DAG.getRoot())); + CodeGenMap.clear(); + DAG.RemoveDeadNodes(); + + // Emit machine code to BB. + ScheduleAndEmitDAG(DAG); +} + + +SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) { + SDNode *N = Op.Val; + if (N->getOpcode() >= ISD::BUILTIN_OP_END/* && + N->getOpcode() < V8ISD::FIRST_NUMBER*/) + return Op; // Already selected. + // If this has already been converted, use it. + std::map::iterator CGMI = CodeGenMap.find(Op); + if (CGMI != CodeGenMap.end()) return CGMI->second; + + switch (N->getOpcode()) { + default: break; + } + + return SelectCode(Op); +} + + +/// createPPCISelDag - This pass converts a legalized DAG into a +/// PowerPC-specific DAG, ready for instruction scheduling. +/// +FunctionPass *llvm::createSparcV8ISelDag(TargetMachine &TM) { + return new SparcV8DAGToDAGISel(TM); +} diff --git a/lib/Target/SparcV8/SparcV8TargetMachine.cpp b/lib/Target/SparcV8/SparcV8TargetMachine.cpp index ce9768ea00b..65e97aa678f 100644 --- a/lib/Target/SparcV8/SparcV8TargetMachine.cpp +++ b/lib/Target/SparcV8/SparcV8TargetMachine.cpp @@ -20,12 +20,17 @@ #include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetMachineRegistry.h" #include "llvm/Transforms/Scalar.h" +#include "llvm/Support/CommandLine.h" #include using namespace llvm; namespace { // Register the target. RegisterTarget X("sparcv8"," SPARC V8 (experimental)"); + + cl::opt DisableV8DAGDAG("disable-v8-dag-isel", cl::Hidden, + cl::desc("Disable DAG-to-DAG isel for V8"), + cl::init(1)); } /// SparcV8TargetMachine ctor - Create an ILP32 architecture model @@ -87,7 +92,10 @@ bool SparcV8TargetMachine::addPassesToEmitFile(PassManager &PM, if (PrintMachineCode) PM.add(new PrintFunctionPass()); - PM.add(createSparcV8SimpleInstructionSelector(*this)); + if (DisableV8DAGDAG) + PM.add(createSparcV8SimpleInstructionSelector(*this)); + else + PM.add(createSparcV8ISelDag(*this)); // Print machine instructions as they were initially generated. if (PrintMachineCode) -- 2.34.1