blob: f3fcaec28c331be8aac946dbee7c1596a35bc389 [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
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
Dan Gohmanb0cf29c2008-08-13 20:19:35 +000049BasicBlock::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()) {
Dan Gohmanbdedd442008-08-20 00:11:48 +000056 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;
Dan Gohmanb0cf29c2008-08-13 20:19:35 +000089 break;
Dan Gohmanbdedd442008-08-20 00:11:48 +000090
Dan Gohman6f2766d2008-08-19 22:31:46 +000091 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 }
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000106 default:
107 // Unhandled instruction. Halt "fast" selection and bail.
108 return I;
109 }
110 }
111
112 return I;
113}
114
Dan Gohmane285a742008-08-14 21:51:29 +0000115FastISel::~FastISel() {}
116
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000117unsigned 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);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000135 unsigned ResultReg = MRI.createVirtualRegister(RC);
136
Dan Gohman8133a522008-08-19 20:46:54 +0000137 MachineInstr *MI = BuildMI(*MF, II, ResultReg);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000138
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);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000148 unsigned ResultReg = MRI.createVirtualRegister(RC);
149
Dan Gohman8133a522008-08-19 20:46:54 +0000150 MachineInstr *MI = BuildMI(*MF, II, ResultReg);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000151 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);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000162 unsigned ResultReg = MRI.createVirtualRegister(RC);
163
Dan Gohman8133a522008-08-19 20:46:54 +0000164 MachineInstr *MI = BuildMI(*MF, II, ResultReg);
Dan Gohmanb0cf29c2008-08-13 20:19:35 +0000165 MI->addOperand(MachineOperand::CreateReg(Op0, false));
166 MI->addOperand(MachineOperand::CreateReg(Op1, false));
167
168 MBB->push_back(MI);
169 return ResultReg;
170}