Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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.  
  77. namespace llvm {
  78.  
  79. class BlockFrequency;
  80. class MachineBlockFrequencyInfo;
  81. class MachineBranchProbabilityInfo;
  82. class MachineOperand;
  83. class MachineRegisterInfo;
  84. class Pass;
  85. class raw_ostream;
  86. class TargetPassConfig;
  87. class 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
  91. class RegBankSelect : public MachineFunctionPass {
  92. public:
  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 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.  
  410. protected:
  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(const 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.  
  618. public:
  619.   /// Create a RegBankSelect pass with the specified \p RunningMode.
  620.   RegBankSelect(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.