Simplify FastISel's constructor argument list, make the FastISel
[oota-llvm.git] / lib / CodeGen / SelectionDAG / FastISel.cpp
1 ///===-- FastISel.cpp - Implementation of the FastISel class --------------===//
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 contains the implementation of the FastISel class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Instructions.h"
15 #include "llvm/CodeGen/FastISel.h"
16 #include "llvm/CodeGen/MachineInstrBuilder.h"
17 #include "llvm/CodeGen/MachineRegisterInfo.h"
18 #include "llvm/Target/TargetInstrInfo.h"
19 #include "llvm/Target/TargetMachine.h"
20 using namespace llvm;
21
22 /// SelectBinaryOp - Select and emit code for a binary operator instruction,
23 /// which has an opcode which directly corresponds to the given ISD opcode.
24 ///
25 bool FastISel::SelectBinaryOp(Instruction *I, ISD::NodeType ISDOpcode,
26                               DenseMap<const Value*, unsigned> &ValueMap) {
27   unsigned Op0 = ValueMap[I->getOperand(0)];
28   unsigned Op1 = ValueMap[I->getOperand(1)];
29   if (Op0 == 0 || Op1 == 0)
30     // Unhandled operand. Halt "fast" selection and bail.
31     return false;
32
33   MVT VT = MVT::getMVT(I->getType(), /*HandleUnknown=*/true);
34   if (VT == MVT::Other || !VT.isSimple())
35     // Unhandled type. Halt "fast" selection and bail.
36     return false;
37
38   unsigned ResultReg = FastEmit_rr(VT.getSimpleVT(), ISDOpcode, Op0, Op1);
39   if (ResultReg == 0)
40     // Target-specific code wasn't able to find a machine opcode for
41     // the given ISD opcode and type. Halt "fast" selection and bail.
42     return false;
43
44   // We successfully emitted code for the given LLVM Instruction.
45   ValueMap[I] = ResultReg;
46   return true;
47 }
48
49 bool FastISel::SelectGetElementPtr(Instruction *I,
50                                    DenseMap<const Value*, unsigned> &ValueMap) {
51   // TODO: implement me
52   return false;
53 }
54
55 BasicBlock::iterator
56 FastISel::SelectInstructions(BasicBlock::iterator Begin,
57                              BasicBlock::iterator End,
58                              DenseMap<const Value*, unsigned> &ValueMap,
59                              MachineBasicBlock *mbb) {
60   MBB = mbb;
61   BasicBlock::iterator I = Begin;
62
63   for (; I != End; ++I) {
64     switch (I->getOpcode()) {
65     case Instruction::Add: {
66       ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FADD : ISD::ADD;
67       if (!SelectBinaryOp(I, Opc, ValueMap))  return I; break;
68     }
69     case Instruction::Sub: {
70       ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FSUB : ISD::SUB;
71       if (!SelectBinaryOp(I, Opc, ValueMap))  return I; break;
72     }
73     case Instruction::Mul: {
74       ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FMUL : ISD::MUL;
75       if (!SelectBinaryOp(I, Opc, ValueMap))  return I; break;
76     }
77     case Instruction::SDiv:
78       if (!SelectBinaryOp(I, ISD::SDIV, ValueMap)) return I; break;
79     case Instruction::UDiv:
80       if (!SelectBinaryOp(I, ISD::UDIV, ValueMap)) return I; break;
81     case Instruction::FDiv:
82       if (!SelectBinaryOp(I, ISD::FDIV, ValueMap)) return I; break;
83     case Instruction::SRem:
84       if (!SelectBinaryOp(I, ISD::SREM, ValueMap)) return I; break;
85     case Instruction::URem:
86       if (!SelectBinaryOp(I, ISD::UREM, ValueMap)) return I; break;
87     case Instruction::FRem:
88       if (!SelectBinaryOp(I, ISD::FREM, ValueMap)) return I; break;
89     case Instruction::Shl:
90       if (!SelectBinaryOp(I, ISD::SHL, ValueMap)) return I; break;
91     case Instruction::LShr:
92       if (!SelectBinaryOp(I, ISD::SRL, ValueMap)) return I; break;
93     case Instruction::AShr:
94       if (!SelectBinaryOp(I, ISD::SRA, ValueMap)) return I; break;
95     case Instruction::And:
96       if (!SelectBinaryOp(I, ISD::AND, ValueMap)) return I; break;
97     case Instruction::Or:
98       if (!SelectBinaryOp(I, ISD::OR, ValueMap)) return I; break;
99     case Instruction::Xor:
100       if (!SelectBinaryOp(I, ISD::XOR, ValueMap)) return I; break;
101
102     case Instruction::GetElementPtr:
103       if (!SelectGetElementPtr(I, ValueMap)) return I;
104       break;
105
106     case Instruction::Br: {
107       BranchInst *BI = cast<BranchInst>(I);
108
109       // For now, check for and handle just the most trivial case: an
110       // unconditional fall-through branch.
111       if (BI->isUnconditional()) {
112          MachineFunction::iterator NextMBB =
113            next(MachineFunction::iterator(MBB));
114          if (NextMBB != MF.end() &&
115              NextMBB->getBasicBlock() == BI->getSuccessor(0)) {
116           MBB->addSuccessor(NextMBB);
117           break;
118         }
119       }
120
121       // Something more complicated. Halt "fast" selection and bail.
122       return I;
123     }
124     default:
125       // Unhandled instruction. Halt "fast" selection and bail.
126       return I;
127     }
128   }
129
130   return I;
131 }
132
133 FastISel::FastISel(MachineFunction &mf)
134   : MF(mf), MRI(mf.getRegInfo()), TII(*mf.getTarget().getInstrInfo()) {
135 }
136
137 FastISel::~FastISel() {}
138
139 unsigned FastISel::FastEmit_(MVT::SimpleValueType, ISD::NodeType) {
140   return 0;
141 }
142
143 unsigned FastISel::FastEmit_r(MVT::SimpleValueType, ISD::NodeType,
144                               unsigned /*Op0*/) {
145   return 0;
146 }
147
148 unsigned FastISel::FastEmit_rr(MVT::SimpleValueType, ISD::NodeType,
149                                unsigned /*Op0*/, unsigned /*Op0*/) {
150   return 0;
151 }
152
153 unsigned FastISel::FastEmitInst_(unsigned MachineInstOpcode,
154                                  const TargetRegisterClass* RC) {
155   unsigned ResultReg = MRI.createVirtualRegister(RC);
156   const TargetInstrDesc &II = TII.get(MachineInstOpcode);
157
158   MachineInstr *MI = BuildMI(MF, II, ResultReg);
159   MBB->push_back(MI);
160   return ResultReg;
161 }
162
163 unsigned FastISel::FastEmitInst_r(unsigned MachineInstOpcode,
164                                   const TargetRegisterClass *RC,
165                                   unsigned Op0) {
166   unsigned ResultReg = MRI.createVirtualRegister(RC);
167   const TargetInstrDesc &II = TII.get(MachineInstOpcode);
168
169   MachineInstr *MI = BuildMI(MF, II, ResultReg).addReg(Op0);
170   MBB->push_back(MI);
171   return ResultReg;
172 }
173
174 unsigned FastISel::FastEmitInst_rr(unsigned MachineInstOpcode,
175                                    const TargetRegisterClass *RC,
176                                    unsigned Op0, unsigned Op1) {
177   unsigned ResultReg = MRI.createVirtualRegister(RC);
178   const TargetInstrDesc &II = TII.get(MachineInstOpcode);
179
180   MachineInstr *MI = BuildMI(MF, II, ResultReg).addReg(Op0).addReg(Op1);
181   MBB->push_back(MI);
182   return ResultReg;
183 }