1 ///===-- FastISel.cpp - Implementation of the FastISel class --------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the implementation of the FastISel class.
12 //===----------------------------------------------------------------------===//
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"
21 /// SelectBinaryOp - Select and emit code for a binary operator instruction,
22 /// which has an opcode which directly corresponds to the given ISD opcode.
24 bool 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 if (Op0 == 0 || Op1 == 0)
29 // Unhandled operand. Halt "fast" selection and bail.
32 MVT VT = MVT::getMVT(I->getType(), /*HandleUnknown=*/true);
33 if (VT == MVT::Other || !VT.isSimple())
34 // Unhandled type. Halt "fast" selection and bail.
37 unsigned ResultReg = FastEmit_rr(VT.getSimpleVT(), ISDOpcode, Op0, Op1);
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.
43 // We successfully emitted code for the given LLVM Instruction.
44 ValueMap[I] = ResultReg;
48 bool FastISel::SelectGetElementPtr(Instruction *I,
49 DenseMap<const Value*, unsigned> &ValueMap) {
55 FastISel::SelectInstructions(BasicBlock::iterator Begin, BasicBlock::iterator End,
56 DenseMap<const Value*, unsigned> &ValueMap) {
57 BasicBlock::iterator I = Begin;
59 for (; I != End; ++I) {
60 switch (I->getOpcode()) {
61 case Instruction::Add: {
62 ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FADD : ISD::ADD;
63 if (!SelectBinaryOp(I, Opc, ValueMap)) return I; break;
65 case Instruction::Sub: {
66 ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FSUB : ISD::SUB;
67 if (!SelectBinaryOp(I, Opc, ValueMap)) return I; break;
69 case Instruction::Mul: {
70 ISD::NodeType Opc = I->getType()->isFPOrFPVector() ? ISD::FMUL : ISD::MUL;
71 if (!SelectBinaryOp(I, Opc, ValueMap)) return I; break;
73 case Instruction::SDiv:
74 if (!SelectBinaryOp(I, ISD::SDIV, ValueMap)) return I; break;
75 case Instruction::UDiv:
76 if (!SelectBinaryOp(I, ISD::UDIV, ValueMap)) return I; break;
77 case Instruction::FDiv:
78 if (!SelectBinaryOp(I, ISD::FDIV, ValueMap)) return I; break;
79 case Instruction::SRem:
80 if (!SelectBinaryOp(I, ISD::SREM, ValueMap)) return I; break;
81 case Instruction::URem:
82 if (!SelectBinaryOp(I, ISD::UREM, ValueMap)) return I; break;
83 case Instruction::FRem:
84 if (!SelectBinaryOp(I, ISD::FREM, ValueMap)) return I; break;
85 case Instruction::Shl:
86 if (!SelectBinaryOp(I, ISD::SHL, ValueMap)) return I; break;
87 case Instruction::LShr:
88 if (!SelectBinaryOp(I, ISD::SRL, ValueMap)) return I; break;
89 case Instruction::AShr:
90 if (!SelectBinaryOp(I, ISD::SRA, ValueMap)) return I; break;
91 case Instruction::And:
92 if (!SelectBinaryOp(I, ISD::AND, ValueMap)) return I; break;
94 if (!SelectBinaryOp(I, ISD::OR, ValueMap)) return I; break;
95 case Instruction::Xor:
96 if (!SelectBinaryOp(I, ISD::XOR, ValueMap)) return I; break;
98 case Instruction::GetElementPtr:
99 if (!SelectGetElementPtr(I, ValueMap)) return I;
102 case Instruction::Br: {
103 BranchInst *BI = cast<BranchInst>(I);
105 // For now, check for and handle just the most trivial case: an
106 // unconditional fall-through branch.
107 if (BI->isUnconditional()) {
108 MachineFunction::iterator NextMBB =
109 next(MachineFunction::iterator(MBB));
110 if (NextMBB != MF->end() &&
111 NextMBB->getBasicBlock() == BI->getSuccessor(0)) {
112 MBB->addSuccessor(NextMBB);
117 // Something more complicated. Halt "fast" selection and bail.
121 // Unhandled instruction. Halt "fast" selection and bail.
129 FastISel::~FastISel() {}
131 unsigned FastISel::FastEmit_(MVT::SimpleValueType, ISD::NodeType) {
135 unsigned FastISel::FastEmit_r(MVT::SimpleValueType, ISD::NodeType,
140 unsigned FastISel::FastEmit_rr(MVT::SimpleValueType, ISD::NodeType,
141 unsigned /*Op0*/, unsigned /*Op0*/) {
145 unsigned FastISel::FastEmitInst_(unsigned MachineInstOpcode,
146 const TargetRegisterClass* RC) {
147 MachineRegisterInfo &MRI = MF->getRegInfo();
148 const TargetInstrDesc &II = TII->get(MachineInstOpcode);
149 unsigned ResultReg = MRI.createVirtualRegister(RC);
151 MachineInstr *MI = BuildMI(*MF, II, ResultReg);
157 unsigned FastISel::FastEmitInst_r(unsigned MachineInstOpcode,
158 const TargetRegisterClass *RC,
160 MachineRegisterInfo &MRI = MF->getRegInfo();
161 const TargetInstrDesc &II = TII->get(MachineInstOpcode);
162 unsigned ResultReg = MRI.createVirtualRegister(RC);
164 MachineInstr *MI = BuildMI(*MF, II, ResultReg);
165 MI->addOperand(MachineOperand::CreateReg(Op0, false));
171 unsigned FastISel::FastEmitInst_rr(unsigned MachineInstOpcode,
172 const TargetRegisterClass *RC,
173 unsigned Op0, unsigned Op1) {
174 MachineRegisterInfo &MRI = MF->getRegInfo();
175 const TargetInstrDesc &II = TII->get(MachineInstOpcode);
176 unsigned ResultReg = MRI.createVirtualRegister(RC);
178 MachineInstr *MI = BuildMI(*MF, II, ResultReg);
179 MI->addOperand(MachineOperand::CreateReg(Op0, false));
180 MI->addOperand(MachineOperand::CreateReg(Op1, false));