]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/lib/Target/PTX/PTXISelDAGToDAG.cpp
Copy head to stable/9 as part of 9.0-RELEASE release cycle.
[FreeBSD/stable/9.git] / contrib / llvm / lib / Target / PTX / PTXISelDAGToDAG.cpp
1 //===-- PTXISelDAGToDAG.cpp - A dag to dag inst selector for PTX ----------===//
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 PTX target.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "PTX.h"
15 #include "PTXTargetMachine.h"
16 #include "llvm/CodeGen/SelectionDAGISel.h"
17 #include "llvm/DerivedTypes.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/raw_ostream.h"
20
21 using namespace llvm;
22
23 namespace {
24 // PTXDAGToDAGISel - PTX specific code to select PTX machine
25 // instructions for SelectionDAG operations.
26 class PTXDAGToDAGISel : public SelectionDAGISel {
27   public:
28     PTXDAGToDAGISel(PTXTargetMachine &TM, CodeGenOpt::Level OptLevel);
29
30     virtual const char *getPassName() const {
31       return "PTX DAG->DAG Pattern Instruction Selection";
32     }
33
34     SDNode *Select(SDNode *Node);
35
36     // Complex Pattern Selectors.
37     bool SelectADDRrr(SDValue &Addr, SDValue &R1, SDValue &R2);
38     bool SelectADDRri(SDValue &Addr, SDValue &Base, SDValue &Offset);
39     bool SelectADDRii(SDValue &Addr, SDValue &Base, SDValue &Offset);
40
41     // Include the pieces auto'gened from the target description
42 #include "PTXGenDAGISel.inc"
43
44   private:
45     // We need this only because we can't match intruction BRAdp
46     // pattern (PTXbrcond bb:$d, ...) in PTXInstrInfo.td
47     SDNode *SelectBRCOND(SDNode *Node);
48
49     bool isImm(const SDValue &operand);
50     bool SelectImm(const SDValue &operand, SDValue &imm);
51
52     const PTXSubtarget& getSubtarget() const;
53 }; // class PTXDAGToDAGISel
54 } // namespace
55
56 // createPTXISelDag - This pass converts a legalized DAG into a
57 // PTX-specific DAG, ready for instruction scheduling
58 FunctionPass *llvm::createPTXISelDag(PTXTargetMachine &TM,
59                                      CodeGenOpt::Level OptLevel) {
60   return new PTXDAGToDAGISel(TM, OptLevel);
61 }
62
63 PTXDAGToDAGISel::PTXDAGToDAGISel(PTXTargetMachine &TM,
64                                  CodeGenOpt::Level OptLevel)
65   : SelectionDAGISel(TM, OptLevel) {}
66
67 SDNode *PTXDAGToDAGISel::Select(SDNode *Node) {
68   switch (Node->getOpcode()) {
69     case ISD::BRCOND:
70       return SelectBRCOND(Node);
71     default:
72       return SelectCode(Node);
73   }
74 }
75
76 SDNode *PTXDAGToDAGISel::SelectBRCOND(SDNode *Node) {
77   assert(Node->getNumOperands() >= 3);
78
79   SDValue Chain  = Node->getOperand(0);
80   SDValue Pred   = Node->getOperand(1);
81   SDValue Target = Node->getOperand(2); // branch target
82   SDValue PredOp = CurDAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32);
83   DebugLoc dl = Node->getDebugLoc();
84
85   assert(Target.getOpcode()  == ISD::BasicBlock);
86   assert(Pred.getValueType() == MVT::i1);
87
88   // Emit BRAdp
89   SDValue Ops[] = { Target, Pred, PredOp, Chain };
90   return CurDAG->getMachineNode(PTX::BRAdp, dl, MVT::Other, Ops, 4);
91 }
92
93 // Match memory operand of the form [reg+reg]
94 bool PTXDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1, SDValue &R2) {
95   if (Addr.getOpcode() != ISD::ADD || Addr.getNumOperands() < 2 ||
96       isImm(Addr.getOperand(0)) || isImm(Addr.getOperand(1)))
97     return false;
98
99   assert(Addr.getValueType().isSimple() && "Type must be simple");
100
101   R1 = Addr;
102   R2 = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT());
103
104   return true;
105 }
106
107 // Match memory operand of the form [reg], [imm+reg], and [reg+imm]
108 bool PTXDAGToDAGISel::SelectADDRri(SDValue &Addr, SDValue &Base,
109                                    SDValue &Offset) {
110   if (Addr.getOpcode() != ISD::ADD) {
111     // let SelectADDRii handle the [imm] case
112     if (isImm(Addr))
113       return false;
114     // it is [reg]
115
116     assert(Addr.getValueType().isSimple() && "Type must be simple");
117
118     Base = Addr;
119     Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT());
120
121     return true;
122   }
123
124   if (Addr.getNumOperands() < 2)
125     return false;
126
127   // let SelectADDRii handle the [imm+imm] case
128   if (isImm(Addr.getOperand(0)) && isImm(Addr.getOperand(1)))
129     return false;
130
131   // try [reg+imm] and [imm+reg]
132   for (int i = 0; i < 2; i ++)
133     if (SelectImm(Addr.getOperand(1-i), Offset)) {
134       Base = Addr.getOperand(i);
135       return true;
136     }
137
138   // neither [reg+imm] nor [imm+reg]
139   return false;
140 }
141
142 // Match memory operand of the form [imm+imm] and [imm]
143 bool PTXDAGToDAGISel::SelectADDRii(SDValue &Addr, SDValue &Base,
144                                    SDValue &Offset) {
145   // is [imm+imm]?
146   if (Addr.getOpcode() == ISD::ADD) {
147     return SelectImm(Addr.getOperand(0), Base) &&
148            SelectImm(Addr.getOperand(1), Offset);
149   }
150
151   // is [imm]?
152   if (SelectImm(Addr, Base)) {
153     assert(Addr.getValueType().isSimple() && "Type must be simple");
154
155     Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT());
156
157     return true;
158   }
159
160   return false;
161 }
162
163 bool PTXDAGToDAGISel::isImm(const SDValue &operand) {
164   return ConstantSDNode::classof(operand.getNode());
165 }
166
167 bool PTXDAGToDAGISel::SelectImm(const SDValue &operand, SDValue &imm) {
168   SDNode *node = operand.getNode();
169   if (!ConstantSDNode::classof(node))
170     return false;
171
172   ConstantSDNode *CN = cast<ConstantSDNode>(node);
173   imm = CurDAG->getTargetConstant(*CN->getConstantIntValue(),
174                                   operand.getValueType());
175   return true;
176 }
177
178 const PTXSubtarget& PTXDAGToDAGISel::getSubtarget() const
179 {
180   return TM.getSubtarget<PTXSubtarget>();
181 }
182