forked from OSchip/llvm-project
[GlobalsModRef] Apply indirect-global rule to all globals initialized from noalias calls
Extend the existing malloc-family specific optimization to all noalias calls. This allows us to handle allocation wrappers, and removes a dependency on a lib-func check in favor of generic attribute usage. Differential Revision: https://reviews.llvm.org/D116980
This commit is contained in:
parent
20404d820c
commit
e838949bee
|
@ -401,14 +401,14 @@ bool GlobalsAAResult::AnalyzeUsesOfPointer(Value *V,
|
|||
|
||||
/// AnalyzeIndirectGlobalMemory - We found an non-address-taken global variable
|
||||
/// which holds a pointer type. See if the global always points to non-aliased
|
||||
/// heap memory: that is, all initializers of the globals are allocations, and
|
||||
/// those allocations have no use other than initialization of the global.
|
||||
/// heap memory: that is, all initializers of the globals store a value known
|
||||
/// to be obtained via a noalias return function call which have no other use.
|
||||
/// Further, all loads out of GV must directly use the memory, not store the
|
||||
/// pointer somewhere. If this is true, we consider the memory pointed to by
|
||||
/// GV to be owned by GV and can disambiguate other pointers from it.
|
||||
bool GlobalsAAResult::AnalyzeIndirectGlobalMemory(GlobalVariable *GV) {
|
||||
// Keep track of values related to the allocation of the memory, f.e. the
|
||||
// value produced by the malloc call and any casts.
|
||||
// value produced by the noalias call and any casts.
|
||||
std::vector<Value *> AllocRelatedValues;
|
||||
|
||||
// If the initializer is a valid pointer, bail.
|
||||
|
@ -438,7 +438,7 @@ bool GlobalsAAResult::AnalyzeIndirectGlobalMemory(GlobalVariable *GV) {
|
|||
// Check the value being stored.
|
||||
Value *Ptr = getUnderlyingObject(SI->getOperand(0));
|
||||
|
||||
if (!isAllocLikeFn(Ptr, &GetTLI(*SI->getFunction())))
|
||||
if (!isNoAliasCall(Ptr))
|
||||
return false; // Too hard to analyze.
|
||||
|
||||
// Analyze all uses of the allocation. If any of them are used in a
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
@G = internal global i32* null ; <i32**> [#uses=3]
|
||||
|
||||
declare i8* @malloc(i32)
|
||||
declare noalias i8* @malloc(i32)
|
||||
define void @malloc_init() {
|
||||
; CHECK-LABEL: @malloc_init(
|
||||
; CHECK-NEXT: [[A:%.*]] = call dereferenceable_or_null(4) i8* @malloc(i32 4)
|
||||
|
@ -36,7 +36,7 @@ define i32 @malloc_test(i32* %P) {
|
|||
|
||||
@G2 = internal global i32* null ; <i32**> [#uses=3]
|
||||
|
||||
declare i8* @calloc(i32, i32)
|
||||
declare noalias i8* @calloc(i32, i32)
|
||||
define void @calloc_init() {
|
||||
; CHECK-LABEL: @calloc_init(
|
||||
; CHECK-NEXT: [[A:%.*]] = call dereferenceable_or_null(4) i8* @calloc(i32 4, i32 1)
|
||||
|
@ -80,12 +80,8 @@ define void @my_alloc_init() {
|
|||
|
||||
define i32 @my_alloc_test(i32* %P) {
|
||||
; CHECK-LABEL: @my_alloc_test(
|
||||
; CHECK-NEXT: [[G1:%.*]] = load i32*, i32** @G3, align 8
|
||||
; CHECK-NEXT: [[H1:%.*]] = load i32, i32* [[G1]], align 4
|
||||
; CHECK-NEXT: store i32 123, i32* [[P:%.*]], align 4
|
||||
; CHECK-NEXT: [[H2:%.*]] = load i32, i32* [[G1]], align 4
|
||||
; CHECK-NEXT: [[X:%.*]] = sub i32 [[H1]], [[H2]]
|
||||
; CHECK-NEXT: ret i32 [[X]]
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
%g1 = load i32*, i32** @G3 ; <i32*> [#uses=2]
|
||||
%h1 = load i32, i32* %g1 ; <i32> [#uses=1]
|
||||
|
|
Loading…
Reference in New Issue