blob: b8e5d2cd2904cbe344333cca5744525168568fe5 [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"
Dan Gohmanbb466332008-08-20 21:05:57 +000019#include "llvm/Target/TargetMachine.h"
Dan Gohmanb0cf29c2008-08-13 20:19:35 +000020using namespace llvm;
21
Dan Gohmanbdedd442008-08-20 00:11:48 +000022/// 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)];
Dan Gohmana7f2dff2008-08-20 00:35:17 +000029 if (Op0 == 0 || Op1 == 0)
30 // Unhandled operand. Halt "fast" selection and bail.
31 return false;
32
Dan Gohmanbdedd442008-08-20 00:11:48 +000033 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
Dan Gohman8014e862008-08-20 00:23:20 +000044 // We successfully emitted code for the given LLVM Instruction.
Dan Gohmanbdedd442008-08-20 00:11:48 +000045 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
Dan Gohmanb0cf29c2008-08-13 20:19:35 +000055BasicBlock::iterator
Dan Gohmanb7864a92008-08-20 18:09:02 +000056FastISel::SelectInstructions(BasicBlock::iterator Begin,
57 BasicBlock::iterator End,
Dan Gohmanbb466332008-08-20 21:05:57 +000058 DenseMap<const Value*, unsigned> &ValueMap,
59 MachineBasicBlock *mbb) {
60 MBB = mbb;
Dan Gohmanb0cf29c2008-08-13 20:19:35 +000061 BasicBlock::iterator I = Begin;
62
63 for (; I != End; ++I) {
64 switch (I->getOpcode()) {
Dan Gohman8014e862008-08-20 00:23:20 +000065 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 }
Dan Gohmanbdedd442008-08-20 00:11:48 +000077 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;
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000104 break;
Dan Gohmanbdedd442008-08-20 00:11:48 +0000105
Dan Gohman6f2766d2008-08-19 22:31:46 +0000106 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.
Dan Gohmane6798b72008-08-20 01:17:01 +0000111 if (BI->isUnconditional()) {
112 MachineFunction::iterator NextMBB =
113 next(MachineFunction::iterator(MBB));
Dan Gohmanbb466332008-08-20 21:05:57 +0000114 if (NextMBB != MF.end() &&
Dan Gohmane6798b72008-08-20 01:17:01 +0000115 NextMBB->getBasicBlock() == BI->getSuccessor(0)) {
116 MBB->addSuccessor(NextMBB);
117 break;
118 }
Dan Gohman6f2766d2008-08-19 22:31:46 +0000119 }
120
121 // Something more complicated. Halt "fast" selection and bail.
122 return I;
123 }
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000124 default:
125 // Unhandled instruction. Halt "fast" selection and bail.
126 return I;
127 }
128 }
129
130 return I;
131}
132
Dan Gohmanbb466332008-08-20 21:05:57 +0000133FastISel::FastISel(MachineFunction &mf)
134 : MF(mf), MRI(mf.getRegInfo()), TII(*mf.getTarget().getInstrInfo()) {
135}
136
Dan Gohmane285a742008-08-14 21:51:29 +0000137FastISel::~FastISel() {}
138
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000139unsigned 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,
Dan Gohman77ad7962008-08-20 18:09:38 +0000154 const TargetRegisterClass* RC) {
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000155 unsigned ResultReg = MRI.createVirtualRegister(RC);
Dan Gohmanbb466332008-08-20 21:05:57 +0000156 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000157
Dan Gohmanf990b572008-08-20 21:10:53 +0000158 MachineInstr *MI = BuildMI(MBB, II, ResultReg);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000159 return ResultReg;
160}
161
162unsigned FastISel::FastEmitInst_r(unsigned MachineInstOpcode,
163 const TargetRegisterClass *RC,
164 unsigned Op0) {
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000165 unsigned ResultReg = MRI.createVirtualRegister(RC);
Dan Gohmanbb466332008-08-20 21:05:57 +0000166 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000167
Dan Gohmanf990b572008-08-20 21:10:53 +0000168 MachineInstr *MI = BuildMI(MBB, II, ResultReg).addReg(Op0);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000169 return ResultReg;
170}
171
172unsigned FastISel::FastEmitInst_rr(unsigned MachineInstOpcode,
173 const TargetRegisterClass *RC,
174 unsigned Op0, unsigned Op1) {
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000175 unsigned ResultReg = MRI.createVirtualRegister(RC);
Dan Gohmanbb466332008-08-20 21:05:57 +0000176 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000177
Dan Gohmanf990b572008-08-20 21:10:53 +0000178 MachineInstr *MI = BuildMI(MBB, II, ResultReg).addReg(Op0).addReg(Op1);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000179 return ResultReg;
180}