FastISel.cpp revision e9ab71e437e58383dd42cc1759c2a224b08370f2
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 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 49BasicBlock::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()) { 56 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; 89 break; 90 91 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 } 106 default: 107 // Unhandled instruction. Halt "fast" selection and bail. 108 return I; 109 } 110 } 111 112 return I; 113} 114 115FastISel::~FastISel() {} 116 117unsigned 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); 135 unsigned ResultReg = MRI.createVirtualRegister(RC); 136 137 MachineInstr *MI = BuildMI(*MF, II, ResultReg); 138 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); 148 unsigned ResultReg = MRI.createVirtualRegister(RC); 149 150 MachineInstr *MI = BuildMI(*MF, II, ResultReg); 151 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); 162 unsigned ResultReg = MRI.createVirtualRegister(RC); 163 164 MachineInstr *MI = BuildMI(*MF, II, ResultReg); 165 MI->addOperand(MachineOperand::CreateReg(Op0, false)); 166 MI->addOperand(MachineOperand::CreateReg(Op1, false)); 167 168 MBB->push_back(MI); 169 return ResultReg; 170} 171