diff options
-rw-r--r-- | lib/Transforms/IPO/ExtractGV.cpp | 30 | ||||
-rw-r--r-- | test/Other/extract-alias.ll | 40 |
2 files changed, 70 insertions, 0 deletions
diff --git a/lib/Transforms/IPO/ExtractGV.cpp b/lib/Transforms/IPO/ExtractGV.cpp index 4c7f0ed236..57c2f6d410 100644 --- a/lib/Transforms/IPO/ExtractGV.cpp +++ b/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/test/Other/extract-alias.ll b/test/Other/extract-alias.ll new file mode 100644 index 0000000000..85d1ae5b1b --- /dev/null +++ b/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 +} |