llvm-extract changes linkages so that functions on both sides of the

split module can see each other. If it is keeping a symbol that already has
a non local linkage, it doesn't need to change it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166908 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2012-10-29 01:59:03 +00:00
parent c0916d30e0
commit 9cb90e7c15
3 changed files with 53 additions and 16 deletions

View File

@ -51,32 +51,44 @@ namespace {
// Visit the GlobalVariables. // Visit the GlobalVariables.
for (Module::global_iterator I = M.global_begin(), E = M.global_end(); for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) { I != E; ++I) {
if (deleteStuff == (bool)Named.count(I) && !I->isDeclaration()) { bool Delete =
I->setInitializer(0); deleteStuff == (bool)Named.count(I) && !I->isDeclaration();
} else { if (!Delete) {
if (I->hasAvailableExternallyLinkage()) if (I->hasAvailableExternallyLinkage())
continue; continue;
if (I->getName() == "llvm.global_ctors") if (I->getName() == "llvm.global_ctors")
continue; continue;
} }
if (I->hasLocalLinkage()) bool Local = I->hasLocalLinkage();
if (Local)
I->setVisibility(GlobalValue::HiddenVisibility); I->setVisibility(GlobalValue::HiddenVisibility);
I->setLinkage(GlobalValue::ExternalLinkage);
if (Local || Delete)
I->setLinkage(GlobalValue::ExternalLinkage);
if (Delete)
I->setInitializer(0);
} }
// Visit the Functions. // Visit the Functions.
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
if (deleteStuff == (bool)Named.count(I) && !I->isDeclaration()) { bool Delete =
I->deleteBody(); deleteStuff == (bool)Named.count(I) && !I->isDeclaration();
} else { if (!Delete) {
if (I->hasAvailableExternallyLinkage()) if (I->hasAvailableExternallyLinkage())
continue; continue;
} }
if (I->hasLocalLinkage()) bool Local = I->hasLocalLinkage();
if (Local)
I->setVisibility(GlobalValue::HiddenVisibility); I->setVisibility(GlobalValue::HiddenVisibility);
I->setLinkage(GlobalValue::ExternalLinkage);
if (Local || Delete)
I->setLinkage(GlobalValue::ExternalLinkage);
if (Delete)
I->deleteBody();
} }
// Visit the Aliases. // Visit the Aliases.
@ -85,9 +97,10 @@ namespace {
Module::alias_iterator CurI = I; Module::alias_iterator CurI = I;
++I; ++I;
if (CurI->hasLocalLinkage()) if (CurI->hasLocalLinkage()) {
CurI->setVisibility(GlobalValue::HiddenVisibility); CurI->setVisibility(GlobalValue::HiddenVisibility);
CurI->setLinkage(GlobalValue::ExternalLinkage); CurI->setLinkage(GlobalValue::ExternalLinkage);
}
if (deleteStuff == (bool)Named.count(CurI)) { if (deleteStuff == (bool)Named.count(CurI)) {
Type *Ty = CurI->getType()->getElementType(); Type *Ty = CurI->getType()->getElementType();

View File

@ -0,0 +1,23 @@
; RUN: llvm-extract -func foo -S < %s | FileCheck %s
; RUN: llvm-extract -delete -func foo -S < %s | FileCheck --check-prefix=DELETE %s
; Test that we don't convert weak_odr to external definitions.
; CHECK: @bar = external global i32
; CHECK: define weak_odr i32* @foo() {
; CHECK-NEXT: ret i32* @bar
; CHECK-NEXT: }
; DELETE: @bar = weak_odr global i32 42
; DELETE: declare i32* @foo()
@bar = weak_odr global i32 42
define weak_odr i32* @foo() {
ret i32* @bar
}
define void @g() {
%c = call i32* @foo()
ret void
}

View File

@ -7,18 +7,19 @@
; llvm-extract uses lazy bitcode loading, so make sure it correctly reads ; llvm-extract uses lazy bitcode loading, so make sure it correctly reads
; from bitcode files in addition to assembly files. ; from bitcode files in addition to assembly files.
; CHECK: define void @foo() { ; CHECK: define hidden void @foo() {
; CHECK: ret void ; CHECK: ret void
; CHECK: } ; CHECK: }
; The linkonce_odr linkage for foo() should be changed to external linkage. ; The private linkage for foo() should be changed to external linkage and
; DELETE: declare void @foo() ; hidden visibility added.
; DELETE: declare hidden void @foo()
; DELETE: define void @bar() { ; DELETE: define void @bar() {
; DELETE: call void @foo() ; DELETE: call void @foo()
; DELETE: ret void ; DELETE: ret void
; DELETE: } ; DELETE: }
define linkonce_odr void @foo() { define private void @foo() {
ret void ret void
} }
define void @bar() { define void @bar() {