llvm.org GIT mirror llvm / 1cca87a
MIR Serialization: Serialize the virtual register operands. Reviewers: Duncan P. N. Exon Smith Differential Revision: http://reviews.llvm.org/D11005 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241959 91177308-0d34-0410-b5e6-96231b3b80d8 Alex Lorenz 5 years ago
8 changed file(s) with 149 addition(s) and 17 deletion(s). Raw diff Collapse all Expand all
114114 return C;
115115 }
116116
117 static Cursor lexVirtualRegister(Cursor C, MIToken &Token) {
118 auto Range = C;
119 C.advance(); // Skip '%'
120 auto NumberRange = C;
121 while (isdigit(C.peek()))
122 C.advance();
123 Token = MIToken(MIToken::VirtualRegister, Range.upto(C),
124 APSInt(NumberRange.upto(C)));
125 return C;
126 }
127
117128 static Cursor maybeLexRegister(Cursor C, MIToken &Token) {
118129 if (C.peek() != '%')
119130 return None;
131 if (isdigit(C.peek(1)))
132 return lexVirtualRegister(C, Token);
120133 auto Range = C;
121134 C.advance(); // Skip '%'
122135 while (isIdentifierChar(C.peek()))
5050 GlobalValue,
5151
5252 // Other tokens
53 IntegerLiteral
53 IntegerLiteral,
54 VirtualRegister
5455 };
5556
5657 private:
7273 bool isError() const { return Kind == Error; }
7374
7475 bool isRegister() const {
75 return Kind == NamedRegister || Kind == underscore;
76 return Kind == NamedRegister || Kind == underscore ||
77 Kind == VirtualRegister;
7678 }
7779
7880 bool isRegisterFlag() const {
9294
9395 bool hasIntegerValue() const {
9496 return Kind == IntegerLiteral || Kind == MachineBasicBlock ||
95 Kind == GlobalValue;
97 Kind == GlobalValue || Kind == VirtualRegister;
9698 }
9799 };
98100
287287 return error(Twine("unknown register name '") + Name + "'");
288288 break;
289289 }
290 case MIToken::VirtualRegister: {
291 unsigned ID;
292 if (getUnsigned(ID))
293 return true;
294 const auto RegInfo = PFS.VirtualRegisterSlots.find(ID);
295 if (RegInfo == PFS.VirtualRegisterSlots.end())
296 return error(Twine("use of undefined virtual register '%") + Twine(ID) +
297 "'");
298 Reg = RegInfo->second;
299 break;
300 }
290301 // TODO: Parse other register kinds.
291302 default:
292303 llvm_unreachable("The current token should be a register");
424435 case MIToken::kw_undef:
425436 case MIToken::underscore:
426437 case MIToken::NamedRegister:
438 case MIToken::VirtualRegister:
427439 return parseRegisterOperand(Dest);
428440 case MIToken::IntegerLiteral:
429441 return parseImmediateOperand(Dest);
2727
2828 struct PerFunctionMIParsingState {
2929 DenseMap MBBSlots;
30 DenseMap VirtualRegisterSlots;
3031 };
3132
3233 bool parseMachineInstr(MachineInstr *&MI, SourceMgr &SM, MachineFunction &MF,
101101 const yaml::MachineBasicBlock &YamlMBB,
102102 const PerFunctionMIParsingState &PFS);
103103
104 bool initializeRegisterInfo(const MachineFunction &MF,
105 MachineRegisterInfo &RegInfo,
106 const yaml::MachineFunction &YamlMF);
104 bool
105 initializeRegisterInfo(const MachineFunction &MF,
106 MachineRegisterInfo &RegInfo,
107 const yaml::MachineFunction &YamlMF,
108 DenseMap &VirtualRegisterSlots);
107109
108110 bool initializeFrameInfo(MachineFrameInfo &MFI,
109111 const yaml::MachineFunction &YamlMF);
257259 MF.setAlignment(YamlMF.Alignment);
258260 MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
259261 MF.setHasInlineAsm(YamlMF.HasInlineAsm);
260 if (initializeRegisterInfo(MF, MF.getRegInfo(), YamlMF))
262 PerFunctionMIParsingState PFS;
263 if (initializeRegisterInfo(MF, MF.getRegInfo(), YamlMF,
264 PFS.VirtualRegisterSlots))
261265 return true;
262266 if (initializeFrameInfo(*MF.getFrameInfo(), YamlMF))
263267 return true;
264268
265 PerFunctionMIParsingState PFS;
266269 const auto &F = *MF.getFunction();
267270 for (const auto &YamlMBB : YamlMF.BasicBlocks) {
268271 const BasicBlock *BB = nullptr;
329332
330333 bool MIRParserImpl::initializeRegisterInfo(
331334 const MachineFunction &MF, MachineRegisterInfo &RegInfo,
332 const yaml::MachineFunction &YamlMF) {
335 const yaml::MachineFunction &YamlMF,
336 DenseMap &VirtualRegisterSlots) {
333337 assert(RegInfo.isSSA());
334338 if (!YamlMF.IsSSA)
335339 RegInfo.leaveSSA();
345349 return error(VReg.Class.SourceRange.Start,
346350 Twine("use of undefined register class '") +
347351 VReg.Class.Value + "'");
348 // TODO: create the mapping from IDs to registers so that the virtual
349 // register references can be parsed correctly.
350 RegInfo.createVirtualRegister(RC);
352 unsigned Reg = RegInfo.createVirtualRegister(RC);
353 // TODO: Report an error when the same virtual register with the same ID is
354 // redefined.
355 VirtualRegisterSlots.insert(std::make_pair(VReg.ID, Reg));
351356 }
352357 return false;
353358 }
249249 static void printReg(unsigned Reg, raw_ostream &OS,
250250 const TargetRegisterInfo *TRI) {
251251 // TODO: Print Stack Slots.
252 // TODO: Print virtual registers.
253252 if (!Reg)
254253 OS << '_';
254 else if (TargetRegisterInfo::isVirtualRegister(Reg))
255 OS << '%' << TargetRegisterInfo::virtReg2Index(Reg);
255256 else if (Reg < TRI->getNumRegs())
256257 OS << '%' << StringRef(TRI->getName(Reg)).lower();
257258 else
0 # RUN: not llc -march=x86-64 -start-after machine-sink -stop-after machine-sink -o /dev/null %s 2>&1 | FileCheck %s
1 # This test ensures that the MIR parser reports an error when parsing a
2 # reference to an undefined virtual register.
3
4 --- |
5
6 define i32 @test(i32 %a) {
7 entry:
8 ret i32 %a
9 }
10
11 ...
12 ---
13 name: test
14 isSSA: true
15 tracksRegLiveness: true
16 registers:
17 - { id: 0, class: gr32 }
18 body:
19 - id: 0
20 name: entry
21 instructions:
22 - '%0 = COPY %edi'
23 # CHECK: [[@LINE+1]]:22: use of undefined virtual register '%10'
24 - '%eax = COPY %10'
25 - 'RETQ %eax'
26 ...
27
0 # RUN: llc -march=x86-64 -start-after machine-sink -stop-after machine-sink -o /dev/null %s | FileCheck %s
1 # This test ensures that the MIR parser parses virtual register definitions
2 # correctly.
1 # This test ensures that the MIR parser parses virtual register definitions and
2 # references correctly.
33
44 --- |
55
66 define i32 @bar(i32 %a) {
7 entry:
8 %0 = icmp sle i32 %a, 10
9 br i1 %0, label %less, label %exit
10
11 less:
12 ret i32 0
13
14 exit:
15 ret i32 %a
16 }
17
18 define i32 @foo(i32 %a) {
719 entry:
820 %0 = icmp sle i32 %a, 10
921 br i1 %0, label %less, label %exit
2941 - { id: 1, class: gr32 }
3042 - { id: 2, class: gr32 }
3143 body:
32 - id: 0
44 - id: 0
45 name: entry
46 # CHECK: %0 = COPY %edi
47 # CHECK-NEXT: %1 = SUB32ri8 %0, 10
48 instructions:
49 - '%0 = COPY %edi'
50 - '%1 = SUB32ri8 %0, 10, implicit-def %eflags'
51 - 'JG_1 %bb.2.exit, implicit %eflags'
52 - 'JMP_1 %bb.1.less'
53 - id: 1
54 name: less
55 # CHECK: %2 = MOV32r0
56 # CHECK-NEXT: %eax = COPY %2
57 instructions:
58 - '%2 = MOV32r0 implicit-def %eflags'
59 - '%eax = COPY %2'
60 - 'RETQ %eax'
61 - id: 2
62 name: exit
63 instructions:
64 - '%eax = COPY %0'
65 - 'RETQ %eax'
3366 ...
34
67 ---
68 name: foo
69 isSSA: true
70 tracksRegLiveness: true
71 # CHECK: name: foo
72 # CHECK: registers:
73 # CHECK-NEXT: - { id: 0, class: gr32 }
74 # CHECK-NEXT: - { id: 1, class: gr32 }
75 # CHECK-NEXT: - { id: 2, class: gr32 }
76 registers:
77 - { id: 2, class: gr32 }
78 - { id: 0, class: gr32 }
79 - { id: 10, class: gr32 }
80 body:
81 - id: 0
82 name: entry
83 # CHECK: %0 = COPY %edi
84 # CHECK-NEXT: %1 = SUB32ri8 %0, 10
85 instructions:
86 - '%2 = COPY %edi'
87 - '%0 = SUB32ri8 %2, 10, implicit-def %eflags'
88 - 'JG_1 %bb.2.exit, implicit %eflags'
89 - 'JMP_1 %bb.1.less'
90 - id: 1
91 name: less
92 # CHECK: %2 = MOV32r0
93 # CHECK-NEXT: %eax = COPY %2
94 instructions:
95 - '%10 = MOV32r0 implicit-def %eflags'
96 - '%eax = COPY %10'
97 - 'RETQ %eax'
98 - id: 2
99 name: exit
100 # CHECK: %eax = COPY %0
101 instructions:
102 - '%eax = COPY %2'
103 - 'RETQ %eax'
104 ...