llvm.org GIT mirror llvm / 05383db
[MIR] Support Customed Register Mask and CSRs The MIR printer dumps a string that describe the register mask of a function. A static predefined list of register masks matches a static list of strings. However when the register mask is not from the static predefined list, there is no descriptor string and the printer fails. This patch adds support to custom register mask printing and dumping. Also the list of callee saved registers (describing the registers that must be preserved for the caller) might be dynamic. As such this data needs to be dumped and parsed back to the Machine Register Info. Differential Revision: https://reviews.llvm.org/D30971 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298207 91177308-0d34-0410-b5e6-96231b3b80d8 Oren Ben Simhon 3 years ago
8 changed file(s) with 129 addition(s) and 146 deletion(s). Raw diff Collapse all Expand all
215215 // Register Info
216216 //===--------------------------------------------------------------------===//
217217
218 /// Returns true if the updated CSR list was initialized and false otherwise.
219 bool isUpdatedCSRsInitialized() const { return IsUpdatedCSRsInitialized; }
220
218221 /// Disables the register from the list of CSRs.
219222 /// I.e. the register will not appear as part of the CSR mask.
220223 /// \see UpdatedCalleeSavedRegs.
224227 /// The function returns the updated CSR list (after taking into account
225228 /// registers that are disabled from the CSR list).
226229 const MCPhysReg *getCalleeSavedRegs() const;
230
231 /// Sets the updated Callee Saved Registers list.
232 /// Notice that it will override ant previously disabled/saved CSRs.
233 void setCalleeSavedRegs(ArrayRef CSRs);
227234
228235 // Strictly for use by MachineInstr.cpp.
229236 void addRegOperandToUseList(MachineOperand *MO);
753760 }
754761
755762 const BitVector &getUsedPhysRegsMask() const { return UsedPhysRegMask; }
756
757 void setUsedPhysRegMask(BitVector &Mask) { UsedPhysRegMask = Mask; }
758763
759764 //===--------------------------------------------------------------------===//
760765 // Reserved Register Info
175175 bool parseIntrinsicOperand(MachineOperand &Dest);
176176 bool parsePredicateOperand(MachineOperand &Dest);
177177 bool parseTargetIndexOperand(MachineOperand &Dest);
178 bool parseCustomRegisterMaskOperand(MachineOperand &Dest);
178179 bool parseLiveoutRegisterMaskOperand(MachineOperand &Dest);
179180 bool parseMachineOperand(MachineOperand &Dest,
180181 Optional &TiedDefIdx);
16661667 Dest = MachineOperand::CreateTargetIndex(unsigned(Index), /*Offset=*/0);
16671668 if (parseOperandsOffset(Dest))
16681669 return true;
1670 return false;
1671 }
1672
1673 bool MIParser::parseCustomRegisterMaskOperand(MachineOperand &Dest) {
1674 assert(Token.stringValue() == "CustomRegMask" && "Expected a custom RegMask");
1675 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
1676 assert(TRI && "Expected target register info");
1677 lex();
1678 if (expectAndConsume(MIToken::lparen))
1679 return true;
1680
1681 uint32_t *Mask = MF.allocateRegisterMask(TRI->getNumRegs());
1682 while (true) {
1683 if (Token.isNot(MIToken::NamedRegister))
1684 return error("expected a named register");
1685 unsigned Reg;
1686 if (parseNamedRegister(Reg))
1687 return true;
1688 lex();
1689 Mask[Reg / 32] |= 1U << (Reg % 32);
1690 // TODO: Report an error if the same register is used more than once.
1691 if (Token.isNot(MIToken::comma))
1692 break;
1693 lex();
1694 }
1695
1696 if (expectAndConsume(MIToken::rparen))
1697 return true;
1698 Dest = MachineOperand::CreateRegMask(Mask);
16691699 return false;
16701700 }
16711701
17661796 Dest = MachineOperand::CreateRegMask(RegMask);
17671797 lex();
17681798 break;
1769 }
1770 LLVM_FALLTHROUGH;
1799 } else
1800 return parseCustomRegisterMaskOperand(Dest);
17711801 default:
17721802 // FIXME: Parse the MCSymbol machine operand.
17731803 return error("expected a machine operand");
466466 RegInfo.addLiveIn(Reg, VReg);
467467 }
468468
469 // Parse the callee saved register mask.
470 BitVector CalleeSavedRegisterMask(RegInfo.getUsedPhysRegsMask().size());
471 if (!YamlMF.CalleeSavedRegisters)
472 return false;
473 for (const auto &RegSource : YamlMF.CalleeSavedRegisters.getValue()) {
474 unsigned Reg = 0;
475 if (parseNamedRegisterReference(PFS, Reg, RegSource.Value, Error))
476 return error(Error, RegSource.SourceRange);
477 CalleeSavedRegisterMask[Reg] = true;
478 }
479 RegInfo.setUsedPhysRegMask(CalleeSavedRegisterMask.flip());
469 // Parse the callee saved registers (Registers that will
470 // be saved for the caller).
471 if (YamlMF.CalleeSavedRegisters) {
472 SmallVector CalleeSavedRegisters;
473 for (const auto &RegSource : YamlMF.CalleeSavedRegisters.getValue()) {
474 unsigned Reg = 0;
475 if (parseNamedRegisterReference(PFS, Reg, RegSource.Value, Error))
476 return error(Error, RegSource.SourceRange);
477 CalleeSavedRegisters.push_back(Reg);
478 }
479 RegInfo.setCalleeSavedRegs(CalleeSavedRegisters);
480 }
481
480482 return false;
481483 }
482484
509511 }
510512
511513 // Compute MachineRegisterInfo::UsedPhysRegMask
512 if (!YamlMF.CalleeSavedRegisters) {
513 for (const MachineBasicBlock &MBB : MF) {
514 for (const MachineInstr &MI : MBB) {
515 for (const MachineOperand &MO : MI.operands()) {
516 if (!MO.isRegMask())
517 continue;
518 MRI.addPhysRegsUsedFromRegMask(MO.getRegMask());
519 }
514 for (const MachineBasicBlock &MBB : MF) {
515 for (const MachineInstr &MI : MBB) {
516 for (const MachineOperand &MO : MI.operands()) {
517 if (!MO.isRegMask())
518 continue;
519 MRI.addPhysRegsUsedFromRegMask(MO.getRegMask());
520520 }
521521 }
522522 }
206206 Out << YamlMF;
207207 }
208208
209 static void printCustomRegMask(const uint32_t *RegMask, raw_ostream &OS,
210 const TargetRegisterInfo *TRI) {
211 assert(RegMask && "Can't print an empty register mask");
212 OS << StringRef("CustomRegMask(");
213
214 bool IsRegInRegMaskFound = false;
215 for (int I = 0, E = TRI->getNumRegs(); I < E; I++) {
216 // Check whether the register is asserted in regmask.
217 if (RegMask[I / 32] & (1u << (I % 32))) {
218 if (IsRegInRegMaskFound)
219 OS << ',';
220 printReg(I, OS, TRI);
221 IsRegInRegMaskFound = true;
222 }
223 }
224
225 OS << ')';
226 }
227
209228 void MIRPrinter::convert(yaml::MachineFunction &MF,
210229 const MachineRegisterInfo &RegInfo,
211230 const TargetRegisterInfo *TRI) {
240259 printReg(I->second, LiveIn.VirtualRegister, TRI);
241260 MF.LiveIns.push_back(LiveIn);
242261 }
243 // The used physical register mask is printed as an inverted callee saved
244 // register mask.
245 const BitVector &UsedPhysRegMask = RegInfo.getUsedPhysRegsMask();
246 if (UsedPhysRegMask.none())
247 return;
248 std::vector CalleeSavedRegisters;
249 for (unsigned I = 0, E = UsedPhysRegMask.size(); I != E; ++I) {
250 if (!UsedPhysRegMask[I]) {
262
263 // Prints the callee saved registers.
264 if (RegInfo.isUpdatedCSRsInitialized()) {
265 const MCPhysReg *CalleeSavedRegs = RegInfo.getCalleeSavedRegs();
266 std::vector CalleeSavedRegisters;
267 for (const MCPhysReg *I = CalleeSavedRegs; *I; ++I) {
251268 yaml::FlowStringValue Reg;
252 printReg(I, Reg, TRI);
269 printReg(*I, Reg, TRI);
253270 CalleeSavedRegisters.push_back(Reg);
254271 }
255 }
256 MF.CalleeSavedRegisters = CalleeSavedRegisters;
272 MF.CalleeSavedRegisters = CalleeSavedRegisters;
273 }
257274 }
258275
259276 void MIRPrinter::convert(ModuleSlotTracker &MST,
861878 if (RegMaskInfo != RegisterMaskIds.end())
862879 OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower();
863880 else
864 llvm_unreachable("Can't print this machine register mask yet.");
881 printCustomRegMask(Op.getRegMask(), OS, TRI);
865882 break;
866883 }
867884 case MachineOperand::MO_RegisterLiveOut: {
588588 return getTargetRegisterInfo()->getCalleeSavedRegs(MF);
589589 }
590590
591 void MachineRegisterInfo::setCalleeSavedRegs(ArrayRef CSRs) {
592 if (IsUpdatedCSRsInitialized)
593 UpdatedCSRs.clear();
594
595 for (MCPhysReg Reg : CSRs)
596 UpdatedCSRs.push_back(Reg);
597
598 // Zero value represents the end of the register list
599 // (no more registers should be pushed).
600 UpdatedCSRs.push_back(0);
601 IsUpdatedCSRsInitialized = true;
602 }
38153815 // In some calling conventions we need to remove the used physical registers
38163816 // from the reg mask.
38173817 if (CallConv == CallingConv::X86_RegCall) {
3818 /// @todo Need to add support in MIPrinter and MIParser to represent
3819 /// the customed RegMask.
38203818 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
38213819
38223820 // Allocate a new Reg Mask and copy Mask.
0 ; RUN: llc -stop-after machine-sink %s -o %t.mir
1 ; RUN: FileCheck %s < %t.mir
2 ; RUN: llc %t.mir -run-pass machine-sink
3 ; Check that callee saved registers are printed in a format that can then be parsed.
4
5 declare x86_regcallcc i32 @callee(i32 %a0, i32 %b0, i32 %c0, i32 %d0, i32 %e0)
6
7 define i32 @caller(i32 %a0) nounwind {
8 %b1 = call x86_regcallcc i32 @callee(i32 %a0, i32 %a0, i32 %a0, i32 %a0, i32 %a0)
9 %b2 = add i32 %b1, %a0
10 ret i32 %b2
11 }
12 ; CHECK: name: caller
13 ; CHECK: CALL64pcrel32 @callee, CustomRegMask(%bh,%bl,%bp,%bpl,%bx,%ebp,%ebx,%esp,%rbp,%rbx,%rsp,%sp,%spl,%r10,%r11,%r12,%r13,%r14,%r15,%xmm8,%xmm9,%xmm10,%xmm11,%xmm12,%xmm13,%xmm14,%xmm15,%r10b,%r11b,%r12b,%r13b,%r14b,%r15b,%r10d,%r11d,%r12d,%r13d,%r14d,%r15d,%r10w,%r11w,%r12w,%r13w,%r14w,%r15w)
14 ; CHECK: RET 0, %eax
15
16 define x86_regcallcc {i32, i32, i32} @test_callee(i32 %a0, i32 %b0, i32 %c0, i32 %d0, i32 %e0) nounwind {
17 %b1 = mul i32 7, %e0
18 %b2 = udiv i32 5, %e0
19 %b3 = mul i32 7, %d0
20 %b4 = insertvalue {i32, i32, i32} undef, i32 %b1, 0
21 %b5 = insertvalue {i32, i32, i32} %b4, i32 %b2, 1
22 %b6 = insertvalue {i32, i32, i32} %b5, i32 %b3, 2
23 ret {i32, i32, i32} %b6
24 }
25 ; CHECK: name: test_callee
26 ; CHECK: calleeSavedRegisters: [ '%rbx', '%rbp', '%rsp', '%r10', '%r11', '%r12',
27 ; CHECK: '%r13', '%r14', '%r15', '%xmm8', '%xmm9', '%xmm10',
28 ; CHECK: '%xmm11', '%xmm12', '%xmm13', '%xmm14', '%xmm15' ]
29 ; CHECK: RET 0, %eax, %ecx, %edx
+0
-109
test/CodeGen/MIR/X86/used-physical-register-info.mir less more
None # RUN: llc -march=x86-64 -run-pass none -o - %s | FileCheck %s
1 # This test ensures that the MIR parser parses the callee saved register mask
2 # correctly and that the MIR parser can infer it as well.
3
4 --- |
5
6 define i32 @compute(i32 %a) #0 {
7 body:
8 %c = mul i32 %a, 11
9 ret i32 %c
10 }
11
12 define i32 @foo(i32 %a) #0 {
13 entry:
14 %b = call i32 @compute(i32 %a)
15 ret i32 %b
16 }
17
18 define i32 @bar(i32 %a) #0 {
19 entry:
20 %b = call i32 @compute(i32 %a)
21 ret i32 %b
22 }
23
24 define i32 @empty(i32 %a) #0 {
25 entry:
26 %b = call i32 @compute(i32 %a)
27 ret i32 %b
28 }
29
30 attributes #0 = { "no-frame-pointer-elim"="false" }
31
32 ...
33 ---
34 # CHECK: name: compute
35 # CHECK: liveins:
36 # CHECK-NEXT: - { reg: '%edi' }
37 # CHECK-NEXT: frameInfo:
38 name: compute
39 liveins:
40 - { reg: '%edi' }
41 frameInfo:
42 stackSize: 8
43 body: |
44 bb.0.body:
45 liveins: %edi
46
47 %eax = IMUL32rri8 %edi, 11, implicit-def %eflags
48 RETQ %eax
49 ...
50 ---
51 name: foo
52 liveins:
53 - { reg: '%edi' }
54 # CHECK: name: foo
55 # CHECK: calleeSavedRegisters: [ '%bh', '%bl', '%bp', '%bpl', '%bx', '%ebp', '%ebx',
56 # CHECK-NEXT: '%rbp', '%rbx', '%r12', '%r13', '%r14', '%r15',
57 # CHECK-NEXT: '%r12b', '%r13b', '%r14b', '%r15b', '%r12d', '%r13d',
58 # CHECK-NEXT: '%r14d', '%r15d', '%r12w', '%r13w', '%r14w', '%r15w' ]
59 calleeSavedRegisters: [ '%bh', '%bl', '%bp', '%bpl', '%bx', '%ebp', '%ebx',
60 '%rbp', '%rbx', '%r12', '%r13', '%r14', '%r15',
61 '%r12b', '%r13b', '%r14b', '%r15b', '%r12d', '%r13d',
62 '%r14d', '%r15d', '%r12w', '%r13w', '%r14w', '%r15w' ]
63 body: |
64 bb.0.entry:
65 liveins: %edi
66
67 PUSH64r %rax, implicit-def %rsp, implicit %rsp
68 CALL64pcrel32 @compute, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp, implicit-def %eax
69 %rdx = POP64r implicit-def %rsp, implicit %rsp
70 RETQ %eax
71 ...
72 ---
73 name: bar
74 liveins:
75 - { reg: '%edi' }
76 # Verify that the callee saved register can be inferred from register mask
77 # machine operands:
78 # CHECK: name: bar
79 # CHECK: calleeSavedRegisters: [ '%bh', '%bl', '%bp', '%bpl', '%bx', '%ebp', '%ebx',
80 # CHECK-NEXT: '%rbp', '%rbx', '%r12', '%r13', '%r14', '%r15',
81 # CHECK-NEXT: '%r12b', '%r13b', '%r14b', '%r15b', '%r12d', '%r13d',
82 # CHECK-NEXT: '%r14d', '%r15d', '%r12w', '%r13w', '%r14w', '%r15w' ]
83 body: |
84 bb.0.entry:
85 liveins: %edi
86
87 PUSH64r %rax, implicit-def %rsp, implicit %rsp
88 CALL64pcrel32 @compute, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp, implicit-def %eax
89 %rdx = POP64r implicit-def %rsp, implicit %rsp
90 RETQ %eax
91 ...
92 ---
93 name: empty
94 liveins:
95 - { reg: '%edi' }
96 # Verify that the callee saved register can be empty.
97 # CHECK: name: empty
98 # CHECK: calleeSavedRegisters: [ ]
99 calleeSavedRegisters: [ ]
100 body: |
101 bb.0.entry:
102 liveins: %edi
103
104 PUSH64r %rax, implicit-def %rsp, implicit %rsp
105 CALL64pcrel32 @compute, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp, implicit-def %eax
106 %rdx = POP64r implicit-def %rsp, implicit %rsp
107 RETQ %eax
108 ...