]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
MFV r316860: 7545 zdb should disable reference tracking
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / CodeGen / GlobalISel / InstructionSelect.cpp
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 }