1//=- llvm/CodeGen/GlobalISel/RegBankSelect.h - Reg Bank Selector --*- C++ -*-=//
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//
9/// \file
10/// This file describes the interface of the MachineFunctionPass
11/// responsible for assigning the generic virtual registers to register bank.
12///
13/// By default, the reg bank selector relies on local decisions to
14/// assign the register bank. In other words, it looks at one instruction
15/// at a time to decide where the operand of that instruction should live.
16///
17/// At higher optimization level, we could imagine that the reg bank selector
18/// would use more global analysis and do crazier thing like duplicating
19/// instructions and so on. This is future work.
20///
21/// For now, the pass uses a greedy algorithm to decide where the operand
22/// of an instruction should live. It asks the target which banks may be
23/// used for each operand of the instruction and what is the cost. Then,
24/// it chooses the solution which minimize the cost of the instruction plus
25/// the cost of any move that may be needed to the values into the right
26/// register bank.
27/// In other words, the cost for an instruction on a register bank RegBank
28/// is: Cost of I on RegBank plus the sum of the cost for bringing the
29/// input operands from their current register bank to RegBank.
30/// Thus, the following formula:
31/// cost(I, RegBank) = cost(I.Opcode, RegBank) +
32///    sum(for each arg in I.arguments: costCrossCopy(arg.RegBank, RegBank))
33///
34/// E.g., Let say we are assigning the register bank for the instruction
35/// defining v2.
36/// v0(A_REGBANK) = ...
37/// v1(A_REGBANK) = ...
38/// v2 = G_ADD i32 v0, v1 <-- MI
39///
40/// The target may say it can generate G_ADD i32 on register bank A and B
41/// with a cost of respectively 5 and 1.
42/// Then, let say the cost of a cross register bank copies from A to B is 1.
43/// The reg bank selector would compare the following two costs:
44/// cost(MI, A_REGBANK) = cost(G_ADD, A_REGBANK) + cost(v0.RegBank, A_REGBANK) +
45///    cost(v1.RegBank, A_REGBANK)
46///                     = 5 + cost(A_REGBANK, A_REGBANK) + cost(A_REGBANK,
47///                                                             A_REGBANK)
48///                     = 5 + 0 + 0 = 5
49/// cost(MI, B_REGBANK) = cost(G_ADD, B_REGBANK) + cost(v0.RegBank, B_REGBANK) +
50///    cost(v1.RegBank, B_REGBANK)
51///                     = 1 + cost(A_REGBANK, B_REGBANK) + cost(A_REGBANK,
52///                                                             B_REGBANK)
53///                     = 1 + 1 + 1 = 3
54/// Therefore, in this specific example, the reg bank selector would choose
55/// bank B for MI.
56/// v0(A_REGBANK) = ...
57/// v1(A_REGBANK) = ...
58/// tmp0(B_REGBANK) = COPY v0
59/// tmp1(B_REGBANK) = COPY v1
60/// v2(B_REGBANK) = G_ADD i32 tmp0, tmp1
61//
62//===----------------------------------------------------------------------===//
63
64#ifndef LLVM_CODEGEN_GLOBALISEL_REGBANKSELECT_H
65#define LLVM_CODEGEN_GLOBALISEL_REGBANKSELECT_H
66
67#include "llvm/ADT/SmallVector.h"
68#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
69#include "llvm/CodeGen/MachineBasicBlock.h"
70#include "llvm/CodeGen/MachineFunctionPass.h"
71#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
72#include "llvm/CodeGen/RegisterBankInfo.h"
73#include <cassert>
74#include <cstdint>
75#include <memory>
76
77namespace llvm {
78
79class BlockFrequency;
80class MachineBlockFrequencyInfo;
81class MachineBranchProbabilityInfo;
82class MachineOperand;
83class MachineRegisterInfo;
84class Pass;
85class raw_ostream;
86class TargetPassConfig;
87class TargetRegisterInfo;
88
89/// This pass implements the reg bank selector pass used in the GlobalISel
90/// pipeline. At the end of this pass, all register operands have been assigned
91class RegBankSelect : public MachineFunctionPass {
92public:
93  static char ID;
94
95  /// List of the modes supported by the RegBankSelect pass.
96  enum Mode {
97    /// Assign the register banks as fast as possible (default).
98    Fast,
99    /// Greedily minimize the cost of assigning register banks.
100    /// This should produce code of greater quality, but will
101    /// require more compile time.
102    Greedy
103  };
104
105  /// Abstract class used to represent an insertion point in a CFG.
106  /// This class records an insertion point and materializes it on
107  /// demand.
108  /// It allows to reason about the frequency of this insertion point,
109  /// without having to logically materialize it (e.g., on an edge),
110  /// before we actually need to insert something.
111  class InsertPoint {
112  protected:
113    /// Tell if the insert point has already been materialized.
114    bool WasMaterialized = false;
115
116    /// Materialize the insertion point.
117    ///
118    /// If isSplit() is true, this involves actually splitting
119    /// the block or edge.
120    ///
121    /// \post getPointImpl() returns a valid iterator.
122    /// \post getInsertMBBImpl() returns a valid basic block.
123    /// \post isSplit() == false ; no more splitting should be required.
124    virtual void materialize() = 0;
125
126    /// Return the materialized insertion basic block.
127    /// Code will be inserted into that basic block.
128    ///
129    /// \pre ::materialize has been called.
130    virtual MachineBasicBlock &getInsertMBBImpl() = 0;
131
132    /// Return the materialized insertion point.
133    /// Code will be inserted before that point.
134    ///
135    /// \pre ::materialize has been called.
136    virtual MachineBasicBlock::iterator getPointImpl() = 0;
137
138  public:
139    virtual ~InsertPoint() = default;
140
141    /// The first call to this method will cause the splitting to
142    /// happen if need be, then sub sequent calls just return
143    /// the iterator to that point. I.e., no more splitting will
144    /// occur.
145    ///
146    /// \return The iterator that should be used with
147    /// MachineBasicBlock::insert. I.e., additional code happens
148    /// before that point.
149    MachineBasicBlock::iterator getPoint() {
150      if (!WasMaterialized) {
151        WasMaterialized = true;
152        assert(canMaterialize() && "Impossible to materialize this point");
153        materialize();
154      }
155      // When we materialized the point we should have done the splitting.
156      assert(!isSplit() && "Wrong pre-condition");
157      return getPointImpl();
158    }
159
160    /// The first call to this method will cause the splitting to
161    /// happen if need be, then sub sequent calls just return
162    /// the basic block that contains the insertion point.
163    /// I.e., no more splitting will occur.
164    ///
165    /// \return The basic block should be used with
166    /// MachineBasicBlock::insert and ::getPoint. The new code should
167    /// happen before that point.
168    MachineBasicBlock &getInsertMBB() {
169      if (!WasMaterialized) {
170        WasMaterialized = true;
171        assert(canMaterialize() && "Impossible to materialize this point");
172        materialize();
173      }
174      // When we materialized the point we should have done the splitting.
175      assert(!isSplit() && "Wrong pre-condition");
176      return getInsertMBBImpl();
177    }
178
179    /// Insert \p MI in the just before ::getPoint()
180    MachineBasicBlock::iterator insert(MachineInstr &MI) {
181      return getInsertMBB().insert(getPoint(), &MI);
182    }
183
184    /// Does this point involve splitting an edge or block?
185    /// As soon as ::getPoint is called and thus, the point
186    /// materialized, the point will not require splitting anymore,
187    /// i.e., this will return false.
188    virtual bool isSplit() const { return false; }
189
190    /// Frequency of the insertion point.
191    /// \p P is used to access the various analysis that will help to
192    /// get that information, like MachineBlockFrequencyInfo.  If \p P
193    /// does not contain enough to return the actual frequency,
194    /// this returns 1.
195    virtual uint64_t frequency(const Pass &P) const { return 1; }
196
197    /// Check whether this insertion point can be materialized.
198    /// As soon as ::getPoint is called and thus, the point materialized
199    /// calling this method does not make sense.
200    virtual bool canMaterialize() const { return false; }
201  };
202
203  /// Insertion point before or after an instruction.
204  class InstrInsertPoint : public InsertPoint {
205  private:
206    /// Insertion point.
207    MachineInstr &Instr;
208
209    /// Does the insertion point is before or after Instr.
210    bool Before;
211
212    void materialize() override;
213
214    MachineBasicBlock::iterator getPointImpl() override {
215      if (Before)
216        return Instr;
217      return Instr.getNextNode() ? *Instr.getNextNode()
218                                 : Instr.getParent()->end();
219    }
220
221    MachineBasicBlock &getInsertMBBImpl() override {
222      return *Instr.getParent();
223    }
224
225  public:
226    /// Create an insertion point before (\p Before=true) or after \p Instr.
227    InstrInsertPoint(MachineInstr &Instr, bool Before = true);
228
229    bool isSplit() const override;
230    uint64_t frequency(const Pass &P) const override;
231
232    // Worst case, we need to slice the basic block, but that is still doable.
233    bool canMaterialize() const override { return true; }
234  };
235
236  /// Insertion point at the beginning or end of a basic block.
237  class MBBInsertPoint : public InsertPoint {
238  private:
239    /// Insertion point.
240    MachineBasicBlock &MBB;
241
242    /// Does the insertion point is at the beginning or end of MBB.
243    bool Beginning;
244
245    void materialize() override { /*Nothing to do to materialize*/
246    }
247
248    MachineBasicBlock::iterator getPointImpl() override {
249      return Beginning ? MBB.begin() : MBB.end();
250    }
251
252    MachineBasicBlock &getInsertMBBImpl() override { return MBB; }
253
254  public:
255    MBBInsertPoint(MachineBasicBlock &MBB, bool Beginning = true)
256        : MBB(MBB), Beginning(Beginning) {
257      // If we try to insert before phis, we should use the insertion
258      // points on the incoming edges.
259      assert((!Beginning || MBB.getFirstNonPHI() == MBB.begin()) &&
260             "Invalid beginning point");
261      // If we try to insert after the terminators, we should use the
262      // points on the outcoming edges.
263      assert((Beginning || MBB.getFirstTerminator() == MBB.end()) &&
264             "Invalid end point");
265    }
266
267    bool isSplit() const override { return false; }
268    uint64_t frequency(const Pass &P) const override;
269    bool canMaterialize() const override { return true; };
270  };
271
272  /// Insertion point on an edge.
273  class EdgeInsertPoint : public InsertPoint {
274  private:
275    /// Source of the edge.
276    MachineBasicBlock &Src;
277
278    /// Destination of the edge.
279    /// After the materialization is done, this hold the basic block
280    /// that resulted from the splitting.
281    MachineBasicBlock *DstOrSplit;
282
283    /// P is used to update the analysis passes as applicable.
284    Pass &P;
285
286    void materialize() override;
287
288    MachineBasicBlock::iterator getPointImpl() override {
289      // DstOrSplit should be the Split block at this point.
290      // I.e., it should have one predecessor, Src, and one successor,
291      // the original Dst.
292      assert(DstOrSplit && DstOrSplit->isPredecessor(&Src) &&
293             DstOrSplit->pred_size() == 1 && DstOrSplit->succ_size() == 1 &&
294             "Did not split?!");
295      return DstOrSplit->begin();
296    }
297
298    MachineBasicBlock &getInsertMBBImpl() override { return *DstOrSplit; }
299
300  public:
301    EdgeInsertPoint(MachineBasicBlock &Src, MachineBasicBlock &Dst, Pass &P)
302        : Src(Src), DstOrSplit(&Dst), P(P) {}
303
304    bool isSplit() const override {
305      return Src.succ_size() > 1 && DstOrSplit->pred_size() > 1;
306    }
307
308    uint64_t frequency(const Pass &P) const override;
309    bool canMaterialize() const override;
310  };
311
312  /// Struct used to represent the placement of a repairing point for
313  /// a given operand.
314  class RepairingPlacement {
315  public:
316    /// Define the kind of action this repairing needs.
317    enum RepairingKind {
318      /// Nothing to repair, just drop this action.
319      None,
320      /// Reparing code needs to happen before InsertPoints.
321      Insert,
322      /// (Re)assign the register bank of the operand.
323      Reassign,
324      /// Mark this repairing placement as impossible.
325      Impossible
326    };
327
328    /// \name Convenient types for a list of insertion points.
329    /// @{
330    using InsertionPoints = SmallVector<std::unique_ptr<InsertPoint>, 2>;
331    using insertpt_iterator = InsertionPoints::iterator;
332    using const_insertpt_iterator = InsertionPoints::const_iterator;
333    /// @}
334
335  private:
336    /// Kind of repairing.
337    RepairingKind Kind;
338    /// Index of the operand that will be repaired.
339    unsigned OpIdx;
340    /// Are all the insert points materializeable?
341    bool CanMaterialize;
342    /// Is there any of the insert points needing splitting?
343    bool HasSplit = false;
344    /// Insertion point for the repair code.
345    /// The repairing code needs to happen just before these points.
346    InsertionPoints InsertPoints;
347    /// Some insertion points may need to update the liveness and such.
348    Pass &P;
349
350  public:
351    /// Create a repairing placement for the \p OpIdx-th operand of
352    /// \p MI. \p TRI is used to make some checks on the register aliases
353    /// if the machine operand is a physical register. \p P is used to
354    /// to update liveness information and such when materializing the
355    /// points.
356    RepairingPlacement(MachineInstr &MI, unsigned OpIdx,
357                       const TargetRegisterInfo &TRI, Pass &P,
358                       RepairingKind Kind = RepairingKind::Insert);
359
360    /// \name Getters.
361    /// @{
362    RepairingKind getKind() const { return Kind; }
363    unsigned getOpIdx() const { return OpIdx; }
364    bool canMaterialize() const { return CanMaterialize; }
365    bool hasSplit() { return HasSplit; }
366    /// @}
367
368    /// \name Overloaded methods to add an insertion point.
369    /// @{
370    /// Add a MBBInsertionPoint to the list of InsertPoints.
371    void addInsertPoint(MachineBasicBlock &MBB, bool Beginning);
372    /// Add a InstrInsertionPoint to the list of InsertPoints.
373    void addInsertPoint(MachineInstr &MI, bool Before);
374    /// Add an EdgeInsertionPoint (\p Src, \p Dst) to the list of InsertPoints.
375    void addInsertPoint(MachineBasicBlock &Src, MachineBasicBlock &Dst);
376    /// Add an InsertPoint to the list of insert points.
377    /// This method takes the ownership of &\p Point.
378    void addInsertPoint(InsertPoint &Point);
379    /// @}
380
381    /// \name Accessors related to the insertion points.
382    /// @{
383    insertpt_iterator begin() { return InsertPoints.begin(); }
384    insertpt_iterator end() { return InsertPoints.end(); }
385
386    const_insertpt_iterator begin() const { return InsertPoints.begin(); }
387    const_insertpt_iterator end() const { return InsertPoints.end(); }
388
389    unsigned getNumInsertPoints() const { return InsertPoints.size(); }
390    /// @}
391
392    /// Change the type of this repairing placement to \p NewKind.
393    /// It is not possible to switch a repairing placement to the
394    /// RepairingKind::Insert. There is no fundamental problem with
395    /// that, but no uses as well, so do not support it for now.
396    ///
397    /// \pre NewKind != RepairingKind::Insert
398    /// \post getKind() == NewKind
399    void switchTo(RepairingKind NewKind) {
400      assert(NewKind != Kind && "Already of the right Kind");
401      Kind = NewKind;
402      InsertPoints.clear();
403      CanMaterialize = NewKind != RepairingKind::Impossible;
404      HasSplit = false;
405      assert(NewKind != RepairingKind::Insert &&
406             "We would need more MI to switch to Insert");
407    }
408  };
409
410protected:
411  /// Helper class used to represent the cost for mapping an instruction.
412  /// When mapping an instruction, we may introduce some repairing code.
413  /// In most cases, the repairing code is local to the instruction,
414  /// thus, we can omit the basic block frequency from the cost.
415  /// However, some alternatives may produce non-local cost, e.g., when
416  /// repairing a phi, and thus we then need to scale the local cost
417  /// to the non-local cost. This class does this for us.
418  /// \note: We could simply always scale the cost. The problem is that
419  /// there are higher chances that we saturate the cost easier and end
420  /// up having the same cost for actually different alternatives.
421  /// Another option would be to use APInt everywhere.
422  class MappingCost {
423  private:
424    /// Cost of the local instructions.
425    /// This cost is free of basic block frequency.
426    uint64_t LocalCost = 0;
427    /// Cost of the non-local instructions.
428    /// This cost should include the frequency of the related blocks.
429    uint64_t NonLocalCost = 0;
430    /// Frequency of the block where the local instructions live.
431    uint64_t LocalFreq;
432
433    MappingCost(uint64_t LocalCost, uint64_t NonLocalCost, uint64_t LocalFreq)
434        : LocalCost(LocalCost), NonLocalCost(NonLocalCost),
435          LocalFreq(LocalFreq) {}
436
437    /// Check if this cost is saturated.
438    bool isSaturated() const;
439
440  public:
441    /// Create a MappingCost assuming that most of the instructions
442    /// will occur in a basic block with \p LocalFreq frequency.
443    MappingCost(BlockFrequency LocalFreq);
444
445    /// Add \p Cost to the local cost.
446    /// \return true if this cost is saturated, false otherwise.
447    bool addLocalCost(uint64_t Cost);
448
449    /// Add \p Cost to the non-local cost.
450    /// Non-local cost should reflect the frequency of their placement.
451    /// \return true if this cost is saturated, false otherwise.
452    bool addNonLocalCost(uint64_t Cost);
453
454    /// Saturate the cost to the maximal representable value.
455    void saturate();
456
457    /// Return an instance of MappingCost that represents an
458    /// impossible mapping.
459    static MappingCost ImpossibleCost();
460
461    /// Check if this is less than \p Cost.
462    bool operator<(const MappingCost &Cost) const;
463    /// Check if this is equal to \p Cost.
464    bool operator==(const MappingCost &Cost) const;
465    /// Check if this is not equal to \p Cost.
466    bool operator!=(const MappingCost &Cost) const { return !(*this == Cost); }
467    /// Check if this is greater than \p Cost.
468    bool operator>(const MappingCost &Cost) const {
469      return *this != Cost && Cost < *this;
470    }
471
472    /// Print this on dbgs() stream.
473    void dump() const;
474
475    /// Print this on \p OS;
476    void print(raw_ostream &OS) const;
477
478    /// Overload the stream operator for easy debug printing.
479    friend raw_ostream &operator<<(raw_ostream &OS, const MappingCost &Cost) {
480      Cost.print(OS);
481      return OS;
482    }
483  };
484
485  /// Interface to the target lowering info related
486  /// to register banks.
487  const RegisterBankInfo *RBI = nullptr;
488
489  /// MRI contains all the register class/bank information that this
490  /// pass uses and updates.
491  MachineRegisterInfo *MRI = nullptr;
492
493  /// Information on the register classes for the current function.
494  const TargetRegisterInfo *TRI = nullptr;
495
496  /// Get the frequency of blocks.
497  /// This is required for non-fast mode.
498  MachineBlockFrequencyInfo *MBFI = nullptr;
499
500  /// Get the frequency of the edges.
501  /// This is required for non-fast mode.
502  MachineBranchProbabilityInfo *MBPI = nullptr;
503
504  /// Current optimization remark emitter. Used to report failures.
505  std::unique_ptr<MachineOptimizationRemarkEmitter> MORE;
506
507  /// Helper class used for every code morphing.
508  MachineIRBuilder MIRBuilder;
509
510  /// Optimization mode of the pass.
511  Mode OptMode;
512
513  /// Current target configuration. Controls how the pass handles errors.
514  const TargetPassConfig *TPC;
515
516  /// Assign the register bank of each operand of \p MI.
517  /// \return True on success, false otherwise.
518  bool assignInstr(MachineInstr &MI);
519
520  /// Initialize the field members using \p MF.
521  void init(MachineFunction &MF);
522
523  /// Check if \p Reg is already assigned what is described by \p ValMapping.
524  /// \p OnlyAssign == true means that \p Reg just needs to be assigned a
525  /// register bank.  I.e., no repairing is necessary to have the
526  /// assignment match.
527  bool assignmentMatch(Register Reg,
528                       const RegisterBankInfo::ValueMapping &ValMapping,
529                       bool &OnlyAssign) const;
530
531  /// Insert repairing code for \p Reg as specified by \p ValMapping.
532  /// The repairing placement is specified by \p RepairPt.
533  /// \p NewVRegs contains all the registers required to remap \p Reg.
534  /// In other words, the number of registers in NewVRegs must be equal
535  /// to ValMapping.BreakDown.size().
536  ///
537  /// The transformation could be sketched as:
538  /// \code
539  /// ... = op Reg
540  /// \endcode
541  /// Becomes
542  /// \code
543  /// <NewRegs> = COPY or extract Reg
544  /// ... = op Reg
545  /// \endcode
546  ///
547  /// and
548  /// \code
549  /// Reg = op ...
550  /// \endcode
551  /// Becomes
552  /// \code
553  /// Reg = op ...
554  /// Reg = COPY or build_sequence <NewRegs>
555  /// \endcode
556  ///
557  /// \pre NewVRegs.size() == ValMapping.BreakDown.size()
558  ///
559  /// \note The caller is supposed to do the rewriting of op if need be.
560  /// I.e., Reg = op ... => <NewRegs> = NewOp ...
561  ///
562  /// \return True if the repairing worked, false otherwise.
563  bool repairReg(MachineOperand &MO,
564                 const RegisterBankInfo::ValueMapping &ValMapping,
565                 RegBankSelect::RepairingPlacement &RepairPt,
566                 const iterator_range<SmallVectorImpl<Register>::const_iterator>
567                     &NewVRegs);
568
569  /// Return the cost of the instruction needed to map \p MO to \p ValMapping.
570  /// The cost is free of basic block frequencies.
571  /// \pre MO.isReg()
572  /// \pre MO is assigned to a register bank.
573  /// \pre ValMapping is a valid mapping for MO.
574  uint64_t
575  getRepairCost(const MachineOperand &MO,
576                const RegisterBankInfo::ValueMapping &ValMapping) const;
577
578  /// Find the best mapping for \p MI from \p PossibleMappings.
579  /// \return a reference on the best mapping in \p PossibleMappings.
580  const RegisterBankInfo::InstructionMapping &
581  findBestMapping(MachineInstr &MI,
582                  RegisterBankInfo::InstructionMappings &PossibleMappings,
583                  SmallVectorImpl<RepairingPlacement> &RepairPts);
584
585  /// Compute the cost of mapping \p MI with \p InstrMapping and
586  /// compute the repairing placement for such mapping in \p
587  /// RepairPts.
588  /// \p BestCost is used to specify when the cost becomes too high
589  /// and thus it is not worth computing the RepairPts.  Moreover if
590  /// \p BestCost == nullptr, the mapping cost is actually not
591  /// computed.
592  MappingCost
593  computeMapping(MachineInstr &MI,
594                 const RegisterBankInfo::InstructionMapping &InstrMapping,
595                 SmallVectorImpl<RepairingPlacement> &RepairPts,
596                 const MappingCost *BestCost = nullptr);
597
598  /// When \p RepairPt involves splitting to repair \p MO for the
599  /// given \p ValMapping, try to change the way we repair such that
600  /// the splitting is not required anymore.
601  ///
602  /// \pre \p RepairPt.hasSplit()
603  /// \pre \p MO == MO.getParent()->getOperand(\p RepairPt.getOpIdx())
604  /// \pre \p ValMapping is the mapping of \p MO for MO.getParent()
605  ///      that implied \p RepairPt.
606  void tryAvoidingSplit(RegBankSelect::RepairingPlacement &RepairPt,
607                        const MachineOperand &MO,
608                        const RegisterBankInfo::ValueMapping &ValMapping) const;
609
610  /// Apply \p Mapping to \p MI. \p RepairPts represents the different
611  /// mapping action that need to happen for the mapping to be
612  /// applied.
613  /// \return True if the mapping was applied sucessfully, false otherwise.
614  bool applyMapping(MachineInstr &MI,
615                    const RegisterBankInfo::InstructionMapping &InstrMapping,
616                    SmallVectorImpl<RepairingPlacement> &RepairPts);
617
618public:
619  /// Create a RegBankSelect pass with the specified \p RunningMode.
620  RegBankSelect(char &PassID = ID, Mode RunningMode = Fast);
621
622  StringRef getPassName() const override { return "RegBankSelect"; }
623
624  void getAnalysisUsage(AnalysisUsage &AU) const override;
625
626  MachineFunctionProperties getRequiredProperties() const override {
627    return MachineFunctionProperties()
628        .set(MachineFunctionProperties::Property::IsSSA)
629        .set(MachineFunctionProperties::Property::Legalized);
630  }
631
632  MachineFunctionProperties getSetProperties() const override {
633    return MachineFunctionProperties().set(
634        MachineFunctionProperties::Property::RegBankSelected);
635  }
636
637  MachineFunctionProperties getClearedProperties() const override {
638    return MachineFunctionProperties()
639      .set(MachineFunctionProperties::Property::NoPHIs);
640  }
641
642  /// Check that our input is fully legal: we require the function to have the
643  /// Legalized property, so it should be.
644  ///
645  /// FIXME: This should be in the MachineVerifier.
646  bool checkFunctionIsLegal(MachineFunction &MF) const;
647
648  /// Walk through \p MF and assign a register bank to every virtual register
649  /// that are still mapped to nothing.
650  /// The target needs to provide a RegisterBankInfo and in particular
651  /// override RegisterBankInfo::getInstrMapping.
652  ///
653  /// Simplified algo:
654  /// \code
655  ///   RBI = MF.subtarget.getRegBankInfo()
656  ///   MIRBuilder.setMF(MF)
657  ///   for each bb in MF
658  ///     for each inst in bb
659  ///       MIRBuilder.setInstr(inst)
660  ///       MappingCosts = RBI.getMapping(inst);
661  ///       Idx = findIdxOfMinCost(MappingCosts)
662  ///       CurRegBank = MappingCosts[Idx].RegBank
663  ///       MRI.setRegBank(inst.getOperand(0).getReg(), CurRegBank)
664  ///       for each argument in inst
665  ///         if (CurRegBank != argument.RegBank)
666  ///           ArgReg = argument.getReg()
667  ///           Tmp = MRI.createNewVirtual(MRI.getSize(ArgReg), CurRegBank)
668  ///           MIRBuilder.buildInstr(COPY, Tmp, ArgReg)
669  ///           inst.getOperand(argument.getOperandNo()).setReg(Tmp)
670  /// \endcode
671  bool assignRegisterBanks(MachineFunction &MF);
672
673  bool runOnMachineFunction(MachineFunction &MF) override;
674};
675
676} // end namespace llvm
677
678#endif // LLVM_CODEGEN_GLOBALISEL_REGBANKSELECT_H
679