1*0b57cec5SDimitry Andric //===- llvm/CodeGen/GlobalISel/InstructionSelect.cpp - InstructionSelect ---==// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric /// \file 9*0b57cec5SDimitry Andric /// This file implements the InstructionSelect class. 10*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 11*0b57cec5SDimitry Andric 12*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" 13*0b57cec5SDimitry Andric #include "llvm/ADT/PostOrderIterator.h" 14*0b57cec5SDimitry Andric #include "llvm/ADT/Twine.h" 15*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 16*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 17*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/Utils.h" 18*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" 19*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 20*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLowering.h" 21*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 22*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 23*0b57cec5SDimitry Andric #include "llvm/Config/config.h" 24*0b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 25*0b57cec5SDimitry Andric #include "llvm/IR/Function.h" 26*0b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 27*0b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 28*0b57cec5SDimitry Andric #include "llvm/Support/TargetRegistry.h" 29*0b57cec5SDimitry Andric 30*0b57cec5SDimitry Andric #define DEBUG_TYPE "instruction-select" 31*0b57cec5SDimitry Andric 32*0b57cec5SDimitry Andric using namespace llvm; 33*0b57cec5SDimitry Andric 34*0b57cec5SDimitry Andric #ifdef LLVM_GISEL_COV_PREFIX 35*0b57cec5SDimitry Andric static cl::opt<std::string> 36*0b57cec5SDimitry Andric CoveragePrefix("gisel-coverage-prefix", cl::init(LLVM_GISEL_COV_PREFIX), 37*0b57cec5SDimitry Andric cl::desc("Record GlobalISel rule coverage files of this " 38*0b57cec5SDimitry Andric "prefix if instrumentation was generated")); 39*0b57cec5SDimitry Andric #else 40*0b57cec5SDimitry Andric static const std::string CoveragePrefix = ""; 41*0b57cec5SDimitry Andric #endif 42*0b57cec5SDimitry Andric 43*0b57cec5SDimitry Andric char InstructionSelect::ID = 0; 44*0b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(InstructionSelect, DEBUG_TYPE, 45*0b57cec5SDimitry Andric "Select target instructions out of generic instructions", 46*0b57cec5SDimitry Andric false, false) 47*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 48*0b57cec5SDimitry Andric INITIALIZE_PASS_END(InstructionSelect, DEBUG_TYPE, 49*0b57cec5SDimitry Andric "Select target instructions out of generic instructions", 50*0b57cec5SDimitry Andric false, false) 51*0b57cec5SDimitry Andric 52*0b57cec5SDimitry Andric InstructionSelect::InstructionSelect() : MachineFunctionPass(ID) { } 53*0b57cec5SDimitry Andric 54*0b57cec5SDimitry Andric void InstructionSelect::getAnalysisUsage(AnalysisUsage &AU) const { 55*0b57cec5SDimitry Andric AU.addRequired<TargetPassConfig>(); 56*0b57cec5SDimitry Andric getSelectionDAGFallbackAnalysisUsage(AU); 57*0b57cec5SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 58*0b57cec5SDimitry Andric } 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andric bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { 61*0b57cec5SDimitry Andric // If the ISel pipeline failed, do not bother running that pass. 62*0b57cec5SDimitry Andric if (MF.getProperties().hasProperty( 63*0b57cec5SDimitry Andric MachineFunctionProperties::Property::FailedISel)) 64*0b57cec5SDimitry Andric return false; 65*0b57cec5SDimitry Andric 66*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Selecting function: " << MF.getName() << '\n'); 67*0b57cec5SDimitry Andric 68*0b57cec5SDimitry Andric const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>(); 69*0b57cec5SDimitry Andric const InstructionSelector *ISel = MF.getSubtarget().getInstructionSelector(); 70*0b57cec5SDimitry Andric CodeGenCoverage CoverageInfo; 71*0b57cec5SDimitry Andric assert(ISel && "Cannot work without InstructionSelector"); 72*0b57cec5SDimitry Andric 73*0b57cec5SDimitry Andric // An optimization remark emitter. Used to report failures. 74*0b57cec5SDimitry Andric MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr); 75*0b57cec5SDimitry Andric 76*0b57cec5SDimitry Andric // FIXME: There are many other MF/MFI fields we need to initialize. 77*0b57cec5SDimitry Andric 78*0b57cec5SDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo(); 79*0b57cec5SDimitry Andric #ifndef NDEBUG 80*0b57cec5SDimitry Andric // Check that our input is fully legal: we require the function to have the 81*0b57cec5SDimitry Andric // Legalized property, so it should be. 82*0b57cec5SDimitry Andric // FIXME: This should be in the MachineVerifier, as the RegBankSelected 83*0b57cec5SDimitry Andric // property check already is. 84*0b57cec5SDimitry Andric if (!DisableGISelLegalityCheck) 85*0b57cec5SDimitry Andric if (const MachineInstr *MI = machineFunctionIsIllegal(MF)) { 86*0b57cec5SDimitry Andric reportGISelFailure(MF, TPC, MORE, "gisel-select", 87*0b57cec5SDimitry Andric "instruction is not legal", *MI); 88*0b57cec5SDimitry Andric return false; 89*0b57cec5SDimitry Andric } 90*0b57cec5SDimitry Andric // FIXME: We could introduce new blocks and will need to fix the outer loop. 91*0b57cec5SDimitry Andric // Until then, keep track of the number of blocks to assert that we don't. 92*0b57cec5SDimitry Andric const size_t NumBlocks = MF.size(); 93*0b57cec5SDimitry Andric #endif 94*0b57cec5SDimitry Andric 95*0b57cec5SDimitry Andric for (MachineBasicBlock *MBB : post_order(&MF)) { 96*0b57cec5SDimitry Andric if (MBB->empty()) 97*0b57cec5SDimitry Andric continue; 98*0b57cec5SDimitry Andric 99*0b57cec5SDimitry Andric // Select instructions in reverse block order. We permit erasing so have 100*0b57cec5SDimitry Andric // to resort to manually iterating and recognizing the begin (rend) case. 101*0b57cec5SDimitry Andric bool ReachedBegin = false; 102*0b57cec5SDimitry Andric for (auto MII = std::prev(MBB->end()), Begin = MBB->begin(); 103*0b57cec5SDimitry Andric !ReachedBegin;) { 104*0b57cec5SDimitry Andric #ifndef NDEBUG 105*0b57cec5SDimitry Andric // Keep track of the insertion range for debug printing. 106*0b57cec5SDimitry Andric const auto AfterIt = std::next(MII); 107*0b57cec5SDimitry Andric #endif 108*0b57cec5SDimitry Andric // Select this instruction. 109*0b57cec5SDimitry Andric MachineInstr &MI = *MII; 110*0b57cec5SDimitry Andric 111*0b57cec5SDimitry Andric // And have our iterator point to the next instruction, if there is one. 112*0b57cec5SDimitry Andric if (MII == Begin) 113*0b57cec5SDimitry Andric ReachedBegin = true; 114*0b57cec5SDimitry Andric else 115*0b57cec5SDimitry Andric --MII; 116*0b57cec5SDimitry Andric 117*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Selecting: \n " << MI); 118*0b57cec5SDimitry Andric 119*0b57cec5SDimitry Andric // We could have folded this instruction away already, making it dead. 120*0b57cec5SDimitry Andric // If so, erase it. 121*0b57cec5SDimitry Andric if (isTriviallyDead(MI, MRI)) { 122*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Is dead; erasing.\n"); 123*0b57cec5SDimitry Andric MI.eraseFromParentAndMarkDBGValuesForRemoval(); 124*0b57cec5SDimitry Andric continue; 125*0b57cec5SDimitry Andric } 126*0b57cec5SDimitry Andric 127*0b57cec5SDimitry Andric if (!ISel->select(MI, CoverageInfo)) { 128*0b57cec5SDimitry Andric // FIXME: It would be nice to dump all inserted instructions. It's 129*0b57cec5SDimitry Andric // not obvious how, esp. considering select() can insert after MI. 130*0b57cec5SDimitry Andric reportGISelFailure(MF, TPC, MORE, "gisel-select", "cannot select", MI); 131*0b57cec5SDimitry Andric return false; 132*0b57cec5SDimitry Andric } 133*0b57cec5SDimitry Andric 134*0b57cec5SDimitry Andric // Dump the range of instructions that MI expanded into. 135*0b57cec5SDimitry Andric LLVM_DEBUG({ 136*0b57cec5SDimitry Andric auto InsertedBegin = ReachedBegin ? MBB->begin() : std::next(MII); 137*0b57cec5SDimitry Andric dbgs() << "Into:\n"; 138*0b57cec5SDimitry Andric for (auto &InsertedMI : make_range(InsertedBegin, AfterIt)) 139*0b57cec5SDimitry Andric dbgs() << " " << InsertedMI; 140*0b57cec5SDimitry Andric dbgs() << '\n'; 141*0b57cec5SDimitry Andric }); 142*0b57cec5SDimitry Andric } 143*0b57cec5SDimitry Andric } 144*0b57cec5SDimitry Andric 145*0b57cec5SDimitry Andric for (MachineBasicBlock &MBB : MF) { 146*0b57cec5SDimitry Andric if (MBB.empty()) 147*0b57cec5SDimitry Andric continue; 148*0b57cec5SDimitry Andric 149*0b57cec5SDimitry Andric // Try to find redundant copies b/w vregs of the same register class. 150*0b57cec5SDimitry Andric bool ReachedBegin = false; 151*0b57cec5SDimitry Andric for (auto MII = std::prev(MBB.end()), Begin = MBB.begin(); !ReachedBegin;) { 152*0b57cec5SDimitry Andric // Select this instruction. 153*0b57cec5SDimitry Andric MachineInstr &MI = *MII; 154*0b57cec5SDimitry Andric 155*0b57cec5SDimitry Andric // And have our iterator point to the next instruction, if there is one. 156*0b57cec5SDimitry Andric if (MII == Begin) 157*0b57cec5SDimitry Andric ReachedBegin = true; 158*0b57cec5SDimitry Andric else 159*0b57cec5SDimitry Andric --MII; 160*0b57cec5SDimitry Andric if (MI.getOpcode() != TargetOpcode::COPY) 161*0b57cec5SDimitry Andric continue; 162*0b57cec5SDimitry Andric unsigned SrcReg = MI.getOperand(1).getReg(); 163*0b57cec5SDimitry Andric unsigned DstReg = MI.getOperand(0).getReg(); 164*0b57cec5SDimitry Andric if (TargetRegisterInfo::isVirtualRegister(SrcReg) && 165*0b57cec5SDimitry Andric TargetRegisterInfo::isVirtualRegister(DstReg)) { 166*0b57cec5SDimitry Andric auto SrcRC = MRI.getRegClass(SrcReg); 167*0b57cec5SDimitry Andric auto DstRC = MRI.getRegClass(DstReg); 168*0b57cec5SDimitry Andric if (SrcRC == DstRC) { 169*0b57cec5SDimitry Andric MRI.replaceRegWith(DstReg, SrcReg); 170*0b57cec5SDimitry Andric MI.eraseFromParentAndMarkDBGValuesForRemoval(); 171*0b57cec5SDimitry Andric } 172*0b57cec5SDimitry Andric } 173*0b57cec5SDimitry Andric } 174*0b57cec5SDimitry Andric } 175*0b57cec5SDimitry Andric 176*0b57cec5SDimitry Andric #ifndef NDEBUG 177*0b57cec5SDimitry Andric const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); 178*0b57cec5SDimitry Andric // Now that selection is complete, there are no more generic vregs. Verify 179*0b57cec5SDimitry Andric // that the size of the now-constrained vreg is unchanged and that it has a 180*0b57cec5SDimitry Andric // register class. 181*0b57cec5SDimitry Andric for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) { 182*0b57cec5SDimitry Andric unsigned VReg = TargetRegisterInfo::index2VirtReg(I); 183*0b57cec5SDimitry Andric 184*0b57cec5SDimitry Andric MachineInstr *MI = nullptr; 185*0b57cec5SDimitry Andric if (!MRI.def_empty(VReg)) 186*0b57cec5SDimitry Andric MI = &*MRI.def_instr_begin(VReg); 187*0b57cec5SDimitry Andric else if (!MRI.use_empty(VReg)) 188*0b57cec5SDimitry Andric MI = &*MRI.use_instr_begin(VReg); 189*0b57cec5SDimitry Andric if (!MI) 190*0b57cec5SDimitry Andric continue; 191*0b57cec5SDimitry Andric 192*0b57cec5SDimitry Andric const TargetRegisterClass *RC = MRI.getRegClassOrNull(VReg); 193*0b57cec5SDimitry Andric if (!RC) { 194*0b57cec5SDimitry Andric reportGISelFailure(MF, TPC, MORE, "gisel-select", 195*0b57cec5SDimitry Andric "VReg has no regclass after selection", *MI); 196*0b57cec5SDimitry Andric return false; 197*0b57cec5SDimitry Andric } 198*0b57cec5SDimitry Andric 199*0b57cec5SDimitry Andric const LLT Ty = MRI.getType(VReg); 200*0b57cec5SDimitry Andric if (Ty.isValid() && Ty.getSizeInBits() > TRI.getRegSizeInBits(*RC)) { 201*0b57cec5SDimitry Andric reportGISelFailure( 202*0b57cec5SDimitry Andric MF, TPC, MORE, "gisel-select", 203*0b57cec5SDimitry Andric "VReg's low-level type and register class have different sizes", *MI); 204*0b57cec5SDimitry Andric return false; 205*0b57cec5SDimitry Andric } 206*0b57cec5SDimitry Andric } 207*0b57cec5SDimitry Andric 208*0b57cec5SDimitry Andric if (MF.size() != NumBlocks) { 209*0b57cec5SDimitry Andric MachineOptimizationRemarkMissed R("gisel-select", "GISelFailure", 210*0b57cec5SDimitry Andric MF.getFunction().getSubprogram(), 211*0b57cec5SDimitry Andric /*MBB=*/nullptr); 212*0b57cec5SDimitry Andric R << "inserting blocks is not supported yet"; 213*0b57cec5SDimitry Andric reportGISelFailure(MF, TPC, MORE, R); 214*0b57cec5SDimitry Andric return false; 215*0b57cec5SDimitry Andric } 216*0b57cec5SDimitry Andric #endif 217*0b57cec5SDimitry Andric auto &TLI = *MF.getSubtarget().getTargetLowering(); 218*0b57cec5SDimitry Andric TLI.finalizeLowering(MF); 219*0b57cec5SDimitry Andric 220*0b57cec5SDimitry Andric LLVM_DEBUG({ 221*0b57cec5SDimitry Andric dbgs() << "Rules covered by selecting function: " << MF.getName() << ":"; 222*0b57cec5SDimitry Andric for (auto RuleID : CoverageInfo.covered()) 223*0b57cec5SDimitry Andric dbgs() << " id" << RuleID; 224*0b57cec5SDimitry Andric dbgs() << "\n\n"; 225*0b57cec5SDimitry Andric }); 226*0b57cec5SDimitry Andric CoverageInfo.emit(CoveragePrefix, 227*0b57cec5SDimitry Andric MF.getSubtarget() 228*0b57cec5SDimitry Andric .getTargetLowering() 229*0b57cec5SDimitry Andric ->getTargetMachine() 230*0b57cec5SDimitry Andric .getTarget() 231*0b57cec5SDimitry Andric .getBackendName()); 232*0b57cec5SDimitry Andric 233*0b57cec5SDimitry Andric // If we successfully selected the function nothing is going to use the vreg 234*0b57cec5SDimitry Andric // types after us (otherwise MIRPrinter would need them). Make sure the types 235*0b57cec5SDimitry Andric // disappear. 236*0b57cec5SDimitry Andric MRI.clearVirtRegTypes(); 237*0b57cec5SDimitry Andric 238*0b57cec5SDimitry Andric // FIXME: Should we accurately track changes? 239*0b57cec5SDimitry Andric return true; 240*0b57cec5SDimitry Andric } 241