1 //===- X86InstructionSelector.cpp ----------------------------*- C++ -*-==// 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 /// \file 10 /// This file implements the targeting of the InstructionSelector class for 11 /// X86. 12 /// \todo This should be generated by TableGen. 13 //===----------------------------------------------------------------------===// 14 15 #include "X86InstructionSelector.h" 16 #include "X86InstrInfo.h" 17 #include "X86RegisterBankInfo.h" 18 #include "X86RegisterInfo.h" 19 #include "X86Subtarget.h" 20 #include "X86TargetMachine.h" 21 #include "llvm/CodeGen/MachineBasicBlock.h" 22 #include "llvm/CodeGen/MachineFunction.h" 23 #include "llvm/CodeGen/MachineInstr.h" 24 #include "llvm/CodeGen/MachineInstrBuilder.h" 25 #include "llvm/CodeGen/MachineRegisterInfo.h" 26 #include "llvm/IR/Type.h" 27 #include "llvm/Support/Debug.h" 28 #include "llvm/Support/raw_ostream.h" 29 30 #define DEBUG_TYPE "X86-isel" 31 32 using namespace llvm; 33 34 #ifndef LLVM_BUILD_GLOBAL_ISEL 35 #error "You shouldn't build this" 36 #endif 37 38 #include "X86GenGlobalISel.inc" 39 40 X86InstructionSelector::X86InstructionSelector(const X86Subtarget &STI, 41 const X86RegisterBankInfo &RBI) 42 : InstructionSelector(), TII(*STI.getInstrInfo()), 43 TRI(*STI.getRegisterInfo()), RBI(RBI) {} 44 45 // FIXME: This should be target-independent, inferred from the types declared 46 // for each class in the bank. 47 static const TargetRegisterClass * 48 getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB) { 49 if (RB.getID() == X86::GPRRegBankID) { 50 if (Ty.getSizeInBits() <= 32) 51 return &X86::GR32RegClass; 52 if (Ty.getSizeInBits() == 64) 53 return &X86::GR64RegClass; 54 } 55 56 llvm_unreachable("Unknown RegBank!"); 57 } 58 59 // Set X86 Opcode and constrain DestReg. 60 static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, 61 MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, 62 const RegisterBankInfo &RBI) { 63 64 unsigned DstReg = I.getOperand(0).getReg(); 65 if (TargetRegisterInfo::isPhysicalRegister(DstReg)) { 66 assert(I.isCopy() && "Generic operators do not allow physical registers"); 67 return true; 68 } 69 70 const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI); 71 const unsigned DstSize = MRI.getType(DstReg).getSizeInBits(); 72 (void)DstSize; 73 unsigned SrcReg = I.getOperand(1).getReg(); 74 const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI); 75 (void)SrcSize; 76 assert((!TargetRegisterInfo::isPhysicalRegister(SrcReg) || I.isCopy()) && 77 "No phys reg on generic operators"); 78 assert((DstSize == SrcSize || 79 // Copies are a mean to setup initial types, the number of 80 // bits may not exactly match. 81 (TargetRegisterInfo::isPhysicalRegister(SrcReg) && 82 DstSize <= RBI.getSizeInBits(SrcReg, MRI, TRI))) && 83 "Copy with different width?!"); 84 85 const TargetRegisterClass *RC = nullptr; 86 87 switch (RegBank.getID()) { 88 case X86::GPRRegBankID: 89 assert((DstSize <= 64) && "GPRs cannot get more than 64-bit width values."); 90 RC = getRegClassForTypeOnBank(MRI.getType(DstReg), RegBank); 91 break; 92 default: 93 llvm_unreachable("Unknown RegBank!"); 94 } 95 96 // No need to constrain SrcReg. It will get constrained when 97 // we hit another of its use or its defs. 98 // Copies do not have constraints. 99 if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) { 100 DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode()) 101 << " operand\n"); 102 return false; 103 } 104 I.setDesc(TII.get(X86::COPY)); 105 return true; 106 } 107 108 bool X86InstructionSelector::select(MachineInstr &I) const { 109 assert(I.getParent() && "Instruction should be in a basic block!"); 110 assert(I.getParent()->getParent() && "Instruction should be in a function!"); 111 112 MachineBasicBlock &MBB = *I.getParent(); 113 MachineFunction &MF = *MBB.getParent(); 114 MachineRegisterInfo &MRI = MF.getRegInfo(); 115 116 unsigned Opcode = I.getOpcode(); 117 if (!isPreISelGenericOpcode(Opcode)) { 118 // Certain non-generic instructions also need some special handling. 119 120 if (I.isCopy()) 121 return selectCopy(I, TII, MRI, TRI, RBI); 122 123 // TODO: handle more cases - LOAD_STACK_GUARD, PHI 124 return true; 125 } 126 127 assert(I.getNumOperands() == I.getNumExplicitOperands() && 128 "Generic instruction has unexpected implicit operands\n"); 129 130 return selectImpl(I); 131 } 132