blob: 996cea0155c58b7c08aafa4ef75fb56414b2a1a6 [file] [log] [blame]
Dan Gohmanb0cf29c2008-08-13 20:19:35 +00001///===-- 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
Dan Gohman6f2766d2008-08-19 22:31:46 +000014#include "llvm/Instructions.h"
Dan Gohmanb0cf29c2008-08-13 20:19:35 +000015#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
Dan Gohmanbdedd442008-08-20 00:11:48 +000021/// 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
Dan Gohman8014e862008-08-20 00:23:20 +000039 // We successfully emitted code for the given LLVM Instruction.
Dan Gohmanbdedd442008-08-20 00:11:48 +000040 ValueMap[I] = ResultReg;
41 return true;
42}
43
44bool FastISel::SelectGetElementPtr(Instruction *I,
45 DenseMap<const Value*, unsigned> &ValueMap) {
46 // TODO: implement me
47 return false;
48}
49
Dan Gohmanb0cf29c2008-08-13 20:19:35 +000050BasicBlock::iterator
51FastISel::SelectInstructions(BasicBlock::iterator Begin, BasicBlock::iterator End,
52 DenseMap<const Value*, unsigned> &ValueMap) {
53 BasicBlock::iterator I = Begin;
54
55 for (; I != End; ++I) {
56 switch (I->getOpcode()) {
Dan Gohman8014e862008-08-20 00:23:20 +000057 case Instruction::Add: {
58 ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FADD : ISD::ADD;
59 if (!SelectBinaryOp(I, Opc, ValueMap)) return I; break;
60 }
61 case Instruction::Sub: {
62 ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FSUB : ISD::SUB;
63 if (!SelectBinaryOp(I, Opc, ValueMap)) return I; break;
64 }
65 case Instruction::Mul: {
66 ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FMUL : ISD::MUL;
67 if (!SelectBinaryOp(I, Opc, ValueMap)) return I; break;
68 }
Dan Gohmanbdedd442008-08-20 00:11:48 +000069 case Instruction::SDiv:
70 if (!SelectBinaryOp(I, ISD::SDIV, ValueMap)) return I; break;
71 case Instruction::UDiv:
72 if (!SelectBinaryOp(I, ISD::UDIV, ValueMap)) return I; break;
73 case Instruction::FDiv:
74 if (!SelectBinaryOp(I, ISD::FDIV, ValueMap)) return I; break;
75 case Instruction::SRem:
76 if (!SelectBinaryOp(I, ISD::SREM, ValueMap)) return I; break;
77 case Instruction::URem:
78 if (!SelectBinaryOp(I, ISD::UREM, ValueMap)) return I; break;
79 case Instruction::FRem:
80 if (!SelectBinaryOp(I, ISD::FREM, ValueMap)) return I; break;
81 case Instruction::Shl:
82 if (!SelectBinaryOp(I, ISD::SHL, ValueMap)) return I; break;
83 case Instruction::LShr:
84 if (!SelectBinaryOp(I, ISD::SRL, ValueMap)) return I; break;
85 case Instruction::AShr:
86 if (!SelectBinaryOp(I, ISD::SRA, ValueMap)) return I; break;
87 case Instruction::And:
88 if (!SelectBinaryOp(I, ISD::AND, ValueMap)) return I; break;
89 case Instruction::Or:
90 if (!SelectBinaryOp(I, ISD::OR, ValueMap)) return I; break;
91 case Instruction::Xor:
92 if (!SelectBinaryOp(I, ISD::XOR, ValueMap)) return I; break;
93
94 case Instruction::GetElementPtr:
95 if (!SelectGetElementPtr(I, ValueMap)) return I;
Dan Gohmanb0cf29c2008-08-13 20:19:35 +000096 break;
Dan Gohmanbdedd442008-08-20 00:11:48 +000097
Dan Gohman6f2766d2008-08-19 22:31:46 +000098 case Instruction::Br: {
99 BranchInst *BI = cast<BranchInst>(I);
100
101 // For now, check for and handle just the most trivial case: an
102 // unconditional fall-through branch.
103 if (BI->isUnconditional() &&
104 next(MachineFunction::iterator(MBB))->getBasicBlock() ==
105 BI->getSuccessor(0)) {
106 MBB->addSuccessor(next(MachineFunction::iterator(MBB)));
107 break;
108 }
109
110 // Something more complicated. Halt "fast" selection and bail.
111 return I;
112 }
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000113 default:
114 // Unhandled instruction. Halt "fast" selection and bail.
115 return I;
116 }
117 }
118
119 return I;
120}
121
Dan Gohmane285a742008-08-14 21:51:29 +0000122FastISel::~FastISel() {}
123
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000124unsigned FastISel::FastEmit_(MVT::SimpleValueType, ISD::NodeType) {
125 return 0;
126}
127
128unsigned FastISel::FastEmit_r(MVT::SimpleValueType, ISD::NodeType,
129 unsigned /*Op0*/) {
130 return 0;
131}
132
133unsigned FastISel::FastEmit_rr(MVT::SimpleValueType, ISD::NodeType,
134 unsigned /*Op0*/, unsigned /*Op0*/) {
135 return 0;
136}
137
138unsigned FastISel::FastEmitInst_(unsigned MachineInstOpcode,
139 const TargetRegisterClass* RC) {
140 MachineRegisterInfo &MRI = MF->getRegInfo();
141 const TargetInstrDesc &II = TII->get(MachineInstOpcode);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000142 unsigned ResultReg = MRI.createVirtualRegister(RC);
143
Dan Gohman8133a522008-08-19 20:46:54 +0000144 MachineInstr *MI = BuildMI(*MF, II, ResultReg);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000145
146 MBB->push_back(MI);
147 return ResultReg;
148}
149
150unsigned FastISel::FastEmitInst_r(unsigned MachineInstOpcode,
151 const TargetRegisterClass *RC,
152 unsigned Op0) {
153 MachineRegisterInfo &MRI = MF->getRegInfo();
154 const TargetInstrDesc &II = TII->get(MachineInstOpcode);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000155 unsigned ResultReg = MRI.createVirtualRegister(RC);
156
Dan Gohman8133a522008-08-19 20:46:54 +0000157 MachineInstr *MI = BuildMI(*MF, II, ResultReg);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000158 MI->addOperand(MachineOperand::CreateReg(Op0, false));
159
160 MBB->push_back(MI);
161 return ResultReg;
162}
163
164unsigned FastISel::FastEmitInst_rr(unsigned MachineInstOpcode,
165 const TargetRegisterClass *RC,
166 unsigned Op0, unsigned Op1) {
167 MachineRegisterInfo &MRI = MF->getRegInfo();
168 const TargetInstrDesc &II = TII->get(MachineInstOpcode);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000169 unsigned ResultReg = MRI.createVirtualRegister(RC);
170
Dan Gohman8133a522008-08-19 20:46:54 +0000171 MachineInstr *MI = BuildMI(*MF, II, ResultReg);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000172 MI->addOperand(MachineOperand::CreateReg(Op0, false));
173 MI->addOperand(MachineOperand::CreateReg(Op1, false));
174
175 MBB->push_back(MI);
176 return ResultReg;
177}