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 @@ -204,10 +204,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 @@ -563,21 +564,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 @@ -588,21 +576,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 &U : enumerate(Uses)) + OS << (U.index() ? ", " : "") << getQualifiedName(U.value()); + OS << " };\n"; } //===----------------------------------------------------------------------===// @@ -908,16 +908,13 @@ Records.startTimer("Emit uses/defs"); for (const CodeGenInstruction *II : Target.getInstructionsByEnumValue()) { Record *Inst = II->TheDef; - std::vector Uses = Inst->getValueAsListOfDefs("Uses"); + std::vector Uses = Inst->getValueAsListOfDefs("Uses"); + std::vector Defs = Inst->getValueAsListOfDefs("Defs"); + llvm::append_range(Uses, Defs); if (!Uses.empty()) { unsigned &IL = EmittedLists[Uses]; if (!IL) PrintDefList(Uses, IL = ++ListNumber, OS); } - std::vector Defs = Inst->getValueAsListOfDefs("Defs"); - if (!Defs.empty()) { - unsigned &IL = EmittedLists[Defs]; - if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS); - } } OperandInfoMapTy OperandInfoIDs; @@ -1115,11 +1112,16 @@ MinOperands = Inst.Operands.back().MIOperandNo + Inst.Operands.back().MINumOperands; + std::vector UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); + std::vector DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); + OS << " { "; OS << Num << ",\t" << MinOperands << ",\t" << Inst.Operands.NumDefs << ",\t" << Inst.TheDef->getValueAsInt("Size") << ",\t" - << SchedModels.getSchedClassIdx(Inst) << ",\t0"; + << SchedModels.getSchedClassIdx(Inst) << ",\t" + << UseList.size() << ",\t" + << DefList.size() << ",\t0"; CodeGenTarget &Target = CDP.getTargetInfo(); @@ -1184,19 +1186,13 @@ OS.write_hex(Value); OS << "ULL, "; - // Emit the implicit uses and defs lists... - std::vector UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); + // Emit the implicit use/def list... + llvm::append_range(UseList, DefList); if (UseList.empty()) OS << "nullptr, "; else OS << "ImplicitList" << EmittedLists[UseList] << ", "; - std::vector DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); - if (DefList.empty()) - OS << "nullptr, "; - else - OS << "ImplicitList" << EmittedLists[DefList] << ", "; - // Emit the operand info. std::vector OperandInfo = GetOperandInfo(Inst); if (OperandInfo.empty())