llvm.org GIT mirror llvm / 1a4def3
MIR Serialization: Serialize the register mask machine operands. This commit implements serialization of the register mask machine operands. This commit serializes only the call preserved register masks that are defined by a target, it doesn't serialize arbitrary register masks. This commit also extends the TargetRegisterInfo class and TableGen so that the users of TRI can get the list of all the call preserved register masks and their names. Reviewers: Duncan P. N. Exon Smith Differential Revision: http://reviews.llvm.org/D10673 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240966 91177308-0d34-0410-b5e6-96231b3b80d8 Alex Lorenz 4 years ago
5 changed file(s) with 134 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
467467 // The default mask clobbers everything. All targets should override.
468468 return nullptr;
469469 }
470
471 /// Return all the call-preserved register masks defined for this target.
472 virtual ArrayRef getRegMasks() const = 0;
473 virtual ArrayRef getRegMaskNames() const = 0;
470474
471475 /// getReservedRegs - Returns a bitset indexed by physical register number
472476 /// indicating if a register is a special register that has particular uses
4141 StringMap Names2InstrOpCodes;
4242 /// Maps from register names to registers.
4343 StringMap Names2Regs;
44 /// Maps from register mask names to register masks.
45 StringMap Names2RegMasks;
4446
4547 public:
4648 MIParser(SourceMgr &SM, MachineFunction &MF, SMDiagnostic &Error,
8890 /// Try to convert a register name to a register number. Return true if the
8991 /// register name is invalid.
9092 bool getRegisterByName(StringRef RegName, unsigned &Reg);
93
94 void initNames2RegMasks();
95
96 /// Check if the given identifier is a name of a register mask.
97 ///
98 /// Return null if the identifier isn't a register mask.
99 const uint32_t *getRegMask(StringRef Identifier);
91100 };
92101
93102 } // end anonymous namespace
167176 // Mark this register as implicit to prevent an assertion when it's added
168177 // to an instruction. This is a temporary workaround until the implicit
169178 // register flag can be parsed.
170 Operands[I].setImplicit();
179 if (Operands[I].isReg())
180 Operands[I].setImplicit();
171181 }
172182 }
173183
301311 return parseGlobalAddressOperand(Dest);
302312 case MIToken::Error:
303313 return true;
314 case MIToken::Identifier:
315 if (const auto *RegMask = getRegMask(Token.stringValue())) {
316 Dest = MachineOperand::CreateRegMask(RegMask);
317 lex();
318 break;
319 }
320 // fallthrough
304321 default:
305322 // TODO: parse the other machine operands.
306323 return error("expected a machine operand");
351368 return false;
352369 }
353370
371 void MIParser::initNames2RegMasks() {
372 if (!Names2RegMasks.empty())
373 return;
374 const auto *TRI = MF.getSubtarget().getRegisterInfo();
375 assert(TRI && "Expected target register info");
376 ArrayRef RegMasks = TRI->getRegMasks();
377 ArrayRef RegMaskNames = TRI->getRegMaskNames();
378 assert(RegMasks.size() == RegMaskNames.size());
379 for (size_t I = 0, E = RegMasks.size(); I < E; ++I)
380 Names2RegMasks.insert(
381 std::make_pair(StringRef(RegMaskNames[I]).lower(), RegMasks[I]));
382 }
383
384 const uint32_t *MIParser::getRegMask(StringRef Identifier) {
385 initNames2RegMasks();
386 auto RegMaskInfo = Names2RegMasks.find(Identifier);
387 if (RegMaskInfo == Names2RegMasks.end())
388 return nullptr;
389 return RegMaskInfo->getValue();
390 }
391
354392 MachineInstr *
355393 llvm::parseMachineInstr(SourceMgr &SM, MachineFunction &MF, StringRef Src,
356394 const DenseMap &MBBSlots,
3232 /// format.
3333 class MIRPrinter {
3434 raw_ostream &OS;
35 DenseMap RegisterMaskIds;
3536
3637 public:
3738 MIRPrinter(raw_ostream &OS) : OS(OS) {}
4142 void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo);
4243 void convert(const Module &M, yaml::MachineBasicBlock &YamlMBB,
4344 const MachineBasicBlock &MBB);
45
46 private:
47 void initRegisterMaskIds(const MachineFunction &MF);
4448 };
4549
4650 /// This class prints out the machine instructions using the MIR serialization
4852 class MIPrinter {
4953 const Module &M;
5054 raw_ostream &OS;
55 const DenseMap &RegisterMaskIds;
5156
5257 public:
53 MIPrinter(const Module &M, raw_ostream &OS) : M(M), OS(OS) {}
58 MIPrinter(const Module &M, raw_ostream &OS,
59 const DenseMap &RegisterMaskIds)
60 : M(M), OS(OS), RegisterMaskIds(RegisterMaskIds) {}
5461
5562 void print(const MachineInstr &MI);
5663 void print(const MachineOperand &Op, const TargetRegisterInfo *TRI);
7683 } // end namespace llvm
7784
7885 void MIRPrinter::print(const MachineFunction &MF) {
86 initRegisterMaskIds(MF);
87
7988 yaml::MachineFunction YamlMF;
8089 YamlMF.Name = MF.getName();
8190 YamlMF.Alignment = MF.getAlignment();
126135 std::string Str;
127136 for (const auto &MI : MBB) {
128137 raw_string_ostream StrOS(Str);
129 MIPrinter(M, StrOS).print(MI);
138 MIPrinter(M, StrOS, RegisterMaskIds).print(MI);
130139 YamlMBB.Instructions.push_back(StrOS.str());
131140 Str.clear();
132141 }
142 }
143
144 void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) {
145 const auto *TRI = MF.getSubtarget().getRegisterInfo();
146 unsigned I = 0;
147 for (const uint32_t *Mask : TRI->getRegMasks())
148 RegisterMaskIds.insert(std::make_pair(Mask, I++));
133149 }
134150
135151 void MIPrinter::print(const MachineInstr &MI) {
200216 Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, &M);
201217 // TODO: Print offset and target flags.
202218 break;
219 case MachineOperand::MO_RegisterMask: {
220 auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
221 if (RegMaskInfo != RegisterMaskIds.end())
222 OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower();
223 else
224 llvm_unreachable("Can't print this machine register mask yet.");
225 break;
226 }
203227 default:
204228 // TODO: Print the other machine operands.
205229 llvm_unreachable("Can't print this machine operand at the moment");
0 # RUN: llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s | FileCheck %s
1 # This test ensures that the MIR parser parses register mask operands correctly.
2
3 --- |
4
5 define i32 @compute(i32 %a) #0 {
6 body:
7 %c = mul i32 %a, 11
8 ret i32 %c
9 }
10
11 define i32 @foo(i32 %a) #0 {
12 entry:
13 %b = call i32 @compute(i32 %a)
14 ret i32 %b
15 }
16
17 attributes #0 = { "no-frame-pointer-elim"="false" }
18
19 ...
20 ---
21 name: compute
22 body:
23 - id: 0
24 name: body
25 instructions:
26 - '%eax = IMUL32rri8 %edi, 11'
27 - 'RETQ %eax'
28 ...
29 ---
30 # CHECK: name: foo
31 name: foo
32 body:
33 - id: 0
34 name: entry
35 instructions:
36 # CHECK: - 'PUSH64r %rax
37 # CHECK-NEXT: - 'CALL64pcrel32 @compute, csr_64, %rsp, %edi, %rsp, %eax'
38 - 'PUSH64r %rax'
39 - 'CALL64pcrel32 @compute, csr_64, %rsp, %edi, %rsp, %eax'
40 - '%rdx = POP64r'
41 - 'RETQ %eax'
42 ...
10931093 << "const TargetRegisterClass *RC) const override;\n"
10941094 << " const int *getRegUnitPressureSets("
10951095 << "unsigned RegUnit) const override;\n"
1096 << " ArrayRef getRegMaskNames() const override;\n"
1097 << " ArrayRef getRegMasks() const override;\n"
10961098 << "};\n\n";
10971099
10981100 const auto &RegisterClasses = RegBank.getRegClasses();
14441446 }
14451447 OS << "\n\n";
14461448
1449 OS << "ArrayRef " << ClassName
1450 << "::getRegMasks() const {\n";
1451 OS << " static const uint32_t *Masks[] = {\n";
1452 for (Record *CSRSet : CSRSets)
1453 OS << " " << CSRSet->getName() << "_RegMask, \n";
1454 OS << " nullptr\n };\n";
1455 OS << " return ArrayRef(Masks, (size_t)" << CSRSets.size()
1456 << ");\n";
1457 OS << "}\n\n";
1458
1459 OS << "ArrayRef " << ClassName
1460 << "::getRegMaskNames() const {\n";
1461 OS << " static const char *Names[] = {\n";
1462 for (Record *CSRSet : CSRSets)
1463 OS << " " << '"' << CSRSet->getName() << '"' << ",\n";
1464 OS << " nullptr\n };\n";
1465 OS << " return ArrayRef(Names, (size_t)" << CSRSets.size()
1466 << ");\n";
1467 OS << "}\n\n";
1468
14471469 OS << "} // End llvm namespace\n";
14481470 OS << "#endif // GET_REGINFO_TARGET_DESC\n\n";
14491471 }