FastISel.cpp revision 4cbe0662abb2cd6025eff51e19574a48f1a83b97
1///===-- 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 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" 19using namespace llvm; 20 21/// 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 if (Op0 == 0 || Op1 == 0) 29 // Unhandled operand. Halt "fast" selection and bail. 30 return false; 31 32 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 43 // We successfully emitted code for the given LLVM Instruction. 44 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 54BasicBlock::iterator 55FastISel::SelectInstructions(BasicBlock::iterator Begin, 56 BasicBlock::iterator End, 57 DenseMap<const Value*, unsigned> &ValueMap) { 58 BasicBlock::iterator I = Begin; 59 60 for (; I != End; ++I) { 61 switch (I->getOpcode()) { 62 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 } 74 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; 101 break; 102 103 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. 108 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 } 116 } 117 118 // Something more complicated. Halt "fast" selection and bail. 119 return I; 120 } 121 default: 122 // Unhandled instruction. Halt "fast" selection and bail. 123 return I; 124 } 125 } 126 127 return I; 128} 129 130FastISel::~FastISel() {} 131 132unsigned 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 unsigned ResultReg = MRI.createVirtualRegister(RC); 150 const TargetInstrDesc &II = TII->get(MachineInstOpcode); 151 152 MachineInstr *MI = BuildMI(*MF, II, ResultReg); 153 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 unsigned ResultReg = MRI.createVirtualRegister(RC); 163 const TargetInstrDesc &II = TII->get(MachineInstOpcode); 164 165 MachineInstr *MI = BuildMI(*MF, II, ResultReg); 166 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 unsigned ResultReg = MRI.createVirtualRegister(RC); 177 const TargetInstrDesc &II = TII->get(MachineInstOpcode); 178 179 MachineInstr *MI = BuildMI(*MF, II, ResultReg); 180 MI->addOperand(MachineOperand::CreateReg(Op0, false)); 181 MI->addOperand(MachineOperand::CreateReg(Op1, false)); 182 183 MBB->push_back(MI); 184 return ResultReg; 185} 186