llvm.org GIT mirror llvm / c0916d3
llvm-extract was unable to handle aliases. It would leave a copy on the output of both llvm-extract foo.ll -func=bar and llvm-extract foo.ll -func=bar -delete so the two new files could not be linked together anymore. With this change alias are handled almost like functions and global variables. Almost because with alias we cannot just clear the initializer/body, we have to create a new declaration and replace the alias with it. The net result is that now the output of the above commands can be linked even if foo.ll has aliases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166907 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 6 years ago
2 changed file(s) with 70 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
7878 I->setLinkage(GlobalValue::ExternalLinkage);
7979 }
8080
81 // Visit the Aliases.
82 for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
83 I != E;) {
84 Module::alias_iterator CurI = I;
85 ++I;
86
87 if (CurI->hasLocalLinkage())
88 CurI->setVisibility(GlobalValue::HiddenVisibility);
89 CurI->setLinkage(GlobalValue::ExternalLinkage);
90
91 if (deleteStuff == (bool)Named.count(CurI)) {
92 Type *Ty = CurI->getType()->getElementType();
93
94 CurI->removeFromParent();
95 llvm::Value *Declaration;
96 if (FunctionType *FTy = dyn_cast(Ty)) {
97 Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage,
98 CurI->getName(), &M);
99
100 } else {
101 Declaration =
102 new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage,
103 0, CurI->getName());
104
105 }
106 CurI->replaceAllUsesWith(Declaration);
107 delete CurI;
108 }
109 }
110
81111 return true;
82112 }
83113 };
0 ; RUN: llvm-extract -func foo -S < %s | FileCheck %s
1 ; RUN: llvm-extract -delete -func foo -S < %s | FileCheck --check-prefix=DELETE %s
2
3 ; Both aliases should be converted to declarations
4 ; CHECK: @zeda0 = external global i32
5 ; CHECK: define i32* @foo() {
6 ; CHECK-NEXT: call void @a0bar()
7 ; CHECK-NEXT: ret i32* @zeda0
8 ; CHECK-NEXT: }
9 ; CHECK: declare void @a0bar()
10
11 ; DELETE: @zed = global i32 0
12 ; DELETE: @zeda0 = alias i32* @zed
13 ; DELETE-NEXT: @a0foo = alias i32* ()* @foo
14 ; DELETE-NEXT: @a0a0bar = alias void ()* @a0bar
15 ; DELETE-NEXT: @a0bar = alias void ()* @bar
16 ; DELETE: declare i32* @foo()
17 ; DELETE: define void @bar() {
18 ; DELETE-NEXT: %c = call i32* @foo()
19 ; DELETE-NEXT: ret void
20 ; DELETE-NEXT: }
21
22 @zed = global i32 0
23 @zeda0 = alias i32* @zed
24
25 @a0foo = alias i32* ()* @foo
26
27 define i32* @foo() {
28 call void @a0bar()
29 ret i32* @zeda0
30 }
31
32 @a0a0bar = alias void ()* @a0bar
33
34 @a0bar = alias void ()* @bar
35
36 define void @bar() {
37 %c = call i32* @foo()
38 ret void
39 }