Skip to content

Commit c0e6b8a

Browse files
committed
IR: Support parsing numeric block ids, and emit them in textual output.
Just as as llvm IR supports explicitly specifying numeric value ids for instructions, and emits them by default in textual output, now do the same for blocks. This is a slightly incompatible change in the textual IR format. Previously, llvm would parse numeric labels as string names. E.g. define void @f() { br label %"55" 55: ret void } defined a label *named* "55", even without needing to be quoted, while the reference required quoting. Now, if you intend a block label which looks like a value number to be a name, you must quote it in the definition too (e.g. `"55":`). Previously, llvm would print nameless blocks only as a comment, and would omit it if there was no predecessor. This could cause confusion for readers of the IR, just as unnamed instructions did prior to the addition of "%5 = " syntax, back in 2008 (PR2480). Now, it will always print a label for an unnamed block, with the exception of the entry block. (IMO it may be better to print it for the entry-block as well. However, that requires updating many more tests.) Thus, the following is supported, and is the canonical printing: define i32 @f(i32, i32) { %3 = add i32 %0, %1 br label %4 4: ret i32 %3 } New test cases covering this behavior are added, and other tests updated as required. Differential Revision: https://reviews.llvm.org/D58548 llvm-svn: 356789
1 parent 5e381fb commit c0e6b8a

38 files changed

+368
-282
lines changed

clang/test/CodeGenCXX/discard-name-values.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ bool test(bool pred) {
1010
// CHECK: br i1 %pred, label %if.then, label %if.end
1111

1212
if (pred) {
13-
// DISCARDVALUE: ; <label>:2:
13+
// DISCARDVALUE: 2:
1414
// DISCARDVALUE-NEXT: tail call void @branch()
1515
// DISCARDVALUE-NEXT: br label %3
1616

@@ -20,7 +20,7 @@ bool test(bool pred) {
2020
branch();
2121
}
2222

23-
// DISCARDVALUE: ; <label>:3:
23+
// DISCARDVALUE: 3:
2424
// DISCARDVALUE-NEXT: ret i1 %0
2525

2626
// CHECK: if.end:

llgo/test/irgen/imports.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ var X interface{}
1313
// CHECK-NEXT: %[[N:.*]] = load i1, i1* @"init$guard"
1414
// CHECK-NEXT: br i1 %[[N]], label %{{.*}}, label %[[L:.*]]
1515

16-
// CHECK: ; <label>:[[L]]
16+
// CHECK: [[L]]:
1717
// CHECK-NEXT: call void @__go_register_gc_roots
1818
// CHECK-NEXT: store i1 true, i1* @"init$guard"
1919
// CHECK-NEXT: call void @fmt..import(i8* undef)

llvm/docs/LangRef.rst

+7-5
Original file line numberDiff line numberDiff line change
@@ -741,11 +741,13 @@ A function definition contains a list of basic blocks, forming the CFG (Control
741741
Flow Graph) for the function. Each basic block may optionally start with a label
742742
(giving the basic block a symbol table entry), contains a list of instructions,
743743
and ends with a :ref:`terminator <terminators>` instruction (such as a branch or
744-
function return). If an explicit label is not provided, a block is assigned an
745-
implicit numbered label, using the next value from the same counter as used for
746-
unnamed temporaries (:ref:`see above<identifiers>`). For example, if a function
747-
entry block does not have an explicit label, it will be assigned label "%0",
748-
then the first unnamed temporary in that block will be "%1", etc.
744+
function return). If an explicit label name is not provided, a block is assigned
745+
an implicit numbered label, using the next value from the same counter as used
746+
for unnamed temporaries (:ref:`see above<identifiers>`). For example, if a
747+
function entry block does not have an explicit label, it will be assigned label
748+
"%0", then the first unnamed temporary in that block will be "%1", etc. If a
749+
numeric label is explicitly specified, it must match the numeric label that
750+
would be used implicitly.
749751

750752
The first basic block in a function is special in two ways: it is
751753
immediately executed on entrance to the function, and it is not allowed

llvm/lib/AsmParser/LLLexer.cpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -1048,7 +1048,17 @@ lltok::Kind LLLexer::LexDigitOrNegative() {
10481048
for (; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)
10491049
/*empty*/;
10501050

1051-
// Check to see if this really is a label afterall, e.g. "-1:".
1051+
// Check if this is a fully-numeric label:
1052+
if (isdigit(TokStart[0]) && CurPtr[0] == ':') {
1053+
uint64_t Val = atoull(TokStart, CurPtr);
1054+
++CurPtr; // Skip the colon.
1055+
if ((unsigned)Val != Val)
1056+
Error("invalid value number (too large)!");
1057+
UIntVal = unsigned(Val);
1058+
return lltok::LabelID;
1059+
}
1060+
1061+
// Check to see if this really is a string label, e.g. "-1:".
10521062
if (isLabelChar(CurPtr[0]) || CurPtr[0] == ':') {
10531063
if (const char *End = isLabelTail(CurPtr)) {
10541064
StrVal.assign(TokStart, End-1);

llvm/lib/AsmParser/LLParser.cpp

+25-8
Original file line numberDiff line numberDiff line change
@@ -2926,13 +2926,27 @@ BasicBlock *LLParser::PerFunctionState::GetBB(unsigned ID, LocTy Loc) {
29262926
/// unnamed. If there is an error, this returns null otherwise it returns
29272927
/// the block being defined.
29282928
BasicBlock *LLParser::PerFunctionState::DefineBB(const std::string &Name,
2929-
LocTy Loc) {
2929+
int NameID, LocTy Loc) {
29302930
BasicBlock *BB;
2931-
if (Name.empty())
2931+
if (Name.empty()) {
2932+
if (NameID != -1 && unsigned(NameID) != NumberedVals.size()) {
2933+
P.Error(Loc, "label expected to be numbered '" +
2934+
Twine(NumberedVals.size()) + "'");
2935+
return nullptr;
2936+
}
29322937
BB = GetBB(NumberedVals.size(), Loc);
2933-
else
2938+
if (!BB) {
2939+
P.Error(Loc, "unable to create block numbered '" +
2940+
Twine(NumberedVals.size()) + "'");
2941+
return nullptr;
2942+
}
2943+
} else {
29342944
BB = GetBB(Name, Loc);
2935-
if (!BB) return nullptr; // Already diagnosed error.
2945+
if (!BB) {
2946+
P.Error(Loc, "unable to create block named '" + Name + "'");
2947+
return nullptr;
2948+
}
2949+
}
29362950

29372951
// Move the block to the end of the function. Forward ref'd blocks are
29382952
// inserted wherever they happen to be referenced.
@@ -5489,20 +5503,23 @@ bool LLParser::ParseFunctionBody(Function &Fn) {
54895503
}
54905504

54915505
/// ParseBasicBlock
5492-
/// ::= LabelStr? Instruction*
5506+
/// ::= (LabelStr|LabelID)? Instruction*
54935507
bool LLParser::ParseBasicBlock(PerFunctionState &PFS) {
54945508
// If this basic block starts out with a name, remember it.
54955509
std::string Name;
5510+
int NameID = -1;
54965511
LocTy NameLoc = Lex.getLoc();
54975512
if (Lex.getKind() == lltok::LabelStr) {
54985513
Name = Lex.getStrVal();
54995514
Lex.Lex();
5515+
} else if (Lex.getKind() == lltok::LabelID) {
5516+
NameID = Lex.getUIntVal();
5517+
Lex.Lex();
55005518
}
55015519

5502-
BasicBlock *BB = PFS.DefineBB(Name, NameLoc);
5520+
BasicBlock *BB = PFS.DefineBB(Name, NameID, NameLoc);
55035521
if (!BB)
5504-
return Error(NameLoc,
5505-
"unable to create block named '" + Name + "'");
5522+
return true;
55065523

55075524
std::string NameStr;
55085525

llvm/lib/AsmParser/LLParser.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ namespace llvm {
445445
/// DefineBB - Define the specified basic block, which is either named or
446446
/// unnamed. If there is an error, this returns null otherwise it returns
447447
/// the block being defined.
448-
BasicBlock *DefineBB(const std::string &Name, LocTy Loc);
448+
BasicBlock *DefineBB(const std::string &Name, int NameID, LocTy Loc);
449449

450450
bool resolveForwardRefBlockAddresses();
451451
};

llvm/lib/AsmParser/LLToken.h

+1
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ enum Kind {
422422
kw_varFlags,
423423

424424
// Unsigned Valued tokens (UIntVal).
425+
LabelID, // 42:
425426
GlobalID, // @42
426427
LocalVarID, // %42
427428
AttrGrpID, // #42

llvm/lib/IR/AsmWriter.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -3482,23 +3482,24 @@ void AssemblyWriter::printArgument(const Argument *Arg, AttributeSet Attrs) {
34823482

34833483
/// printBasicBlock - This member is called for each basic block in a method.
34843484
void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
3485+
bool IsEntryBlock = BB == &BB->getParent()->getEntryBlock();
34853486
if (BB->hasName()) { // Print out the label if it exists...
34863487
Out << "\n";
34873488
PrintLLVMName(Out, BB->getName(), LabelPrefix);
34883489
Out << ':';
3489-
} else if (!BB->use_empty()) { // Don't print block # of no uses...
3490-
Out << "\n; <label>:";
3490+
} else if (!IsEntryBlock) {
3491+
Out << "\n";
34913492
int Slot = Machine.getLocalSlot(BB);
34923493
if (Slot != -1)
34933494
Out << Slot << ":";
34943495
else
3495-
Out << "<badref>";
3496+
Out << "<badref>:";
34963497
}
34973498

34983499
if (!BB->getParent()) {
34993500
Out.PadToColumn(50);
35003501
Out << "; Error: Block without parent!";
3501-
} else if (BB != &BB->getParent()->getEntryBlock()) { // Not the entry block?
3502+
} else if (!IsEntryBlock) {
35023503
// Output predecessors for the block.
35033504
Out.PadToColumn(50);
35043505
Out << ";";

llvm/test/Analysis/DominanceFrontier/new_pm_test.ll

+29-29
Original file line numberDiff line numberDiff line change
@@ -3,48 +3,48 @@
33

44
define void @a_linear_impl_fig_1() nounwind {
55
0:
6-
br label %"1"
6+
br label %1
77
1:
8-
br label %"2"
8+
br label %2
99
2:
10-
br label %"3"
10+
br label %3
1111
3:
12-
br i1 1, label %"13", label %"4"
12+
br i1 1, label %12, label %4
1313
4:
14-
br i1 1, label %"5", label %"1"
14+
br i1 1, label %5, label %1
1515
5:
16-
br i1 1, label %"8", label %"6"
16+
br i1 1, label %8, label %6
1717
6:
18-
br i1 1, label %"7", label %"4"
18+
br i1 1, label %7, label %4
1919
7:
2020
ret void
2121
8:
22-
br i1 1, label %"9", label %"1"
22+
br i1 1, label %9, label %1
2323
9:
24-
br label %"10"
24+
br label %10
2525
10:
26-
br i1 1, label %"12", label %"11"
26+
br i1 1, label %13, label %11
2727
11:
28-
br i1 1, label %"9", label %"8"
29-
13:
30-
br i1 1, label %"2", label %"1"
28+
br i1 1, label %9, label %8
3129
12:
32-
switch i32 0, label %"1" [ i32 0, label %"9"
33-
i32 1, label %"8"]
30+
br i1 1, label %2, label %1
31+
13:
32+
switch i32 0, label %1 [ i32 0, label %9
33+
i32 1, label %8]
3434
}
3535

3636
; CHECK: DominanceFrontier for function: a_linear_impl_fig_1
37-
; CHECK-DAG: DomFrontier for BB %"0" is:
38-
; CHECK-DAG: DomFrontier for BB %"11" is: %"{{[8|9]}}" %"{{[8|9]}}"
39-
; CHECK-DAG: DomFrontier for BB %"1" is: %"1"
40-
; CHECK-DAG: DomFrontier for BB %"2" is: %"{{[1|2]}}" %"{{[1|2]}}"
41-
; CHECK-DAG: DomFrontier for BB %"3" is: %"{{[1|2]}}" %"{{[1|2]}}"
42-
; CHECK-DAG: DomFrontier for BB %"13" is: %"{{[1|2]}}" %"{{[1|2]}}"
43-
; CHECK-DAG: DomFrontier for BB %"4" is: %"{{[1|4]}}" %"{{[1|4]}}"
44-
; CHECK-DAG: DomFrontier for BB %"5" is: %"{{[1|4]}}" %"{{[1|4]}}"
45-
; CHECK-DAG: DomFrontier for BB %"8" is: %"{{[1|8]}}" %"{{[1|8]}}"
46-
; CHECK-DAG: DomFrontier for BB %"6" is: %"4"
47-
; CHECK-DAG: DomFrontier for BB %"7" is:
48-
; CHECK-DAG: DomFrontier for BB %"9" is: %"{{[1|8|9]}}" %"{{[1|8|9]}}" %"{{[1|8|9]}}"
49-
; CHECK-DAG: DomFrontier for BB %"10" is: %"{{[1|8|9]}}" %"{{[1|8|9]}}" %"{{[1|8|9]}}"
50-
; CHECK-DAG: DomFrontier for BB %"12" is: %"{{[1|8|9]}}" %"{{[1|8|9]}}" %"{{[1|8|9]}}"
37+
; CHECK-DAG: DomFrontier for BB %0 is:
38+
; CHECK-DAG: DomFrontier for BB %11 is: %{{[8|9]}} %{{[8|9]}}
39+
; CHECK-DAG: DomFrontier for BB %1 is: %1
40+
; CHECK-DAG: DomFrontier for BB %2 is: %{{[1|2]}} %{{[1|2]}}
41+
; CHECK-DAG: DomFrontier for BB %3 is: %{{[1|2]}} %{{[1|2]}}
42+
; CHECK-DAG: DomFrontier for BB %12 is: %{{[1|2]}} %{{[1|2]}}
43+
; CHECK-DAG: DomFrontier for BB %4 is: %{{[1|4]}} %{{[1|4]}}
44+
; CHECK-DAG: DomFrontier for BB %5 is: %{{[1|4]}} %{{[1|4]}}
45+
; CHECK-DAG: DomFrontier for BB %8 is: %{{[1|8]}} %{{[1|8]}}
46+
; CHECK-DAG: DomFrontier for BB %6 is: %4
47+
; CHECK-DAG: DomFrontier for BB %7 is:
48+
; CHECK-DAG: DomFrontier for BB %9 is: %{{[1|8|9]}} %{{[1|8|9]}} %{{[1|8|9]}}
49+
; CHECK-DAG: DomFrontier for BB %10 is: %{{[1|8|9]}} %{{[1|8|9]}} %{{[1|8|9]}}
50+
; CHECK-DAG: DomFrontier for BB %13 is: %{{[1|8|9]}} %{{[1|8|9]}} %{{[1|8|9]}}

llvm/test/Analysis/RegionInfo/cond_loop.ll

+6-6
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@
77
; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
88

99
define void @normal_condition() nounwind {
10-
5:
10+
"5":
1111
br label %"0"
1212

13-
0:
13+
"0":
1414
br label %"1"
15-
1:
15+
"1":
1616
br i1 1, label %"2", label %"3"
17-
2:
17+
"2":
1818
ret void
19-
3:
19+
"3":
2020
br i1 1, label %"1", label %"4"
21-
4:
21+
"4":
2222
br label %"0"
2323
}
2424

llvm/test/Analysis/RegionInfo/condition_forward_edge.ll

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
88

99
define void @normal_condition() nounwind {
10-
0:
10+
"0":
1111
br label %"1"
12-
1:
12+
"1":
1313
br i1 1, label %"2", label %"3"
14-
2:
14+
"2":
1515
br label %"3"
16-
3:
16+
"3":
1717
ret void
1818
}
1919
; CHECK-NOT: =>

llvm/test/Analysis/RegionInfo/condition_same_exit.ll

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@
77
; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
88

99
define void @normal_condition() nounwind {
10-
0:
10+
"0":
1111
br i1 1, label %"1", label %"4"
1212

13-
1:
13+
"1":
1414
br i1 1, label %"2", label %"3"
15-
2:
15+
"2":
1616
br label %"4"
17-
3:
17+
"3":
1818
br label %"4"
19-
4:
19+
"4":
2020
ret void
2121
}
2222
; CHECK-NOT: =>

llvm/test/Analysis/RegionInfo/condition_simple.ll

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
88

99
define void @normal_condition() nounwind {
10-
0:
10+
"0":
1111
br label %"1"
12-
1:
12+
"1":
1313
br i1 1, label %"2", label %"3"
14-
2:
14+
"2":
1515
br label %"4"
16-
3:
16+
"3":
1717
br label %"4"
18-
4:
18+
"4":
1919
ret void
2020
}
2121

llvm/test/Analysis/RegionInfo/infinite_loop.ll

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44

55
define void @normal_condition() nounwind {
66
0:
7-
br label %"1"
7+
br label %1
88
1:
9-
br i1 1, label %"2", label %"3"
9+
br i1 1, label %2, label %3
1010
2:
11-
br label %"2"
11+
br label %2
1212
3:
13-
br label %"4"
13+
br label %4
1414
4:
1515
ret void
1616
}
1717
; CHECK-NOT: =>
1818
; CHECK: [0] 0 => <Function Return>
19-
; STAT: 1 region - The # of regions
19+
; STAT: 1 region - The # of regions

llvm/test/Analysis/RegionInfo/infinite_loop_2.ll

+9-9
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,23 @@
55
; RUN: opt -regions -print-region-style=rn -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
66

77
define void @normal_condition() nounwind {
8-
0:
8+
"0":
99
br label %"1"
10-
1:
10+
"1":
1111
br i1 1, label %"2", label %"3"
12-
2:
12+
"2":
1313
br label %"5"
14-
5:
14+
"5":
1515
br i1 1, label %"11", label %"12"
16-
11:
16+
"11":
1717
br label %"6"
18-
12:
18+
"12":
1919
br label %"6"
20-
6:
20+
"6":
2121
br label %"2"
22-
3:
22+
"3":
2323
br label %"4"
24-
4:
24+
"4":
2525
ret void
2626
}
2727
; CHECK-NOT: =>

0 commit comments

Comments
 (0)