llvm.org GIT mirror llvm / b90e8d3
[llvm-extract] Expose the group extraction feature of the BlockExtractor This patch extends the `-bb` option to be able to use the group extraction feature from the BlockExtractor. In particular, `-bb=func:bb` is modified to support a list of basic blocks per function: `-bb=func:bb1[;bb2...]` that will be extracted together if at all possible (region must be single entry.) Differential Revision: https://reviews.llvm.org/D60973 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@359464 91177308-0d34-0410-b5e6-96231b3b80d8 Quentin Colombet 1 year, 5 months ago
2 changed file(s) with 144 addition(s) and 13 deletion(s). Raw diff Collapse all Expand all
0 ; RUN: llvm-extract -bb 'foo:if;then;else' -bb 'bar:bb14;bb20' -S %s | FileCheck %s
1 ; Extract two groups of basic blocks in two different functions.
2
3
4 ; The first extracted function is the region composed by the
5 ; blocks if, then, and else from foo.
6 ; CHECK: define dso_local void @foo.if.split(i32 %arg1, i32 %arg, i32* %tmp.0.ce.out) {
7 ; CHECK: newFuncRoot:
8 ; CHECK: br label %if.split
9 ;
10 ; CHECK: end.exitStub: ; preds = %end.split
11 ; CHECK: ret void
12 ;
13 ; CHECK: then: ; preds = %if.split
14 ; CHECK: %tmp12 = shl i32 %arg1, 2
15 ; CHECK: %tmp13 = add nsw i32 %tmp12, %arg
16 ; CHECK: br label %end.split
17 ;
18 ; CHECK: else: ; preds = %if.split
19 ; CHECK: %tmp22 = mul nsw i32 %arg, 3
20 ; CHECK: %tmp24 = sdiv i32 %arg1, 6
21 ; CHECK: %tmp25 = add nsw i32 %tmp24, %tmp22
22 ; CHECK: br label %end.split
23 ;
24 ; CHECK: if.split: ; preds = %newFuncRoot
25 ; CHECK: %tmp5 = icmp sgt i32 %arg, 0
26 ; CHECK: %tmp8 = icmp sgt i32 %arg1, 0
27 ; CHECK: %or.cond = and i1 %tmp5, %tmp8
28 ; CHECK: br i1 %or.cond, label %then, label %else
29 ;
30 ; CHECK: end.split: ; preds = %then, %else
31 ; CHECK: %tmp.0.ce = phi i32 [ %tmp13, %then ], [ %tmp25, %else ]
32 ; CHECK: store i32 %tmp.0.ce, i32* %tmp.0.ce.out
33 ; CHECK: br label %end.exitStub
34 ; CHECK: }
35
36 ; The second extracted function is the region composed by the blocks
37 ; bb14 and bb20 from bar.
38 ; CHECK: define dso_local i1 @bar.bb14(i32 %arg1, i32 %arg, i32* %tmp25.out) {
39 ; CHECK: newFuncRoot:
40 ; CHECK: br label %bb14
41 ;
42 ; CHECK: bb26.exitStub: ; preds = %bb14
43 ; CHECK: ret i1 true
44 ;
45 ; CHECK: bb30.exitStub: ; preds = %bb20
46 ; CHECK: ret i1 false
47 ;
48 ; CHECK: bb14: ; preds = %newFuncRoot
49 ; CHECK: %tmp0 = and i32 %arg1, %arg
50 ; CHECK: %tmp1 = icmp slt i32 %tmp0, 0
51 ; CHECK: br i1 %tmp1, label %bb20, label %bb26.exitStub
52 ;
53 ; CHECK: bb20: ; preds = %bb14
54 ; CHECK: %tmp22 = mul nsw i32 %arg, 3
55 ; CHECK: %tmp24 = sdiv i32 %arg1, 6
56 ; CHECK: %tmp25 = add nsw i32 %tmp24, %tmp22
57 ; CHECK: store i32 %tmp25, i32* %tmp25.out
58 ; CHECK: br label %bb30.exitStub
59 ; CHECK: }
60
61 define i32 @foo(i32 %arg, i32 %arg1) {
62 if:
63 %tmp5 = icmp sgt i32 %arg, 0
64 %tmp8 = icmp sgt i32 %arg1, 0
65 %or.cond = and i1 %tmp5, %tmp8
66 br i1 %or.cond, label %then, label %else
67
68 then:
69 %tmp12 = shl i32 %arg1, 2
70 %tmp13 = add nsw i32 %tmp12, %arg
71 br label %end
72
73 else:
74 %tmp22 = mul nsw i32 %arg, 3
75 %tmp24 = sdiv i32 %arg1, 6
76 %tmp25 = add nsw i32 %tmp24, %tmp22
77 br label %end
78
79 end:
80 %tmp.0 = phi i32 [ %tmp13, %then ], [ %tmp25, %else ]
81 %and0 = and i32 %tmp.0, %arg
82 %cmp1 = icmp slt i32 %and0, 0
83 br i1 %cmp1, label %ret0, label %ret1
84
85 ret0:
86 ret i32 0
87
88 ret1:
89 ret i32 1
90 }
91
92 define i32 @bar(i32 %arg, i32 %arg1) {
93 bb:
94 %tmp5 = icmp sgt i32 %arg, 0
95 %tmp8 = icmp sgt i32 %arg1, 0
96 %or.cond = and i1 %tmp5, %tmp8
97 br i1 %or.cond, label %bb9, label %bb14
98
99 bb9: ; preds = %bb
100 %tmp12 = shl i32 %arg1, 2
101 %tmp13 = add nsw i32 %tmp12, %arg
102 br label %bb30
103
104 bb14: ; preds = %bb
105 %tmp0 = and i32 %arg1, %arg
106 %tmp1 = icmp slt i32 %tmp0, 0
107 br i1 %tmp1, label %bb20, label %bb26
108
109 bb20: ; preds = %bb14
110 %tmp22 = mul nsw i32 %arg, 3
111 %tmp24 = sdiv i32 %arg1, 6
112 %tmp25 = add nsw i32 %tmp24, %tmp22
113 br label %bb30
114
115 bb26: ; preds = %bb14
116 %tmp29 = sub nsw i32 %arg, %arg1
117 br label %bb30
118
119 bb30: ; preds = %bb26, %bb20, %bb9
120 %tmp.0 = phi i32 [ %tmp13, %bb9 ], [ %tmp25, %bb20 ], [ %tmp29, %bb26 ]
121 ret i32 %tmp.0
122 }
123
228228 }
229229
230230 // Figure out which BasicBlocks we should extract.
231 SmallVector<BasicBlock *, 4> BBs;
231 SmallVector<SmallVector, 4> GroupOfBBs;
232232 for (StringRef StrPair : ExtractBlocks) {
233233 auto BBInfo = StrPair.split(':');
234234 // Get the function.
240240 }
241241 // Do not materialize this function.
242242 GVs.insert(F);
243 // Get the basic block.
244 auto Res = llvm::find_if(*F, [&](const BasicBlock &BB) {
245 return BB.getName().equals(BBInfo.second);
246 });
247 if (Res == F->end()) {
248 errs() << argv[0] << ": function " << F->getName()
249 << " doesn't contain a basic block named '" << BBInfo.second
250 << "'!\n";
251 return 1;
252 }
253 BBs.push_back(&*Res);
243 // Get the basic blocks.
244 SmallVector BBs;
245 SmallVector BBNames;
246 BBInfo.second.split(BBNames, ';', /*MaxSplit=*/-1,
247 /*KeepEmpty=*/false);
248 for (StringRef BBName : BBNames) {
249 auto Res = llvm::find_if(*F, [&](const BasicBlock &BB) {
250 return BB.getName().equals(BBName);
251 });
252 if (Res == F->end()) {
253 errs() << argv[0] << ": function " << F->getName()
254 << " doesn't contain a basic block named '" << BBInfo.second
255 << "'!\n";
256 return 1;
257 }
258 BBs.push_back(&*Res);
259 }
260 GroupOfBBs.push_back(BBs);
254261 }
255262
256263 // Use *argv instead of argv[0] to work around a wrong GCC warning.
315322 // functions.
316323 if (!ExtractBlocks.empty()) {
317324 legacy::PassManager PM;
318 PM.add(createBlockExtractorPass(BBs, true));
325 PM.add(createBlockExtractorPass(GroupOfBBs, true));
319326 PM.run(*M);
320327 }
321328