mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:12:47 +01:00
Make sure that any new and optimized objects created during GlobalOPT copy all the attributes from the base object.
Summary: Make sure that any new and optimized objects created during GlobalOPT copy all the attributes from the base object. A good example of improper behavior in the current implementation is section information associated with the GlobalObject. If a section was set for it, and GlobalOpt is creating/modifying a new object based on this one (often copying the original name), without this change new object will be placed in a default section, resulting in inappropriate properties of the new variable. The argument here is that if customer specified a section for a variable, any changes to it that compiler does should not cause it to change that section allocation. Moreover, any other properties worth representation in copyAttributesFrom() should also be propagated. Reviewers: jmolloy, joker-eph, joker.eph Subscribers: slarin, joker.eph, rafael, tobiasvk, llvm-commits Differential Revision: http://reviews.llvm.org/D16074 llvm-svn: 258556
This commit is contained in:
parent
85ea6e2ccc
commit
7b219abac0
@ -499,6 +499,7 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV, const DataLayout &DL) {
|
||||
GV->getThreadLocalMode(),
|
||||
GV->getType()->getAddressSpace());
|
||||
NGV->setExternallyInitialized(GV->isExternallyInitialized());
|
||||
NGV->copyAttributesFrom(GV);
|
||||
Globals.push_back(NGV);
|
||||
NewGlobals.push_back(NGV);
|
||||
|
||||
@ -533,6 +534,7 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV, const DataLayout &DL) {
|
||||
GV->getThreadLocalMode(),
|
||||
GV->getType()->getAddressSpace());
|
||||
NGV->setExternallyInitialized(GV->isExternallyInitialized());
|
||||
NGV->copyAttributesFrom(GV);
|
||||
Globals.push_back(NGV);
|
||||
NewGlobals.push_back(NGV);
|
||||
|
||||
@ -1291,6 +1293,7 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, CallInst *CI,
|
||||
*GV->getParent(), PFieldTy, false, GlobalValue::InternalLinkage,
|
||||
Constant::getNullValue(PFieldTy), GV->getName() + ".f" + Twine(FieldNo),
|
||||
nullptr, GV->getThreadLocalMode());
|
||||
NGV->copyAttributesFrom(GV);
|
||||
FieldGlobals.push_back(NGV);
|
||||
|
||||
unsigned TypeSize = DL.getTypeAllocSize(FieldTy);
|
||||
@ -1610,6 +1613,7 @@ static bool TryToShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) {
|
||||
GV->getName()+".b",
|
||||
GV->getThreadLocalMode(),
|
||||
GV->getType()->getAddressSpace());
|
||||
NewGV->copyAttributesFrom(GV);
|
||||
GV->getParent()->getGlobalList().insert(GV->getIterator(), NewGV);
|
||||
|
||||
Constant *InitVal = GV->getInitializer();
|
||||
|
30
test/Transforms/GlobalOpt/GSROA-section.ll
Normal file
30
test/Transforms/GlobalOpt/GSROA-section.ll
Normal file
@ -0,0 +1,30 @@
|
||||
; This test lets globalopt split the global struct and array into different
|
||||
; values. The pass needs to preserve section attribute.
|
||||
|
||||
; RUN: opt < %s -globalopt -S | FileCheck %s
|
||||
; Check that the new global values still have their section assignment.
|
||||
; CHECK: @struct
|
||||
; CHECK: section ".foo"
|
||||
; CHECK: @array
|
||||
; CHECK-NOT: section ".foo"
|
||||
|
||||
@struct = internal global { i32, i32 } zeroinitializer, section ".foo"
|
||||
@array = internal global [ 2 x i32 ] zeroinitializer
|
||||
|
||||
define i32 @foo() {
|
||||
%A = load i32, i32* getelementptr ({ i32, i32 }, { i32, i32 }* @struct, i32 0, i32 0)
|
||||
%B = load i32, i32* getelementptr ([ 2 x i32 ], [ 2 x i32 ]* @array, i32 0, i32 0)
|
||||
; Use the loaded values, so they won't get removed completely
|
||||
%R = add i32 %A, %B
|
||||
ret i32 %R
|
||||
}
|
||||
|
||||
; We put stores in a different function, so that the global variables won't get
|
||||
; optimized away completely.
|
||||
define void @bar(i32 %R) {
|
||||
store i32 %R, i32* getelementptr ([ 2 x i32 ], [ 2 x i32 ]* @array, i32 0, i32 0)
|
||||
store i32 %R, i32* getelementptr ({ i32, i32 }, { i32, i32 }* @struct, i32 0, i32 0)
|
||||
ret void
|
||||
}
|
||||
|
||||
|
28
test/Transforms/GlobalOpt/MallocSROA-section.ll
Normal file
28
test/Transforms/GlobalOpt/MallocSROA-section.ll
Normal file
@ -0,0 +1,28 @@
|
||||
; RUN: opt -globalopt -S < %s | FileCheck %s
|
||||
; CHECK: @Y.f0
|
||||
; CHECK: section ".foo"
|
||||
; CHECK: @Y.f1
|
||||
; CHECK: section ".foo"
|
||||
|
||||
%struct.xyz = type { double, i32 }
|
||||
|
||||
@Y = internal global %struct.xyz* null ,section ".foo" ; <%struct.xyz**> [#uses=2]
|
||||
@numf2s = external global i32 ; <i32*> [#uses=1]
|
||||
|
||||
define void @init_net() {
|
||||
entry:
|
||||
%0 = load i32, i32* @numf2s, align 4 ; <i32> [#uses=1]
|
||||
%mallocsize2 = shl i32 %0, 4 ; <i32> [#uses=1]
|
||||
%malloccall3 = tail call i8* @malloc(i32 %mallocsize2) ; <i8*> [#uses=1]
|
||||
%1 = bitcast i8* %malloccall3 to %struct.xyz* ; <%struct.xyz*> [#uses=1]
|
||||
store %struct.xyz* %1, %struct.xyz** @Y, align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @load_train() {
|
||||
entry:
|
||||
%0 = load %struct.xyz*, %struct.xyz** @Y, align 8 ; <%struct.xyz*> [#uses=0]
|
||||
ret void
|
||||
}
|
||||
|
||||
declare noalias i8* @malloc(i32)
|
27
test/Transforms/GlobalOpt/SROA-section.ll
Normal file
27
test/Transforms/GlobalOpt/SROA-section.ll
Normal file
@ -0,0 +1,27 @@
|
||||
; Verify that section assignment is copied during SROA
|
||||
; RUN: opt < %s -globalopt -S | FileCheck %s
|
||||
; CHECK: @G.0
|
||||
; CHECK: section ".foo"
|
||||
; CHECK: @G.1
|
||||
; CHECK: section ".foo"
|
||||
; CHECK: @G.2
|
||||
; CHECK: section ".foo"
|
||||
|
||||
%T = type { double, double, double }
|
||||
@G = internal global %T zeroinitializer, align 16, section ".foo"
|
||||
|
||||
define void @test() {
|
||||
store double 1.0, double* getelementptr (%T, %T* @G, i32 0, i32 0), align 16
|
||||
store double 2.0, double* getelementptr (%T, %T* @G, i32 0, i32 1), align 8
|
||||
store double 3.0, double* getelementptr (%T, %T* @G, i32 0, i32 2), align 16
|
||||
ret void
|
||||
}
|
||||
|
||||
define double @test2() {
|
||||
%V1 = load double, double* getelementptr (%T, %T* @G, i32 0, i32 0), align 16
|
||||
%V2 = load double, double* getelementptr (%T, %T* @G, i32 0, i32 1), align 8
|
||||
%V3 = load double, double* getelementptr (%T, %T* @G, i32 0, i32 2), align 16
|
||||
%R = fadd double %V1, %V2
|
||||
%R2 = fadd double %R, %V3
|
||||
ret double %R2
|
||||
}
|
Loading…
Reference in New Issue
Block a user