blob: 9ccfe0f7b014e00317590e1dad42fb3422931854 [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)];
Dan Gohmana7f2dff2008-08-20 00:35:17 +000028 if (Op0 == 0 || Op1 == 0)
29 // Unhandled operand. Halt "fast" selection and bail.
30 return false;
31
Dan Gohmanbdedd442008-08-20 00:11:48 +000032 MVT VT = MVT::getMVT(I->getType(), /*HandleUnknown=*/true);
33 if (VT == MVT::Other || !VT.isSimple())
34 // Unhandled type. Halt "fast" selection and bail.
35 return false;
36
37 unsigned ResultReg = FastEmit_rr(VT.getSimpleVT(), ISDOpcode, Op0, Op1);
38 if (ResultReg == 0)
39 // Target-specific code wasn't able to find a machine opcode for
40 // the given ISD opcode and type. Halt "fast" selection and bail.
41 return false;
42
Dan Gohman8014e862008-08-20 00:23:20 +000043 // We successfully emitted code for the given LLVM Instruction.
Dan Gohmanbdedd442008-08-20 00:11:48 +000044 ValueMap[I] = ResultReg;
45 return true;
46}
47
48bool FastISel::SelectGetElementPtr(Instruction *I,
49 DenseMap<const Value*, unsigned> &ValueMap) {
50 // TODO: implement me
51 return false;
52}
53
Dan Gohmanb0cf29c2008-08-13 20:19:35 +000054BasicBlock::iterator
Dan Gohmanb7864a92008-08-20 18:09:02 +000055FastISel::SelectInstructions(BasicBlock::iterator Begin,
56 BasicBlock::iterator End,
Dan Gohmanb0cf29c2008-08-13 20:19:35 +000057 DenseMap<const Value*, unsigned> &ValueMap) {
58 BasicBlock::iterator I = Begin;
59
60 for (; I != End; ++I) {
61 switch (I->getOpcode()) {
Dan Gohman8014e862008-08-20 00:23:20 +000062 case Instruction::Add: {
63 ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FADD : ISD::ADD;
64 if (!SelectBinaryOp(I, Opc, ValueMap)) return I; break;
65 }
66 case Instruction::Sub: {
67 ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FSUB : ISD::SUB;
68 if (!SelectBinaryOp(I, Opc, ValueMap)) return I; break;
69 }
70 case Instruction::Mul: {
71 ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FMUL : ISD::MUL;
72 if (!SelectBinaryOp(I, Opc, ValueMap)) return I; break;
73 }
Dan Gohmanbdedd442008-08-20 00:11:48 +000074 case Instruction::SDiv:
75 if (!SelectBinaryOp(I, ISD::SDIV, ValueMap)) return I; break;
76 case Instruction::UDiv:
77 if (!SelectBinaryOp(I, ISD::UDIV, ValueMap)) return I; break;
78 case Instruction::FDiv:
79 if (!SelectBinaryOp(I, ISD::FDIV, ValueMap)) return I; break;
80 case Instruction::SRem:
81 if (!SelectBinaryOp(I, ISD::SREM, ValueMap)) return I; break;
82 case Instruction::URem:
83 if (!SelectBinaryOp(I, ISD::UREM, ValueMap)) return I; break;
84 case Instruction::FRem:
85 if (!SelectBinaryOp(I, ISD::FREM, ValueMap)) return I; break;
86 case Instruction::Shl:
87 if (!SelectBinaryOp(I, ISD::SHL, ValueMap)) return I; break;
88 case Instruction::LShr:
89 if (!SelectBinaryOp(I, ISD::SRL, ValueMap)) return I; break;
90 case Instruction::AShr:
91 if (!SelectBinaryOp(I, ISD::SRA, ValueMap)) return I; break;
92 case Instruction::And:
93 if (!SelectBinaryOp(I, ISD::AND, ValueMap)) return I; break;
94 case Instruction::Or:
95 if (!SelectBinaryOp(I, ISD::OR, ValueMap)) return I; break;
96 case Instruction::Xor:
97 if (!SelectBinaryOp(I, ISD::XOR, ValueMap)) return I; break;
98
99 case Instruction::GetElementPtr:
100 if (!SelectGetElementPtr(I, ValueMap)) return I;
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000101 break;
Dan Gohmanbdedd442008-08-20 00:11:48 +0000102
Dan Gohman6f2766d2008-08-19 22:31:46 +0000103 case Instruction::Br: {
104 BranchInst *BI = cast<BranchInst>(I);
105
106 // For now, check for and handle just the most trivial case: an
107 // unconditional fall-through branch.
Dan Gohmane6798b72008-08-20 01:17:01 +0000108 if (BI->isUnconditional()) {
109 MachineFunction::iterator NextMBB =
110 next(MachineFunction::iterator(MBB));
111 if (NextMBB != MF->end() &&
112 NextMBB->getBasicBlock() == BI->getSuccessor(0)) {
113 MBB->addSuccessor(NextMBB);
114 break;
115 }
Dan Gohman6f2766d2008-08-19 22:31:46 +0000116 }
117
118 // Something more complicated. Halt "fast" selection and bail.
119 return I;
120 }
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000121 default:
122 // Unhandled instruction. Halt "fast" selection and bail.
123 return I;
124 }
125 }
126
127 return I;
128}
129
Dan Gohmane285a742008-08-14 21:51:29 +0000130FastISel::~FastISel() {}
131
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000132unsigned FastISel::FastEmit_(MVT::SimpleValueType, ISD::NodeType) {
133 return 0;
134}
135
136unsigned FastISel::FastEmit_r(MVT::SimpleValueType, ISD::NodeType,
137 unsigned /*Op0*/) {
138 return 0;
139}
140
141unsigned FastISel::FastEmit_rr(MVT::SimpleValueType, ISD::NodeType,
142 unsigned /*Op0*/, unsigned /*Op0*/) {
143 return 0;
144}
145
146unsigned FastISel::FastEmitInst_(unsigned MachineInstOpcode,
147 const TargetRegisterClass* RC) {
148 MachineRegisterInfo &MRI = MF->getRegInfo();
149 const TargetInstrDesc &II = TII->get(MachineInstOpcode);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000150 unsigned ResultReg = MRI.createVirtualRegister(RC);
151
Dan Gohman8133a522008-08-19 20:46:54 +0000152 MachineInstr *MI = BuildMI(*MF, II, ResultReg);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000153
154 MBB->push_back(MI);
155 return ResultReg;
156}
157
158unsigned FastISel::FastEmitInst_r(unsigned MachineInstOpcode,
159 const TargetRegisterClass *RC,
160 unsigned Op0) {
161 MachineRegisterInfo &MRI = MF->getRegInfo();
162 const TargetInstrDesc &II = TII->get(MachineInstOpcode);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000163 unsigned ResultReg = MRI.createVirtualRegister(RC);
164
Dan Gohman8133a522008-08-19 20:46:54 +0000165 MachineInstr *MI = BuildMI(*MF, II, ResultReg);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000166 MI->addOperand(MachineOperand::CreateReg(Op0, false));
167
168 MBB->push_back(MI);
169 return ResultReg;
170}
171
172unsigned FastISel::FastEmitInst_rr(unsigned MachineInstOpcode,
173 const TargetRegisterClass *RC,
174 unsigned Op0, unsigned Op1) {
175 MachineRegisterInfo &MRI = MF->getRegInfo();
176 const TargetInstrDesc &II = TII->get(MachineInstOpcode);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000177 unsigned ResultReg = MRI.createVirtualRegister(RC);
178
Dan Gohman8133a522008-08-19 20:46:54 +0000179 MachineInstr *MI = BuildMI(*MF, II, ResultReg);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000180 MI->addOperand(MachineOperand::CreateReg(Op0, false));
181 MI->addOperand(MachineOperand::CreateReg(Op1, false));
182
183 MBB->push_back(MI);
184 return ResultReg;
185}