llvm.org GIT mirror llvm / 0e13821
GC poses hazards to the inliner. Consider: define void @f() { ... call i32 @g() ... } define void @g() { ... } The hazards are: - @f and @g have GC, but they differ GC. Inlining is invalid. This may never occur. - @f has no GC, but @g does. g's GC must be propagated to @f. The other scenarios are safe: - @f and @g have the same GC. - @f and @g have no GC. - @g has no GC. This patch adds inliner checks for the former two scenarios. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45351 91177308-0d34-0410-b5e6-96231b3b80d8 Gordon Henriksen 12 years ago
3 changed file(s) with 60 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
200200 BasicBlock *OrigBB = TheCall->getParent();
201201 Function *Caller = OrigBB->getParent();
202202
203
204 // GC poses two hazards to inlining, which only occur when the callee has GC:
205 // 1. If the caller has no GC, then the callee's GC must be propagated to the
206 // caller.
207 // 2. If the caller has a differing GC, it is invalid to inline.
208 if (CalledFunc->hasCollector()) {
209 if (!Caller->hasCollector())
210 Caller->setCollector(CalledFunc->getCollector());
211 else if (CalledFunc->getCollector() != Caller->getCollector())
212 return false;
213 }
214
215
203216 // Get an iterator to the last basic block in the function, which will have
204217 // the new function inlined after it.
205218 //
0 ; RUN: llvm-as < %s | opt -inline | llvm-dis | grep example
1
2 %IntArray = type { i32, [0 x i32*] }
3
4 declare void @llvm.gcroot(i8**, i8*) nounwind
5
6 define i32 @f() {
7 %x = call i32 @g( ) ; [#uses=1]
8 ret i32 %x
9 }
10
11 define internal i32 @g() gc "example" {
12 %root = alloca i8* ; [#uses=2]
13 call void @llvm.gcroot( i8** %root, i8* null )
14 %obj = call %IntArray* @h( ) ; <%IntArray*> [#uses=2]
15 %obj.2 = bitcast %IntArray* %obj to i8* ; [#uses=1]
16 store i8* %obj.2, i8** %root
17 %Length.ptr = getelementptr %IntArray* %obj, i32 0, i32 0 ; [#uses=1]
18 %Length = load i32* %Length.ptr ; [#uses=1]
19 ret i32 %Length
20 }
21
22 declare %IntArray* @h()
0 ; RUN: llvm-as < %s | opt -inline | llvm-dis | grep sample
1 ; RUN: llvm-as < %s | opt -inline | llvm-dis | grep example
2
3 %IntArray = type { i32, [0 x i32*] }
4
5 declare void @llvm.gcroot(i8**, i8*) nounwind
6
7 define i32 @f() gc "sample" {
8 %x = call i32 @g( ) ; [#uses=1]
9 ret i32 %x
10 }
11
12 define internal i32 @g() gc "example" {
13 %root = alloca i8* ; [#uses=2]
14 call void @llvm.gcroot( i8** %root, i8* null )
15 %obj = call %IntArray* @h( ) ; <%IntArray*> [#uses=2]
16 %obj.2 = bitcast %IntArray* %obj to i8* ; [#uses=1]
17 store i8* %obj.2, i8** %root
18 %Length.ptr = getelementptr %IntArray* %obj, i32 0, i32 0 ; [#uses=1]
19 %Length = load i32* %Length.ptr ; [#uses=1]
20 ret i32 %Length
21 }
22
23 declare %IntArray* @h()