FastISel.cpp revision 0fb23e3f764d090d0ad1331d38aafd329d94c4d5
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" 19#include "llvm/Target/TargetMachine.h" 20using namespace llvm; 21 22/// 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)]; 29 if (Op0 == 0 || Op1 == 0) 30 // Unhandled operand. Halt "fast" selection and bail. 31 return false; 32 33 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 44 // We successfully emitted code for the given LLVM Instruction. 45 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 55BasicBlock::iterator 56FastISel::SelectInstructions(BasicBlock::iterator Begin, 57 BasicBlock::iterator End, 58 DenseMap<const Value*, unsigned> &ValueMap, 59 MachineBasicBlock *mbb) { 60 MBB = mbb; 61 BasicBlock::iterator I = Begin; 62 63 for (; I != End; ++I) { 64 switch (I->getOpcode()) { 65 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 } 77 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; 104 break; 105 106 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. 111 if (BI->isUnconditional()) { 112 MachineFunction::iterator NextMBB = 113 next(MachineFunction::iterator(MBB)); 114 if (NextMBB != MF.end() && 115 NextMBB->getBasicBlock() == BI->getSuccessor(0)) { 116 MBB->addSuccessor(NextMBB); 117 break; 118 } 119 } 120 121 // Something more complicated. Halt "fast" selection and bail. 122 return I; 123 } 124 default: 125 // Unhandled instruction. Halt "fast" selection and bail. 126 return I; 127 } 128 } 129 130 return I; 131} 132 133FastISel::FastISel(MachineFunction &mf) 134 : MF(mf), MRI(mf.getRegInfo()), TII(*mf.getTarget().getInstrInfo()) { 135} 136 137FastISel::~FastISel() {} 138 139unsigned 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, 154 const TargetRegisterClass* RC) { 155 unsigned ResultReg = MRI.createVirtualRegister(RC); 156 const TargetInstrDesc &II = TII.get(MachineInstOpcode); 157 158 MachineInstr *MI = BuildMI(MBB, II, ResultReg); 159 return ResultReg; 160} 161 162unsigned FastISel::FastEmitInst_r(unsigned MachineInstOpcode, 163 const TargetRegisterClass *RC, 164 unsigned Op0) { 165 unsigned ResultReg = MRI.createVirtualRegister(RC); 166 const TargetInstrDesc &II = TII.get(MachineInstOpcode); 167 168 MachineInstr *MI = BuildMI(MBB, II, ResultReg).addReg(Op0); 169 return ResultReg; 170} 171 172unsigned FastISel::FastEmitInst_rr(unsigned MachineInstOpcode, 173 const TargetRegisterClass *RC, 174 unsigned Op0, unsigned Op1) { 175 unsigned ResultReg = MRI.createVirtualRegister(RC); 176 const TargetInstrDesc &II = TII.get(MachineInstOpcode); 177 178 MachineInstr *MI = BuildMI(MBB, II, ResultReg).addReg(Op0).addReg(Op1); 179 return ResultReg; 180} 181