diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -592,7 +592,7 @@ /// Returns the total number of definitions. unsigned getNumDefs() const { - return getNumExplicitDefs() + MCID->getNumImplicitDefs(); + return getNumExplicitDefs() + MCID->implicit_defs().size(); } /// Returns true if the instruction has implicit definition. diff --git a/llvm/include/llvm/MC/MCInstrDesc.h b/llvm/include/llvm/MC/MCInstrDesc.h --- a/llvm/include/llvm/MC/MCInstrDesc.h +++ b/llvm/include/llvm/MC/MCInstrDesc.h @@ -572,6 +572,9 @@ /// /// This method returns null if the instruction has no implicit uses. const MCPhysReg *getImplicitUses() const { return ImplicitUses; } + ArrayRef implicit_uses() const { + return {ImplicitUses, getNumImplicitUses()}; + } /// Return the number of implicit uses this instruction has. unsigned getNumImplicitUses() const { @@ -594,6 +597,9 @@ /// /// This method returns null if the instruction has no implicit defs. const MCPhysReg *getImplicitDefs() const { return ImplicitDefs; } + ArrayRef implicit_defs() const { + return {ImplicitDefs, getNumImplicitDefs()}; + } /// Return the number of implicit defs this instruct has. unsigned getNumImplicitDefs() const { @@ -608,11 +614,7 @@ /// Return true if this instruction implicitly /// uses the specified physical register. bool hasImplicitUseOfPhysReg(unsigned Reg) const { - if (const MCPhysReg *ImpUses = getImplicitUses()) - for (; *ImpUses; ++ImpUses) - if (*ImpUses == Reg) - return true; - return false; + return is_contained(implicit_uses(), Reg); } /// Return true if this instruction implicitly diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -1419,14 +1419,10 @@ // Gather all the expected implicit operands. SmallVector ImplicitOperands; - if (MCID.getImplicitDefs()) - for (const MCPhysReg *ImpDefs = MCID.getImplicitDefs(); *ImpDefs; ++ImpDefs) - ImplicitOperands.push_back( - MachineOperand::CreateReg(*ImpDefs, true, true)); - if (MCID.getImplicitUses()) - for (const MCPhysReg *ImpUses = MCID.getImplicitUses(); *ImpUses; ++ImpUses) - ImplicitOperands.push_back( - MachineOperand::CreateReg(*ImpUses, false, true)); + for (MCPhysReg ImpDef : MCID.implicit_defs()) + ImplicitOperands.push_back(MachineOperand::CreateReg(ImpDef, true, true)); + for (MCPhysReg ImpUse : MCID.implicit_uses()) + ImplicitOperands.push_back(MachineOperand::CreateReg(ImpUse, false, true)); const auto *TRI = MF.getSubtarget().getRegisterInfo(); assert(TRI && "Expected target register info"); diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -84,14 +84,10 @@ } void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) { - if (MCID->getImplicitDefs()) - for (const MCPhysReg *ImpDefs = MCID->getImplicitDefs(); *ImpDefs; - ++ImpDefs) - addOperand(MF, MachineOperand::CreateReg(*ImpDefs, true, true)); - if (MCID->getImplicitUses()) - for (const MCPhysReg *ImpUses = MCID->getImplicitUses(); *ImpUses; - ++ImpUses) - addOperand(MF, MachineOperand::CreateReg(*ImpUses, false, true)); + for (MCPhysReg ImpDef : MCID->implicit_defs()) + addOperand(MF, MachineOperand::CreateReg(ImpDef, true, true)); + for (MCPhysReg ImpUse : MCID->implicit_uses()) + addOperand(MF, MachineOperand::CreateReg(ImpUse, false, true)); } /// MachineInstr ctor - This constructor creates a MachineInstr and adds the @@ -103,8 +99,8 @@ assert(DbgLoc.hasTrivialDestructor() && "Expected trivial destructor"); // Reserve space for the expected number of operands. - if (unsigned NumOps = MCID->getNumOperands() + - MCID->getNumImplicitDefs() + MCID->getNumImplicitUses()) { + if (unsigned NumOps = MCID->getNumOperands() + MCID->implicit_defs().size() + + MCID->implicit_uses().size()) { CapOperands = OperandCapacity::get(NumOps); Operands = MF.allocateOperandArray(CapOperands); } diff --git a/llvm/lib/CodeGen/RDFGraph.cpp b/llvm/lib/CodeGen/RDFGraph.cpp --- a/llvm/lib/CodeGen/RDFGraph.cpp +++ b/llvm/lib/CodeGen/RDFGraph.cpp @@ -623,7 +623,7 @@ return true; const MCInstrDesc &D = In.getDesc(); - if (!D.getImplicitDefs() && !D.getImplicitUses()) + if (D.implicit_defs().empty() && D.implicit_uses().empty()) return false; const MachineOperand &Op = In.getOperand(OpNum); // If there is a sub-register, treat the operand as non-fixed. Currently, @@ -632,14 +632,9 @@ if (Op.getSubReg() != 0) return false; Register Reg = Op.getReg(); - const MCPhysReg *ImpR = Op.isDef() ? D.getImplicitDefs() - : D.getImplicitUses(); - if (!ImpR) - return false; - while (*ImpR) - if (*ImpR++ == Reg) - return true; - return false; + ArrayRef ImpOps = + Op.isDef() ? D.implicit_defs() : D.implicit_uses(); + return is_contained(ImpOps, Reg); } // diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1939,7 +1939,7 @@ .addReg(Op0); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), ResultReg) - .addReg(II.getImplicitDefs()[0]); + .addReg(II.implicit_defs()[0]); } return ResultReg; @@ -1964,7 +1964,7 @@ .addReg(Op1); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), ResultReg) - .addReg(II.getImplicitDefs()[0]); + .addReg(II.implicit_defs()[0]); } return ResultReg; } @@ -1991,7 +1991,7 @@ .addReg(Op2); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), ResultReg) - .addReg(II.getImplicitDefs()[0]); + .addReg(II.implicit_defs()[0]); } return ResultReg; } @@ -2014,7 +2014,7 @@ .addImm(Imm); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), ResultReg) - .addReg(II.getImplicitDefs()[0]); + .addReg(II.implicit_defs()[0]); } return ResultReg; } @@ -2039,7 +2039,7 @@ .addImm(Imm2); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), ResultReg) - .addReg(II.getImplicitDefs()[0]); + .addReg(II.implicit_defs()[0]); } return ResultReg; } @@ -2059,7 +2059,7 @@ .addFPImm(FPImm); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), ResultReg) - .addReg(II.getImplicitDefs()[0]); + .addReg(II.implicit_defs()[0]); } return ResultReg; } @@ -2085,7 +2085,7 @@ .addImm(Imm); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), ResultReg) - .addReg(II.getImplicitDefs()[0]); + .addReg(II.implicit_defs()[0]); } return ResultReg; } @@ -2102,7 +2102,7 @@ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II).addImm(Imm); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), ResultReg) - .addReg(II.getImplicitDefs()[0]); + .addReg(II.implicit_defs()[0]); } return ResultReg; } diff --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp --- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -1021,8 +1021,8 @@ countOperands(Node, II.getNumOperands() - NumDefs, NumImpUses); bool HasVRegVariadicDefs = !MF->getTarget().usesPhysRegsForValues() && II.isVariadic() && II.variadicOpsAreDefs(); - bool HasPhysRegOuts = NumResults > NumDefs && - II.getImplicitDefs() != nullptr && !HasVRegVariadicDefs; + bool HasPhysRegOuts = NumResults > NumDefs && !II.implicit_defs().empty() && + !HasVRegVariadicDefs; #ifndef NDEBUG unsigned NumMIOperands = NodeOperands + NumResults; if (II.isVariadic()) @@ -1030,8 +1030,8 @@ "Too few operands for a variadic node!"); else assert(NumMIOperands >= II.getNumOperands() && - NumMIOperands <= II.getNumOperands() + II.getNumImplicitDefs() + - NumImpUses && + NumMIOperands <= + II.getNumOperands() + II.implicit_defs().size() + NumImpUses && "#operands for dag node doesn't match .td file!"); #endif @@ -1128,7 +1128,7 @@ // Additional results must be physical register defs. if (HasPhysRegOuts) { for (unsigned i = NumDefs; i < NumResults; ++i) { - Register Reg = II.getImplicitDefs()[i - NumDefs]; + Register Reg = II.implicit_defs()[i - NumDefs]; if (!Node->hasAnyUseOfValue(i)) continue; // This implicitly defined physreg has a use. @@ -1149,8 +1149,7 @@ } // Collect declared implicit uses. const MCInstrDesc &MCID = TII->get(F->getMachineOpcode()); - UsedRegs.append(MCID.getImplicitUses(), - MCID.getImplicitUses() + MCID.getNumImplicitUses()); + append_range(UsedRegs, MCID.implicit_uses()); // In addition to declared implicit uses, we must also check for // direct RegisterSDNode operands. for (unsigned i = 0, e = F->getNumOperands(); i != e; ++i) @@ -1163,7 +1162,7 @@ } // Finally mark unused registers as dead. - if (!UsedRegs.empty() || II.getImplicitDefs() || II.hasOptionalDef()) + if (!UsedRegs.empty() || !II.implicit_defs().empty() || II.hasOptionalDef()) MIB->setPhysRegsDeadExcept(UsedRegs, *TRI); // STATEPOINT is too 'dynamic' to have meaningful machine description. diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp --- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp @@ -426,11 +426,11 @@ NumRes = 1; } else { const MCInstrDesc &MCID = TII->get(N->getMachineOpcode()); - assert(MCID.getImplicitDefs() && + assert(!MCID.implicit_defs().empty() && "Physical reg def must be in implicit def list!"); NumRes = MCID.getNumDefs(); - for (const MCPhysReg *ImpDef = MCID.getImplicitDefs(); *ImpDef; ++ImpDef) { - if (Reg == *ImpDef) + for (MCPhysReg ImpDef : MCID.implicit_defs()) { + if (Reg == ImpDef) break; ++NumRes; } @@ -527,11 +527,8 @@ if (!Node->isMachineOpcode()) continue; const MCInstrDesc &MCID = TII->get(Node->getMachineOpcode()); - if (!MCID.getImplicitDefs()) - continue; - for (const MCPhysReg *Reg = MCID.getImplicitDefs(); *Reg; ++Reg) { - CheckForLiveRegDef(SU, *Reg, LiveRegDefs, RegAdded, LRegs, TRI); - } + for (MCPhysReg Reg : MCID.implicit_defs()) + CheckForLiveRegDef(SU, Reg, LiveRegDefs, RegAdded, LRegs, TRI); } return !LRegs.empty(); } diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp --- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp @@ -1284,11 +1284,11 @@ NumRes = 1; } else { const MCInstrDesc &MCID = TII->get(N->getMachineOpcode()); - assert(MCID.getImplicitDefs() && + assert(!MCID.implicit_defs().empty() && "Physical reg def must be in implicit def list!"); NumRes = MCID.getNumDefs(); - for (const MCPhysReg *ImpDef = MCID.getImplicitDefs(); *ImpDef; ++ImpDef) { - if (Reg == *ImpDef) + for (MCPhysReg ImpDef : MCID.implicit_defs()) { + if (Reg == ImpDef) break; ++NumRes; } @@ -1439,10 +1439,8 @@ CheckForLiveRegDef(SU, Reg, LiveRegDefs.get(), RegAdded, LRegs, TRI); } } - if (!MCID.getImplicitDefs()) - continue; - for (const MCPhysReg *Reg = MCID.getImplicitDefs(); *Reg; ++Reg) - CheckForLiveRegDef(SU, *Reg, LiveRegDefs.get(), RegAdded, LRegs, TRI); + for (MCPhysReg Reg : MCID.implicit_defs()) + CheckForLiveRegDef(SU, Reg, LiveRegDefs.get(), RegAdded, LRegs, TRI); } return !LRegs.empty(); @@ -2867,10 +2865,10 @@ ScheduleDAGRRList *scheduleDAG, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) { - const MCPhysReg *ImpDefs - = TII->get(SU->getNode()->getMachineOpcode()).getImplicitDefs(); + ArrayRef ImpDefs = + TII->get(SU->getNode()->getMachineOpcode()).implicit_defs(); const uint32_t *RegMask = getNodeRegMask(SU->getNode()); - if(!ImpDefs && !RegMask) + if (ImpDefs.empty() && !RegMask) return false; for (const SDep &Succ : SU->Succs) { @@ -2884,14 +2882,14 @@ scheduleDAG->IsReachable(DepSU, SuccPred.getSUnit())) return true; - if (ImpDefs) - for (const MCPhysReg *ImpDef = ImpDefs; *ImpDef; ++ImpDef) - // Return true if SU clobbers this physical register use and the - // definition of the register reaches from DepSU. IsReachable queries - // a topological forward sort of the DAG (following the successors). - if (TRI->regsOverlap(*ImpDef, SuccPred.getReg()) && - scheduleDAG->IsReachable(DepSU, SuccPred.getSUnit())) - return true; + for (MCPhysReg ImpDef : ImpDefs) { + // Return true if SU clobbers this physical register use and the + // definition of the register reaches from DepSU. IsReachable queries + // a topological forward sort of the DAG (following the successors). + if (TRI->regsOverlap(ImpDef, SuccPred.getReg()) && + scheduleDAG->IsReachable(DepSU, SuccPred.getSUnit())) + return true; + } } } return false; @@ -2904,16 +2902,16 @@ const TargetRegisterInfo *TRI) { SDNode *N = SuccSU->getNode(); unsigned NumDefs = TII->get(N->getMachineOpcode()).getNumDefs(); - const MCPhysReg *ImpDefs = TII->get(N->getMachineOpcode()).getImplicitDefs(); - assert(ImpDefs && "Caller should check hasPhysRegDefs"); + ArrayRef ImpDefs = TII->get(N->getMachineOpcode()).implicit_defs(); + assert(!ImpDefs.empty() && "Caller should check hasPhysRegDefs"); for (const SDNode *SUNode = SU->getNode(); SUNode; SUNode = SUNode->getGluedNode()) { if (!SUNode->isMachineOpcode()) continue; - const MCPhysReg *SUImpDefs = - TII->get(SUNode->getMachineOpcode()).getImplicitDefs(); + ArrayRef SUImpDefs = + TII->get(SUNode->getMachineOpcode()).implicit_defs(); const uint32_t *SURegMask = getNodeRegMask(SUNode); - if (!SUImpDefs && !SURegMask) + if (SUImpDefs.empty() && !SURegMask) continue; for (unsigned i = NumDefs, e = N->getNumValues(); i != e; ++i) { MVT VT = N->getSimpleValueType(i); @@ -2924,10 +2922,7 @@ MCPhysReg Reg = ImpDefs[i - NumDefs]; if (SURegMask && MachineOperand::clobbersPhysReg(SURegMask, Reg)) return true; - if (!SUImpDefs) - continue; - for (;*SUImpDefs; ++SUImpDefs) { - MCPhysReg SUReg = *SUImpDefs; + for (MCPhysReg SUReg : SUImpDefs) { if (TRI->regsOverlap(Reg, SUReg)) return true; } diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp --- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp @@ -464,7 +464,7 @@ // Find all predecessors and successors of the group. for (SDNode *N = SU.getNode(); N; N = N->getGluedNode()) { if (N->isMachineOpcode() && - TII->get(N->getMachineOpcode()).getImplicitDefs()) { + !TII->get(N->getMachineOpcode()).implicit_defs().empty()) { SU.hasPhysRegClobbers = true; unsigned NumUsed = InstrEmitter::CountResults(N); while (NumUsed != 0 && !N->hasAnyUseOfValue(NumUsed - 1)) diff --git a/llvm/lib/MC/MCInstrDesc.cpp b/llvm/lib/MC/MCInstrDesc.cpp --- a/llvm/lib/MC/MCInstrDesc.cpp +++ b/llvm/lib/MC/MCInstrDesc.cpp @@ -31,10 +31,9 @@ bool MCInstrDesc::hasImplicitDefOfPhysReg(unsigned Reg, const MCRegisterInfo *MRI) const { - if (const MCPhysReg *ImpDefs = getImplicitDefs()) - for (; *ImpDefs; ++ImpDefs) - if (*ImpDefs == Reg || (MRI && MRI->isSubRegister(Reg, *ImpDefs))) - return true; + for (MCPhysReg ImpDef : implicit_defs()) + if (ImpDef == Reg || (MRI && MRI->isSubRegister(Reg, ImpDef))) + return true; return false; } diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -6058,9 +6058,7 @@ } // Consider implicit defs to be clobbers. Think of cpuid and push. - ArrayRef ImpDefs(Desc.getImplicitDefs(), - Desc.getNumImplicitDefs()); - llvm::append_range(ClobberRegs, ImpDefs); + llvm::append_range(ClobberRegs, Desc.implicit_defs()); } // Set the number of Outputs and Inputs. diff --git a/llvm/lib/MC/MCParser/MasmParser.cpp b/llvm/lib/MC/MCParser/MasmParser.cpp --- a/llvm/lib/MC/MCParser/MasmParser.cpp +++ b/llvm/lib/MC/MCParser/MasmParser.cpp @@ -7466,9 +7466,7 @@ } // Consider implicit defs to be clobbers. Think of cpuid and push. - ArrayRef ImpDefs(Desc.getImplicitDefs(), - Desc.getNumImplicitDefs()); - llvm::append_range(ClobberRegs, ImpDefs); + llvm::append_range(ClobberRegs, Desc.implicit_defs()); } // Set the number of Outputs and Inputs. diff --git a/llvm/lib/MCA/InstrBuilder.cpp b/llvm/lib/MCA/InstrBuilder.cpp --- a/llvm/lib/MCA/InstrBuilder.cpp +++ b/llvm/lib/MCA/InstrBuilder.cpp @@ -312,7 +312,7 @@ // According to assumption 2. register reads start at #(NumExplicitDefs-1). // That means, register R1 from the example is both read and written. unsigned NumExplicitDefs = MCDesc.getNumDefs(); - unsigned NumImplicitDefs = MCDesc.getNumImplicitDefs(); + unsigned NumImplicitDefs = MCDesc.implicit_defs().size(); unsigned NumWriteLatencyEntries = SCDesc.NumWriteLatencyEntries; unsigned TotalDefs = NumExplicitDefs + NumImplicitDefs; if (MCDesc.hasOptionalDef()) @@ -365,7 +365,7 @@ unsigned Index = NumExplicitDefs + CurrentDef; WriteDescriptor &Write = ID.Writes[Index]; Write.OpIndex = ~CurrentDef; - Write.RegisterID = MCDesc.getImplicitDefs()[CurrentDef]; + Write.RegisterID = MCDesc.implicit_defs()[CurrentDef]; if (Index < NumWriteLatencyEntries) { const MCWriteLatencyEntry &WLE = *STI.getWriteLatencyEntry(&SCDesc, Index); @@ -435,7 +435,7 @@ unsigned SchedClassID) { const MCInstrDesc &MCDesc = MCII.get(MCI.getOpcode()); unsigned NumExplicitUses = MCDesc.getNumOperands() - MCDesc.getNumDefs(); - unsigned NumImplicitUses = MCDesc.getNumImplicitUses(); + unsigned NumImplicitUses = MCDesc.implicit_uses().size(); // Remove the optional definition. if (MCDesc.hasOptionalDef()) --NumExplicitUses; @@ -464,7 +464,7 @@ ReadDescriptor &Read = ID.Reads[CurrentUse + I]; Read.OpIndex = ~I; Read.UseIndex = NumExplicitUses + I; - Read.RegisterID = MCDesc.getImplicitUses()[I]; + Read.RegisterID = MCDesc.implicit_uses()[I]; Read.SchedClassID = SchedClassID; LLVM_DEBUG(dbgs() << "\t\t[Use][I] OpIdx=" << ~Read.OpIndex << ", UseIndex=" << Read.UseIndex << ", RegisterID=" diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -3332,9 +3332,7 @@ unsigned AMDGPUAsmParser::findImplicitSGPRReadInVOP(const MCInst &Inst) const { const MCInstrDesc &Desc = MII.get(Inst.getOpcode()); - const unsigned Num = Desc.getNumImplicitUses(); - for (unsigned i = 0; i < Num; ++i) { - unsigned Reg = Desc.getImplicitUses()[i]; + for (MCPhysReg Reg : Desc.implicit_uses()) { switch (Reg) { case AMDGPU::FLAT_SCR: case AMDGPU::VCC: diff --git a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp --- a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp +++ b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp @@ -993,9 +993,8 @@ // if we replace an s_and_b32 with a copy, we don't need the implicit scc def // anymore. const MCInstrDesc &Desc = MI.getDesc(); - unsigned NumOps = Desc.getNumOperands() + - Desc.getNumImplicitUses() + - Desc.getNumImplicitDefs(); + unsigned NumOps = Desc.getNumOperands() + Desc.implicit_uses().size() + + Desc.implicit_defs().size(); for (unsigned I = MI.getNumOperands() - 1; I >= NumOps; --I) MI.removeOperand(I); diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp @@ -120,7 +120,7 @@ // rematerialization if there are virtual register uses. We allow this, // therefore this method includes SOP instructions as well. return !MI.hasImplicitDef() && - MI.getNumImplicitOperands() == MI.getDesc().getNumImplicitUses() && + MI.getNumImplicitOperands() == MI.getDesc().implicit_uses().size() && !MI.mayRaiseFPException(); } @@ -2115,7 +2115,7 @@ .addReg(VecReg, RegState::Implicit | (IsUndef ? RegState::Undef : 0)); const int ImpDefIdx = - OpDesc.getNumOperands() + OpDesc.getNumImplicitUses(); + OpDesc.getNumOperands() + OpDesc.implicit_uses().size(); const int ImpUseIdx = ImpDefIdx + 1; MIB->tieOperands(ImpDefIdx, ImpUseIdx); MI.eraseFromParent(); @@ -2153,7 +2153,8 @@ .addReg(VecReg, RegState::Implicit | (IsUndef ? RegState::Undef : 0)); - const int ImpDefIdx = OpDesc.getNumOperands() + OpDesc.getNumImplicitUses(); + const int ImpDefIdx = + OpDesc.getNumOperands() + OpDesc.implicit_uses().size(); const int ImpUseIdx = ImpDefIdx + 1; MIB->tieOperands(ImpDefIdx, ImpUseIdx); @@ -3653,14 +3654,7 @@ // Skip the full operand and register alias search modifiesRegister // does. There's only a handful of instructions that touch this, it's only an // implicit def, and doesn't alias any other registers. - if (const MCPhysReg *ImpDef = MI.getDesc().getImplicitDefs()) { - for (; ImpDef && *ImpDef; ++ImpDef) { - if (*ImpDef == AMDGPU::MODE) - return true; - } - } - - return false; + return is_contained(MI.getDesc().implicit_defs(), AMDGPU::MODE); } bool SIInstrInfo::hasUnwantedEffectsWhenEXECEmpty(const MachineInstr &MI) const { @@ -4541,8 +4535,8 @@ const bool IsDst = Desc.getOpcode() == AMDGPU::V_MOVRELD_B32_e32 || Desc.getOpcode() == AMDGPU::V_MOVRELD_B32_e64; - const unsigned StaticNumOps = Desc.getNumOperands() + - Desc.getNumImplicitUses(); + const unsigned StaticNumOps = + Desc.getNumOperands() + Desc.implicit_uses().size(); const unsigned NumImplicitOps = IsDst ? 2 : 1; // Allow additional implicit operands. This allows a fixup done by the post diff --git a/llvm/lib/Target/AMDGPU/SIShrinkInstructions.cpp b/llvm/lib/Target/AMDGPU/SIShrinkInstructions.cpp --- a/llvm/lib/Target/AMDGPU/SIShrinkInstructions.cpp +++ b/llvm/lib/Target/AMDGPU/SIShrinkInstructions.cpp @@ -203,8 +203,9 @@ MachineInstr &MI) const { MachineFunction &MF = *MI.getMF(); for (unsigned i = MI.getDesc().getNumOperands() + - MI.getDesc().getNumImplicitUses() + - MI.getDesc().getNumImplicitDefs(), e = MI.getNumOperands(); + MI.getDesc().implicit_uses().size() + + MI.getDesc().implicit_defs().size(), + e = MI.getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI.getOperand(i); if ((MO.isReg() && MO.isImplicit()) || MO.isRegMask()) @@ -595,8 +596,9 @@ void SIShrinkInstructions::dropInstructionKeepingImpDefs( MachineInstr &MI) const { for (unsigned i = MI.getDesc().getNumOperands() + - MI.getDesc().getNumImplicitUses() + - MI.getDesc().getNumImplicitDefs(), e = MI.getNumOperands(); + MI.getDesc().implicit_uses().size() + + MI.getDesc().implicit_defs().size(), + e = MI.getNumOperands(); i != e; ++i) { const MachineOperand &Op = MI.getOperand(i); if (!Op.isDef()) diff --git a/llvm/lib/Target/ARM/ARMFastISel.cpp b/llvm/lib/Target/ARM/ARMFastISel.cpp --- a/llvm/lib/Target/ARM/ARMFastISel.cpp +++ b/llvm/lib/Target/ARM/ARMFastISel.cpp @@ -310,7 +310,7 @@ .addReg(Op0)); AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), ResultReg) - .addReg(II.getImplicitDefs()[0])); + .addReg(II.implicit_defs()[0])); } return ResultReg; } @@ -337,7 +337,7 @@ .addReg(Op1)); AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), ResultReg) - .addReg(II.getImplicitDefs()[0])); + .addReg(II.implicit_defs()[0])); } return ResultReg; } @@ -362,7 +362,7 @@ .addImm(Imm)); AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), ResultReg) - .addReg(II.getImplicitDefs()[0])); + .addReg(II.implicit_defs()[0])); } return ResultReg; } @@ -381,7 +381,7 @@ .addImm(Imm)); AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), ResultReg) - .addReg(II.getImplicitDefs()[0])); + .addReg(II.implicit_defs()[0])); } return ResultReg; } diff --git a/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp b/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp --- a/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp +++ b/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp @@ -253,10 +253,7 @@ } static bool HasImplicitCPSRDef(const MCInstrDesc &MCID) { - for (const MCPhysReg *Regs = MCID.getImplicitDefs(); *Regs; ++Regs) - if (*Regs == ARM::CPSR) - return true; - return false; + return is_contained(MCID.implicit_defs(), ARM::CPSR); } // Check for a likely high-latency flag def. diff --git a/llvm/lib/Target/Hexagon/HexagonGenMux.cpp b/llvm/lib/Target/Hexagon/HexagonGenMux.cpp --- a/llvm/lib/Target/Hexagon/HexagonGenMux.cpp +++ b/llvm/lib/Target/Hexagon/HexagonGenMux.cpp @@ -160,12 +160,10 @@ // First, get the implicit defs and uses for this instruction. unsigned Opc = MI->getOpcode(); const MCInstrDesc &D = HII->get(Opc); - if (const MCPhysReg *R = D.getImplicitDefs()) - while (*R) - expandReg(*R++, Defs); - if (const MCPhysReg *R = D.getImplicitUses()) - while (*R) - expandReg(*R++, Uses); + for (MCPhysReg R : D.implicit_defs()) + expandReg(R, Defs); + for (MCPhysReg R : D.implicit_uses()) + expandReg(R, Uses); // Look over all operands, and collect explicit defs and uses. for (const MachineOperand &MO : MI->operands()) { diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp @@ -98,41 +98,38 @@ for (unsigned i = MCID.getNumDefs(); i < MCID.getNumOperands(); ++i) if (MCI.getOperand(i).isReg()) initReg(MCI, MCI.getOperand(i).getReg(), PredReg, isTrue); - for (unsigned i = 0; i < MCID.getNumImplicitUses(); ++i) - initReg(MCI, MCID.getImplicitUses()[i], PredReg, isTrue); + for (MCPhysReg ImpUse : MCID.implicit_uses()) + initReg(MCI, ImpUse, PredReg, isTrue); const bool IgnoreTmpDst = (HexagonMCInstrInfo::hasTmpDst(MCII, MCI) || HexagonMCInstrInfo::hasHvxTmp(MCII, MCI)) && STI.getFeatureBits()[Hexagon::ArchV69]; // Get implicit register definitions. - if (const MCPhysReg *ImpDef = MCID.getImplicitDefs()) - for (; *ImpDef; ++ImpDef) { - unsigned R = *ImpDef; - - if (Hexagon::R31 != R && MCID.isCall()) - // Any register other than the LR and the PC are actually volatile ones - // as defined by the ABI, not modified implicitly by the call insn. - continue; - if (Hexagon::PC == R) - // Branches are the only insns that can change the PC, - // otherwise a read-only register. - continue; + for (MCPhysReg R : MCID.implicit_defs()) { + if (Hexagon::R31 != R && MCID.isCall()) + // Any register other than the LR and the PC are actually volatile ones + // as defined by the ABI, not modified implicitly by the call insn. + continue; + if (Hexagon::PC == R) + // Branches are the only insns that can change the PC, + // otherwise a read-only register. + continue; - if (Hexagon::USR_OVF == R) - // Many insns change the USR implicitly, but only one or another flag. - // The instruction table models the USR.OVF flag, which can be - // implicitly modified more than once, but cannot be modified in the - // same packet with an instruction that modifies is explicitly. Deal - // with such situations individually. - SoftDefs.insert(R); - else if (HexagonMCInstrInfo::isPredReg(RI, R) && - HexagonMCInstrInfo::isPredicateLate(MCII, MCI)) - // Include implicit late predicates. - LatePreds.insert(R); - else if (!IgnoreTmpDst) - Defs[R].insert(PredSense(PredReg, isTrue)); - } + if (Hexagon::USR_OVF == R) + // Many insns change the USR implicitly, but only one or another flag. + // The instruction table models the USR.OVF flag, which can be + // implicitly modified more than once, but cannot be modified in the + // same packet with an instruction that modifies is explicitly. Deal + // with such situations individually. + SoftDefs.insert(R); + else if (HexagonMCInstrInfo::isPredReg(RI, R) && + HexagonMCInstrInfo::isPredicateLate(MCII, MCI)) + // Include implicit late predicates. + LatePreds.insert(R); + else if (!IgnoreTmpDst) + Defs[R].insert(PredSense(PredReg, isTrue)); + } // Figure out explicit register definitions. for (unsigned i = 0; i < MCID.getNumDefs(); ++i) { diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp @@ -642,11 +642,8 @@ Hexagon::fixup_Hexagon_GPREL16_2, Hexagon::fixup_Hexagon_GPREL16_3 }; assert(Shift < std::size(GPRelFixups)); - auto UsesGP = [] (const MCInstrDesc &D) { - for (const MCPhysReg *U = D.getImplicitUses(); U && *U; ++U) - if (*U == Hexagon::GP) - return true; - return false; + auto UsesGP = [](const MCInstrDesc &D) { + return is_contained(D.implicit_uses(), Hexagon::GP); }; if (UsesGP(MCID)) FixupKind = GPRelFixups[Shift]; diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -2740,18 +2740,18 @@ const MCInstrDesc &NewDesc = get(NewOpC); MI->setDesc(NewDesc); - if (NewDesc.getImplicitDefs()) - for (const MCPhysReg *ImpDefs = NewDesc.getImplicitDefs(); - *ImpDefs; ++ImpDefs) - if (!MI->definesRegister(*ImpDefs)) - MI->addOperand(*MI->getParent()->getParent(), - MachineOperand::CreateReg(*ImpDefs, true, true)); - if (NewDesc.getImplicitUses()) - for (const MCPhysReg *ImpUses = NewDesc.getImplicitUses(); - *ImpUses; ++ImpUses) - if (!MI->readsRegister(*ImpUses)) - MI->addOperand(*MI->getParent()->getParent(), - MachineOperand::CreateReg(*ImpUses, false, true)); + for (MCPhysReg ImpDef : NewDesc.implicit_defs()) { + if (!MI->definesRegister(ImpDef)) { + MI->addOperand(*MI->getParent()->getParent(), + MachineOperand::CreateReg(ImpDef, true, true)); + } + } + for (MCPhysReg ImpUse : NewDesc.implicit_uses()) { + if (!MI->readsRegister(ImpUse)) { + MI->addOperand(*MI->getParent()->getParent(), + MachineOperand::CreateReg(ImpUse, false, true)); + } + } } assert(MI->definesRegister(PPC::CR0) && "Record-form instruction does not define cr0?"); diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp @@ -522,7 +522,7 @@ APInt &Mask) const { const MCInstrDesc &Desc = Info->get(Inst.getOpcode()); unsigned NumDefs = Desc.getNumDefs(); - unsigned NumImplicitDefs = Desc.getNumImplicitDefs(); + unsigned NumImplicitDefs = Desc.implicit_defs().size(); assert(Mask.getBitWidth() == NumDefs + NumImplicitDefs && "Unexpected number of bits in the mask!"); @@ -561,7 +561,7 @@ } for (unsigned I = 0, E = NumImplicitDefs; I < E; ++I) { - const MCPhysReg Reg = Desc.getImplicitDefs()[I]; + const MCPhysReg Reg = Desc.implicit_defs()[I]; if (ClearsSuperReg(Reg)) Mask.setBit(NumDefs + I); } diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp --- a/llvm/lib/Target/X86/X86FastISel.cpp +++ b/llvm/lib/Target/X86/X86FastISel.cpp @@ -4001,7 +4001,7 @@ .addReg(Op3); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), ResultReg) - .addReg(II.getImplicitDefs()[0]); + .addReg(II.implicit_defs()[0]); } return ResultReg; } diff --git a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h --- a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h +++ b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h @@ -58,8 +58,7 @@ // registers and the registers reachable from them (aliasing registers). // - Info: a shortcut for MCInstrDesc::operands()[Index]. // - TiedToIndex: the index of the Operand holding the value or -1. -// - ImplicitReg: a pointer to the register value when Operand is Implicit, -// nullptr otherwise. +// - ImplicitReg: the register value when Operand is Implicit, 0 otherwise. // - VariableIndex: the index of the Variable holding the value for this Operand // or -1 if this operand is implicit. struct Operand { @@ -86,7 +85,7 @@ const RegisterAliasingTracker *Tracker = nullptr; // Set for Register Op. const MCOperandInfo *Info = nullptr; // Set for Explicit Op. std::optional TiedToIndex; // Set for Reg&Explicit Op. - const MCPhysReg *ImplicitReg = nullptr; // Set for Implicit Op. + MCPhysReg ImplicitReg = 0; // Non-0 for Implicit Op. std::optional VariableIndex; // Set for Explicit Op. }; diff --git a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp --- a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp +++ b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp @@ -67,7 +67,7 @@ unsigned Operand::getImplicitReg() const { assert(ImplicitReg); - return *ImplicitReg; + return ImplicitReg; } const RegisterAliasingTracker &Operand::getRegisterAliasing() const { @@ -128,21 +128,19 @@ Operand.Info = &OpInfo; Operands.push_back(Operand); } - for (const MCPhysReg *MCPhysReg = Description->getImplicitDefs(); - MCPhysReg && *MCPhysReg; ++MCPhysReg, ++OpIndex) { + for (MCPhysReg MCPhysReg : Description->implicit_defs()) { Operand Operand; - Operand.Index = OpIndex; + Operand.Index = OpIndex++; Operand.IsDef = true; - Operand.Tracker = &RATC.getRegister(*MCPhysReg); + Operand.Tracker = &RATC.getRegister(MCPhysReg); Operand.ImplicitReg = MCPhysReg; Operands.push_back(Operand); } - for (const MCPhysReg *MCPhysReg = Description->getImplicitUses(); - MCPhysReg && *MCPhysReg; ++MCPhysReg, ++OpIndex) { + for (MCPhysReg MCPhysReg : Description->implicit_uses()) { Operand Operand; - Operand.Index = OpIndex; + Operand.Index = OpIndex++; Operand.IsDef = false; - Operand.Tracker = &RATC.getRegister(*MCPhysReg); + Operand.Tracker = &RATC.getRegister(MCPhysReg); Operand.ImplicitReg = MCPhysReg; Operands.push_back(Operand); } diff --git a/llvm/tools/llvm-reduce/deltas/ReduceRegisterDefs.cpp b/llvm/tools/llvm-reduce/deltas/ReduceRegisterDefs.cpp --- a/llvm/tools/llvm-reduce/deltas/ReduceRegisterDefs.cpp +++ b/llvm/tools/llvm-reduce/deltas/ReduceRegisterDefs.cpp @@ -40,8 +40,8 @@ int NumOperands = MI.getNumOperands(); int NumRequiredOps = MI.getNumExplicitOperands() + - MI.getDesc().getNumImplicitDefs() + - MI.getDesc().getNumImplicitUses(); + MI.getDesc().implicit_defs().size() + + MI.getDesc().implicit_uses().size(); bool HaveDelete = false; // Do an initial scan in case the instruction defines the same register diff --git a/llvm/tools/llvm-reduce/deltas/ReduceRegisterUses.cpp b/llvm/tools/llvm-reduce/deltas/ReduceRegisterUses.cpp --- a/llvm/tools/llvm-reduce/deltas/ReduceRegisterUses.cpp +++ b/llvm/tools/llvm-reduce/deltas/ReduceRegisterUses.cpp @@ -29,8 +29,8 @@ int NumOperands = MI.getNumOperands(); int NumRequiredOps = MI.getNumExplicitOperands() + - MI.getDesc().getNumImplicitDefs() + - MI.getDesc().getNumImplicitUses(); + MI.getDesc().implicit_defs().size() + + MI.getDesc().implicit_uses().size(); for (int I = NumOperands - 1; I >= 0; --I) { MachineOperand &MO = MI.getOperand(I); diff --git a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp --- a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp @@ -73,10 +73,10 @@ // - hasAliasingImplicitRegisters (execution is always serial) // - hasAliasingRegisters const unsigned Opcode = X86::ADC16i16; - EXPECT_THAT(InstrInfo.get(Opcode).getImplicitDefs()[0], X86::AX); - EXPECT_THAT(InstrInfo.get(Opcode).getImplicitDefs()[1], X86::EFLAGS); - EXPECT_THAT(InstrInfo.get(Opcode).getImplicitUses()[0], X86::AX); - EXPECT_THAT(InstrInfo.get(Opcode).getImplicitUses()[1], X86::EFLAGS); + EXPECT_THAT(InstrInfo.get(Opcode).implicit_defs()[0], X86::AX); + EXPECT_THAT(InstrInfo.get(Opcode).implicit_defs()[1], X86::EFLAGS); + EXPECT_THAT(InstrInfo.get(Opcode).implicit_uses()[0], X86::AX); + EXPECT_THAT(InstrInfo.get(Opcode).implicit_uses()[1], X86::EFLAGS); const auto CodeTemplates = checkAndGetCodeTemplates(Opcode); ASSERT_THAT(CodeTemplates, SizeIs(1)); const auto &CT = CodeTemplates[0]; @@ -99,7 +99,7 @@ // - hasTiedRegisters (execution is always serial) // - hasAliasingRegisters const unsigned Opcode = X86::ADD16ri; - EXPECT_THAT(InstrInfo.get(Opcode).getImplicitDefs()[0], X86::EFLAGS); + EXPECT_THAT(InstrInfo.get(Opcode).implicit_defs()[0], X86::EFLAGS); const auto CodeTemplates = checkAndGetCodeTemplates(Opcode); ASSERT_THAT(CodeTemplates, SizeIs(1)); const auto &CT = CodeTemplates[0];