summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-10-29 00:27:55 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-10-29 00:27:55 +0000
commit9d30d0fc674d40005b38d73f210834ce11a56e66 (patch)
tree03be0d2804c8e85a899c2fac2bb4c7b0f9c023ff
parente6c31579beecd89292810b77fdfc02f5d090f938 (diff)
downloadbcm5719-llvm-9d30d0fc674d40005b38d73f210834ce11a56e66.tar.gz
bcm5719-llvm-9d30d0fc674d40005b38d73f210834ce11a56e66.zip
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. llvm-svn: 166907
-rw-r--r--llvm/lib/Transforms/IPO/ExtractGV.cpp30
-rw-r--r--llvm/test/Other/extract-alias.ll40
2 files changed, 70 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/IPO/ExtractGV.cpp b/llvm/lib/Transforms/IPO/ExtractGV.cpp
index 4c7f0ed2364..57c2f6d410d 100644
--- a/llvm/lib/Transforms/IPO/ExtractGV.cpp
+++ b/llvm/lib/Transforms/IPO/ExtractGV.cpp
@@ -79,6 +79,36 @@ namespace {
I->setLinkage(GlobalValue::ExternalLinkage);
}
+ // Visit the Aliases.
+ for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
+ I != E;) {
+ Module::alias_iterator CurI = I;
+ ++I;
+
+ if (CurI->hasLocalLinkage())
+ CurI->setVisibility(GlobalValue::HiddenVisibility);
+ CurI->setLinkage(GlobalValue::ExternalLinkage);
+
+ if (deleteStuff == (bool)Named.count(CurI)) {
+ Type *Ty = CurI->getType()->getElementType();
+
+ CurI->removeFromParent();
+ llvm::Value *Declaration;
+ if (FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
+ Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage,
+ CurI->getName(), &M);
+
+ } else {
+ Declaration =
+ new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage,
+ 0, CurI->getName());
+
+ }
+ CurI->replaceAllUsesWith(Declaration);
+ delete CurI;
+ }
+ }
+
return true;
}
};
diff --git a/llvm/test/Other/extract-alias.ll b/llvm/test/Other/extract-alias.ll
new file mode 100644
index 00000000000..85d1ae5b1b5
--- /dev/null
+++ b/llvm/test/Other/extract-alias.ll
@@ -0,0 +1,40 @@
+; RUN: llvm-extract -func foo -S < %s | FileCheck %s
+; RUN: llvm-extract -delete -func foo -S < %s | FileCheck --check-prefix=DELETE %s
+
+; Both aliases should be converted to declarations
+; CHECK: @zeda0 = external global i32
+; CHECK: define i32* @foo() {
+; CHECK-NEXT: call void @a0bar()
+; CHECK-NEXT: ret i32* @zeda0
+; CHECK-NEXT: }
+; CHECK: declare void @a0bar()
+
+; DELETE: @zed = global i32 0
+; DELETE: @zeda0 = alias i32* @zed
+; DELETE-NEXT: @a0foo = alias i32* ()* @foo
+; DELETE-NEXT: @a0a0bar = alias void ()* @a0bar
+; DELETE-NEXT: @a0bar = alias void ()* @bar
+; DELETE: declare i32* @foo()
+; DELETE: define void @bar() {
+; DELETE-NEXT: %c = call i32* @foo()
+; DELETE-NEXT: ret void
+; DELETE-NEXT: }
+
+@zed = global i32 0
+@zeda0 = alias i32* @zed
+
+@a0foo = alias i32* ()* @foo
+
+define i32* @foo() {
+ call void @a0bar()
+ ret i32* @zeda0
+}
+
+@a0a0bar = alias void ()* @a0bar
+
+@a0bar = alias void ()* @bar
+
+define void @bar() {
+ %c = call i32* @foo()
+ ret void
+}
OpenPOWER on IntegriCloud