unsigned MachineRegisterInfo::createGenericVirtualRegister(LLT Ty) { assert(Ty.isValid() && "Cannot create empty virtual register"); // New virtual register number. unsigned Reg = TargetRegisterInfo::index2VirtReg(getNumVirtRegs()); VRegInfo.grow(Reg); // FIXME: Should we use a dummy register bank? VRegInfo[Reg].first = static_cast<RegisterBank *>(nullptr); getVRegToType()[Reg] = Ty; RegAllocHints.grow(Reg); if (TheDelegate) TheDelegate->MRI_NoteNewVirtualRegister(Reg); return Reg; }
unsigned TargetRegisterInfo::getRegSizeInBits(unsigned Reg, const MachineRegisterInfo &MRI) const { const TargetRegisterClass *RC{}; if (isPhysicalRegister(Reg)) { // The size is not directly available for physical registers. // Instead, we need to access a register class that contains Reg and // get the size of that register class. RC = getMinimalPhysRegClass(Reg); } else { LLT Ty = MRI.getType(Reg); unsigned RegSize = Ty.isValid() ? Ty.getSizeInBits() : 0; // If Reg is not a generic register, query the register class to // get its size. if (RegSize) return RegSize; // Since Reg is not a generic register, it must have a register class. RC = MRI.getRegClass(Reg); } assert(RC && "Unable to deduce the register class"); return getRegSizeInBits(*RC); }
void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST, LLT TypeToPrint, bool PrintDef, bool IsStandalone, bool ShouldPrintRegisterTies, unsigned TiedOperandIdx, const TargetRegisterInfo *TRI, const TargetIntrinsicInfo *IntrinsicInfo) const { printTargetFlags(OS, *this); switch (getType()) { case MachineOperand::MO_Register: { unsigned Reg = getReg(); if (isImplicit()) OS << (isDef() ? "implicit-def " : "implicit "); else if (PrintDef && isDef()) // Print the 'def' flag only when the operand is defined after '='. OS << "def "; if (isInternalRead()) OS << "internal "; if (isDead()) OS << "dead "; if (isKill()) OS << "killed "; if (isUndef()) OS << "undef "; if (isEarlyClobber()) OS << "early-clobber "; if (TargetRegisterInfo::isPhysicalRegister(getReg()) && isRenamable()) OS << "renamable "; // isDebug() is exactly true for register operands of a DBG_VALUE. So we // simply infer it when parsing and do not need to print it. const MachineRegisterInfo *MRI = nullptr; if (TargetRegisterInfo::isVirtualRegister(Reg)) { if (const MachineFunction *MF = getMFIfAvailable(*this)) { MRI = &MF->getRegInfo(); } } OS << printReg(Reg, TRI, 0, MRI); // Print the sub register. if (unsigned SubReg = getSubReg()) { if (TRI) OS << '.' << TRI->getSubRegIndexName(SubReg); else OS << ".subreg" << SubReg; } // Print the register class / bank. if (TargetRegisterInfo::isVirtualRegister(Reg)) { if (const MachineFunction *MF = getMFIfAvailable(*this)) { const MachineRegisterInfo &MRI = MF->getRegInfo(); if (IsStandalone || !PrintDef || MRI.def_empty(Reg)) { OS << ':'; OS << printRegClassOrBank(Reg, MRI, TRI); } } } // Print ties. if (ShouldPrintRegisterTies && isTied() && !isDef()) OS << "(tied-def " << TiedOperandIdx << ")"; // Print types. if (TypeToPrint.isValid()) OS << '(' << TypeToPrint << ')'; break; } case MachineOperand::MO_Immediate: OS << getImm(); break; case MachineOperand::MO_CImmediate: getCImm()->printAsOperand(OS, /*PrintType=*/true, MST); break; case MachineOperand::MO_FPImmediate: getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST); break; case MachineOperand::MO_MachineBasicBlock: OS << printMBBReference(*getMBB()); break; case MachineOperand::MO_FrameIndex: { int FrameIndex = getIndex(); bool IsFixed = false; const MachineFrameInfo *MFI = nullptr; if (const MachineFunction *MF = getMFIfAvailable(*this)) MFI = &MF->getFrameInfo(); printFrameIndex(OS, FrameIndex, IsFixed, MFI); break; } case MachineOperand::MO_ConstantPoolIndex: OS << "%const." << getIndex(); printOperandOffset(OS, getOffset()); break; case MachineOperand::MO_TargetIndex: { OS << "target-index("; const char *Name = "<unknown>"; if (const MachineFunction *MF = getMFIfAvailable(*this)) if (const auto *TargetIndexName = getTargetIndexName(*MF, getIndex())) Name = TargetIndexName; OS << Name << ')'; printOperandOffset(OS, getOffset()); break; } case MachineOperand::MO_JumpTableIndex: OS << printJumpTableEntryReference(getIndex()); break; case MachineOperand::MO_GlobalAddress: getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); printOperandOffset(OS, getOffset()); break; case MachineOperand::MO_ExternalSymbol: { StringRef Name = getSymbolName(); OS << '&'; if (Name.empty()) { OS << "\"\""; } else { printLLVMNameWithoutPrefix(OS, Name); } printOperandOffset(OS, getOffset()); break; } case MachineOperand::MO_BlockAddress: { OS << "blockaddress("; getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false, MST); OS << ", "; printIRBlockReference(OS, *getBlockAddress()->getBasicBlock(), MST); OS << ')'; MachineOperand::printOperandOffset(OS, getOffset()); break; } case MachineOperand::MO_RegisterMask: { OS << "<regmask"; if (TRI) { unsigned NumRegsInMask = 0; unsigned NumRegsEmitted = 0; for (unsigned i = 0; i < TRI->getNumRegs(); ++i) { unsigned MaskWord = i / 32; unsigned MaskBit = i % 32; if (getRegMask()[MaskWord] & (1 << MaskBit)) { if (PrintRegMaskNumRegs < 0 || NumRegsEmitted <= static_cast<unsigned>(PrintRegMaskNumRegs)) { OS << " " << printReg(i, TRI); NumRegsEmitted++; } NumRegsInMask++; } } if (NumRegsEmitted != NumRegsInMask) OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more..."; } else { OS << " ..."; } OS << ">"; break; } case MachineOperand::MO_RegisterLiveOut: { const uint32_t *RegMask = getRegLiveOut(); OS << "liveout("; if (!TRI) { OS << "<unknown>"; } else { bool IsCommaNeeded = false; for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) { if (RegMask[Reg / 32] & (1U << (Reg % 32))) { if (IsCommaNeeded) OS << ", "; OS << printReg(Reg, TRI); IsCommaNeeded = true; } } } OS << ")"; break; } case MachineOperand::MO_Metadata: getMetadata()->printAsOperand(OS, MST); break; case MachineOperand::MO_MCSymbol: printSymbol(OS, *getMCSymbol()); break; case MachineOperand::MO_CFIIndex: { if (const MachineFunction *MF = getMFIfAvailable(*this)) printCFI(OS, MF->getFrameInstructions()[getCFIIndex()], TRI); else OS << "<cfi directive>"; break; } case MachineOperand::MO_IntrinsicID: { Intrinsic::ID ID = getIntrinsicID(); if (ID < Intrinsic::num_intrinsics) OS << "intrinsic(@" << Intrinsic::getName(ID, None) << ')'; else if (IntrinsicInfo) OS << "intrinsic(@" << IntrinsicInfo->getName(ID) << ')'; else OS << "intrinsic(" << ID << ')'; break; } case MachineOperand::MO_Predicate: { auto Pred = static_cast<CmpInst::Predicate>(getPredicate()); OS << (CmpInst::isIntPredicate(Pred) ? "int" : "float") << "pred(" << CmpInst::getPredicateName(Pred) << ')'; break; } } }
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: 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; } 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; } } }