| 1 | //===- llvm/CodeGen/GlobalISel/InstructionSelect.cpp - InstructionSelect ---==// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | /// \file |
| 9 | /// This file implements the InstructionSelect class. |
| 10 | //===----------------------------------------------------------------------===// |
| 11 | |
| 12 | #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" |
| 13 | #include "llvm/ADT/PostOrderIterator.h" |
| 14 | #include "llvm/ADT/ScopeExit.h" |
| 15 | #include "llvm/ADT/SetVector.h" |
| 16 | #include "llvm/Analysis/LazyBlockFrequencyInfo.h" |
| 17 | #include "llvm/Analysis/ProfileSummaryInfo.h" |
| 18 | #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" |
| 19 | #include "llvm/CodeGen/GlobalISel/GISelValueTracking.h" |
| 20 | #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" |
| 21 | #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" |
| 22 | #include "llvm/CodeGen/GlobalISel/Utils.h" |
| 23 | #include "llvm/CodeGen/MachineFrameInfo.h" |
| 24 | #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" |
| 25 | #include "llvm/CodeGen/MachineRegisterInfo.h" |
| 26 | #include "llvm/CodeGen/TargetLowering.h" |
| 27 | #include "llvm/CodeGen/TargetOpcodes.h" |
| 28 | #include "llvm/CodeGen/TargetPassConfig.h" |
| 29 | #include "llvm/CodeGen/TargetSubtargetInfo.h" |
| 30 | #include "llvm/Config/config.h" |
| 31 | #include "llvm/IR/Function.h" |
| 32 | #include "llvm/MC/TargetRegistry.h" |
| 33 | #include "llvm/Support/CodeGenCoverage.h" |
| 34 | #include "llvm/Support/Debug.h" |
| 35 | #include "llvm/Support/DebugCounter.h" |
| 36 | #include "llvm/Target/TargetMachine.h" |
| 37 | |
| 38 | #define DEBUG_TYPE "instruction-select" |
| 39 | |
| 40 | using namespace llvm; |
| 41 | |
| 42 | DEBUG_COUNTER(GlobalISelCounter, "globalisel" , |
| 43 | "Controls whether to select function with GlobalISel" ); |
| 44 | |
| 45 | #ifdef LLVM_GISEL_COV_PREFIX |
| 46 | static cl::opt<std::string> |
| 47 | CoveragePrefix("gisel-coverage-prefix" , cl::init(LLVM_GISEL_COV_PREFIX), |
| 48 | cl::desc("Record GlobalISel rule coverage files of this " |
| 49 | "prefix if instrumentation was generated" )); |
| 50 | #else |
| 51 | static const std::string CoveragePrefix; |
| 52 | #endif |
| 53 | |
| 54 | char InstructionSelect::ID = 0; |
| 55 | INITIALIZE_PASS_BEGIN(InstructionSelect, DEBUG_TYPE, |
| 56 | "Select target instructions out of generic instructions" , |
| 57 | false, false) |
| 58 | INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) |
| 59 | INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy) |
| 60 | INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass) |
| 61 | INITIALIZE_PASS_DEPENDENCY(LazyBlockFrequencyInfoPass) |
| 62 | INITIALIZE_PASS_END(InstructionSelect, DEBUG_TYPE, |
| 63 | "Select target instructions out of generic instructions" , |
| 64 | false, false) |
| 65 | |
| 66 | InstructionSelect::InstructionSelect(CodeGenOptLevel OL, char &PassID) |
| 67 | : MachineFunctionPass(PassID), OptLevel(OL) {} |
| 68 | |
| 69 | /// This class observes instruction insertions/removals. |
| 70 | /// InstructionSelect stores an iterator of the instruction prior to the one |
| 71 | /// that is currently being selected to determine which instruction to select |
| 72 | /// next. Previously this meant that selecting multiple instructions at once was |
| 73 | /// illegal behavior due to potential invalidation of this iterator. This is |
| 74 | /// a non-obvious limitation for selector implementers. Therefore, to allow |
| 75 | /// deletion of arbitrary instructions, we detect this case and continue |
| 76 | /// selection with the predecessor of the deleted instruction. |
| 77 | class InstructionSelect::MIIteratorMaintainer : public GISelChangeObserver { |
| 78 | #ifndef NDEBUG |
| 79 | SmallSetVector<const MachineInstr *, 32> CreatedInstrs; |
| 80 | #endif |
| 81 | public: |
| 82 | MachineBasicBlock::reverse_iterator MII; |
| 83 | |
| 84 | void changingInstr(MachineInstr &MI) override { |
| 85 | llvm_unreachable("InstructionSelect does not track changed instructions!" ); |
| 86 | } |
| 87 | void changedInstr(MachineInstr &MI) override { |
| 88 | llvm_unreachable("InstructionSelect does not track changed instructions!" ); |
| 89 | } |
| 90 | |
| 91 | void createdInstr(MachineInstr &MI) override { |
| 92 | LLVM_DEBUG(dbgs() << "Creating: " << MI; CreatedInstrs.insert(&MI)); |
| 93 | } |
| 94 | |
| 95 | void erasingInstr(MachineInstr &MI) override { |
| 96 | LLVM_DEBUG(dbgs() << "Erasing: " << MI; CreatedInstrs.remove(&MI)); |
| 97 | if (MII.getInstrIterator().getNodePtr() == &MI) { |
| 98 | // If the iterator points to the MI that will be erased (i.e. the MI prior |
| 99 | // to the MI that is currently being selected), the iterator would be |
| 100 | // invalidated. Continue selection with its predecessor. |
| 101 | ++MII; |
| 102 | LLVM_DEBUG(dbgs() << "Instruction removal updated iterator.\n" ); |
| 103 | } |
| 104 | } |
| 105 | |
| 106 | void reportFullyCreatedInstrs() { |
| 107 | LLVM_DEBUG({ |
| 108 | if (CreatedInstrs.empty()) { |
| 109 | dbgs() << "Created no instructions.\n" ; |
| 110 | } else { |
| 111 | dbgs() << "Created:\n" ; |
| 112 | for (const auto *MI : CreatedInstrs) { |
| 113 | dbgs() << " " << *MI; |
| 114 | } |
| 115 | CreatedInstrs.clear(); |
| 116 | } |
| 117 | }); |
| 118 | } |
| 119 | }; |
| 120 | |
| 121 | void InstructionSelect::getAnalysisUsage(AnalysisUsage &AU) const { |
| 122 | AU.addRequired<TargetPassConfig>(); |
| 123 | AU.addRequired<GISelValueTrackingAnalysisLegacy>(); |
| 124 | AU.addPreserved<GISelValueTrackingAnalysisLegacy>(); |
| 125 | |
| 126 | if (OptLevel != CodeGenOptLevel::None) { |
| 127 | AU.addRequired<ProfileSummaryInfoWrapperPass>(); |
| 128 | LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU); |
| 129 | } |
| 130 | getSelectionDAGFallbackAnalysisUsage(AU); |
| 131 | MachineFunctionPass::getAnalysisUsage(AU); |
| 132 | } |
| 133 | |
| 134 | bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { |
| 135 | // If the ISel pipeline failed, do not bother running that pass. |
| 136 | if (MF.getProperties().hasFailedISel()) |
| 137 | return false; |
| 138 | |
| 139 | ISel = MF.getSubtarget().getInstructionSelector(); |
| 140 | ISel->TPC = &getAnalysis<TargetPassConfig>(); |
| 141 | |
| 142 | // FIXME: Properly override OptLevel in TargetMachine. See OptLevelChanger |
| 143 | CodeGenOptLevel OldOptLevel = OptLevel; |
| 144 | auto RestoreOptLevel = make_scope_exit(F: [=]() { OptLevel = OldOptLevel; }); |
| 145 | OptLevel = MF.getFunction().hasOptNone() ? CodeGenOptLevel::None |
| 146 | : MF.getTarget().getOptLevel(); |
| 147 | |
| 148 | VT = &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF); |
| 149 | if (OptLevel != CodeGenOptLevel::None) { |
| 150 | PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI(); |
| 151 | if (PSI && PSI->hasProfileSummary()) |
| 152 | BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI(); |
| 153 | } |
| 154 | |
| 155 | return selectMachineFunction(MF); |
| 156 | } |
| 157 | |
| 158 | bool InstructionSelect::selectMachineFunction(MachineFunction &MF) { |
| 159 | LLVM_DEBUG(dbgs() << "Selecting function: " << MF.getName() << '\n'); |
| 160 | assert(ISel && "Cannot work without InstructionSelector" ); |
| 161 | |
| 162 | const TargetPassConfig &TPC = *ISel->TPC; |
| 163 | CodeGenCoverage CoverageInfo; |
| 164 | ISel->setupMF(mf&: MF, vt: VT, covinfo: &CoverageInfo, psi: PSI, bfi: BFI); |
| 165 | |
| 166 | // An optimization remark emitter. Used to report failures. |
| 167 | MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr); |
| 168 | ISel->MORE = &MORE; |
| 169 | |
| 170 | // FIXME: There are many other MF/MFI fields we need to initialize. |
| 171 | |
| 172 | MachineRegisterInfo &MRI = MF.getRegInfo(); |
| 173 | #ifndef NDEBUG |
| 174 | // Check that our input is fully legal: we require the function to have the |
| 175 | // Legalized property, so it should be. |
| 176 | // FIXME: This should be in the MachineVerifier, as the RegBankSelected |
| 177 | // property check already is. |
| 178 | if (!DisableGISelLegalityCheck) |
| 179 | if (const MachineInstr *MI = machineFunctionIsIllegal(MF)) { |
| 180 | reportGISelFailure(MF, TPC, MORE, "gisel-select" , |
| 181 | "instruction is not legal" , *MI); |
| 182 | return false; |
| 183 | } |
| 184 | // FIXME: We could introduce new blocks and will need to fix the outer loop. |
| 185 | // Until then, keep track of the number of blocks to assert that we don't. |
| 186 | const size_t NumBlocks = MF.size(); |
| 187 | #endif |
| 188 | // Keep track of selected blocks, so we can delete unreachable ones later. |
| 189 | DenseSet<MachineBasicBlock *> SelectedBlocks; |
| 190 | |
| 191 | { |
| 192 | // Observe IR insertions and removals during selection. |
| 193 | // We only install a MachineFunction::Delegate instead of a |
| 194 | // GISelChangeObserver, because we do not want notifications about changed |
| 195 | // instructions. This prevents significant compile-time regressions from |
| 196 | // e.g. constrainOperandRegClass(). |
| 197 | GISelObserverWrapper AllObservers; |
| 198 | MIIteratorMaintainer MIIMaintainer; |
| 199 | AllObservers.addObserver(O: &MIIMaintainer); |
| 200 | RAIIDelegateInstaller DelInstaller(MF, &AllObservers); |
| 201 | ISel->AllObservers = &AllObservers; |
| 202 | |
| 203 | for (MachineBasicBlock *MBB : post_order(G: &MF)) { |
| 204 | ISel->CurMBB = MBB; |
| 205 | SelectedBlocks.insert(V: MBB); |
| 206 | |
| 207 | // Select instructions in reverse block order. |
| 208 | MIIMaintainer.MII = MBB->rbegin(); |
| 209 | for (auto End = MBB->rend(); MIIMaintainer.MII != End;) { |
| 210 | MachineInstr &MI = *MIIMaintainer.MII; |
| 211 | // Increment early to skip instructions inserted by select(). |
| 212 | ++MIIMaintainer.MII; |
| 213 | |
| 214 | LLVM_DEBUG(dbgs() << "\nSelect: " << MI); |
| 215 | if (!selectInstr(MI)) { |
| 216 | LLVM_DEBUG(dbgs() << "Selection failed!\n" ; |
| 217 | MIIMaintainer.reportFullyCreatedInstrs()); |
| 218 | reportGISelFailure(MF, TPC, MORE, PassName: "gisel-select" , Msg: "cannot select" , |
| 219 | MI); |
| 220 | return false; |
| 221 | } |
| 222 | LLVM_DEBUG(MIIMaintainer.reportFullyCreatedInstrs()); |
| 223 | } |
| 224 | } |
| 225 | } |
| 226 | |
| 227 | for (MachineBasicBlock &MBB : MF) { |
| 228 | if (MBB.empty()) |
| 229 | continue; |
| 230 | |
| 231 | if (!SelectedBlocks.contains(V: &MBB)) { |
| 232 | // This is an unreachable block and therefore hasn't been selected, since |
| 233 | // the main selection loop above uses a postorder block traversal. |
| 234 | // We delete all the instructions in this block since it's unreachable. |
| 235 | MBB.clear(); |
| 236 | // Don't delete the block in case the block has it's address taken or is |
| 237 | // still being referenced by a phi somewhere. |
| 238 | continue; |
| 239 | } |
| 240 | // Try to find redundant copies b/w vregs of the same register class. |
| 241 | for (auto MII = MBB.rbegin(), End = MBB.rend(); MII != End;) { |
| 242 | MachineInstr &MI = *MII; |
| 243 | ++MII; |
| 244 | |
| 245 | if (MI.getOpcode() != TargetOpcode::COPY) |
| 246 | continue; |
| 247 | Register SrcReg = MI.getOperand(i: 1).getReg(); |
| 248 | Register DstReg = MI.getOperand(i: 0).getReg(); |
| 249 | if (SrcReg.isVirtual() && DstReg.isVirtual()) { |
| 250 | auto SrcRC = MRI.getRegClass(Reg: SrcReg); |
| 251 | auto DstRC = MRI.getRegClass(Reg: DstReg); |
| 252 | if (SrcRC == DstRC) { |
| 253 | MRI.replaceRegWith(FromReg: DstReg, ToReg: SrcReg); |
| 254 | MI.eraseFromParent(); |
| 255 | } |
| 256 | } |
| 257 | } |
| 258 | } |
| 259 | |
| 260 | #ifndef NDEBUG |
| 261 | const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); |
| 262 | // Now that selection is complete, there are no more generic vregs. Verify |
| 263 | // that the size of the now-constrained vreg is unchanged and that it has a |
| 264 | // register class. |
| 265 | for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) { |
| 266 | Register VReg = Register::index2VirtReg(I); |
| 267 | |
| 268 | MachineInstr *MI = nullptr; |
| 269 | if (!MRI.def_empty(VReg)) |
| 270 | MI = &*MRI.def_instr_begin(VReg); |
| 271 | else if (!MRI.use_empty(VReg)) { |
| 272 | MI = &*MRI.use_instr_begin(VReg); |
| 273 | // Debug value instruction is permitted to use undefined vregs. |
| 274 | if (MI->isDebugValue()) |
| 275 | continue; |
| 276 | } |
| 277 | if (!MI) |
| 278 | continue; |
| 279 | |
| 280 | const TargetRegisterClass *RC = MRI.getRegClassOrNull(VReg); |
| 281 | if (!RC) { |
| 282 | reportGISelFailure(MF, TPC, MORE, "gisel-select" , |
| 283 | "VReg has no regclass after selection" , *MI); |
| 284 | return false; |
| 285 | } |
| 286 | |
| 287 | const LLT Ty = MRI.getType(VReg); |
| 288 | if (Ty.isValid() && |
| 289 | TypeSize::isKnownGT(Ty.getSizeInBits(), TRI.getRegSizeInBits(*RC))) { |
| 290 | reportGISelFailure( |
| 291 | MF, TPC, MORE, "gisel-select" , |
| 292 | "VReg's low-level type and register class have different sizes" , *MI); |
| 293 | return false; |
| 294 | } |
| 295 | } |
| 296 | |
| 297 | if (MF.size() != NumBlocks) { |
| 298 | MachineOptimizationRemarkMissed R("gisel-select" , "GISelFailure" , |
| 299 | MF.getFunction().getSubprogram(), |
| 300 | /*MBB=*/nullptr); |
| 301 | R << "inserting blocks is not supported yet" ; |
| 302 | reportGISelFailure(MF, TPC, MORE, R); |
| 303 | return false; |
| 304 | } |
| 305 | #endif |
| 306 | |
| 307 | if (!DebugCounter::shouldExecute(CounterName: GlobalISelCounter)) { |
| 308 | dbgs() << "Falling back for function " << MF.getName() << "\n" ; |
| 309 | MF.getProperties().setFailedISel(); |
| 310 | return false; |
| 311 | } |
| 312 | |
| 313 | // Determine if there are any calls in this machine function. Ported from |
| 314 | // SelectionDAG. |
| 315 | MachineFrameInfo &MFI = MF.getFrameInfo(); |
| 316 | for (const auto &MBB : MF) { |
| 317 | if (MFI.hasCalls() && MF.hasInlineAsm()) |
| 318 | break; |
| 319 | |
| 320 | for (const auto &MI : MBB) { |
| 321 | if ((MI.isCall() && !MI.isReturn()) || MI.isStackAligningInlineAsm()) |
| 322 | MFI.setHasCalls(true); |
| 323 | if (MI.isInlineAsm()) |
| 324 | MF.setHasInlineAsm(true); |
| 325 | } |
| 326 | } |
| 327 | |
| 328 | // FIXME: FinalizeISel pass calls finalizeLowering, so it's called twice. |
| 329 | auto &TLI = *MF.getSubtarget().getTargetLowering(); |
| 330 | TLI.finalizeLowering(MF); |
| 331 | |
| 332 | LLVM_DEBUG({ |
| 333 | dbgs() << "Rules covered by selecting function: " << MF.getName() << ":" ; |
| 334 | for (auto RuleID : CoverageInfo.covered()) |
| 335 | dbgs() << " id" << RuleID; |
| 336 | dbgs() << "\n\n" ; |
| 337 | }); |
| 338 | CoverageInfo.emit(FilePrefix: CoveragePrefix, |
| 339 | BackendName: TLI.getTargetMachine().getTarget().getBackendName()); |
| 340 | |
| 341 | // If we successfully selected the function nothing is going to use the vreg |
| 342 | // types after us (otherwise MIRPrinter would need them). Make sure the types |
| 343 | // disappear. |
| 344 | MRI.clearVirtRegTypes(); |
| 345 | |
| 346 | // FIXME: Should we accurately track changes? |
| 347 | return true; |
| 348 | } |
| 349 | |
| 350 | bool InstructionSelect::selectInstr(MachineInstr &MI) { |
| 351 | MachineRegisterInfo &MRI = ISel->MF->getRegInfo(); |
| 352 | |
| 353 | // We could have folded this instruction away already, making it dead. |
| 354 | // If so, erase it. |
| 355 | if (isTriviallyDead(MI, MRI)) { |
| 356 | LLVM_DEBUG(dbgs() << "Is dead.\n" ); |
| 357 | salvageDebugInfo(MRI, MI); |
| 358 | MI.eraseFromParent(); |
| 359 | return true; |
| 360 | } |
| 361 | |
| 362 | // Eliminate hints or G_CONSTANT_FOLD_BARRIER. |
| 363 | if (isPreISelGenericOptimizationHint(Opcode: MI.getOpcode()) || |
| 364 | MI.getOpcode() == TargetOpcode::G_CONSTANT_FOLD_BARRIER) { |
| 365 | auto [DstReg, SrcReg] = MI.getFirst2Regs(); |
| 366 | |
| 367 | // At this point, the destination register class of the op may have |
| 368 | // been decided. |
| 369 | // |
| 370 | // Propagate that through to the source register. |
| 371 | const TargetRegisterClass *DstRC = MRI.getRegClassOrNull(Reg: DstReg); |
| 372 | if (DstRC) |
| 373 | MRI.setRegClass(Reg: SrcReg, RC: DstRC); |
| 374 | assert(canReplaceReg(DstReg, SrcReg, MRI) && |
| 375 | "Must be able to replace dst with src!" ); |
| 376 | MI.eraseFromParent(); |
| 377 | MRI.replaceRegWith(FromReg: DstReg, ToReg: SrcReg); |
| 378 | return true; |
| 379 | } |
| 380 | |
| 381 | if (MI.getOpcode() == TargetOpcode::G_INVOKE_REGION_START) { |
| 382 | MI.eraseFromParent(); |
| 383 | return true; |
| 384 | } |
| 385 | |
| 386 | return ISel->select(I&: MI); |
| 387 | } |
| 388 | |