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