File indexing completed on 2026-05-10 08:43:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
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
0022
0023
0024
0025
0026
0027 void finalizeBundle(MachineBasicBlock &MBB,
0028 MachineBasicBlock::instr_iterator FirstMI,
0029 MachineBasicBlock::instr_iterator LastMI);
0030
0031
0032
0033
0034
0035
0036 MachineBasicBlock::instr_iterator finalizeBundle(MachineBasicBlock &MBB,
0037 MachineBasicBlock::instr_iterator FirstMI);
0038
0039
0040
0041 bool finalizeBundles(MachineFunction &MF);
0042
0043
0044 inline MachineBasicBlock::instr_iterator getBundleStart(
0045 MachineBasicBlock::instr_iterator I) {
0046 while (I->isBundledWithPred())
0047 --I;
0048 return I;
0049 }
0050
0051
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
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
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
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
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
0101
0102 void advance() {
0103 while (OpI == OpE) {
0104
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
0116
0117
0118
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
0129
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
0136 bool isValid() const { return OpI != OpE; }
0137
0138
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
0150
0151
0152 return InstrI == Arg.InstrI &&
0153 (OpI == Arg.OpI || (OpI == OpE && Arg.OpI == Arg.OpE));
0154 }
0155
0156
0157
0158 unsigned getOperandNo() const {
0159 return OpI - InstrI->operands_begin();
0160 }
0161 };
0162
0163
0164
0165
0166 class MIBundleOperands : public MIBundleOperandIteratorBase<MachineOperand> {
0167
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
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
0183
0184
0185 class ConstMIBundleOperands
0186 : public MIBundleOperandIteratorBase<const MachineOperand> {
0187
0188
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
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
0216
0217
0218 struct VirtRegInfo {
0219
0220
0221 bool Reads;
0222
0223
0224 bool Writes;
0225
0226
0227
0228
0229 bool Tied;
0230 };
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240 VirtRegInfo AnalyzeVirtRegInBundle(
0241 MachineInstr &MI, Register Reg,
0242 SmallVectorImpl<std::pair<MachineInstr *, unsigned>> *Ops = nullptr);
0243
0244
0245
0246 std::pair<LaneBitmask, LaneBitmask>
0247 AnalyzeVirtRegLanesInBundle(const MachineInstr &MI, Register Reg,
0248 const MachineRegisterInfo &MRI,
0249 const TargetRegisterInfo &TRI);
0250
0251
0252
0253 struct PhysRegInfo {
0254
0255
0256 bool Clobbered;
0257
0258
0259
0260 bool Defined;
0261
0262
0263 bool FullyDefined;
0264
0265
0266
0267 bool Read;
0268
0269 bool FullyRead;
0270
0271
0272
0273
0274
0275 bool DeadDef;
0276
0277
0278
0279 bool PartialDeadDef;
0280
0281
0282 bool Killed;
0283 };
0284
0285
0286
0287
0288
0289
0290
0291 PhysRegInfo AnalyzePhysRegInBundle(const MachineInstr &MI, Register Reg,
0292 const TargetRegisterInfo *TRI);
0293
0294 }
0295
0296 #endif