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/Twine.h" 16 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 17 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 18 #include "llvm/CodeGen/MachineRegisterInfo.h" 19 #include "llvm/CodeGen/TargetPassConfig.h" 20 #include "llvm/IR/Function.h" 21 #include "llvm/Support/CommandLine.h" 22 #include "llvm/Support/Debug.h" 23 #include "llvm/Target/TargetSubtargetInfo.h" 24 25 #define DEBUG_TYPE "instruction-select" 26 27 using namespace llvm; 28 29 char InstructionSelect::ID = 0; 30 INITIALIZE_PASS_BEGIN(InstructionSelect, DEBUG_TYPE, 31 "Select target instructions out of generic instructions", 32 false, false) 33 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 34 INITIALIZE_PASS_END(InstructionSelect, DEBUG_TYPE, 35 "Select target instructions out of generic instructions", 36 false, false) 37 38 InstructionSelect::InstructionSelect() : MachineFunctionPass(ID) { 39 initializeInstructionSelectPass(*PassRegistry::getPassRegistry()); 40 } 41 42 void InstructionSelect::getAnalysisUsage(AnalysisUsage &AU) const { 43 AU.addRequired<TargetPassConfig>(); 44 MachineFunctionPass::getAnalysisUsage(AU); 45 } 46 47 static void reportSelectionError(const MachineInstr *MI, const Twine &Message) { 48 const MachineFunction &MF = *MI->getParent()->getParent(); 49 std::string ErrStorage; 50 raw_string_ostream Err(ErrStorage); 51 Err << Message << ":\nIn function: " << MF.getName() << '\n'; 52 if (MI) 53 Err << *MI << '\n'; 54 report_fatal_error(Err.str()); 55 } 56 57 bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { 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 // FIXME: freezeReservedRegs is now done in IRTranslator, but there are many 70 // other MF/MFI fields we need to initialize. 71 72 const MachineRegisterInfo &MRI = MF.getRegInfo(); 73 74 #ifndef NDEBUG 75 // Check that our input is fully legal: we require the function to have the 76 // Legalized property, so it should be. 77 // FIXME: This should be in the MachineVerifier, but it can't use the 78 // LegalizerInfo as it's currently in the separate GlobalISel library. 79 // The RegBankSelected property is already checked in the verifier. Note 80 // that it has the same layering problem, but we only use inline methods so 81 // end up not needing to link against the GlobalISel library. 82 if (const LegalizerInfo *MLI = MF.getSubtarget().getLegalizerInfo()) 83 for (const MachineBasicBlock &MBB : MF) 84 for (const MachineInstr &MI : MBB) 85 if (isPreISelGenericOpcode(MI.getOpcode()) && !MLI->isLegal(MI, MRI)) 86 reportSelectionError(&MI, "Instruction is not legal"); 87 88 #endif 89 // FIXME: We could introduce new blocks and will need to fix the outer loop. 90 // Until then, keep track of the number of blocks to assert that we don't. 91 const size_t NumBlocks = MF.size(); 92 93 bool Failed = false; 94 for (MachineBasicBlock *MBB : post_order(&MF)) { 95 if (MBB->empty()) 96 continue; 97 98 // Select instructions in reverse block order. We permit erasing so have 99 // to resort to manually iterating and recognizing the begin (rend) case. 100 bool ReachedBegin = false; 101 for (auto MII = std::prev(MBB->end()), Begin = MBB->begin(); 102 !ReachedBegin;) { 103 #ifndef NDEBUG 104 // Keep track of the insertion range for debug printing. 105 const auto AfterIt = std::next(MII); 106 #endif 107 // Select this instruction. 108 MachineInstr &MI = *MII; 109 110 // And have our iterator point to the next instruction, if there is one. 111 if (MII == Begin) 112 ReachedBegin = true; 113 else 114 --MII; 115 116 DEBUG(dbgs() << "Selecting: \n " << MI); 117 118 if (!ISel->select(MI)) { 119 if (TPC.isGlobalISelAbortEnabled()) 120 // FIXME: It would be nice to dump all inserted instructions. It's 121 // not 122 // obvious how, esp. considering select() can insert after MI. 123 reportSelectionError(&MI, "Cannot select"); 124 Failed = true; 125 break; 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 auto *MI = MRI.def_instr_begin(VReg) == MRI.def_instr_end() 146 ? nullptr 147 : &*MRI.def_instr_begin(VReg); 148 if (!RC) { 149 if (TPC.isGlobalISelAbortEnabled()) 150 reportSelectionError(MI, "VReg as no regclass after selection"); 151 Failed = true; 152 break; 153 } 154 155 if (VRegToType.second.isValid() && 156 VRegToType.second.getSizeInBits() > (RC->getSize() * 8)) { 157 if (TPC.isGlobalISelAbortEnabled()) 158 reportSelectionError( 159 MI, "VReg has explicit size different from class size"); 160 Failed = true; 161 break; 162 } 163 } 164 165 MRI.getVRegToType().clear(); 166 167 if (!TPC.isGlobalISelAbortEnabled() && (Failed || MF.size() == NumBlocks)) { 168 MF.getProperties().set(MachineFunctionProperties::Property::FailedISel); 169 return false; 170 } 171 assert(MF.size() == NumBlocks && "Inserting blocks is not supported yet"); 172 173 // FIXME: Should we accurately track changes? 174 return true; 175 } 176