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 @@ -207,10 +207,11 @@ unsigned char NumDefs; // Num of args that are definitions unsigned char Size; // Number of bytes in encoding. unsigned short SchedClass; // enum identifying instr sched class + unsigned char NumImplicitUses; // Num of regs implicitly used + unsigned char NumImplicitDefs; // Num of regs implicitly defined uint64_t Flags; // Flags identifying machine instr class uint64_t TSFlags; // Target Specific Flag values - const MCPhysReg *ImplicitUses; // Registers implicitly read by this instr - const MCPhysReg *ImplicitDefs; // Registers implicitly defined by this instr + const MCPhysReg *ImplicitOps; // List of implicit uses followed by defs const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands /// Returns the value of the specified operand constraint if @@ -566,21 +567,8 @@ /// flags register. In this case, the instruction is marked as implicitly /// reading the flags. Likewise, the variable shift instruction on X86 is /// marked as implicitly reading the 'CL' register, which it always does. - /// - /// 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 { - if (!ImplicitUses) - return 0; - unsigned i = 0; - for (; ImplicitUses[i]; ++i) /*empty*/ - ; - return i; + return {ImplicitOps, NumImplicitUses}; } /// Return a list of registers that are potentially written by any @@ -591,21 +579,8 @@ /// instruction always deposits the quotient and remainder in the EAX/EDX /// registers. For that instruction, this will return a list containing the /// EAX/EDX/EFLAGS registers. - /// - /// 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 { - if (!ImplicitDefs) - return 0; - unsigned i = 0; - for (; ImplicitDefs[i]; ++i) /*empty*/ - ; - return i; + return {ImplicitOps + NumImplicitUses, NumImplicitDefs}; } /// Return true if this instruction implicitly diff --git a/llvm/unittests/CodeGen/MachineInstrTest.cpp b/llvm/unittests/CodeGen/MachineInstrTest.cpp --- a/llvm/unittests/CodeGen/MachineInstrTest.cpp +++ b/llvm/unittests/CodeGen/MachineInstrTest.cpp @@ -54,9 +54,9 @@ MCOperandInfo OpInfo[] = { {0, 0, MCOI::OPERAND_REGISTER, 0}, {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}}; - MCInstrDesc MCID = { - 0, NumOps, NumDefs, 0, 0, 1ULL << MCID::HasOptionalDef, - 0, nullptr, nullptr, OpInfo}; + MCInstrDesc MCID = {0, NumOps, NumDefs, 0, + 0, 0, 0, 1ULL << MCID::HasOptionalDef, + 0, nullptr, OpInfo}; // Create two MIs with different virtual reg defs and the same uses. unsigned VirtualDef1 = -42; // The value doesn't matter, but the sign does. @@ -125,9 +125,9 @@ MCOperandInfo OpInfo[] = { {0, 0, MCOI::OPERAND_REGISTER, 0}, {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}}; - MCInstrDesc MCID = { - 0, NumOps, NumDefs, 0, 0, 1ULL << MCID::HasOptionalDef, - 0, nullptr, nullptr, OpInfo}; + MCInstrDesc MCID = {0, NumOps, NumDefs, 0, + 0, 0, 0, 1ULL << MCID::HasOptionalDef, + 0, nullptr, OpInfo}; // Define a series of instructions with different kinds of operands and make // sure that the hash function is consistent with isEqual for various @@ -201,7 +201,7 @@ auto MF = createMachineFunction(Ctx, Mod); MCOperandInfo OpInfo{0, 0, MCOI::OPERAND_REGISTER, 0}; - MCInstrDesc MCID = {0, 1, 1, 0, 0, 0, 0, nullptr, nullptr, &OpInfo}; + MCInstrDesc MCID = {0, 1, 1, 0, 0, 0, 0, 0, 0, nullptr, &OpInfo}; DIFile *DIF = DIFile::getDistinct(Ctx, "filename", ""); DISubprogram *DIS = DISubprogram::getDistinct( @@ -228,7 +228,7 @@ auto MF = createMachineFunction(Ctx, Mod); auto MBB = MF->CreateMachineBasicBlock(); - MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, nullptr, nullptr, nullptr}; + MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr, nullptr}; auto MII = MBB->begin(); MachineInstrSpan MIS(MII, MBB); @@ -245,7 +245,7 @@ auto MF = createMachineFunction(Ctx, Mod); auto MBB = MF->CreateMachineBasicBlock(); - MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, nullptr, nullptr, nullptr}; + MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr, nullptr}; auto MII = MBB->end(); MachineInstrSpan MIS(MII, MBB); @@ -260,7 +260,7 @@ LLVMContext Ctx; Module Mod("Module", Ctx); auto MF = createMachineFunction(Ctx, Mod); - MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, nullptr, nullptr, nullptr}; + MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr, nullptr}; auto MI = MF->CreateMachineInstr(MCID, DebugLoc()); auto MAI = MCAsmInfo(); @@ -320,7 +320,7 @@ LLVMContext Ctx; Module Mod("Module", Ctx); auto MF = createMachineFunction(Ctx, Mod); - MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, nullptr, nullptr, nullptr}; + MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr, nullptr}; auto MI = MF->CreateMachineInstr(MCID, DebugLoc()); auto MAI = MCAsmInfo(); @@ -361,7 +361,7 @@ LLVMContext Ctx; Module Mod("Module", Ctx); auto MF = createMachineFunction(Ctx, Mod); - MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, nullptr, nullptr, nullptr}; + MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr, nullptr}; auto MI = MF->CreateMachineInstr(MCID, DebugLoc()); auto MAI = MCAsmInfo(); @@ -428,9 +428,11 @@ TargetOpcode::DBG_INSTR_REF, TargetOpcode::DBG_PHI, TargetOpcode::DBG_LABEL}) { const MCInstrDesc MCID = { - Opcode, 0, 0, - 0, 0, (1ULL << MCID::Pseudo) | (1ULL << MCID::Variadic), - 0, nullptr, nullptr, + Opcode, 0, + 0, 0, + 0, 0, + 0, (1ULL << MCID::Pseudo) | (1ULL << MCID::Variadic), + 0, nullptr, nullptr}; auto *MI = MF->CreateMachineInstr(MCID, DebugLoc()); @@ -461,7 +463,7 @@ Module Mod("Module", Ctx); auto MF = createMachineFunction(Ctx, Mod); auto MBB = MF->CreateMachineBasicBlock(); - MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, nullptr, nullptr, nullptr}; + MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr, nullptr}; EXPECT_THAT(BuildMI(*MF, MIMD, MCID), HasMIMetadata(MIMD)); EXPECT_THAT(BuildMI(*MF, MIMD, MCID), HasMIMetadata(MIMD)); EXPECT_THAT(BuildMI(*MBB, MBB->end(), MIMD, MCID), HasMIMetadata(MIMD)); diff --git a/llvm/unittests/CodeGen/RegAllocScoreTest.cpp b/llvm/unittests/CodeGen/RegAllocScoreTest.cpp --- a/llvm/unittests/CodeGen/RegAllocScoreTest.cpp +++ b/llvm/unittests/CodeGen/RegAllocScoreTest.cpp @@ -64,7 +64,7 @@ const std::array MockInstrDescs{{ #define MOCK_SPEC(IGNORE, OPCODE, FLAGS) \ - {OPCODE, 0, 0, 0, 0, FLAGS, 0, nullptr, nullptr, nullptr}, + {OPCODE, 0, 0, 0, 0, 0, 0, FLAGS, 0, nullptr, nullptr}, MOCK_INSTR(MOCK_SPEC) #undef MOCK_SPEC }}; diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp --- a/llvm/utils/TableGen/InstrInfoEmitter.cpp +++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp @@ -117,9 +117,9 @@ static void PrintDefList(const std::vector &Uses, unsigned Num, raw_ostream &OS) { OS << "static const MCPhysReg ImplicitList" << Num << "[] = { "; - for (Record *U : Uses) - OS << getQualifiedName(U) << ", "; - OS << "0 };\n"; + for (auto [Idx, U] : enumerate(Uses)) + OS << (Idx ? ", " : "") << getQualifiedName(U); + OS << " };\n"; } //===----------------------------------------------------------------------===// @@ -907,18 +907,13 @@ // Emit all of the instruction's implicit uses and defs. Records.startTimer("Emit uses/defs"); for (const CodeGenInstruction *II : Target.getInstructionsByEnumValue()) { - if (!II->ImplicitUses.empty()) { - unsigned &IL = EmittedLists[II->ImplicitUses]; + std::vector ImplicitOps = II->ImplicitUses; + llvm::append_range(ImplicitOps, II->ImplicitDefs); + if (!ImplicitOps.empty()) { + unsigned &IL = EmittedLists[ImplicitOps]; if (!IL) { IL = ++ListNumber; - PrintDefList(II->ImplicitUses, IL, OS); - } - } - if (!II->ImplicitDefs.empty()) { - unsigned &IL = EmittedLists[II->ImplicitDefs]; - if (!IL) { - IL = ++ListNumber; - PrintDefList(II->ImplicitDefs, IL, OS); + PrintDefList(ImplicitOps, IL, OS); } } } @@ -1122,7 +1117,9 @@ OS << Num << ",\t" << MinOperands << ",\t" << Inst.Operands.NumDefs << ",\t" << Inst.TheDef->getValueAsInt("Size") << ",\t" - << SchedModels.getSchedClassIdx(Inst) << ",\t0"; + << SchedModels.getSchedClassIdx(Inst) << ",\t" + << Inst.ImplicitUses.size() << ",\t" + << Inst.ImplicitDefs.size() << ",\t0"; CodeGenTarget &Target = CDP.getTargetInfo(); @@ -1187,16 +1184,13 @@ OS.write_hex(Value); OS << "ULL, "; - // Emit the implicit uses and defs lists... - if (Inst.ImplicitUses.empty()) - OS << "nullptr, "; - else - OS << "ImplicitList" << EmittedLists[Inst.ImplicitUses] << ", "; - - if (Inst.ImplicitDefs.empty()) + // Emit the implicit use/def list... + std::vector ImplicitOps = Inst.ImplicitUses; + llvm::append_range(ImplicitOps, Inst.ImplicitDefs); + if (ImplicitOps.empty()) OS << "nullptr, "; else - OS << "ImplicitList" << EmittedLists[Inst.ImplicitDefs] << ", "; + OS << "ImplicitList" << EmittedLists[ImplicitOps] << ", "; // Emit the operand info. std::vector OperandInfo = GetOperandInfo(Inst);