1 //===- llvm/CodeGen/GlobalISel/InstructionSelect.cpp - InstructionSelect ---==// 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 InstructionSelect class. 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" 14 #include "llvm/ADT/PostOrderIterator.h" 15 #include "llvm/ADT/ScopeExit.h" 16 #include "llvm/ADT/Twine.h" 17 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 18 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 19 #include "llvm/CodeGen/GlobalISel/Utils.h" 20 #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" 21 #include "llvm/CodeGen/MachineRegisterInfo.h" 22 #include "llvm/CodeGen/TargetPassConfig.h" 23 #include "llvm/IR/Function.h" 24 #include "llvm/Support/CommandLine.h" 25 #include "llvm/Support/Debug.h" 26 #include "llvm/Target/TargetSubtargetInfo.h" 27 28 #define DEBUG_TYPE "instruction-select" 29 30 using namespace llvm; 31 32 char InstructionSelect::ID = 0; 33 INITIALIZE_PASS_BEGIN(InstructionSelect, DEBUG_TYPE, 34 "Select target instructions out of generic instructions", 35 false, false) 36 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 37 INITIALIZE_PASS_END(InstructionSelect, DEBUG_TYPE, 38 "Select target instructions out of generic instructions", 39 false, false) 40 41 InstructionSelect::InstructionSelect() : MachineFunctionPass(ID) { 42 initializeInstructionSelectPass(*PassRegistry::getPassRegistry()); 43 } 44 45 void InstructionSelect::getAnalysisUsage(AnalysisUsage &AU) const { 46 AU.addRequired<TargetPassConfig>(); 47 MachineFunctionPass::getAnalysisUsage(AU); 48 } 49 50 bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { 51 const MachineRegisterInfo &MRI = MF.getRegInfo(); 52 53 // No matter what happens, whether we successfully select the function or not, 54 // nothing is going to use the vreg types after us. Make sure they disappear. 55 auto ClearVRegTypesOnReturn = 56 make_scope_exit([&]() { MRI.getVRegToType().clear(); }); 57 58 // If the ISel pipeline failed, do not bother running that pass. 59 if (MF.getProperties().hasProperty( 60 MachineFunctionProperties::Property::FailedISel)) 61 return false; 62 63 DEBUG(dbgs() << "Selecting function: " << MF.getName() << '\n'); 64 65 const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>(); 66 const InstructionSelector *ISel = MF.getSubtarget().getInstructionSelector(); 67 assert(ISel && "Cannot work without InstructionSelector"); 68 69 // An optimization remark emitter. Used to report failures. 70 MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr); 71 72 // FIXME: freezeReservedRegs is now done in IRTranslator, but there are many 73 // other MF/MFI fields we need to initialize. 74 75 #ifndef NDEBUG 76 // Check that our input is fully legal: we require the function to have the 77 // Legalized property, so it should be. 78 // FIXME: This should be in the MachineVerifier, but it can't use the 79 // LegalizerInfo as it's currently in the separate GlobalISel library. 80 // The RegBankSelected property is already checked in the verifier. Note 81 // that it has the same layering problem, but we only use inline methods so 82 // end up not needing to link against the GlobalISel library. 83 if (const LegalizerInfo *MLI = MF.getSubtarget().getLegalizerInfo()) 84 for (MachineBasicBlock &MBB : MF) 85 for (MachineInstr &MI : MBB) 86 if (isPreISelGenericOpcode(MI.getOpcode()) && !MLI->isLegal(MI, MRI)) { 87 reportGISelFailure(MF, TPC, MORE, "gisel-select", 88 "instruction is not legal", MI); 89 return false; 90 } 91 92 #endif 93 // FIXME: We could introduce new blocks and will need to fix the outer loop. 94 // Until then, keep track of the number of blocks to assert that we don't. 95 const size_t NumBlocks = MF.size(); 96 97 for (MachineBasicBlock *MBB : post_order(&MF)) { 98 if (MBB->empty()) 99 continue; 100 101 // Select instructions in reverse block order. We permit erasing so have 102 // to resort to manually iterating and recognizing the begin (rend) case. 103 bool ReachedBegin = false; 104 for (auto MII = std::prev(MBB->end()), Begin = MBB->begin(); 105 !ReachedBegin;) { 106 #ifndef NDEBUG 107 // Keep track of the insertion range for debug printing. 108 const auto AfterIt = std::next(MII); 109 #endif 110 // Select this instruction. 111 MachineInstr &MI = *MII; 112 113 // And have our iterator point to the next instruction, if there is one. 114 if (MII == Begin) 115 ReachedBegin = true; 116 else 117 --MII; 118 119 DEBUG(dbgs() << "Selecting: \n " << MI); 120 121 if (!ISel->select(MI)) { 122 // FIXME: It would be nice to dump all inserted instructions. It's 123 // not obvious how, esp. considering select() can insert after MI. 124 reportGISelFailure(MF, TPC, MORE, "gisel-select", "cannot select", MI); 125 return false; 126 } 127 128 // Dump the range of instructions that MI expanded into. 129 DEBUG({ 130 auto InsertedBegin = ReachedBegin ? MBB->begin() : std::next(MII); 131 dbgs() << "Into:\n"; 132 for (auto &InsertedMI : make_range(InsertedBegin, AfterIt)) 133 dbgs() << " " << InsertedMI; 134 dbgs() << '\n'; 135 }); 136 } 137 } 138 139 // Now that selection is complete, there are no more generic vregs. Verify 140 // that the size of the now-constrained vreg is unchanged and that it has a 141 // register class. 142 for (auto &VRegToType : MRI.getVRegToType()) { 143 unsigned VReg = VRegToType.first; 144 auto *RC = MRI.getRegClassOrNull(VReg); 145 MachineInstr *MI = nullptr; 146 if (!MRI.def_empty(VReg)) 147 MI = &*MRI.def_instr_begin(VReg); 148 else if (!MRI.use_empty(VReg)) 149 MI = &*MRI.use_instr_begin(VReg); 150 151 if (MI && !RC) { 152 reportGISelFailure(MF, TPC, MORE, "gisel-select", 153 "VReg has no regclass after selection", *MI); 154 return false; 155 } else if (!RC) 156 continue; 157 158 if (VRegToType.second.isValid() && 159 VRegToType.second.getSizeInBits() > (RC->getSize() * 8)) { 160 reportGISelFailure(MF, TPC, MORE, "gisel-select", 161 "VReg has explicit size different from class size", 162 *MI); 163 return false; 164 } 165 } 166 167 if (MF.size() != NumBlocks) { 168 MachineOptimizationRemarkMissed R("gisel-select", "GISelFailure", 169 MF.getFunction()->getSubprogram(), 170 /*MBB=*/nullptr); 171 R << "inserting blocks is not supported yet"; 172 reportGISelFailure(MF, TPC, MORE, R); 173 return false; 174 } 175 176 // FIXME: Should we accurately track changes? 177 return true; 178 } 179