mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-01 01:31:26 +00:00
[MC] Store operand info immediately after the TargetInsts table. NFC.
This shrinks MCInstrDesc (and hence the whole TargetInsts table) because we can store a 16-bit offset value to access the operands info, instead of a pointer. This also reduces the number of relocs that need to be applied when LLVM is compiled as position-independent code. Differential Revision: https://reviews.llvm.org/D142219
This commit is contained in:
parent
1220c5d4ac
commit
8dcdc37a5f
@ -210,9 +210,9 @@ public:
|
||||
unsigned char NumImplicitUses; // Num of regs implicitly used
|
||||
unsigned char NumImplicitDefs; // Num of regs implicitly defined
|
||||
unsigned short ImplicitOffset; // Offset to start of implicit op list
|
||||
unsigned short OpInfoOffset; // Offset to info about operands
|
||||
uint64_t Flags; // Flags identifying machine instr class
|
||||
uint64_t TSFlags; // Target Specific Flag values
|
||||
const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands
|
||||
|
||||
/// Returns the value of the specified operand constraint if
|
||||
/// it is present. Returns -1 if it is not present.
|
||||
@ -237,7 +237,8 @@ public:
|
||||
unsigned getNumOperands() const { return NumOperands; }
|
||||
|
||||
ArrayRef<MCOperandInfo> operands() const {
|
||||
return ArrayRef(OpInfo, NumOperands);
|
||||
auto OpInfo = reinterpret_cast<const MCOperandInfo *>(this + Opcode + 1);
|
||||
return ArrayRef(OpInfo + OpInfoOffset, NumOperands);
|
||||
}
|
||||
|
||||
/// Return the number of MachineOperands that are register
|
||||
@ -563,8 +564,9 @@ public:
|
||||
/// reading the flags. Likewise, the variable shift instruction on X86 is
|
||||
/// marked as implicitly reading the 'CL' register, which it always does.
|
||||
ArrayRef<MCPhysReg> implicit_uses() const {
|
||||
auto ImplicitOps = reinterpret_cast<const MCPhysReg *>(this + Opcode + 1);
|
||||
return {ImplicitOps + ImplicitOffset, NumImplicitUses};
|
||||
auto ImplicitOps =
|
||||
reinterpret_cast<const MCPhysReg *>(this + Opcode + 1) + ImplicitOffset;
|
||||
return {ImplicitOps, NumImplicitUses};
|
||||
}
|
||||
|
||||
/// Return a list of registers that are potentially written by any
|
||||
@ -576,8 +578,9 @@ public:
|
||||
/// registers. For that instruction, this will return a list containing the
|
||||
/// EAX/EDX/EFLAGS registers.
|
||||
ArrayRef<MCPhysReg> implicit_defs() const {
|
||||
auto ImplicitOps = reinterpret_cast<const MCPhysReg *>(this + Opcode + 1);
|
||||
return {ImplicitOps + ImplicitOffset + NumImplicitUses, NumImplicitDefs};
|
||||
auto ImplicitOps =
|
||||
reinterpret_cast<const MCPhysReg *>(this + Opcode + 1) + ImplicitOffset;
|
||||
return {ImplicitOps + NumImplicitUses, NumImplicitDefs};
|
||||
}
|
||||
|
||||
/// Return true if this instruction implicitly
|
||||
|
@ -51,23 +51,24 @@ TEST(IsIdenticalToTest, DifferentDefs) {
|
||||
|
||||
unsigned short NumOps = 2;
|
||||
unsigned char NumDefs = 1;
|
||||
MCOperandInfo OpInfo[] = {
|
||||
{0, 0, MCOI::OPERAND_REGISTER, 0},
|
||||
{0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}};
|
||||
MCInstrDesc MCID = {
|
||||
0, NumOps, NumDefs, 0, 0, 0, 0, 0, 1ULL << MCID::HasOptionalDef,
|
||||
0, OpInfo};
|
||||
struct {
|
||||
MCInstrDesc MCID;
|
||||
MCOperandInfo OpInfo[2];
|
||||
} Table = {
|
||||
{0, NumOps, NumDefs, 0, 0, 0, 0, 0, 0, 1ULL << MCID::HasOptionalDef, 0},
|
||||
{{0, 0, MCOI::OPERAND_REGISTER, 0},
|
||||
{0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}}};
|
||||
|
||||
// Create two MIs with different virtual reg defs and the same uses.
|
||||
unsigned VirtualDef1 = -42; // The value doesn't matter, but the sign does.
|
||||
unsigned VirtualDef2 = -43;
|
||||
unsigned VirtualUse = -44;
|
||||
|
||||
auto MI1 = MF->CreateMachineInstr(MCID, DebugLoc());
|
||||
auto MI1 = MF->CreateMachineInstr(Table.MCID, DebugLoc());
|
||||
MI1->addOperand(*MF, MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
|
||||
MI1->addOperand(*MF, MachineOperand::CreateReg(VirtualUse, /*isDef*/ false));
|
||||
|
||||
auto MI2 = MF->CreateMachineInstr(MCID, DebugLoc());
|
||||
auto MI2 = MF->CreateMachineInstr(Table.MCID, DebugLoc());
|
||||
MI2->addOperand(*MF, MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
|
||||
MI2->addOperand(*MF, MachineOperand::CreateReg(VirtualUse, /*isDef*/ false));
|
||||
|
||||
@ -83,11 +84,11 @@ TEST(IsIdenticalToTest, DifferentDefs) {
|
||||
// sentinel register.
|
||||
unsigned SentinelReg = 0;
|
||||
|
||||
auto MI3 = MF->CreateMachineInstr(MCID, DebugLoc());
|
||||
auto MI3 = MF->CreateMachineInstr(Table.MCID, DebugLoc());
|
||||
MI3->addOperand(*MF, MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
|
||||
MI3->addOperand(*MF, MachineOperand::CreateReg(SentinelReg, /*isDef*/ true));
|
||||
|
||||
auto MI4 = MF->CreateMachineInstr(MCID, DebugLoc());
|
||||
auto MI4 = MF->CreateMachineInstr(Table.MCID, DebugLoc());
|
||||
MI4->addOperand(*MF, MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
|
||||
MI4->addOperand(*MF, MachineOperand::CreateReg(SentinelReg, /*isDef*/ false));
|
||||
|
||||
@ -122,12 +123,13 @@ TEST(MachineInstrExpressionTraitTest, IsEqualAgreesWithGetHashValue) {
|
||||
|
||||
unsigned short NumOps = 2;
|
||||
unsigned char NumDefs = 1;
|
||||
MCOperandInfo OpInfo[] = {
|
||||
{0, 0, MCOI::OPERAND_REGISTER, 0},
|
||||
{0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}};
|
||||
MCInstrDesc MCID = {
|
||||
0, NumOps, NumDefs, 0, 0, 0, 0, 0, 1ULL << MCID::HasOptionalDef,
|
||||
0, OpInfo};
|
||||
struct {
|
||||
MCInstrDesc MCID;
|
||||
MCOperandInfo OpInfo[2];
|
||||
} Table = {
|
||||
{0, NumOps, NumDefs, 0, 0, 0, 0, 0, 0, 1ULL << MCID::HasOptionalDef, 0},
|
||||
{{0, 0, MCOI::OPERAND_REGISTER, 0},
|
||||
{0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}}};
|
||||
|
||||
// Define a series of instructions with different kinds of operands and make
|
||||
// sure that the hash function is consistent with isEqual for various
|
||||
@ -138,37 +140,37 @@ TEST(MachineInstrExpressionTraitTest, IsEqualAgreesWithGetHashValue) {
|
||||
unsigned SentinelReg = 0;
|
||||
unsigned PhysicalReg = 45;
|
||||
|
||||
auto VD1VU = MF->CreateMachineInstr(MCID, DebugLoc());
|
||||
auto VD1VU = MF->CreateMachineInstr(Table.MCID, DebugLoc());
|
||||
VD1VU->addOperand(*MF,
|
||||
MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
|
||||
VD1VU->addOperand(*MF,
|
||||
MachineOperand::CreateReg(VirtualReg, /*isDef*/ false));
|
||||
|
||||
auto VD2VU = MF->CreateMachineInstr(MCID, DebugLoc());
|
||||
auto VD2VU = MF->CreateMachineInstr(Table.MCID, DebugLoc());
|
||||
VD2VU->addOperand(*MF,
|
||||
MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
|
||||
VD2VU->addOperand(*MF,
|
||||
MachineOperand::CreateReg(VirtualReg, /*isDef*/ false));
|
||||
|
||||
auto VD1SU = MF->CreateMachineInstr(MCID, DebugLoc());
|
||||
auto VD1SU = MF->CreateMachineInstr(Table.MCID, DebugLoc());
|
||||
VD1SU->addOperand(*MF,
|
||||
MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
|
||||
VD1SU->addOperand(*MF,
|
||||
MachineOperand::CreateReg(SentinelReg, /*isDef*/ false));
|
||||
|
||||
auto VD1SD = MF->CreateMachineInstr(MCID, DebugLoc());
|
||||
auto VD1SD = MF->CreateMachineInstr(Table.MCID, DebugLoc());
|
||||
VD1SD->addOperand(*MF,
|
||||
MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
|
||||
VD1SD->addOperand(*MF,
|
||||
MachineOperand::CreateReg(SentinelReg, /*isDef*/ true));
|
||||
|
||||
auto VD2PU = MF->CreateMachineInstr(MCID, DebugLoc());
|
||||
auto VD2PU = MF->CreateMachineInstr(Table.MCID, DebugLoc());
|
||||
VD2PU->addOperand(*MF,
|
||||
MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
|
||||
VD2PU->addOperand(*MF,
|
||||
MachineOperand::CreateReg(PhysicalReg, /*isDef*/ false));
|
||||
|
||||
auto VD2PD = MF->CreateMachineInstr(MCID, DebugLoc());
|
||||
auto VD2PD = MF->CreateMachineInstr(Table.MCID, DebugLoc());
|
||||
VD2PD->addOperand(*MF,
|
||||
MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
|
||||
VD2PD->addOperand(*MF,
|
||||
@ -200,8 +202,11 @@ TEST(MachineInstrPrintingTest, DebugLocPrinting) {
|
||||
Module Mod("Module", Ctx);
|
||||
auto MF = createMachineFunction(Ctx, Mod);
|
||||
|
||||
MCOperandInfo OpInfo{0, 0, MCOI::OPERAND_REGISTER, 0};
|
||||
MCInstrDesc MCID = {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, &OpInfo};
|
||||
struct {
|
||||
MCInstrDesc MCID;
|
||||
MCOperandInfo OpInfo;
|
||||
} Table = {{0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, MCOI::OPERAND_REGISTER, 0}};
|
||||
|
||||
DIFile *DIF = DIFile::getDistinct(Ctx, "filename", "");
|
||||
DISubprogram *DIS = DISubprogram::getDistinct(
|
||||
@ -209,7 +214,7 @@ TEST(MachineInstrPrintingTest, DebugLocPrinting) {
|
||||
DISubprogram::SPFlagZero, nullptr);
|
||||
DILocation *DIL = DILocation::get(Ctx, 1, 5, DIS);
|
||||
DebugLoc DL(DIL);
|
||||
MachineInstr *MI = MF->CreateMachineInstr(MCID, DL);
|
||||
MachineInstr *MI = MF->CreateMachineInstr(Table.MCID, DL);
|
||||
MI->addOperand(*MF, MachineOperand::CreateReg(0, /*isDef*/ true));
|
||||
|
||||
std::string str;
|
||||
@ -228,7 +233,7 @@ TEST(MachineInstrSpan, DistanceBegin) {
|
||||
auto MF = createMachineFunction(Ctx, Mod);
|
||||
auto MBB = MF->CreateMachineBasicBlock();
|
||||
|
||||
MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr};
|
||||
MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
auto MII = MBB->begin();
|
||||
MachineInstrSpan MIS(MII, MBB);
|
||||
@ -245,7 +250,7 @@ TEST(MachineInstrSpan, DistanceEnd) {
|
||||
auto MF = createMachineFunction(Ctx, Mod);
|
||||
auto MBB = MF->CreateMachineBasicBlock();
|
||||
|
||||
MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr};
|
||||
MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
auto MII = MBB->end();
|
||||
MachineInstrSpan MIS(MII, MBB);
|
||||
@ -260,7 +265,7 @@ TEST(MachineInstrExtraInfo, AddExtraInfo) {
|
||||
LLVMContext Ctx;
|
||||
Module Mod("Module", Ctx);
|
||||
auto MF = createMachineFunction(Ctx, Mod);
|
||||
MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr};
|
||||
MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
|
||||
auto MAI = MCAsmInfo();
|
||||
@ -320,7 +325,7 @@ TEST(MachineInstrExtraInfo, ChangeExtraInfo) {
|
||||
LLVMContext Ctx;
|
||||
Module Mod("Module", Ctx);
|
||||
auto MF = createMachineFunction(Ctx, Mod);
|
||||
MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr};
|
||||
MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
|
||||
auto MAI = MCAsmInfo();
|
||||
@ -361,7 +366,7 @@ TEST(MachineInstrExtraInfo, RemoveExtraInfo) {
|
||||
LLVMContext Ctx;
|
||||
Module Mod("Module", Ctx);
|
||||
auto MF = createMachineFunction(Ctx, Mod);
|
||||
MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr};
|
||||
MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
|
||||
auto MAI = MCAsmInfo();
|
||||
@ -428,10 +433,9 @@ TEST(MachineInstrDebugValue, AddDebugValueOperand) {
|
||||
TargetOpcode::DBG_INSTR_REF, TargetOpcode::DBG_PHI,
|
||||
TargetOpcode::DBG_LABEL}) {
|
||||
const MCInstrDesc MCID = {
|
||||
Opcode, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, (1ULL << MCID::Pseudo) | (1ULL << MCID::Variadic),
|
||||
0, nullptr};
|
||||
Opcode, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, (1ULL << MCID::Pseudo) | (1ULL << MCID::Variadic),
|
||||
0};
|
||||
|
||||
auto *MI = MF->CreateMachineInstr(MCID, DebugLoc());
|
||||
MI->addOperand(*MF, MachineOperand::CreateReg(0, /*isDef*/ false));
|
||||
@ -461,7 +465,7 @@ TEST(MachineInstrBuilder, BuildMI) {
|
||||
Module Mod("Module", Ctx);
|
||||
auto MF = createMachineFunction(Ctx, Mod);
|
||||
auto MBB = MF->CreateMachineBasicBlock();
|
||||
MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr};
|
||||
MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
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));
|
||||
|
@ -64,7 +64,7 @@ enum MockInstrId {
|
||||
|
||||
const std::array<MCInstrDesc, MockInstrId::TotalMockInstrs> MockInstrDescs{{
|
||||
#define MOCK_SPEC(IGNORE, OPCODE, FLAGS) \
|
||||
{OPCODE, 0, 0, 0, 0, 0, 0, 0, FLAGS, 0, nullptr},
|
||||
{OPCODE, 0, 0, 0, 0, 0, 0, 0, 0, FLAGS, 0},
|
||||
MOCK_INSTR(MOCK_SPEC)
|
||||
#undef MOCK_SPEC
|
||||
}};
|
||||
|
@ -61,7 +61,9 @@ public:
|
||||
private:
|
||||
void emitEnums(raw_ostream &OS);
|
||||
|
||||
typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy;
|
||||
typedef std::vector<std::string> OperandInfoTy;
|
||||
typedef std::vector<OperandInfoTy> OperandInfoListTy;
|
||||
typedef std::map<OperandInfoTy, unsigned> OperandInfoMapTy;
|
||||
|
||||
/// The keys of this map are maps which have OpName enum values as their keys
|
||||
/// and instruction operand indices as their values. The values of this map
|
||||
@ -86,9 +88,8 @@ private:
|
||||
void emitFeatureVerifier(raw_ostream &OS, const CodeGenTarget &Target);
|
||||
void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
|
||||
Record *InstrInfo,
|
||||
std::map<std::vector<Record*>, unsigned> &EL,
|
||||
const OperandInfoMapTy &OpInfo,
|
||||
raw_ostream &OS);
|
||||
std::map<std::vector<Record *>, unsigned> &EL,
|
||||
const OperandInfoMapTy &OperandInfo, raw_ostream &OS);
|
||||
void emitOperandTypeMappings(
|
||||
raw_ostream &OS, const CodeGenTarget &Target,
|
||||
ArrayRef<const CodeGenInstruction *> NumberedInstructions);
|
||||
@ -108,8 +109,10 @@ private:
|
||||
ArrayRef<const CodeGenInstruction *> NumberedInstructions);
|
||||
|
||||
// Operand information.
|
||||
void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs);
|
||||
std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst);
|
||||
unsigned CollectOperandInfo(OperandInfoListTy &OperandInfoList,
|
||||
OperandInfoMapTy &OperandInfoMap);
|
||||
void EmitOperandInfo(raw_ostream &OS, OperandInfoListTy &OperandInfoList);
|
||||
OperandInfoTy GetOperandInfo(const CodeGenInstruction &Inst);
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
@ -118,9 +121,9 @@ private:
|
||||
// Operand Info Emission.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
std::vector<std::string>
|
||||
InstrInfoEmitter::OperandInfoTy
|
||||
InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
|
||||
std::vector<std::string> Result;
|
||||
OperandInfoTy Result;
|
||||
|
||||
for (auto &Op : Inst.Operands) {
|
||||
// Handle aggregate operands and normal operands the same way by expanding
|
||||
@ -207,23 +210,30 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS,
|
||||
OperandInfoMapTy &OperandInfoIDs) {
|
||||
// ID #0 is for no operand info.
|
||||
unsigned OperandListNum = 0;
|
||||
OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum;
|
||||
|
||||
unsigned
|
||||
InstrInfoEmitter::CollectOperandInfo(OperandInfoListTy &OperandInfoList,
|
||||
OperandInfoMapTy &OperandInfoMap) {
|
||||
const CodeGenTarget &Target = CDP.getTargetInfo();
|
||||
unsigned Offset = 0;
|
||||
for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
|
||||
std::vector<std::string> OperandInfo = GetOperandInfo(*Inst);
|
||||
unsigned &N = OperandInfoIDs[OperandInfo];
|
||||
if (N != 0) continue;
|
||||
OperandInfoTy OperandInfo = GetOperandInfo(*Inst);
|
||||
if (OperandInfoMap.insert({OperandInfo, Offset}).second) {
|
||||
OperandInfoList.push_back(OperandInfo);
|
||||
Offset += OperandInfo.size();
|
||||
}
|
||||
}
|
||||
return Offset;
|
||||
}
|
||||
|
||||
N = ++OperandListNum;
|
||||
OS << "static const MCOperandInfo OperandInfo" << N << "[] = { ";
|
||||
for (const std::string &Info : OperandInfo)
|
||||
OS << "{ " << Info << " }, ";
|
||||
OS << "};\n";
|
||||
void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS,
|
||||
OperandInfoListTy &OperandInfoList) {
|
||||
unsigned Offset = 0;
|
||||
for (auto &OperandInfo : OperandInfoList) {
|
||||
OS << " /* " << Offset << " */";
|
||||
for (auto &Info : OperandInfo)
|
||||
OS << " { " << Info << " },";
|
||||
OS << '\n';
|
||||
Offset += OperandInfo.size();
|
||||
}
|
||||
}
|
||||
|
||||
@ -886,6 +896,13 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
|
||||
const std::string &TargetName = std::string(Target.getName());
|
||||
Record *InstrInfo = Target.getInstructionSet();
|
||||
|
||||
// Collect all of the operand info records.
|
||||
Records.startTimer("Collect operand info");
|
||||
OperandInfoListTy OperandInfoList;
|
||||
OperandInfoMapTy OperandInfoMap;
|
||||
unsigned OperandInfoSize =
|
||||
CollectOperandInfo(OperandInfoList, OperandInfoMap);
|
||||
|
||||
// Collect all of the instruction's implicit uses and defs.
|
||||
Records.startTimer("Collect uses/defs");
|
||||
std::map<std::vector<Record*>, unsigned> EmittedLists;
|
||||
@ -908,8 +925,11 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
|
||||
|
||||
OS << "struct " << TargetName << "InstrTable {\n";
|
||||
OS << " MCInstrDesc Insts[" << NumberedInstructions.size() << "];\n";
|
||||
OS << " static_assert(alignof(MCInstrDesc) >= alignof(MCPhysReg), "
|
||||
"\"Unwanted padding between Insts and ImplicitOps\");\n";
|
||||
OS << " static_assert(alignof(MCInstrDesc) >= alignof(MCOperandInfo), "
|
||||
"\"Unwanted padding between Insts and OperandInfo\");\n";
|
||||
OS << " MCOperandInfo OperandInfo[" << OperandInfoSize << "];\n";
|
||||
OS << " static_assert(alignof(MCOperandInfo) >= alignof(MCPhysReg), "
|
||||
"\"Unwanted padding between OperandInfo and ImplicitOps\");\n";
|
||||
OS << " MCPhysReg ImplicitOps[" << std::max(ImplicitListSize, 1U) << "];\n";
|
||||
OS << "};\n\n";
|
||||
|
||||
@ -921,14 +941,12 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
|
||||
OS << "#undef GET_INSTRINFO_MC_DESC\n";
|
||||
OS << "namespace llvm {\n\n";
|
||||
|
||||
// Emit all of the operand info records.
|
||||
Records.startTimer("Emit operand info");
|
||||
OperandInfoMapTy OperandInfoIDs;
|
||||
EmitOperandInfo(OS, OperandInfoIDs);
|
||||
OS << "\n";
|
||||
|
||||
// Emit all of the MCInstrDesc records in reverse ENUM ordering.
|
||||
Records.startTimer("Emit InstrDesc records");
|
||||
OS << "static_assert(sizeof(MCOperandInfo) % sizeof(MCPhysReg) == 0);\n";
|
||||
OS << "static constexpr unsigned " << TargetName << "ImpOpBase = sizeof "
|
||||
<< TargetName << "InstrTable::OperandInfo / (sizeof(MCPhysReg));\n\n";
|
||||
|
||||
OS << "extern const " << TargetName << "InstrTable " << TargetName
|
||||
<< "Descs = {\n {\n";
|
||||
SequenceToOffsetTable<std::string> InstrNames;
|
||||
@ -937,11 +955,17 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
|
||||
// Keep a list of the instruction names.
|
||||
InstrNames.add(std::string(Inst->TheDef->getName()));
|
||||
// Emit the record into the table.
|
||||
emitRecord(*Inst, --Num, InstrInfo, EmittedLists, OperandInfoIDs, OS);
|
||||
emitRecord(*Inst, --Num, InstrInfo, EmittedLists, OperandInfoMap, OS);
|
||||
}
|
||||
|
||||
OS << " }, {\n";
|
||||
|
||||
// Emit all of the operand info records.
|
||||
Records.startTimer("Emit operand info");
|
||||
EmitOperandInfo(OS, OperandInfoList);
|
||||
|
||||
OS << " }, {\n";
|
||||
|
||||
// Emit all of the instruction's implicit uses and defs.
|
||||
Records.startTimer("Emit uses/defs");
|
||||
for (auto &List : ImplicitLists) {
|
||||
@ -1115,11 +1139,10 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
|
||||
emitFeatureVerifier(OS, Target);
|
||||
}
|
||||
|
||||
void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
|
||||
Record *InstrInfo,
|
||||
std::map<std::vector<Record*>, unsigned> &EmittedLists,
|
||||
const OperandInfoMapTy &OpInfo,
|
||||
raw_ostream &OS) {
|
||||
void InstrInfoEmitter::emitRecord(
|
||||
const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo,
|
||||
std::map<std::vector<Record *>, unsigned> &EmittedLists,
|
||||
const OperandInfoMapTy &OperandInfoMap, raw_ostream &OS) {
|
||||
int MinOperands = 0;
|
||||
if (!Inst.Operands.empty())
|
||||
// Each logical operand can be multiple MI operands.
|
||||
@ -1131,13 +1154,18 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
|
||||
<< Inst.TheDef->getValueAsInt("Size") << ",\t"
|
||||
<< SchedModels.getSchedClassIdx(Inst) << ",\t";
|
||||
|
||||
CodeGenTarget &Target = CDP.getTargetInfo();
|
||||
|
||||
// Emit the implicit use/def list...
|
||||
OS << Inst.ImplicitUses.size() << ",\t" << Inst.ImplicitDefs.size() << ",\t";
|
||||
std::vector<Record *> ImplicitOps = Inst.ImplicitUses;
|
||||
llvm::append_range(ImplicitOps, Inst.ImplicitDefs);
|
||||
OS << EmittedLists[ImplicitOps] << ",\t0";
|
||||
OS << Target.getName() << "ImpOpBase + " << EmittedLists[ImplicitOps]
|
||||
<< ",\t";
|
||||
|
||||
CodeGenTarget &Target = CDP.getTargetInfo();
|
||||
// Emit the operand info offset.
|
||||
OperandInfoTy OperandInfo = GetOperandInfo(Inst);
|
||||
OS << OperandInfoMap.find(OperandInfo)->second << ",\t0";
|
||||
|
||||
// Emit all of the target independent flags...
|
||||
if (Inst.isPreISelOpcode) OS << "|(1ULL<<MCID::PreISelOpcode)";
|
||||
@ -1198,14 +1226,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
|
||||
}
|
||||
OS << ", 0x";
|
||||
OS.write_hex(Value);
|
||||
OS << "ULL, ";
|
||||
|
||||
// Emit the operand info.
|
||||
std::vector<std::string> OperandInfo = GetOperandInfo(Inst);
|
||||
if (OperandInfo.empty())
|
||||
OS << "nullptr";
|
||||
else
|
||||
OS << "OperandInfo" << OpInfo.find(OperandInfo)->second;
|
||||
OS << "ULL";
|
||||
|
||||
OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user