// Dump the range of instructions from B to E with their slot indexes. static void dumpMachineInstrRangeWithSlotIndex(MachineBasicBlock::iterator B, MachineBasicBlock::iterator E, LiveIntervals const &LIS, const char *const header, unsigned VReg =0) { char NextLine = '\n'; char SlotIndent = '\t'; if (std::next(B) == E) { NextLine = ' '; SlotIndent = ' '; } dbgs() << '\t' << header << ": " << NextLine; for (MachineBasicBlock::iterator I = B; I != E; ++I) { SlotIndex Idx = LIS.getInstructionIndex(I).getRegSlot(); // If a register was passed in and this instruction has it as a // destination that is marked as an early clobber, print the // early-clobber slot index. if (VReg) { MachineOperand *MO = I->findRegisterDefOperand(VReg); if (MO && MO->isEarlyClobber()) Idx = Idx.getRegSlot(true); } dbgs() << SlotIndent << Idx << '\t' << *I; } }
MachineOperand AMDGPUInstructionSelector::getSubOperand64(MachineOperand &MO, unsigned SubIdx) const { MachineInstr *MI = MO.getParent(); MachineBasicBlock *BB = MO.getParent()->getParent(); MachineFunction *MF = BB->getParent(); MachineRegisterInfo &MRI = MF->getRegInfo(); unsigned DstReg = MRI.createVirtualRegister(&AMDGPU::SGPR_32RegClass); if (MO.isReg()) { unsigned ComposedSubIdx = TRI.composeSubRegIndices(MO.getSubReg(), SubIdx); unsigned Reg = MO.getReg(); BuildMI(*BB, MI, MI->getDebugLoc(), TII.get(AMDGPU::COPY), DstReg) .addReg(Reg, 0, ComposedSubIdx); return MachineOperand::CreateReg(DstReg, MO.isDef(), MO.isImplicit(), MO.isKill(), MO.isDead(), MO.isUndef(), MO.isEarlyClobber(), 0, MO.isDebug(), MO.isInternalRead()); } assert(MO.isImm()); APInt Imm(64, MO.getImm()); switch (SubIdx) { default: llvm_unreachable("do not know to split immediate with this sub index."); case AMDGPU::sub0: return MachineOperand::CreateImm(Imm.getLoBits(32).getSExtValue()); case AMDGPU::sub1: return MachineOperand::CreateImm(Imm.getHiBits(32).getSExtValue()); } }
static void createDeadDef(SlotIndexes &Indexes, VNInfo::Allocator &Alloc, LiveRange &LR, const MachineOperand &MO) { const MachineInstr &MI = *MO.getParent(); SlotIndex DefIdx = Indexes.getInstructionIndex(MI).getRegSlot(MO.isEarlyClobber()); // Create the def in LR. This may find an existing def. LR.createDeadDef(DefIdx, Alloc); }
// Copy MachineOperand with all flags except setting it as implicit. static MachineOperand copyRegOperandAsImplicit(const MachineOperand &Orig) { assert(!Orig.isImplicit()); return MachineOperand::CreateReg(Orig.getReg(), Orig.isDef(), true, Orig.isKill(), Orig.isDead(), Orig.isUndef(), Orig.isEarlyClobber(), Orig.getSubReg(), Orig.isDebug(), Orig.isInternalRead()); }
/// isPartialRedef - Return true if the specified def at the specific index is /// partially re-defining the specified live interval. A common case of this is /// a definition of the sub-register. bool LiveIntervals::isPartialRedef(SlotIndex MIIdx, MachineOperand &MO, LiveInterval &interval) { if (!MO.getSubReg() || MO.isEarlyClobber()) return false; SlotIndex RedefIndex = MIIdx.getRegSlot(); const LiveRange *OldLR = interval.getLiveRangeContaining(RedefIndex.getRegSlot(true)); MachineInstr *DefMI = getInstructionFromIndex(OldLR->valno->def); if (DefMI != 0) { return DefMI->findRegisterDefOperandIdx(interval.reg) != -1; } return false; }
// Check all machine operands that reference the antidependent register and must // be replaced by NewReg. Return true if any of their parent instructions may // clobber the new register. // // Note: AntiDepReg may be referenced by a two-address instruction such that // it's use operand is tied to a def operand. We guard against the case in which // the two-address instruction also defines NewReg, as may happen with // pre/postincrement loads. In this case, both the use and def operands are in // RegRefs because the def is inserted by PrescanInstruction and not erased // during ScanInstruction. So checking for an instructions with definitions of // both NewReg and AntiDepReg covers it. bool CriticalAntiDepBreaker::isNewRegClobberedByRefs(RegRefIter RegRefBegin, RegRefIter RegRefEnd, unsigned NewReg) { for (RegRefIter I = RegRefBegin; I != RegRefEnd; ++I ) { MachineOperand *RefOper = I->second; // Don't allow the instruction defining AntiDepReg to earlyclobber its // operands, in case they may be assigned to NewReg. In this case antidep // breaking must fail, but it's too rare to bother optimizing. if (RefOper->isDef() && RefOper->isEarlyClobber()) return true; // Handle cases in which this instructions defines NewReg. MachineInstr *MI = RefOper->getParent(); for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &CheckOper = MI->getOperand(i); if (CheckOper.isRegMask() && CheckOper.clobbersPhysReg(NewReg)) return true; if (!CheckOper.isReg() || !CheckOper.isDef() || CheckOper.getReg() != NewReg) continue; // Don't allow the instruction to define NewReg and AntiDepReg. // When AntiDepReg is renamed it will be an illegal op. if (RefOper->isDef()) return true; // Don't allow an instruction using AntiDepReg to be earlyclobbered by // NewReg if (CheckOper.isEarlyClobber()) return true; // Don't allow inline asm to define NewReg at all. Who know what it's // doing with it. if (MI->isInlineAsm()) return true; } } return false; }
void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI, unsigned I, bool ShouldPrintRegisterTies, bool IsDef) { printTargetFlags(Op); switch (Op.getType()) { case MachineOperand::MO_Register: if (Op.isImplicit()) OS << (Op.isDef() ? "implicit-def " : "implicit "); else if (!IsDef && Op.isDef()) // Print the 'def' flag only when the operand is defined after '='. OS << "def "; if (Op.isInternalRead()) OS << "internal "; if (Op.isDead()) OS << "dead "; if (Op.isKill()) OS << "killed "; if (Op.isUndef()) OS << "undef "; if (Op.isEarlyClobber()) OS << "early-clobber "; if (Op.isDebug()) OS << "debug-use "; printReg(Op.getReg(), OS, TRI); // Print the sub register. if (Op.getSubReg() != 0) OS << ':' << TRI->getSubRegIndexName(Op.getSubReg()); if (ShouldPrintRegisterTies && Op.isTied() && !Op.isDef()) OS << "(tied-def " << Op.getParent()->findTiedOperandIdx(I) << ")"; break; case MachineOperand::MO_Immediate: OS << Op.getImm(); break; case MachineOperand::MO_CImmediate: Op.getCImm()->printAsOperand(OS, /*PrintType=*/true, MST); break; case MachineOperand::MO_FPImmediate: Op.getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST); break; case MachineOperand::MO_MachineBasicBlock: printMBBReference(*Op.getMBB()); break; case MachineOperand::MO_FrameIndex: printStackObjectReference(Op.getIndex()); break; case MachineOperand::MO_ConstantPoolIndex: OS << "%const." << Op.getIndex(); printOffset(Op.getOffset()); break; case MachineOperand::MO_TargetIndex: { OS << "target-index("; if (const auto *Name = getTargetIndexName( *Op.getParent()->getParent()->getParent(), Op.getIndex())) OS << Name; else OS << "<unknown>"; OS << ')'; printOffset(Op.getOffset()); break; } case MachineOperand::MO_JumpTableIndex: OS << "%jump-table." << Op.getIndex(); break; case MachineOperand::MO_ExternalSymbol: OS << '$'; printLLVMNameWithoutPrefix(OS, Op.getSymbolName()); printOffset(Op.getOffset()); break; case MachineOperand::MO_GlobalAddress: Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); printOffset(Op.getOffset()); break; case MachineOperand::MO_BlockAddress: OS << "blockaddress("; Op.getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false, MST); OS << ", "; printIRBlockReference(*Op.getBlockAddress()->getBasicBlock()); OS << ')'; printOffset(Op.getOffset()); break; case MachineOperand::MO_RegisterMask: { auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask()); if (RegMaskInfo != RegisterMaskIds.end()) OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower(); else llvm_unreachable("Can't print this machine register mask yet."); break; } case MachineOperand::MO_RegisterLiveOut: { const uint32_t *RegMask = Op.getRegLiveOut(); OS << "liveout("; bool IsCommaNeeded = false; for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) { if (RegMask[Reg / 32] & (1U << (Reg % 32))) { if (IsCommaNeeded) OS << ", "; printReg(Reg, OS, TRI); IsCommaNeeded = true; } } OS << ")"; break; } case MachineOperand::MO_Metadata: Op.getMetadata()->printAsOperand(OS, MST); break; case MachineOperand::MO_MCSymbol: OS << "<mcsymbol " << *Op.getMCSymbol() << ">"; break; case MachineOperand::MO_CFIIndex: { const auto &MMI = Op.getParent()->getParent()->getParent()->getMMI(); print(MMI.getFrameInstructions()[Op.getCFIIndex()], TRI); break; } } }
bool LiveVariables::HandlePhysRegKill(unsigned Reg, MachineInstr *MI) { MachineInstr *LastDef = PhysRegDef[Reg]; MachineInstr *LastUse = PhysRegUse[Reg]; if (!LastDef && !LastUse) return false; MachineInstr *LastRefOrPartRef = LastUse ? LastUse : LastDef; unsigned LastRefOrPartRefDist = DistanceMap[LastRefOrPartRef]; // The whole register is used. // AL = // AH = // // = AX // = AL, AX<imp-use, kill> // AX = // // Or whole register is defined, but not used at all. // AX<dead> = // ... // AX = // // Or whole register is defined, but only partly used. // AX<dead> = AL<imp-def> // = AL<kill> // AX = MachineInstr *LastPartDef = nullptr; unsigned LastPartDefDist = 0; SmallSet<unsigned, 8> PartUses; for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) { unsigned SubReg = *SubRegs; MachineInstr *Def = PhysRegDef[SubReg]; if (Def && Def != LastDef) { // There was a def of this sub-register in between. This is a partial // def, keep track of the last one. unsigned Dist = DistanceMap[Def]; if (Dist > LastPartDefDist) { LastPartDefDist = Dist; LastPartDef = Def; } continue; } if (MachineInstr *Use = PhysRegUse[SubReg]) { for (MCSubRegIterator SS(SubReg, TRI, /*IncludeSelf=*/true); SS.isValid(); ++SS) PartUses.insert(*SS); unsigned Dist = DistanceMap[Use]; if (Dist > LastRefOrPartRefDist) { LastRefOrPartRefDist = Dist; LastRefOrPartRef = Use; } } } if (!PhysRegUse[Reg]) { // Partial uses. Mark register def dead and add implicit def of // sub-registers which are used. // EAX<dead> = op AL<imp-def> // That is, EAX def is dead but AL def extends pass it. PhysRegDef[Reg]->addRegisterDead(Reg, TRI, true); for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) { unsigned SubReg = *SubRegs; if (!PartUses.count(SubReg)) continue; bool NeedDef = true; if (PhysRegDef[Reg] == PhysRegDef[SubReg]) { MachineOperand *MO = PhysRegDef[Reg]->findRegisterDefOperand(SubReg); if (MO) { NeedDef = false; assert(!MO->isDead()); } } if (NeedDef) PhysRegDef[Reg]->addOperand(MachineOperand::CreateReg(SubReg, true/*IsDef*/, true/*IsImp*/)); MachineInstr *LastSubRef = FindLastRefOrPartRef(SubReg); if (LastSubRef) LastSubRef->addRegisterKilled(SubReg, TRI, true); else { LastRefOrPartRef->addRegisterKilled(SubReg, TRI, true); for (MCSubRegIterator SS(SubReg, TRI, /*IncludeSelf=*/true); SS.isValid(); ++SS) PhysRegUse[*SS] = LastRefOrPartRef; } for (MCSubRegIterator SS(SubReg, TRI); SS.isValid(); ++SS) PartUses.erase(*SS); } } else if (LastRefOrPartRef == PhysRegDef[Reg] && LastRefOrPartRef != MI) { if (LastPartDef) // The last partial def kills the register. LastPartDef->addOperand(MachineOperand::CreateReg(Reg, false/*IsDef*/, true/*IsImp*/, true/*IsKill*/)); else { MachineOperand *MO = LastRefOrPartRef->findRegisterDefOperand(Reg, false, TRI); bool NeedEC = MO->isEarlyClobber() && MO->getReg() != Reg; // If the last reference is the last def, then it's not used at all. // That is, unless we are currently processing the last reference itself. LastRefOrPartRef->addRegisterDead(Reg, TRI, true); if (NeedEC) { // If we are adding a subreg def and the superreg def is marked early // clobber, add an early clobber marker to the subreg def. MO = LastRefOrPartRef->findRegisterDefOperand(Reg); if (MO) MO->setIsEarlyClobber(); } } } else LastRefOrPartRef->addRegisterKilled(Reg, TRI, true); return true; }
void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, MachineBasicBlock::iterator mi, SlotIndex MIIdx, MachineOperand& MO, unsigned MOIdx, LiveInterval &interval) { DEBUG(dbgs() << "\t\tregister: " << PrintReg(interval.reg, tri_)); // Virtual registers may be defined multiple times (due to phi // elimination and 2-addr elimination). Much of what we do only has to be // done once for the vreg. We use an empty interval to detect the first // time we see a vreg. LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg); if (interval.empty()) { // Get the Idx of the defining instructions. SlotIndex defIndex = MIIdx.getRegSlot(MO.isEarlyClobber()); // Make sure the first definition is not a partial redefinition. Add an // <imp-def> of the full register. // FIXME: LiveIntervals shouldn't modify the code like this. Whoever // created the machine instruction should annotate it with <undef> flags // as needed. Then we can simply assert here. The REG_SEQUENCE lowering // is the main suspect. if (MO.getSubReg()) { mi->addRegisterDefined(interval.reg); // Mark all defs of interval.reg on this instruction as reading <undef>. for (unsigned i = MOIdx, e = mi->getNumOperands(); i != e; ++i) { MachineOperand &MO2 = mi->getOperand(i); if (MO2.isReg() && MO2.getReg() == interval.reg && MO2.getSubReg()) MO2.setIsUndef(); } } MachineInstr *CopyMI = NULL; if (mi->isCopyLike()) { CopyMI = mi; } VNInfo *ValNo = interval.getNextValue(defIndex, CopyMI, VNInfoAllocator); assert(ValNo->id == 0 && "First value in interval is not 0?"); // Loop over all of the blocks that the vreg is defined in. There are // two cases we have to handle here. The most common case is a vreg // whose lifetime is contained within a basic block. In this case there // will be a single kill, in MBB, which comes after the definition. if (vi.Kills.size() == 1 && vi.Kills[0]->getParent() == mbb) { // FIXME: what about dead vars? SlotIndex killIdx; if (vi.Kills[0] != mi) killIdx = getInstructionIndex(vi.Kills[0]).getRegSlot(); else killIdx = defIndex.getDeadSlot(); // If the kill happens after the definition, we have an intra-block // live range. if (killIdx > defIndex) { assert(vi.AliveBlocks.empty() && "Shouldn't be alive across any blocks!"); LiveRange LR(defIndex, killIdx, ValNo); interval.addRange(LR); DEBUG(dbgs() << " +" << LR << "\n"); return; } } // The other case we handle is when a virtual register lives to the end // of the defining block, potentially live across some blocks, then is // live into some number of blocks, but gets killed. Start by adding a // range that goes from this definition to the end of the defining block. LiveRange NewLR(defIndex, getMBBEndIdx(mbb), ValNo); DEBUG(dbgs() << " +" << NewLR); interval.addRange(NewLR); bool PHIJoin = lv_->isPHIJoin(interval.reg); if (PHIJoin) { // A phi join register is killed at the end of the MBB and revived as a new // valno in the killing blocks. assert(vi.AliveBlocks.empty() && "Phi join can't pass through blocks"); DEBUG(dbgs() << " phi-join"); ValNo->setHasPHIKill(true); } else { // Iterate over all of the blocks that the variable is completely // live in, adding [insrtIndex(begin), instrIndex(end)+4) to the // live interval. for (SparseBitVector<>::iterator I = vi.AliveBlocks.begin(), E = vi.AliveBlocks.end(); I != E; ++I) { MachineBasicBlock *aliveBlock = mf_->getBlockNumbered(*I); LiveRange LR(getMBBStartIdx(aliveBlock), getMBBEndIdx(aliveBlock), ValNo); interval.addRange(LR); DEBUG(dbgs() << " +" << LR); } } // Finally, this virtual register is live from the start of any killing // block to the 'use' slot of the killing instruction. for (unsigned i = 0, e = vi.Kills.size(); i != e; ++i) { MachineInstr *Kill = vi.Kills[i]; SlotIndex Start = getMBBStartIdx(Kill->getParent()); SlotIndex killIdx = getInstructionIndex(Kill).getRegSlot(); // Create interval with one of a NEW value number. Note that this value // number isn't actually defined by an instruction, weird huh? :) if (PHIJoin) { assert(getInstructionFromIndex(Start) == 0 && "PHI def index points at actual instruction."); ValNo = interval.getNextValue(Start, 0, VNInfoAllocator); ValNo->setIsPHIDef(true); } LiveRange LR(Start, killIdx, ValNo); interval.addRange(LR); DEBUG(dbgs() << " +" << LR); } } else { if (MultipleDefsBySameMI(*mi, MOIdx)) // Multiple defs of the same virtual register by the same instruction. // e.g. %reg1031:5<def>, %reg1031:6<def> = VLD1q16 %reg1024<kill>, ... // This is likely due to elimination of REG_SEQUENCE instructions. Return // here since there is nothing to do. return; // If this is the second time we see a virtual register definition, it // must be due to phi elimination or two addr elimination. If this is // the result of two address elimination, then the vreg is one of the // def-and-use register operand. // It may also be partial redef like this: // 80 %reg1041:6<def> = VSHRNv4i16 %reg1034<kill>, 12, pred:14, pred:%reg0 // 120 %reg1041:5<def> = VSHRNv4i16 %reg1039<kill>, 12, pred:14, pred:%reg0 bool PartReDef = isPartialRedef(MIIdx, MO, interval); if (PartReDef || mi->isRegTiedToUseOperand(MOIdx)) { // If this is a two-address definition, then we have already processed // the live range. The only problem is that we didn't realize there // are actually two values in the live interval. Because of this we // need to take the LiveRegion that defines this register and split it // into two values. SlotIndex RedefIndex = MIIdx.getRegSlot(MO.isEarlyClobber()); const LiveRange *OldLR = interval.getLiveRangeContaining(RedefIndex.getRegSlot(true)); VNInfo *OldValNo = OldLR->valno; SlotIndex DefIndex = OldValNo->def.getRegSlot(); // Delete the previous value, which should be short and continuous, // because the 2-addr copy must be in the same MBB as the redef. interval.removeRange(DefIndex, RedefIndex); // The new value number (#1) is defined by the instruction we claimed // defined value #0. VNInfo *ValNo = interval.createValueCopy(OldValNo, VNInfoAllocator); // Value#0 is now defined by the 2-addr instruction. OldValNo->def = RedefIndex; OldValNo->setCopy(0); // A re-def may be a copy. e.g. %reg1030:6<def> = VMOVD %reg1026, ... if (PartReDef && mi->isCopyLike()) OldValNo->setCopy(&*mi); // Add the new live interval which replaces the range for the input copy. LiveRange LR(DefIndex, RedefIndex, ValNo); DEBUG(dbgs() << " replace range with " << LR); interval.addRange(LR); // If this redefinition is dead, we need to add a dummy unit live // range covering the def slot. if (MO.isDead()) interval.addRange(LiveRange(RedefIndex, RedefIndex.getDeadSlot(), OldValNo)); DEBUG({ dbgs() << " RESULT: "; interval.print(dbgs(), tri_); }); } else if (lv_->isPHIJoin(interval.reg)) {
void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { printTargetFlags(Op); switch (Op.getType()) { case MachineOperand::MO_Register: // TODO: Print the other register flags. if (Op.isImplicit()) OS << (Op.isDef() ? "implicit-def " : "implicit "); if (Op.isDead()) OS << "dead "; if (Op.isKill()) OS << "killed "; if (Op.isUndef()) OS << "undef "; if (Op.isEarlyClobber()) OS << "early-clobber "; if (Op.isDebug()) OS << "debug-use "; printReg(Op.getReg(), OS, TRI); // Print the sub register. if (Op.getSubReg() != 0) OS << ':' << TRI->getSubRegIndexName(Op.getSubReg()); break; case MachineOperand::MO_Immediate: OS << Op.getImm(); break; case MachineOperand::MO_CImmediate: Op.getCImm()->printAsOperand(OS, /*PrintType=*/true, MST); break; case MachineOperand::MO_FPImmediate: Op.getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST); break; case MachineOperand::MO_MachineBasicBlock: printMBBReference(*Op.getMBB()); break; case MachineOperand::MO_FrameIndex: printStackObjectReference(Op.getIndex()); break; case MachineOperand::MO_ConstantPoolIndex: OS << "%const." << Op.getIndex(); printOffset(Op.getOffset()); break; case MachineOperand::MO_TargetIndex: { OS << "target-index("; if (const auto *Name = getTargetIndexName( *Op.getParent()->getParent()->getParent(), Op.getIndex())) OS << Name; else OS << "<unknown>"; OS << ')'; printOffset(Op.getOffset()); break; } case MachineOperand::MO_JumpTableIndex: OS << "%jump-table." << Op.getIndex(); break; case MachineOperand::MO_ExternalSymbol: OS << '$'; printLLVMNameWithoutPrefix(OS, Op.getSymbolName()); printOffset(Op.getOffset()); break; case MachineOperand::MO_GlobalAddress: Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); printOffset(Op.getOffset()); break; case MachineOperand::MO_BlockAddress: OS << "blockaddress("; Op.getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false, MST); OS << ", "; printIRBlockReference(*Op.getBlockAddress()->getBasicBlock()); OS << ')'; printOffset(Op.getOffset()); break; case MachineOperand::MO_RegisterMask: { auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask()); if (RegMaskInfo != RegisterMaskIds.end()) OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower(); else llvm_unreachable("Can't print this machine register mask yet."); break; } case MachineOperand::MO_Metadata: Op.getMetadata()->printAsOperand(OS, MST); break; case MachineOperand::MO_CFIIndex: { const auto &MMI = Op.getParent()->getParent()->getParent()->getMMI(); print(MMI.getFrameInstructions()[Op.getCFIIndex()], TRI); break; } default: // TODO: Print the other machine operands. llvm_unreachable("Can't print this machine operand at the moment"); } }
void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI, unsigned I, bool ShouldPrintRegisterTies, LLT TypeToPrint, bool IsDef) { printTargetFlags(Op); switch (Op.getType()) { case MachineOperand::MO_Register: if (Op.isImplicit()) OS << (Op.isDef() ? "implicit-def " : "implicit "); else if (!IsDef && Op.isDef()) // Print the 'def' flag only when the operand is defined after '='. OS << "def "; if (Op.isInternalRead()) OS << "internal "; if (Op.isDead()) OS << "dead "; if (Op.isKill()) OS << "killed "; if (Op.isUndef()) OS << "undef "; if (Op.isEarlyClobber()) OS << "early-clobber "; if (Op.isDebug()) OS << "debug-use "; printReg(Op.getReg(), OS, TRI); // Print the sub register. if (Op.getSubReg() != 0) OS << '.' << TRI->getSubRegIndexName(Op.getSubReg()); if (ShouldPrintRegisterTies && Op.isTied() && !Op.isDef()) OS << "(tied-def " << Op.getParent()->findTiedOperandIdx(I) << ")"; if (TypeToPrint.isValid()) OS << '(' << TypeToPrint << ')'; break; case MachineOperand::MO_Immediate: OS << Op.getImm(); break; case MachineOperand::MO_CImmediate: Op.getCImm()->printAsOperand(OS, /*PrintType=*/true, MST); break; case MachineOperand::MO_FPImmediate: Op.getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST); break; case MachineOperand::MO_MachineBasicBlock: printMBBReference(*Op.getMBB()); break; case MachineOperand::MO_FrameIndex: printStackObjectReference(Op.getIndex()); break; case MachineOperand::MO_ConstantPoolIndex: OS << "%const." << Op.getIndex(); printOffset(Op.getOffset()); break; case MachineOperand::MO_TargetIndex: OS << "target-index("; if (const auto *Name = getTargetIndexName( *Op.getParent()->getParent()->getParent(), Op.getIndex())) OS << Name; else OS << "<unknown>"; OS << ')'; printOffset(Op.getOffset()); break; case MachineOperand::MO_JumpTableIndex: OS << "%jump-table." << Op.getIndex(); break; case MachineOperand::MO_ExternalSymbol: { StringRef Name = Op.getSymbolName(); OS << '$'; if (Name.empty()) { OS << "\"\""; } else { printLLVMNameWithoutPrefix(OS, Name); } printOffset(Op.getOffset()); break; } case MachineOperand::MO_GlobalAddress: Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); printOffset(Op.getOffset()); break; case MachineOperand::MO_BlockAddress: OS << "blockaddress("; Op.getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false, MST); OS << ", "; printIRBlockReference(*Op.getBlockAddress()->getBasicBlock()); OS << ')'; printOffset(Op.getOffset()); break; case MachineOperand::MO_RegisterMask: { auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask()); if (RegMaskInfo != RegisterMaskIds.end()) OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower(); else printCustomRegMask(Op.getRegMask(), OS, TRI); break; } case MachineOperand::MO_RegisterLiveOut: { const uint32_t *RegMask = Op.getRegLiveOut(); OS << "liveout("; bool IsCommaNeeded = false; for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) { if (RegMask[Reg / 32] & (1U << (Reg % 32))) { if (IsCommaNeeded) OS << ", "; printReg(Reg, OS, TRI); IsCommaNeeded = true; } } OS << ")"; break; } case MachineOperand::MO_Metadata: Op.getMetadata()->printAsOperand(OS, MST); break; case MachineOperand::MO_MCSymbol: OS << "<mcsymbol " << *Op.getMCSymbol() << ">"; break; case MachineOperand::MO_CFIIndex: { const MachineFunction &MF = *Op.getParent()->getParent()->getParent(); print(MF.getFrameInstructions()[Op.getCFIIndex()], TRI); break; } case MachineOperand::MO_IntrinsicID: { Intrinsic::ID ID = Op.getIntrinsicID(); if (ID < Intrinsic::num_intrinsics) OS << "intrinsic(@" << Intrinsic::getName(ID, None) << ')'; else { const MachineFunction &MF = *Op.getParent()->getParent()->getParent(); const TargetIntrinsicInfo *TII = MF.getTarget().getIntrinsicInfo(); OS << "intrinsic(@" << TII->getName(ID) << ')'; } break; } case MachineOperand::MO_Predicate: { auto Pred = static_cast<CmpInst::Predicate>(Op.getPredicate()); OS << (CmpInst::isIntPredicate(Pred) ? "int" : "float") << "pred(" << CmpInst::getPredicateName(Pred) << ')'; break; } } }