16756a2c9SAhmed Bougacha //===- llvm/CodeGen/GlobalISel/InstructionSelect.cpp - InstructionSelect ---==//
26756a2c9SAhmed Bougacha //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66756a2c9SAhmed Bougacha //
76756a2c9SAhmed Bougacha //===----------------------------------------------------------------------===//
86756a2c9SAhmed Bougacha /// \file
96756a2c9SAhmed Bougacha /// This file implements the InstructionSelect class.
106756a2c9SAhmed Bougacha //===----------------------------------------------------------------------===//
116756a2c9SAhmed Bougacha
126756a2c9SAhmed Bougacha #include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
136756a2c9SAhmed Bougacha #include "llvm/ADT/PostOrderIterator.h"
148a316045SAmara Emerson #include "llvm/ADT/ScopeExit.h"
158a316045SAmara Emerson #include "llvm/Analysis/LazyBlockFrequencyInfo.h"
168a316045SAmara Emerson #include "llvm/Analysis/ProfileSummaryInfo.h"
17caff0a88SMatt Arsenault #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
186756a2c9SAhmed Bougacha #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
1969fa84a6STim Northover #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
20ae9dadecSAhmed Bougacha #include "llvm/CodeGen/GlobalISel/Utils.h"
217ac10399SAmara Emerson #include "llvm/CodeGen/MachineFrameInfo.h"
2289b57061SReid Kleckner #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
236756a2c9SAhmed Bougacha #include "llvm/CodeGen/MachineRegisterInfo.h"
24b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetLowering.h"
25948abf0aSQuentin Colombet #include "llvm/CodeGen/TargetPassConfig.h"
26b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetSubtargetInfo.h"
27f76f3154SDaniel Sanders #include "llvm/Config/config.h"
286756a2c9SAhmed Bougacha #include "llvm/IR/Function.h"
2989b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h"
30*ed98c1b3Sserge-sans-paille #include "llvm/Support/CodeGenCoverage.h"
316756a2c9SAhmed Bougacha #include "llvm/Support/CommandLine.h"
326756a2c9SAhmed Bougacha #include "llvm/Support/Debug.h"
33fe0006c8SSimon Pilgrim #include "llvm/Target/TargetMachine.h"
346756a2c9SAhmed Bougacha
356756a2c9SAhmed Bougacha #define DEBUG_TYPE "instruction-select"
366756a2c9SAhmed Bougacha
376756a2c9SAhmed Bougacha using namespace llvm;
386756a2c9SAhmed Bougacha
39f76f3154SDaniel Sanders #ifdef LLVM_GISEL_COV_PREFIX
40f76f3154SDaniel Sanders static cl::opt<std::string>
41f76f3154SDaniel Sanders CoveragePrefix("gisel-coverage-prefix", cl::init(LLVM_GISEL_COV_PREFIX),
42f76f3154SDaniel Sanders cl::desc("Record GlobalISel rule coverage files of this "
43f76f3154SDaniel Sanders "prefix if instrumentation was generated"));
44f76f3154SDaniel Sanders #else
4512fc9ca3SKazu Hirata static const std::string CoveragePrefix;
46f76f3154SDaniel Sanders #endif
47f76f3154SDaniel Sanders
486756a2c9SAhmed Bougacha char InstructionSelect::ID = 0;
49948abf0aSQuentin Colombet INITIALIZE_PASS_BEGIN(InstructionSelect, DEBUG_TYPE,
506756a2c9SAhmed Bougacha "Select target instructions out of generic instructions",
51948abf0aSQuentin Colombet false, false)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)52948abf0aSQuentin Colombet INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
53466ec2d5SMatt Arsenault INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
548a316045SAmara Emerson INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
558a316045SAmara Emerson INITIALIZE_PASS_DEPENDENCY(LazyBlockFrequencyInfoPass)
56948abf0aSQuentin Colombet INITIALIZE_PASS_END(InstructionSelect, DEBUG_TYPE,
57948abf0aSQuentin Colombet "Select target instructions out of generic instructions",
58948abf0aSQuentin Colombet false, false)
596756a2c9SAhmed Bougacha
608a316045SAmara Emerson InstructionSelect::InstructionSelect(CodeGenOpt::Level OL)
618a316045SAmara Emerson : MachineFunctionPass(ID), OptLevel(OL) {}
628a316045SAmara Emerson
638a316045SAmara Emerson // In order not to crash when calling getAnalysis during testing with -run-pass
648a316045SAmara Emerson // we use the default opt level here instead of None, so that the addRequired()
658a316045SAmara Emerson // calls are made in getAnalysisUsage().
InstructionSelect()668a316045SAmara Emerson InstructionSelect::InstructionSelect()
678a316045SAmara Emerson : MachineFunctionPass(ID), OptLevel(CodeGenOpt::Default) {}
686756a2c9SAhmed Bougacha
getAnalysisUsage(AnalysisUsage & AU) const69948abf0aSQuentin Colombet void InstructionSelect::getAnalysisUsage(AnalysisUsage &AU) const {
70948abf0aSQuentin Colombet AU.addRequired<TargetPassConfig>();
71caff0a88SMatt Arsenault AU.addRequired<GISelKnownBitsAnalysis>();
72caff0a88SMatt Arsenault AU.addPreserved<GISelKnownBitsAnalysis>();
735a16306cSMatt Arsenault
745a16306cSMatt Arsenault if (OptLevel != CodeGenOpt::None) {
758a316045SAmara Emerson AU.addRequired<ProfileSummaryInfoWrapperPass>();
768a316045SAmara Emerson LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
778a316045SAmara Emerson }
7890ad6835SMatthias Braun getSelectionDAGFallbackAnalysisUsage(AU);
79948abf0aSQuentin Colombet MachineFunctionPass::getAnalysisUsage(AU);
80948abf0aSQuentin Colombet }
81948abf0aSQuentin Colombet
runOnMachineFunction(MachineFunction & MF)826756a2c9SAhmed Bougacha bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
836049524dSQuentin Colombet // If the ISel pipeline failed, do not bother running that pass.
846049524dSQuentin Colombet if (MF.getProperties().hasProperty(
856049524dSQuentin Colombet MachineFunctionProperties::Property::FailedISel))
866049524dSQuentin Colombet return false;
876049524dSQuentin Colombet
88d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Selecting function: " << MF.getName() << '\n');
896756a2c9SAhmed Bougacha
90948abf0aSQuentin Colombet const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
91e14c91b7SAmara Emerson InstructionSelector *ISel = MF.getSubtarget().getInstructionSelector();
928a316045SAmara Emerson
938a316045SAmara Emerson CodeGenOpt::Level OldOptLevel = OptLevel;
948a316045SAmara Emerson auto RestoreOptLevel = make_scope_exit([=]() { OptLevel = OldOptLevel; });
958a316045SAmara Emerson OptLevel = MF.getFunction().hasOptNone() ? CodeGenOpt::None
968a316045SAmara Emerson : MF.getTarget().getOptLevel();
978a316045SAmara Emerson
985a16306cSMatt Arsenault GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
998a316045SAmara Emerson if (OptLevel != CodeGenOpt::None) {
1008a316045SAmara Emerson PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
1018a316045SAmara Emerson if (PSI && PSI->hasProfileSummary())
1028a316045SAmara Emerson BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
1038a316045SAmara Emerson }
1048a316045SAmara Emerson
105f76f3154SDaniel Sanders CodeGenCoverage CoverageInfo;
1066756a2c9SAhmed Bougacha assert(ISel && "Cannot work without InstructionSelector");
1078a316045SAmara Emerson ISel->setupMF(MF, KB, CoverageInfo, PSI, BFI);
1086756a2c9SAhmed Bougacha
109ae9dadecSAhmed Bougacha // An optimization remark emitter. Used to report failures.
110ae9dadecSAhmed Bougacha MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
111ae9dadecSAhmed Bougacha
1124682ac6cSMatthias Braun // FIXME: There are many other MF/MFI fields we need to initialize.
1136756a2c9SAhmed Bougacha
11413229affSRoman Tereshin MachineRegisterInfo &MRI = MF.getRegInfo();
1156756a2c9SAhmed Bougacha #ifndef NDEBUG
11624d0d4d2SAhmed Bougacha // Check that our input is fully legal: we require the function to have the
11724d0d4d2SAhmed Bougacha // Legalized property, so it should be.
1182b94972eSRoman Tereshin // FIXME: This should be in the MachineVerifier, as the RegBankSelected
1192b94972eSRoman Tereshin // property check already is.
1202b94972eSRoman Tereshin if (!DisableGISelLegalityCheck)
1212b94972eSRoman Tereshin if (const MachineInstr *MI = machineFunctionIsIllegal(MF)) {
122ae9dadecSAhmed Bougacha reportGISelFailure(MF, TPC, MORE, "gisel-select",
1232b94972eSRoman Tereshin "instruction is not legal", *MI);
124ae9dadecSAhmed Bougacha return false;
125ae9dadecSAhmed Bougacha }
1266756a2c9SAhmed Bougacha // FIXME: We could introduce new blocks and will need to fix the outer loop.
1276756a2c9SAhmed Bougacha // Until then, keep track of the number of blocks to assert that we don't.
1286756a2c9SAhmed Bougacha const size_t NumBlocks = MF.size();
1297097e83dSAmara Emerson #endif
1306bc64e24SAmara Emerson // Keep track of selected blocks, so we can delete unreachable ones later.
1316bc64e24SAmara Emerson DenseSet<MachineBasicBlock *> SelectedBlocks;
1326756a2c9SAhmed Bougacha
1336756a2c9SAhmed Bougacha for (MachineBasicBlock *MBB : post_order(&MF)) {
1348a316045SAmara Emerson ISel->CurMBB = MBB;
1356bc64e24SAmara Emerson SelectedBlocks.insert(MBB);
136db273a12SAhmed Bougacha if (MBB->empty())
137db273a12SAhmed Bougacha continue;
138db273a12SAhmed Bougacha
139db273a12SAhmed Bougacha // Select instructions in reverse block order. We permit erasing so have
140db273a12SAhmed Bougacha // to resort to manually iterating and recognizing the begin (rend) case.
141db273a12SAhmed Bougacha bool ReachedBegin = false;
142db273a12SAhmed Bougacha for (auto MII = std::prev(MBB->end()), Begin = MBB->begin();
143db273a12SAhmed Bougacha !ReachedBegin;) {
144e09ae201SDavid L. Jones #ifndef NDEBUG
145db273a12SAhmed Bougacha // Keep track of the insertion range for debug printing.
146db273a12SAhmed Bougacha const auto AfterIt = std::next(MII);
147e09ae201SDavid L. Jones #endif
148db273a12SAhmed Bougacha // Select this instruction.
149db273a12SAhmed Bougacha MachineInstr &MI = *MII;
150db273a12SAhmed Bougacha
151db273a12SAhmed Bougacha // And have our iterator point to the next instruction, if there is one.
152db273a12SAhmed Bougacha if (MII == Begin)
153db273a12SAhmed Bougacha ReachedBegin = true;
154db273a12SAhmed Bougacha else
155db273a12SAhmed Bougacha --MII;
156db273a12SAhmed Bougacha
157d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Selecting: \n " << MI);
158db273a12SAhmed Bougacha
159931904d7SAhmed Bougacha // We could have folded this instruction away already, making it dead.
160931904d7SAhmed Bougacha // If so, erase it.
161931904d7SAhmed Bougacha if (isTriviallyDead(MI, MRI)) {
162d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Is dead; erasing.\n");
163f108c7f5SJack Andersen MI.eraseFromParent();
164931904d7SAhmed Bougacha continue;
165931904d7SAhmed Bougacha }
166931904d7SAhmed Bougacha
167d6656c3bSJessica Paquette // Eliminate hints.
168d6656c3bSJessica Paquette if (isPreISelGenericOptimizationHint(MI.getOpcode())) {
169d6656c3bSJessica Paquette Register DstReg = MI.getOperand(0).getReg();
170d6656c3bSJessica Paquette Register SrcReg = MI.getOperand(1).getReg();
17148096633SJessica Paquette
17248096633SJessica Paquette // At this point, the destination register class of the hint may have
17348096633SJessica Paquette // been decided.
17448096633SJessica Paquette //
17548096633SJessica Paquette // Propagate that through to the source register.
17648096633SJessica Paquette const TargetRegisterClass *DstRC = MRI.getRegClassOrNull(DstReg);
17748096633SJessica Paquette if (DstRC)
17848096633SJessica Paquette MRI.setRegClass(SrcReg, DstRC);
17948096633SJessica Paquette assert(canReplaceReg(DstReg, SrcReg, MRI) &&
18048096633SJessica Paquette "Must be able to replace dst with src!");
181d6656c3bSJessica Paquette MI.eraseFromParent();
182d6656c3bSJessica Paquette MRI.replaceRegWith(DstReg, SrcReg);
183d6656c3bSJessica Paquette continue;
184d6656c3bSJessica Paquette }
185d6656c3bSJessica Paquette
186e14c91b7SAmara Emerson if (!ISel->select(MI)) {
1876cddfc14STim Northover // FIXME: It would be nice to dump all inserted instructions. It's
1881f5c5054SJustin Bogner // not obvious how, esp. considering select() can insert after MI.
189ae9dadecSAhmed Bougacha reportGISelFailure(MF, TPC, MORE, "gisel-select", "cannot select", MI);
1901b333944SAhmed Bougacha return false;
191948abf0aSQuentin Colombet }
19253a03a28SAhmed Bougacha
19353a03a28SAhmed Bougacha // Dump the range of instructions that MI expanded into.
194d34e60caSNicola Zaghen LLVM_DEBUG({
19553a03a28SAhmed Bougacha auto InsertedBegin = ReachedBegin ? MBB->begin() : std::next(MII);
19653a03a28SAhmed Bougacha dbgs() << "Into:\n";
19753a03a28SAhmed Bougacha for (auto &InsertedMI : make_range(InsertedBegin, AfterIt))
19853a03a28SAhmed Bougacha dbgs() << " " << InsertedMI;
19953a03a28SAhmed Bougacha dbgs() << '\n';
20053a03a28SAhmed Bougacha });
2016756a2c9SAhmed Bougacha }
2026756a2c9SAhmed Bougacha }
2036756a2c9SAhmed Bougacha
204f2aa2af2SAditya Nandakumar for (MachineBasicBlock &MBB : MF) {
205f2aa2af2SAditya Nandakumar if (MBB.empty())
206f2aa2af2SAditya Nandakumar continue;
207f2aa2af2SAditya Nandakumar
2086bc64e24SAmara Emerson if (!SelectedBlocks.contains(&MBB)) {
2096bc64e24SAmara Emerson // This is an unreachable block and therefore hasn't been selected, since
2106bc64e24SAmara Emerson // the main selection loop above uses a postorder block traversal.
2116bc64e24SAmara Emerson // We delete all the instructions in this block since it's unreachable.
2126bc64e24SAmara Emerson MBB.clear();
2136bc64e24SAmara Emerson // Don't delete the block in case the block has it's address taken or is
2146bc64e24SAmara Emerson // still being referenced by a phi somewhere.
2156bc64e24SAmara Emerson continue;
2166bc64e24SAmara Emerson }
217f2aa2af2SAditya Nandakumar // Try to find redundant copies b/w vregs of the same register class.
218f2aa2af2SAditya Nandakumar bool ReachedBegin = false;
219f2aa2af2SAditya Nandakumar for (auto MII = std::prev(MBB.end()), Begin = MBB.begin(); !ReachedBegin;) {
220f2aa2af2SAditya Nandakumar // Select this instruction.
221f2aa2af2SAditya Nandakumar MachineInstr &MI = *MII;
222f2aa2af2SAditya Nandakumar
223f2aa2af2SAditya Nandakumar // And have our iterator point to the next instruction, if there is one.
224f2aa2af2SAditya Nandakumar if (MII == Begin)
225f2aa2af2SAditya Nandakumar ReachedBegin = true;
226f2aa2af2SAditya Nandakumar else
227f2aa2af2SAditya Nandakumar --MII;
228f2aa2af2SAditya Nandakumar if (MI.getOpcode() != TargetOpcode::COPY)
229f2aa2af2SAditya Nandakumar continue;
2300c476111SDaniel Sanders Register SrcReg = MI.getOperand(1).getReg();
2310c476111SDaniel Sanders Register DstReg = MI.getOperand(0).getReg();
2322bea69bfSDaniel Sanders if (Register::isVirtualRegister(SrcReg) &&
2332bea69bfSDaniel Sanders Register::isVirtualRegister(DstReg)) {
234f2aa2af2SAditya Nandakumar auto SrcRC = MRI.getRegClass(SrcReg);
235f2aa2af2SAditya Nandakumar auto DstRC = MRI.getRegClass(DstReg);
236f2aa2af2SAditya Nandakumar if (SrcRC == DstRC) {
237f2aa2af2SAditya Nandakumar MRI.replaceRegWith(DstReg, SrcReg);
2386a2413c4SDavid Stenberg MI.eraseFromParent();
239f2aa2af2SAditya Nandakumar }
240f2aa2af2SAditya Nandakumar }
241f2aa2af2SAditya Nandakumar }
242f2aa2af2SAditya Nandakumar }
243f2aa2af2SAditya Nandakumar
2447097e83dSAmara Emerson #ifndef NDEBUG
2457097e83dSAmara Emerson const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
2466cddfc14STim Northover // Now that selection is complete, there are no more generic vregs. Verify
2476cddfc14STim Northover // that the size of the now-constrained vreg is unchanged and that it has a
2486cddfc14STim Northover // register class.
24913229affSRoman Tereshin for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
2502bea69bfSDaniel Sanders unsigned VReg = Register::index2VirtReg(I);
25113229affSRoman Tereshin
252480609d0STim Northover MachineInstr *MI = nullptr;
253c94d7033STim Northover if (!MRI.def_empty(VReg))
254480609d0STim Northover MI = &*MRI.def_instr_begin(VReg);
255f108c7f5SJack Andersen else if (!MRI.use_empty(VReg)) {
256480609d0STim Northover MI = &*MRI.use_instr_begin(VReg);
257f108c7f5SJack Andersen // Debug value instruction is permitted to use undefined vregs.
258f108c7f5SJack Andersen if (MI->isDebugValue())
259f108c7f5SJack Andersen continue;
260f108c7f5SJack Andersen }
26113229affSRoman Tereshin if (!MI)
26213229affSRoman Tereshin continue;
263480609d0STim Northover
26413229affSRoman Tereshin const TargetRegisterClass *RC = MRI.getRegClassOrNull(VReg);
26513229affSRoman Tereshin if (!RC) {
266ae9dadecSAhmed Bougacha reportGISelFailure(MF, TPC, MORE, "gisel-select",
267ae9dadecSAhmed Bougacha "VReg has no regclass after selection", *MI);
2681b333944SAhmed Bougacha return false;
26913229affSRoman Tereshin }
2706cddfc14STim Northover
27113229affSRoman Tereshin const LLT Ty = MRI.getType(VReg);
27213229affSRoman Tereshin if (Ty.isValid() && Ty.getSizeInBits() > TRI.getRegSizeInBits(*RC)) {
27313229affSRoman Tereshin reportGISelFailure(
27413229affSRoman Tereshin MF, TPC, MORE, "gisel-select",
27513229affSRoman Tereshin "VReg's low-level type and register class have different sizes", *MI);
276948abf0aSQuentin Colombet return false;
277948abf0aSQuentin Colombet }
2781b333944SAhmed Bougacha }
2791b333944SAhmed Bougacha
2801b333944SAhmed Bougacha if (MF.size() != NumBlocks) {
281ae9dadecSAhmed Bougacha MachineOptimizationRemarkMissed R("gisel-select", "GISelFailure",
282f1caa283SMatthias Braun MF.getFunction().getSubprogram(),
2837c88a4e1SAhmed Bougacha /*MBB=*/nullptr);
284ae9dadecSAhmed Bougacha R << "inserting blocks is not supported yet";
285ae9dadecSAhmed Bougacha reportGISelFailure(MF, TPC, MORE, R);
2861b333944SAhmed Bougacha return false;
2871b333944SAhmed Bougacha }
2887097e83dSAmara Emerson #endif
2897ac10399SAmara Emerson // Determine if there are any calls in this machine function. Ported from
2907ac10399SAmara Emerson // SelectionDAG.
2917ac10399SAmara Emerson MachineFrameInfo &MFI = MF.getFrameInfo();
2927ac10399SAmara Emerson for (const auto &MBB : MF) {
2937ac10399SAmara Emerson if (MFI.hasCalls() && MF.hasInlineAsm())
2947ac10399SAmara Emerson break;
2957ac10399SAmara Emerson
2967ac10399SAmara Emerson for (const auto &MI : MBB) {
2977ac10399SAmara Emerson if ((MI.isCall() && !MI.isReturn()) || MI.isStackAligningInlineAsm())
2987ac10399SAmara Emerson MFI.setHasCalls(true);
2997ac10399SAmara Emerson if (MI.isInlineAsm())
3007ac10399SAmara Emerson MF.setHasInlineAsm(true);
3017ac10399SAmara Emerson }
3027ac10399SAmara Emerson }
3037ac10399SAmara Emerson
304521ebc16SMatt Arsenault // FIXME: FinalizeISel pass calls finalizeLowering, so it's called twice.
305521ebc16SMatt Arsenault auto &TLI = *MF.getSubtarget().getTargetLowering();
306521ebc16SMatt Arsenault TLI.finalizeLowering(MF);
3077ac10399SAmara Emerson
308d34e60caSNicola Zaghen LLVM_DEBUG({
30938489ed4SRoman Tereshin dbgs() << "Rules covered by selecting function: " << MF.getName() << ":";
31038489ed4SRoman Tereshin for (auto RuleID : CoverageInfo.covered())
31138489ed4SRoman Tereshin dbgs() << " id" << RuleID;
31238489ed4SRoman Tereshin dbgs() << "\n\n";
31338489ed4SRoman Tereshin });
314f76f3154SDaniel Sanders CoverageInfo.emit(CoveragePrefix,
315521ebc16SMatt Arsenault TLI.getTargetMachine().getTarget().getBackendName());
316f76f3154SDaniel Sanders
3173054eceaSRoman Tereshin // If we successfully selected the function nothing is going to use the vreg
3183054eceaSRoman Tereshin // types after us (otherwise MIRPrinter would need them). Make sure the types
3193054eceaSRoman Tereshin // disappear.
32013229affSRoman Tereshin MRI.clearVirtRegTypes();
3213054eceaSRoman Tereshin
3226756a2c9SAhmed Bougacha // FIXME: Should we accurately track changes?
3236756a2c9SAhmed Bougacha return true;
3246756a2c9SAhmed Bougacha }
325