1 //===-- AlphaISelDAGToDAG.cpp - Alpha pattern matching inst selector ------===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by Andrew Lenharth and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines a pattern matching instruction selector for Alpha,
11 // converting from a legalized dag to a Alpha dag.
13 //===----------------------------------------------------------------------===//
16 #include "AlphaTargetMachine.h"
17 #include "AlphaISelLowering.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/MachineFunction.h"
20 #include "llvm/CodeGen/SSARegMap.h"
21 #include "llvm/CodeGen/SelectionDAG.h"
22 #include "llvm/CodeGen/SelectionDAGISel.h"
23 #include "llvm/Target/TargetOptions.h"
24 #include "llvm/ADT/Statistic.h"
25 #include "llvm/Constants.h"
26 #include "llvm/GlobalValue.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/MathExtras.h"
33 //===--------------------------------------------------------------------===//
34 /// AlphaDAGToDAGISel - Alpha specific code to select Alpha machine
35 /// instructions for SelectionDAG operations.
37 class AlphaDAGToDAGISel : public SelectionDAGISel {
38 AlphaTargetLowering AlphaLowering;
41 AlphaDAGToDAGISel(TargetMachine &TM)
42 : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {}
44 /// getI64Imm - Return a target constant with the specified value, of type
46 inline SDOperand getI64Imm(unsigned Imm) {
47 return CurDAG->getTargetConstant(Imm, MVT::i64);
50 virtual bool runOnFunction(Function &Fn) {
51 return SelectionDAGISel::runOnFunction(Fn);
54 // Select - Convert the specified operand from a target-independent to a
55 // target-specific node if it hasn't already been changed.
56 SDOperand Select(SDOperand Op);
58 /// InstructionSelectBasicBlock - This callback is invoked by
59 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
60 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
62 virtual const char *getPassName() const {
63 return "Alpha DAG->DAG Pattern Instruction Selection";
66 // Include the pieces autogenerated from the target description.
67 #include "AlphaGenDAGISel.inc"
73 /// InstructionSelectBasicBlock - This callback is invoked by
74 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
75 void AlphaDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
78 // The selection process is inherently a bottom-up recursive process (users
79 // select their uses before themselves). Given infinite stack space, we
80 // could just start selecting on the root and traverse the whole graph. In
81 // practice however, this causes us to run out of stack space on large basic
82 // blocks. To avoid this problem, select the entry node, then all its uses,
83 // iteratively instead of recursively.
84 std::vector<SDOperand> Worklist;
85 Worklist.push_back(DAG.getEntryNode());
87 // Note that we can do this in the Alpha target (scanning forward across token
88 // chain edges) because no nodes ever get folded across these edges. On a
89 // target like X86 which supports load/modify/store operations, this would
90 // have to be more careful.
91 while (!Worklist.empty()) {
92 SDOperand Node = Worklist.back();
95 // Chose from the least deep of the top two nodes.
96 if (!Worklist.empty() &&
97 Worklist.back().Val->getNodeDepth() < Node.Val->getNodeDepth())
98 std::swap(Worklist.back(), Node);
100 if ((Node.Val->getOpcode() >= ISD::BUILTIN_OP_END &&
101 Node.Val->getOpcode() < AlphaISD::FIRST_NUMBER) ||
102 CodeGenMap.count(Node)) continue;
104 for (SDNode::use_iterator UI = Node.Val->use_begin(),
105 E = Node.Val->use_end(); UI != E; ++UI) {
106 // Scan the values. If this use has a value that is a token chain, add it
109 for (unsigned i = 0, e = User->getNumValues(); i != e; ++i)
110 if (User->getValueType(i) == MVT::Other) {
111 Worklist.push_back(SDOperand(User, i));
116 // Finally, legalize this node.
120 // Select target instructions for the DAG.
121 DAG.setRoot(Select(DAG.getRoot()));
123 DAG.RemoveDeadNodes();
125 // Emit machine code to BB.
126 ScheduleAndEmitDAG(DAG);
129 // Select - Convert the specified operand from a target-independent to a
130 // target-specific node if it hasn't already been changed.
131 SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) {
133 if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
134 N->getOpcode() < AlphaISD::FIRST_NUMBER)
135 return Op; // Already selected.
137 // If this has already been converted, use it.
138 std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
139 if (CGMI != CodeGenMap.end()) return CGMI->second;
141 switch (N->getOpcode()) {
143 case ISD::DYNAMIC_STACKALLOC:
149 assert(0 && "You want these too?");
151 case ISD::TokenFactor: {
153 if (N->getNumOperands() == 2) {
154 SDOperand Op0 = Select(N->getOperand(0));
155 SDOperand Op1 = Select(N->getOperand(1));
156 New = CurDAG->getNode(ISD::TokenFactor, MVT::Other, Op0, Op1);
158 std::vector<SDOperand> Ops;
159 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
160 Ops.push_back(Select(N->getOperand(i)));
161 New = CurDAG->getNode(ISD::TokenFactor, MVT::Other, Ops);
164 CodeGenMap[Op] = New;
167 case ISD::CopyFromReg: {
168 SDOperand Chain = Select(N->getOperand(0));
169 if (Chain == N->getOperand(0)) return Op; // No change
170 SDOperand New = CurDAG->getCopyFromReg(Chain,
171 cast<RegisterSDNode>(N->getOperand(1))->getReg(), N->getValueType(0));
172 return New.getValue(Op.ResNo);
174 case ISD::CopyToReg: {
175 SDOperand Chain = Select(N->getOperand(0));
176 SDOperand Reg = N->getOperand(1);
177 SDOperand Val = Select(N->getOperand(2));
178 SDOperand New = CurDAG->getNode(ISD::CopyToReg, MVT::Other,
180 CodeGenMap[Op] = New;
184 if (N->getValueType(0) == MVT::i64)
185 CurDAG->SelectNodeTo(N, Alpha::IDEF, MVT::i64);
186 // else if (N->getValueType(0) == MVT::f32)
187 // CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F4, MVT::f32);
189 // CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F8, MVT::f64);
190 return SDOperand(N, 0);
191 case ISD::FrameIndex: {
192 // int FI = cast<FrameIndexSDNode>(N)->getIndex();
193 // CurDAG->SelectNodeTo(N, Alpha::LDA, MVT::i64,
194 // CurDAG->getTargetFrameIndex(FI, MVT::i32),
196 // return SDOperand(N, 0);
197 assert(0 && "Frame?, you are suppose to look through the window, not at the frame!");
199 case ISD::ConstantPool: {
200 // Constant *C = cast<ConstantPoolSDNode>(N)->get();
201 // SDOperand Tmp, CPI = CurDAG->getTargetConstantPool(C, MVT::i32);
203 // Tmp = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(),CPI);
205 // Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, CPI);
206 // CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, CPI);
207 // return SDOperand(N, 0);
208 assert(0 && "Constants are overrated");
210 case ISD::GlobalAddress: {
211 // GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
213 // SDOperand GA = CurDAG->getTargetGlobalAddress(GV, MVT::i32);
215 // Tmp = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(), GA);
217 // Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, GA);
219 // if (GV->hasWeakLinkage() || GV->isExternal())
220 // CurDAG->SelectNodeTo(N, PPC::LWZ, MVT::i32, GA, Tmp);
222 // CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, GA);
223 // return SDOperand(N, 0);
224 assert(0 && "GlobalAddresses are for wimps");
227 case ISD::CALLSEQ_START:
228 case ISD::CALLSEQ_END: {
229 unsigned Amt = cast<ConstantSDNode>(N->getOperand(1))->getValue();
230 unsigned Opc = N->getOpcode() == ISD::CALLSEQ_START ?
231 Alpha::ADJUSTSTACKDOWN : Alpha::ADJUSTSTACKUP;
232 CurDAG->SelectNodeTo(N, Opc, MVT::Other,
233 getI64Imm(Amt), Select(N->getOperand(0)));
234 return SDOperand(N, 0);
237 SDOperand Chain = Select(N->getOperand(0)); // Token chain.
239 if (N->getNumOperands() == 2) {
240 SDOperand Val = Select(N->getOperand(1));
241 if (N->getOperand(1).getValueType() == MVT::i64) {
242 Chain = CurDAG->getCopyToReg(Chain, Alpha::R0, Val);
245 //BuildMI(BB, Alpha::RET, 2, Alpha::R31).addReg(Alpha::R26).addImm(1);
247 // FIXME: add restoring of the RA to R26 to the chain
248 // Finally, select this to a ret instruction.
249 CurDAG->SelectNodeTo(N, Alpha::RETDAG, MVT::Other, Chain);
250 return SDOperand(N, 0);
257 return SelectCode(Op);
260 /// createAlphaISelDag - This pass converts a legalized DAG into a
261 /// Alpha-specific DAG, ready for instruction scheduling.
263 FunctionPass *llvm::createAlphaISelDag(TargetMachine &TM) {
264 return new AlphaDAGToDAGISel(TM);