llvm.org GIT mirror llvm / 438a491
MIR Serialization: Serialize machine basic block operands. This commit serializes machine basic block operands. The machine basic block operands use the following syntax: %bb.<id>[.<name>] This commit also modifies the YAML representation for the machine basic blocks - a new, required field 'id' is added to the MBB YAML mapping. The id is used to resolve the MBB references to the actual MBBs. And while the name of the MBB can be included in a MBB reference, this name isn't used to resolve MBB references - as it's possible that multiple MBBs will reference the same BB and thus they will have the same name. If the name is specified, the parser will verify that it is equal to the name of the MBB with the specified id. Reviewers: Duncan P. N. Exon Smith Differential Revision: http://reviews.llvm.org/D10608 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240792 91177308-0d34-0410-b5e6-96231b3b80d8 Alex Lorenz 5 years ago
25 changed file(s) with 418 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
6363 namespace yaml {
6464
6565 struct MachineBasicBlock {
66 unsigned ID;
6667 std::string Name;
6768 unsigned Alignment = 0;
6869 bool IsLandingPad = false;
7475
7576 template <> struct MappingTraits {
7677 static void mapping(IO &YamlIO, MachineBasicBlock &MBB) {
78 YamlIO.mapRequired("id", MBB.ID);
7779 YamlIO.mapOptional("name", MBB.Name,
7880 std::string()); // Don't print out an empty name.
7981 YamlIO.mapOptional("alignment", MBB.Alignment);
3434
3535 char peek(int I = 0) const { return End - Ptr <= I ? 0 : Ptr[I]; }
3636
37 void advance() { ++Ptr; }
37 void advance(unsigned I = 1) { Ptr += I; }
3838
3939 StringRef remaining() const { return StringRef(Ptr, End - Ptr); }
4040
6969 return C;
7070 }
7171
72 static Cursor lexMachineBasicBlock(
73 Cursor C, MIToken &Token,
74 function_ref ErrorCallback) {
75 auto Range = C;
76 C.advance(4); // Skip '%bb.'
77 if (!isdigit(C.peek())) {
78 Token = MIToken(MIToken::Error, C.remaining());
79 ErrorCallback(C.location(), "expected a number after '%bb.'");
80 return C;
81 }
82 auto NumberRange = C;
83 while (isdigit(C.peek()))
84 C.advance();
85 StringRef Number = NumberRange.upto(C);
86 unsigned StringOffset = 4 + Number.size(); // Drop '%bb.'
87 if (C.peek() == '.') {
88 C.advance(); // Skip '.'
89 ++StringOffset;
90 while (isIdentifierChar(C.peek()))
91 C.advance();
92 }
93 Token = MIToken(MIToken::MachineBasicBlock, Range.upto(C), APSInt(Number),
94 StringOffset);
95 return C;
96 }
97
7298 static Cursor lexPercent(Cursor C, MIToken &Token) {
7399 auto Range = C;
74100 C.advance(); // Skip '%'
75101 while (isIdentifierChar(C.peek()))
76102 C.advance();
77 Token = MIToken(MIToken::NamedRegister, Range.upto(C));
103 Token = MIToken(MIToken::NamedRegister, Range.upto(C),
104 /*StringOffset=*/1); // Drop the '%'
78105 return C;
79106 }
80107
118145 auto Char = C.peek();
119146 if (isalpha(Char) || Char == '_')
120147 return lexIdentifier(C, Token).remaining();
121 if (Char == '%')
148 if (Char == '%') {
149 if (C.remaining().startswith("%bb."))
150 return lexMachineBasicBlock(C, Token, ErrorCallback).remaining();
122151 return lexPercent(C, Token).remaining();
152 }
123153 if (isdigit(Char) || (Char == '-' && isdigit(C.peek(1))))
124154 return lexIntegerLiteral(C, Token).remaining();
125155 MIToken::TokenKind Kind = symbolToken(Char);
3838 // Identifier tokens
3939 Identifier,
4040 NamedRegister,
41 MachineBasicBlock,
4142
4243 // Other tokens
4344 IntegerLiteral
4546
4647 private:
4748 TokenKind Kind;
49 unsigned StringOffset;
4850 StringRef Range;
4951 APSInt IntVal;
5052
5153 public:
52 MIToken(TokenKind Kind, StringRef Range) : Kind(Kind), Range(Range) {}
54 MIToken(TokenKind Kind, StringRef Range, unsigned StringOffset = 0)
55 : Kind(Kind), StringOffset(StringOffset), Range(Range) {}
5356
54 MIToken(TokenKind Kind, StringRef Range, const APSInt &IntVal)
55 : Kind(Kind), Range(Range), IntVal(IntVal) {}
57 MIToken(TokenKind Kind, StringRef Range, const APSInt &IntVal,
58 unsigned StringOffset = 0)
59 : Kind(Kind), StringOffset(StringOffset), Range(Range), IntVal(IntVal) {}
5660
5761 TokenKind kind() const { return Kind; }
5862
6872
6973 StringRef::iterator location() const { return Range.begin(); }
7074
71 StringRef stringValue() const { return Range; }
75 StringRef stringValue() const { return Range.drop_front(StringOffset); }
7276
7377 const APSInt &integerValue() const { return IntVal; }
78
79 bool hasIntegerValue() const {
80 return Kind == IntegerLiteral || Kind == MachineBasicBlock;
81 }
7482 };
7583
7684 /// Consume a single machine instruction token in the given source and return
3131 SMDiagnostic &Error;
3232 StringRef Source, CurrentSource;
3333 MIToken Token;
34 /// Maps from basic block numbers to MBBs.
35 const DenseMap &MBBSlots;
3436 /// Maps from instruction names to op codes.
3537 StringMap Names2InstrOpCodes;
3638 /// Maps from register names to registers.
3840
3941 public:
4042 MIParser(SourceMgr &SM, MachineFunction &MF, SMDiagnostic &Error,
41 StringRef Source);
43 StringRef Source,
44 const DenseMap &MBBSlots);
4245
4346 void lex();
4447
5760 bool parseRegister(unsigned &Reg);
5861 bool parseRegisterOperand(MachineOperand &Dest, bool IsDef = false);
5962 bool parseImmediateOperand(MachineOperand &Dest);
63 bool parseMBBOperand(MachineOperand &Dest);
6064 bool parseMachineOperand(MachineOperand &Dest);
6165
6266 private:
67 /// Convert the integer literal in the current token into an unsigned integer.
68 ///
69 /// Return true if an error occurred.
70 bool getUnsigned(unsigned &Result);
71
6372 void initNames2InstrOpCodes();
6473
6574 /// Try to convert an instruction name to an opcode. Return true if the
7887 } // end anonymous namespace
7988
8089 MIParser::MIParser(SourceMgr &SM, MachineFunction &MF, SMDiagnostic &Error,
81 StringRef Source)
90 StringRef Source,
91 const DenseMap &MBBSlots)
8292 : SM(SM), MF(MF), Error(Error), Source(Source), CurrentSource(Source),
83 Token(MIToken::Error, StringRef()) {}
93 Token(MIToken::Error, StringRef()), MBBSlots(MBBSlots) {}
8494
8595 void MIParser::lex() {
8696 CurrentSource = lexMIToken(
177187 Reg = 0;
178188 break;
179189 case MIToken::NamedRegister: {
180 StringRef Name = Token.stringValue().drop_front(1); // Drop the '%'
190 StringRef Name = Token.stringValue();
181191 if (getRegisterByName(Name, Reg))
182192 return error(Twine("unknown register name '") + Name + "'");
183193 break;
211221 return false;
212222 }
213223
224 bool MIParser::getUnsigned(unsigned &Result) {
225 assert(Token.hasIntegerValue() && "Expected a token with an integer value");
226 const uint64_t Limit = uint64_t(std::numeric_limits::max()) + 1;
227 uint64_t Val64 = Token.integerValue().getLimitedValue(Limit);
228 if (Val64 == Limit)
229 return error("expected 32-bit integer (too large)");
230 Result = Val64;
231 return false;
232 }
233
234 bool MIParser::parseMBBOperand(MachineOperand &Dest) {
235 assert(Token.is(MIToken::MachineBasicBlock));
236 unsigned Number;
237 if (getUnsigned(Number))
238 return true;
239 auto MBBInfo = MBBSlots.find(Number);
240 if (MBBInfo == MBBSlots.end())
241 return error(Twine("use of undefined machine basic block #") +
242 Twine(Number));
243 MachineBasicBlock *MBB = MBBInfo->second;
244 if (!Token.stringValue().empty() && Token.stringValue() != MBB->getName())
245 return error(Twine("the name of machine basic block #") + Twine(Number) +
246 " isn't '" + Token.stringValue() + "'");
247 Dest = MachineOperand::CreateMBB(MBB);
248 lex();
249 return false;
250 }
251
214252 bool MIParser::parseMachineOperand(MachineOperand &Dest) {
215253 switch (Token.kind()) {
216254 case MIToken::underscore:
218256 return parseRegisterOperand(Dest);
219257 case MIToken::IntegerLiteral:
220258 return parseImmediateOperand(Dest);
259 case MIToken::MachineBasicBlock:
260 return parseMBBOperand(Dest);
221261 case MIToken::Error:
222262 return true;
223263 default:
270310 return false;
271311 }
272312
273 MachineInstr *llvm::parseMachineInstr(SourceMgr &SM, MachineFunction &MF,
274 StringRef Src, SMDiagnostic &Error) {
275 return MIParser(SM, MF, Error, Src).parse();
276 }
313 MachineInstr *
314 llvm::parseMachineInstr(SourceMgr &SM, MachineFunction &MF, StringRef Src,
315 const DenseMap &MBBSlots,
316 SMDiagnostic &Error) {
317 return MIParser(SM, MF, Error, Src, MBBSlots).parse();
318 }
1313 #ifndef LLVM_LIB_CODEGEN_MIRPARSER_MIPARSER_H
1414 #define LLVM_LIB_CODEGEN_MIRPARSER_MIPARSER_H
1515
16 #include "llvm/ADT/DenseMap.h"
1617 #include "llvm/ADT/StringRef.h"
1718
1819 namespace llvm {
1920
21 class MachineBasicBlock;
2022 class MachineInstr;
2123 class MachineFunction;
2224 class SMDiagnostic;
2325 class SourceMgr;
2426
25 MachineInstr *parseMachineInstr(SourceMgr &SM, MachineFunction &MF,
26 StringRef Src, SMDiagnostic &Error);
27 MachineInstr *
28 parseMachineInstr(SourceMgr &SM, MachineFunction &MF, StringRef Src,
29 const DenseMap &MBBSlots,
30 SMDiagnostic &Error);
2731
2832 } // end namespace llvm
2933
1313
1414 #include "llvm/CodeGen/MIRParser/MIRParser.h"
1515 #include "MIParser.h"
16 #include "llvm/ADT/DenseMap.h"
1617 #include "llvm/ADT/StringRef.h"
1718 #include "llvm/ADT/StringMap.h"
1819 #include "llvm/ADT/STLExtras.h"
8081 /// Initialize the machine basic block using it's YAML representation.
8182 ///
8283 /// Return true if an error occurred.
83 bool initializeMachineBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB,
84 const yaml::MachineBasicBlock &YamlMBB);
84 bool initializeMachineBasicBlock(
85 MachineFunction &MF, MachineBasicBlock &MBB,
86 const yaml::MachineBasicBlock &YamlMBB,
87 const DenseMap &MBBSlots);
8588
8689 bool initializeRegisterInfo(MachineRegisterInfo &RegInfo,
8790 const yaml::MachineFunction &YamlMF);
219222 return true;
220223
221224 const auto &F = *MF.getFunction();
225 DenseMap MBBSlots;
222226 for (const auto &YamlMBB : YamlMF.BasicBlocks) {
223227 const BasicBlock *BB = nullptr;
224228 if (!YamlMBB.Name.empty()) {
230234 }
231235 auto *MBB = MF.CreateMachineBasicBlock(BB);
232236 MF.insert(MF.end(), MBB);
233 if (initializeMachineBasicBlock(MF, *MBB, YamlMBB))
237 bool WasInserted = MBBSlots.insert(std::make_pair(YamlMBB.ID, MBB)).second;
238 if (!WasInserted)
239 return error(Twine("redefinition of machine basic block with id #") +
240 Twine(YamlMBB.ID));
241 }
242
243 // Initialize the machine basic blocks after creating them all so that the
244 // machine instructions parser can resolve the MBB references.
245 unsigned I = 0;
246 for (const auto &YamlMBB : YamlMF.BasicBlocks) {
247 if (initializeMachineBasicBlock(MF, *MF.getBlockNumbered(I++), YamlMBB,
248 MBBSlots))
234249 return true;
235250 }
236251 return false;
238253
239254 bool MIRParserImpl::initializeMachineBasicBlock(
240255 MachineFunction &MF, MachineBasicBlock &MBB,
241 const yaml::MachineBasicBlock &YamlMBB) {
256 const yaml::MachineBasicBlock &YamlMBB,
257 const DenseMap &MBBSlots) {
242258 MBB.setAlignment(YamlMBB.Alignment);
243259 if (YamlMBB.AddressTaken)
244260 MBB.setHasAddressTaken();
246262 // Parse the instructions.
247263 for (const auto &MISource : YamlMBB.Instructions) {
248264 SMDiagnostic Error;
249 if (auto *MI = parseMachineInstr(SM, MF, MISource.Value, Error)) {
265 if (auto *MI = parseMachineInstr(SM, MF, MISource.Value, MBBSlots, Error)) {
250266 MBB.insert(MBB.end(), MI);
251267 continue;
252268 }
8080 YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice();
8181 YamlMF.HasInlineAsm = MF.hasInlineAsm();
8282 convert(YamlMF, MF.getRegInfo());
83
84 int I = 0;
8385 for (const auto &MBB : MF) {
86 // TODO: Allow printing of non sequentially numbered MBBs.
87 // This is currently needed as the basic block references get their index
88 // from MBB.getNumber(), thus it should be sequential so that the parser can
89 // map back to the correct MBBs when parsing the output.
90 assert(MBB.getNumber() == I++ &&
91 "Can't print MBBs that aren't sequentially numbered");
8492 yaml::MachineBasicBlock YamlMBB;
8593 convert(YamlMBB, MBB);
8694 YamlMF.BasicBlocks.push_back(YamlMBB);
98106
99107 void MIRPrinter::convert(yaml::MachineBasicBlock &YamlMBB,
100108 const MachineBasicBlock &MBB) {
109 assert(MBB.getNumber() >= 0 && "Invalid MBB number");
110 YamlMBB.ID = (unsigned)MBB.getNumber();
101111 // TODO: Serialize unnamed BB references.
102112 if (const auto *BB = MBB.getBasicBlock())
103113 YamlMBB.Name = BB->hasName() ? BB->getName() : "";
172182 case MachineOperand::MO_Immediate:
173183 OS << Op.getImm();
174184 break;
185 case MachineOperand::MO_MachineBasicBlock:
186 OS << "%bb." << Op.getMBB()->getNumber();
187 if (const auto *BB = Op.getMBB()->getBasicBlock()) {
188 if (BB->hasName())
189 OS << '.' << BB->getName();
190 }
191 break;
175192 default:
176193 // TODO: Print the other machine operands.
177194 llvm_unreachable("Can't print this machine operand at the moment");
1010 ---
1111 name: foo
1212 body:
13 - name: entry
13 - id: 0
14 name: entry
1415 instructions:
1516 # CHECK: [[@LINE+1]]:24: expected a machine operand
1617 - '%eax = XOR32rr ='
0 # RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
1
2 --- |
3
4 define i32 @foo(i32* %p) {
5 entry:
6 %a = load i32, i32* %p
7 %b = icmp sle i32 %a, 10
8 br i1 %b, label %yes, label %nah
9
10 yes:
11 ret i32 0
12
13 nah:
14 ret i32 %a
15 }
16
17 ...
18 ---
19 name: foo
20 body:
21 - id: 0
22 name: entry
23 instructions:
24 - '%eax = MOV32rm %rdi, 1, _, 0, _'
25 - 'CMP32ri8 %eax, 10'
26 # CHECK: [[@LINE+1]]:18: expected a number after '%bb.'
27 - 'JG_1 %bb.nah'
28 - id: 1
29 name: yes
30 instructions:
31 - '%eax = MOV32r0'
32 - id: 2
33 name: nah
34 instructions:
35 - 'RETQ %eax'
36 ...
1717 # CHECK: name: foo
1818 name: foo
1919 body:
20 - name: entry
20 - id: 0
21 name: entry
2122 instructions:
2223 # CHECK: - '%eax = MOV32ri 42'
2324 # CHECK-NEXT: - 'RETQ %eax'
2829 # CHECK: name: bar
2930 name: bar
3031 body:
31 - name: entry
32 - id: 0
33 name: entry
3234 instructions:
3335 # CHECK: - '%eax = MOV32ri -11'
3436 # CHECK-NEXT: - 'RETQ %eax'
0 # RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
1
2 --- |
3
4 define i32 @foo(i32* %p) {
5 entry:
6 %a = load i32, i32* %p
7 %b = icmp sle i32 %a, 10
8 br i1 %b, label %0, label %1
9
10 ;
11 ret i32 0
12
13 ;
14 ret i32 %a
15 }
16
17 ...
18 ---
19 name: foo
20 body:
21 - id: 0
22 name: entry
23 instructions:
24 - '%eax = MOV32rm %rdi, 1, _, 0, _'
25 - 'CMP32ri8 %eax, 10'
26 # CHECK: [[@LINE+1]]:14: expected 32-bit integer (too large)
27 - 'JG_1 %bb.123456789123456'
28 - id: 1
29 instructions:
30 - '%eax = MOV32r0'
31 - id: 2
32 instructions:
33 - 'RETQ %eax'
34 ...
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 machine basic block operands.
2
3 --- |
4
5 define i32 @foo(i32* %p) {
6 entry:
7 %a = load i32, i32* %p
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 @bar(i32* %p) {
19 entry:
20 %a = load i32, i32* %p
21 %b = icmp sle i32 %a, 10
22 br i1 %b, label %0, label %1
23
24 ;
25 ret i32 0
26
27 ;
28 ret i32 %a
29 }
30
31 ...
32 ---
33 # CHECK: name: foo
34 name: foo
35 body:
36 # CHECK: name: entry
37 - id: 0
38 name: entry
39 instructions:
40 - '%eax = MOV32rm %rdi, 1, _, 0, _'
41 # CHECK: - 'CMP32ri8 %eax, 10
42 # CHECK-NEXT: - 'JG_1 %bb.2.exit
43 - 'CMP32ri8 %eax, 10'
44 - 'JG_1 %bb.2.exit'
45 # CHECK: name: less
46 - id: 1
47 name: less
48 instructions:
49 - '%eax = MOV32r0'
50 - id: 2
51 name: exit
52 instructions:
53 - 'RETQ %eax'
54 ...
55 ---
56 # CHECK: name: bar
57 name: bar
58 body:
59 # CHECK: name: entry
60 - id: 0
61 name: entry
62 instructions:
63 - '%eax = MOV32rm %rdi, 1, _, 0, _'
64 # CHECK: - 'CMP32ri8 %eax, 10
65 # CHECK-NEXT: - 'JG_1 %bb.2
66 - 'CMP32ri8 %eax, 10'
67 - 'JG_1 %bb.3'
68 - id: 1
69 instructions:
70 - '%eax = MOV32r0'
71 - id: 3
72 instructions:
73 - 'RETQ %eax'
74 ...
1414 # CHECK: name: inc
1515 name: inc
1616 body:
17 - name: entry
17 - id: 0
18 name: entry
1819 instructions:
1920 # CHECK: - IMUL32rri8
2021 # CHECK-NEXT: - RETQ
1010 ---
1111 name: foo
1212 body:
13 - name: entry
13 - id: 0
14 name: entry
1415 instructions:
1516 # CHECK: [[@LINE+1]]:29: expected ',' before the next machine operand
1617 - '%eax = XOR32rr %eax %eflags'
1010 ---
1111 name: foo
1212 body:
13 - name: entry
13 - id: 0
14 name: entry
1415 instructions:
1516 # CHECK: [[@LINE+1]]:9: expected a machine instruction
1617 - ''
1212 # CHECK: name: foo
1313 name: foo
1414 body:
15 - name: entry
15 - id: 0
16 name: entry
1617 instructions:
1718 # CHECK: - '%eax = MOV32r0
1819 # CHECK-NEXT: - 'RETQ %eax
1313 # CHECK: name: deref
1414 name: deref
1515 body:
16 - name: entry
16 - id: 0
17 name: entry
1718 instructions:
1819 # CHECK: - '%eax = MOV32rm %rdi, 1, _, 0, _'
1920 # CHECK-NEXT: - 'RETQ %eax'
1212 ---
1313 name: foo
1414 body:
15 - name: entry
15 - id: 0
16 name: entry
1617 instructions:
1718 # CHECK: [[@LINE+1]]:8: unknown machine instruction name 'retJust0'
1819 - retJust0
0 # RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
1 # This test ensures that an error is reported when an invalid machine basic
2 # block index is used.
3
4
5 --- |
6
7 define i32 @foo(i32* %p) {
8 entry:
9 %a = load i32, i32* %p
10 %b = icmp sle i32 %a, 10
11 br i1 %b, label %0, label %1
12
13 ;
14 ret i32 0
15
16 ;
17 ret i32 %a
18 }
19
20 ...
21 ---
22 name: foo
23 body:
24 - id: 0
25 name: entry
26 instructions:
27 - '%eax = MOV32rm %rdi, 1, _, 0, _'
28 - 'CMP32ri8 %eax, 10'
29 # CHECK: [[@LINE+1]]:14: use of undefined machine basic block #4
30 - 'JG_1 %bb.4'
31 - id: 1
32 instructions:
33 - '%eax = MOV32r0'
34 - id: 2
35 instructions:
36 - 'RETQ %eax'
37 ...
0 # RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
1 # This test ensures that an error is reported when an unknown named machine
2 # basic block is encountered.
3
4 --- |
5
6 define i32 @foo(i32* %p) {
7 entry:
8 %a = load i32, i32* %p
9 %0 = icmp sle i32 %a, 10
10 br i1 %0, label %less, label %exit
11
12 less:
13 ret i32 0
14
15 exit:
16 ret i32 %a
17 }
18
19 ...
20 ---
21 name: foo
22 body:
23 - id: 0
24 name: entry
25 instructions:
26 - '%eax = MOV32rm %rdi, 1, _, 0, _'
27 - 'CMP32ri8 %eax, 10'
28 # CHECK: [[@LINE+1]]:14: the name of machine basic block #2 isn't 'hit'
29 - 'JG_1 %bb.2.hit'
30 - id: 1
31 name: less
32 instructions:
33 - '%eax = MOV32r0'
34 - id: 2
35 name: exit
36 instructions:
37 - 'RETQ %eax'
38 ...
1212 ---
1313 name: foo
1414 body:
15 - name: entry
15 - id: 0
16 name: entry
1617 instructions:
1718 # CHECK: [[@LINE+1]]:9: unknown register name 'xax'
1819 - '%xax = MOV32r0'
1010 ---
1111 name: foo
1212 body:
13 - name: entry
13 - id: 0
14 name: entry
1415 instructions:
1516 # CHECK: [[@LINE+1]]:9: unexpected character '`'
1617 - '` RETQ'
1616 ---
1717 # CHECK: name: foo
1818 # CHECK: body:
19 # CHECK-NEXT: - name: entry
19 # CHECK-NEXT: - id: 0
20 # CHECK-NEXT: name: entry
2021 # CHECK-NEXT: alignment: 0
2122 # CHECK-NEXT: isLandingPad: false
2223 # CHECK-NEXT: addressTaken: false
2324 name: foo
2425 body:
25 - name: entry
26 - id: 0
27 name: entry
2628 ...
2729 ---
2830 # CHECK: name: bar
2931 # CHECK: body:
30 # CHECK-NEXT: - name: start
32 # CHECK-NEXT: - id: 0
33 # CHECK-NEXT: name: start
3134 # CHECK-NEXT: alignment: 4
3235 # CHECK-NEXT: isLandingPad: false
3336 # CHECK-NEXT: addressTaken: false
34 # CHECK-NEXT: - alignment: 0
37 # CHECK-NEXT: - id: 1
38 # CHECK-NEXT: alignment: 0
3539 # CHECK-NEXT: isLandingPad: false
3640 # CHECK-NEXT: addressTaken: true
3741 name: bar
3842 body:
39 - name: start
43 - id: 0
44 name: start
4045 alignment: 4
41 - addressTaken: true
46 - id: 1
47 addressTaken: true
4248 ...
0 # RUN: not llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
1
2 --- |
3
4 define i32 @foo() {
5 entry:
6 ret i32 0
7 }
8
9 ...
10 ---
11 name: foo
12 body:
13 # CHECK: redefinition of machine basic block with id #0
14 - id: 0
15 - id: 0
16 ...
1313 name: foo
1414 body:
1515 # CHECK: basic block 'entrie' is not defined in the function 'foo'
16 - name: entrie
16 - id: 0
17 name: entrie
1718 ...