Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:31

0001 //===- llvm/CodeGen/MachineInstrBundle.h - MI bundle utilities --*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file provide utility functions to manipulate machine instruction
0010 // bundles.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CODEGEN_MACHINEINSTRBUNDLE_H
0015 #define LLVM_CODEGEN_MACHINEINSTRBUNDLE_H
0016 
0017 #include "llvm/CodeGen/MachineBasicBlock.h"
0018 
0019 namespace llvm {
0020 
0021 /// finalizeBundle - Finalize a machine instruction bundle which includes
0022 /// a sequence of instructions starting from FirstMI to LastMI (exclusive).
0023 /// This routine adds a BUNDLE instruction to represent the bundle, it adds
0024 /// IsInternalRead markers to MachineOperands which are defined inside the
0025 /// bundle, and it copies externally visible defs and uses to the BUNDLE
0026 /// instruction.
0027 void finalizeBundle(MachineBasicBlock &MBB,
0028                     MachineBasicBlock::instr_iterator FirstMI,
0029                     MachineBasicBlock::instr_iterator LastMI);
0030 
0031 /// finalizeBundle - Same functionality as the previous finalizeBundle except
0032 /// the last instruction in the bundle is not provided as an input. This is
0033 /// used in cases where bundles are pre-determined by marking instructions
0034 /// with 'InsideBundle' marker. It returns the MBB instruction iterator that
0035 /// points to the end of the bundle.
0036 MachineBasicBlock::instr_iterator finalizeBundle(MachineBasicBlock &MBB,
0037                     MachineBasicBlock::instr_iterator FirstMI);
0038 
0039 /// finalizeBundles - Finalize instruction bundles in the specified
0040 /// MachineFunction. Return true if any bundles are finalized.
0041 bool finalizeBundles(MachineFunction &MF);
0042 
0043 /// Returns an iterator to the first instruction in the bundle containing \p I.
0044 inline MachineBasicBlock::instr_iterator getBundleStart(
0045     MachineBasicBlock::instr_iterator I) {
0046   while (I->isBundledWithPred())
0047     --I;
0048   return I;
0049 }
0050 
0051 /// Returns an iterator to the first instruction in the bundle containing \p I.
0052 inline MachineBasicBlock::const_instr_iterator getBundleStart(
0053     MachineBasicBlock::const_instr_iterator I) {
0054   while (I->isBundledWithPred())
0055     --I;
0056   return I;
0057 }
0058 
0059 /// Returns an iterator pointing beyond the bundle containing \p I.
0060 inline MachineBasicBlock::instr_iterator getBundleEnd(
0061     MachineBasicBlock::instr_iterator I) {
0062   while (I->isBundledWithSucc())
0063     ++I;
0064   ++I;
0065   return I;
0066 }
0067 
0068 /// Returns an iterator pointing beyond the bundle containing \p I.
0069 inline MachineBasicBlock::const_instr_iterator getBundleEnd(
0070     MachineBasicBlock::const_instr_iterator I) {
0071   while (I->isBundledWithSucc())
0072     ++I;
0073   ++I;
0074   return I;
0075 }
0076 
0077 //===----------------------------------------------------------------------===//
0078 // MachineBundleOperand iterator
0079 //
0080 
0081 /// MIBundleOperandIteratorBase - Iterator that visits all operands in a bundle
0082 /// of MachineInstrs. This class is not intended to be used directly, use one
0083 /// of the sub-classes instead.
0084 ///
0085 /// Intended use:
0086 ///
0087 ///   for (MIBundleOperands MIO(MI); MIO.isValid(); ++MIO) {
0088 ///     if (!MIO->isReg())
0089 ///       continue;
0090 ///     ...
0091 ///   }
0092 ///
0093 template <typename ValueT>
0094 class MIBundleOperandIteratorBase
0095     : public iterator_facade_base<MIBundleOperandIteratorBase<ValueT>,
0096                                   std::forward_iterator_tag, ValueT> {
0097   MachineBasicBlock::instr_iterator InstrI, InstrE;
0098   MachineInstr::mop_iterator OpI, OpE;
0099 
0100   // If the operands on InstrI are exhausted, advance InstrI to the next
0101   // bundled instruction with operands.
0102   void advance() {
0103     while (OpI == OpE) {
0104       // Don't advance off the basic block, or into a new bundle.
0105       if (++InstrI == InstrE || !InstrI->isInsideBundle()) {
0106         InstrI = InstrE;
0107         break;
0108       }
0109       OpI = InstrI->operands_begin();
0110       OpE = InstrI->operands_end();
0111     }
0112   }
0113 
0114 protected:
0115   /// MIBundleOperandIteratorBase - Create an iterator that visits all operands
0116   /// on MI, or all operands on every instruction in the bundle containing MI.
0117   ///
0118   /// @param MI The instruction to examine.
0119   ///
0120   explicit MIBundleOperandIteratorBase(MachineInstr &MI) {
0121     InstrI = getBundleStart(MI.getIterator());
0122     InstrE = MI.getParent()->instr_end();
0123     OpI = InstrI->operands_begin();
0124     OpE = InstrI->operands_end();
0125     advance();
0126   }
0127 
0128   /// Constructor for an iterator past the last iteration: both instruction
0129   /// iterators point to the end of the BB and OpI == OpE.
0130   explicit MIBundleOperandIteratorBase(MachineBasicBlock::instr_iterator InstrE,
0131                                        MachineInstr::mop_iterator OpE)
0132       : InstrI(InstrE), InstrE(InstrE), OpI(OpE), OpE(OpE) {}
0133 
0134 public:
0135   /// isValid - Returns true until all the operands have been visited.
0136   bool isValid() const { return OpI != OpE; }
0137 
0138   /// Preincrement.  Move to the next operand.
0139   void operator++() {
0140     assert(isValid() && "Cannot advance MIOperands beyond the last operand");
0141     ++OpI;
0142     advance();
0143   }
0144 
0145   ValueT &operator*() const { return *OpI; }
0146   ValueT *operator->() const { return &*OpI; }
0147 
0148   bool operator==(const MIBundleOperandIteratorBase &Arg) const {
0149     // Iterators are equal, if InstrI matches and either OpIs match or OpI ==
0150     // OpE match for both. The second condition allows us to construct an 'end'
0151     // iterator, without finding the last instruction in a bundle up-front.
0152     return InstrI == Arg.InstrI &&
0153            (OpI == Arg.OpI || (OpI == OpE && Arg.OpI == Arg.OpE));
0154   }
0155   /// getOperandNo - Returns the number of the current operand relative to its
0156   /// instruction.
0157   ///
0158   unsigned getOperandNo() const {
0159     return OpI - InstrI->operands_begin();
0160   }
0161 };
0162 
0163 /// MIBundleOperands - Iterate over all operands in a bundle of machine
0164 /// instructions.
0165 ///
0166 class MIBundleOperands : public MIBundleOperandIteratorBase<MachineOperand> {
0167   /// Constructor for an iterator past the last iteration.
0168   MIBundleOperands(MachineBasicBlock::instr_iterator InstrE,
0169                    MachineInstr::mop_iterator OpE)
0170       : MIBundleOperandIteratorBase(InstrE, OpE) {}
0171 
0172 public:
0173   MIBundleOperands(MachineInstr &MI) : MIBundleOperandIteratorBase(MI) {}
0174 
0175   /// Returns an iterator past the last iteration.
0176   static MIBundleOperands end(const MachineBasicBlock &MBB) {
0177     return {const_cast<MachineBasicBlock &>(MBB).instr_end(),
0178             const_cast<MachineBasicBlock &>(MBB).instr_begin()->operands_end()};
0179   }
0180 };
0181 
0182 /// ConstMIBundleOperands - Iterate over all operands in a const bundle of
0183 /// machine instructions.
0184 ///
0185 class ConstMIBundleOperands
0186     : public MIBundleOperandIteratorBase<const MachineOperand> {
0187 
0188   /// Constructor for an iterator past the last iteration.
0189   ConstMIBundleOperands(MachineBasicBlock::instr_iterator InstrE,
0190                         MachineInstr::mop_iterator OpE)
0191       : MIBundleOperandIteratorBase(InstrE, OpE) {}
0192 
0193 public:
0194   ConstMIBundleOperands(const MachineInstr &MI)
0195       : MIBundleOperandIteratorBase(const_cast<MachineInstr &>(MI)) {}
0196 
0197   /// Returns an iterator past the last iteration.
0198   static ConstMIBundleOperands end(const MachineBasicBlock &MBB) {
0199     return {const_cast<MachineBasicBlock &>(MBB).instr_end(),
0200             const_cast<MachineBasicBlock &>(MBB).instr_begin()->operands_end()};
0201   }
0202 };
0203 
0204 inline iterator_range<ConstMIBundleOperands>
0205 const_mi_bundle_ops(const MachineInstr &MI) {
0206   return make_range(ConstMIBundleOperands(MI),
0207                     ConstMIBundleOperands::end(*MI.getParent()));
0208 }
0209 
0210 inline iterator_range<MIBundleOperands> mi_bundle_ops(MachineInstr &MI) {
0211   return make_range(MIBundleOperands(MI),
0212                     MIBundleOperands::end(*MI.getParent()));
0213 }
0214 
0215 /// VirtRegInfo - Information about a virtual register used by a set of
0216 /// operands.
0217 ///
0218 struct VirtRegInfo {
0219   /// Reads - One of the operands read the virtual register.  This does not
0220   /// include undef or internal use operands, see MO::readsReg().
0221   bool Reads;
0222 
0223   /// Writes - One of the operands writes the virtual register.
0224   bool Writes;
0225 
0226   /// Tied - Uses and defs must use the same register. This can be because of
0227   /// a two-address constraint, or there may be a partial redefinition of a
0228   /// sub-register.
0229   bool Tied;
0230 };
0231 
0232 /// AnalyzeVirtRegInBundle - Analyze how the current instruction or bundle uses
0233 /// a virtual register.  This function should not be called after operator++(),
0234 /// it expects a fresh iterator.
0235 ///
0236 /// @param Reg The virtual register to analyze.
0237 /// @param Ops When set, this vector will receive an (MI, OpNum) entry for
0238 ///            each operand referring to Reg.
0239 /// @returns A filled-in RegInfo struct.
0240 VirtRegInfo AnalyzeVirtRegInBundle(
0241     MachineInstr &MI, Register Reg,
0242     SmallVectorImpl<std::pair<MachineInstr *, unsigned>> *Ops = nullptr);
0243 
0244 /// Return a pair of lane masks (reads, writes) indicating which lanes this
0245 /// instruction uses with Reg.
0246 std::pair<LaneBitmask, LaneBitmask>
0247 AnalyzeVirtRegLanesInBundle(const MachineInstr &MI, Register Reg,
0248                             const MachineRegisterInfo &MRI,
0249                             const TargetRegisterInfo &TRI);
0250 
0251 /// Information about how a physical register Reg is used by a set of
0252 /// operands.
0253 struct PhysRegInfo {
0254   /// There is a regmask operand indicating Reg is clobbered.
0255   /// \see MachineOperand::CreateRegMask().
0256   bool Clobbered;
0257 
0258   /// Reg or one of its aliases is defined. The definition may only cover
0259   /// parts of the register.
0260   bool Defined;
0261   /// Reg or a super-register is defined. The definition covers the full
0262   /// register.
0263   bool FullyDefined;
0264 
0265   /// Reg or one of its aliases is read. The register may only be read
0266   /// partially.
0267   bool Read;
0268   /// Reg or a super-register is read. The full register is read.
0269   bool FullyRead;
0270 
0271   /// Either:
0272   /// - Reg is FullyDefined and all defs of reg or an overlapping
0273   ///   register are dead, or
0274   /// - Reg is completely dead because "defined" by a clobber.
0275   bool DeadDef;
0276 
0277   /// Reg is Defined and all defs of reg or an overlapping register are
0278   /// dead.
0279   bool PartialDeadDef;
0280 
0281   /// There is a use operand of reg or a super-register with kill flag set.
0282   bool Killed;
0283 };
0284 
0285 /// AnalyzePhysRegInBundle - Analyze how the current instruction or bundle uses
0286 /// a physical register.  This function should not be called after operator++(),
0287 /// it expects a fresh iterator.
0288 ///
0289 /// @param Reg The physical register to analyze.
0290 /// @returns A filled-in PhysRegInfo struct.
0291 PhysRegInfo AnalyzePhysRegInBundle(const MachineInstr &MI, Register Reg,
0292                                    const TargetRegisterInfo *TRI);
0293 
0294 } // End llvm namespace
0295 
0296 #endif