a318536c0680605d42426858f3e05c76988a3d87
[oota-llvm.git] / lib / Target / SystemZ / SystemZISelDAGToDAG.cpp
1 //==-- SystemZISelDAGToDAG.cpp - A dag to dag inst selector for SystemZ ---===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines an instruction selector for the SystemZ target.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "SystemZ.h"
15 #include "SystemZISelLowering.h"
16 #include "SystemZTargetMachine.h"
17 #include "llvm/DerivedTypes.h"
18 #include "llvm/Function.h"
19 #include "llvm/Intrinsics.h"
20 #include "llvm/CallingConv.h"
21 #include "llvm/Constants.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
26 #include "llvm/CodeGen/SelectionDAG.h"
27 #include "llvm/CodeGen/SelectionDAGISel.h"
28 #include "llvm/Target/TargetLowering.h"
29 #include "llvm/Support/Compiler.h"
30 #include "llvm/Support/Debug.h"
31 using namespace llvm;
32
33 /// SystemZDAGToDAGISel - SystemZ specific code to select SystemZ machine
34 /// instructions for SelectionDAG operations.
35 ///
36 namespace {
37   class SystemZDAGToDAGISel : public SelectionDAGISel {
38     SystemZTargetLowering &Lowering;
39     const SystemZSubtarget &Subtarget;
40
41   public:
42     SystemZDAGToDAGISel(SystemZTargetMachine &TM, CodeGenOpt::Level OptLevel)
43       : SelectionDAGISel(TM, OptLevel),
44         Lowering(*TM.getTargetLowering()),
45         Subtarget(*TM.getSubtargetImpl()) { }
46
47     virtual void InstructionSelect();
48
49     virtual const char *getPassName() const {
50       return "SystemZ DAG->DAG Pattern Instruction Selection";
51     }
52
53     /// getI16Imm - Return a target constant with the specified value, of type
54     /// i16.
55     inline SDValue getI16Imm(uint64_t Imm) {
56       return CurDAG->getTargetConstant(Imm, MVT::i16);
57     }
58
59     /// getI32Imm - Return a target constant with the specified value, of type
60     /// i32.
61     inline SDValue getI32Imm(uint64_t Imm) {
62       return CurDAG->getTargetConstant(Imm, MVT::i32);
63     }
64
65     // Include the pieces autogenerated from the target description.
66     #include "SystemZGenDAGISel.inc"
67
68   private:
69     SDNode *Select(SDValue Op);
70
71   #ifndef NDEBUG
72     unsigned Indent;
73   #endif
74   };
75 }  // end anonymous namespace
76
77 /// createSystemZISelDag - This pass converts a legalized DAG into a
78 /// SystemZ-specific DAG, ready for instruction scheduling.
79 ///
80 FunctionPass *llvm::createSystemZISelDag(SystemZTargetMachine &TM,
81                                         CodeGenOpt::Level OptLevel) {
82   return new SystemZDAGToDAGISel(TM, OptLevel);
83 }
84
85
86 /// InstructionSelect - This callback is invoked by
87 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
88 void SystemZDAGToDAGISel::InstructionSelect() {
89   DEBUG(BB->dump());
90
91   // Codegen the basic block.
92 #ifndef NDEBUG
93   DOUT << "===== Instruction selection begins:\n";
94   Indent = 0;
95 #endif
96   SelectRoot(*CurDAG);
97 #ifndef NDEBUG
98   DOUT << "===== Instruction selection ends:\n";
99 #endif
100
101   CurDAG->RemoveDeadNodes();
102 }
103
104 SDNode *SystemZDAGToDAGISel::Select(SDValue Op) {
105   SDNode *Node = Op.getNode();
106   DebugLoc dl = Op.getDebugLoc();
107
108   // Dump information about the Node being selected
109   #ifndef NDEBUG
110   DOUT << std::string(Indent, ' ') << "Selecting: ";
111   DEBUG(Node->dump(CurDAG));
112   DOUT << "\n";
113   Indent += 2;
114   #endif
115
116   // If we have a custom node, we already have selected!
117   if (Node->isMachineOpcode()) {
118     #ifndef NDEBUG
119     DOUT << std::string(Indent-2, ' ') << "== ";
120     DEBUG(Node->dump(CurDAG));
121     DOUT << "\n";
122     Indent -= 2;
123     #endif
124     return NULL;
125   }
126
127   // Select the default instruction
128   SDNode *ResNode = SelectCode(Op);
129
130   #ifndef NDEBUG
131   DOUT << std::string(Indent-2, ' ') << "=> ";
132   if (ResNode == NULL || ResNode == Op.getNode())
133     DEBUG(Op.getNode()->dump(CurDAG));
134   else
135     DEBUG(ResNode->dump(CurDAG));
136   DOUT << "\n";
137   Indent -= 2;
138   #endif
139
140   return ResNode;
141 }