FastISel.cpp revision 0fb23e3f764d090d0ad1331d38aafd329d94c4d5
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"
20using 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///
25bool 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
49bool FastISel::SelectGetElementPtr(Instruction *I,
50                                   DenseMap<const Value*, unsigned> &ValueMap) {
51  // TODO: implement me
52  return false;
53}
54
55BasicBlock::iterator
56FastISel::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
133FastISel::FastISel(MachineFunction &mf)
134  : MF(mf), MRI(mf.getRegInfo()), TII(*mf.getTarget().getInstrInfo()) {
135}
136
137FastISel::~FastISel() {}
138
139unsigned FastISel::FastEmit_(MVT::SimpleValueType, ISD::NodeType) {
140  return 0;
141}
142
143unsigned FastISel::FastEmit_r(MVT::SimpleValueType, ISD::NodeType,
144                              unsigned /*Op0*/) {
145  return 0;
146}
147
148unsigned FastISel::FastEmit_rr(MVT::SimpleValueType, ISD::NodeType,
149                               unsigned /*Op0*/, unsigned /*Op0*/) {
150  return 0;
151}
152
153unsigned 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(MBB, II, ResultReg);
159  return ResultReg;
160}
161
162unsigned FastISel::FastEmitInst_r(unsigned MachineInstOpcode,
163                                  const TargetRegisterClass *RC,
164                                  unsigned Op0) {
165  unsigned ResultReg = MRI.createVirtualRegister(RC);
166  const TargetInstrDesc &II = TII.get(MachineInstOpcode);
167
168  MachineInstr *MI = BuildMI(MBB, II, ResultReg).addReg(Op0);
169  return ResultReg;
170}
171
172unsigned FastISel::FastEmitInst_rr(unsigned MachineInstOpcode,
173                                   const TargetRegisterClass *RC,
174                                   unsigned Op0, unsigned Op1) {
175  unsigned ResultReg = MRI.createVirtualRegister(RC);
176  const TargetInstrDesc &II = TII.get(MachineInstOpcode);
177
178  MachineInstr *MI = BuildMI(MBB, II, ResultReg).addReg(Op0).addReg(Op1);
179  return ResultReg;
180}
181