mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
[Attributor] Deduce "noalias" attribute
Summary: This patch adds very basic deduction for noalias. Reviewers: jdoerfert, sstefan1 Reviewed By: jdoerfert Tags: LLVM Differential Revision: https://reviews.llvm.org/D66207 llvm-svn: 370295
This commit is contained in:
parent
9699027971
commit
2f43095878
@ -1559,6 +1559,12 @@ struct AANoAliasImpl : AANoAlias {
|
|||||||
struct AANoAliasFloating final : AANoAliasImpl {
|
struct AANoAliasFloating final : AANoAliasImpl {
|
||||||
AANoAliasFloating(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
|
AANoAliasFloating(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
|
||||||
|
|
||||||
|
/// See AbstractAttribute::initialize(...).
|
||||||
|
void initialize(Attributor &A) override {
|
||||||
|
// TODO: It isn't sound to initialize as the same with `AANoAliasImpl`
|
||||||
|
// because `noalias` may not be valid in the current position.
|
||||||
|
}
|
||||||
|
|
||||||
/// See AbstractAttribute::updateImpl(...).
|
/// See AbstractAttribute::updateImpl(...).
|
||||||
ChangeStatus updateImpl(Attributor &A) override {
|
ChangeStatus updateImpl(Attributor &A) override {
|
||||||
// TODO: Implement this.
|
// TODO: Implement this.
|
||||||
@ -1572,14 +1578,10 @@ struct AANoAliasFloating final : AANoAliasImpl {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// NoAlias attribute for an argument.
|
/// NoAlias attribute for an argument.
|
||||||
struct AANoAliasArgument final : AANoAliasImpl {
|
struct AANoAliasArgument final
|
||||||
AANoAliasArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
|
: AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
|
||||||
|
AANoAliasArgument(const IRPosition &IRP)
|
||||||
/// See AbstractAttribute::updateImpl(...).
|
: AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>(IRP) {}
|
||||||
ChangeStatus updateImpl(Attributor &A) override {
|
|
||||||
// TODO: Implement this.
|
|
||||||
return indicatePessimisticFixpoint();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// See AbstractAttribute::trackStatistics()
|
/// See AbstractAttribute::trackStatistics()
|
||||||
void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
|
void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
|
||||||
@ -1588,6 +1590,12 @@ struct AANoAliasArgument final : AANoAliasImpl {
|
|||||||
struct AANoAliasCallSiteArgument final : AANoAliasImpl {
|
struct AANoAliasCallSiteArgument final : AANoAliasImpl {
|
||||||
AANoAliasCallSiteArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
|
AANoAliasCallSiteArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
|
||||||
|
|
||||||
|
/// See AbstractAttribute::initialize(...).
|
||||||
|
void initialize(Attributor &A) override {
|
||||||
|
// TODO: It isn't sound to initialize as the same with `AANoAliasImpl`
|
||||||
|
// because `noalias` may not be valid in the current position.
|
||||||
|
}
|
||||||
|
|
||||||
/// See AbstractAttribute::updateImpl(...).
|
/// See AbstractAttribute::updateImpl(...).
|
||||||
ChangeStatus updateImpl(Attributor &A) override {
|
ChangeStatus updateImpl(Attributor &A) override {
|
||||||
// TODO: Implement this.
|
// TODO: Implement this.
|
||||||
@ -2814,6 +2822,9 @@ void Attributor::identifyDefaultAbstractAttributes(
|
|||||||
// Every argument with pointer type might be marked nonnull.
|
// Every argument with pointer type might be marked nonnull.
|
||||||
checkAndRegisterAA<AANonNullArgument>(ArgPos, *this, Whitelist);
|
checkAndRegisterAA<AANonNullArgument>(ArgPos, *this, Whitelist);
|
||||||
|
|
||||||
|
// Every argument with pointer type might be marked noalias.
|
||||||
|
checkAndRegisterAA<AANoAliasArgument>(ArgPos, *this, Whitelist);
|
||||||
|
|
||||||
// Every argument with pointer type might be marked dereferenceable.
|
// Every argument with pointer type might be marked dereferenceable.
|
||||||
checkAndRegisterAA<AADereferenceableArgument>(ArgPos, *this, Whitelist);
|
checkAndRegisterAA<AADereferenceableArgument>(ArgPos, *this, Whitelist);
|
||||||
|
|
||||||
@ -2879,6 +2890,10 @@ void Attributor::identifyDefaultAbstractAttributes(
|
|||||||
checkAndRegisterAA<AANonNullCallSiteArgument>(CSArgPos, *this,
|
checkAndRegisterAA<AANonNullCallSiteArgument>(CSArgPos, *this,
|
||||||
Whitelist);
|
Whitelist);
|
||||||
|
|
||||||
|
// Call site argument attribute "no-alias".
|
||||||
|
checkAndRegisterAA<AANoAliasCallSiteArgument>(CSArgPos, *this,
|
||||||
|
Whitelist);
|
||||||
|
|
||||||
// Call site argument attribute "dereferenceable".
|
// Call site argument attribute "dereferenceable".
|
||||||
checkAndRegisterAA<AADereferenceableCallSiteArgument>(CSArgPos, *this,
|
checkAndRegisterAA<AADereferenceableCallSiteArgument>(CSArgPos, *this,
|
||||||
Whitelist);
|
Whitelist);
|
||||||
|
49
test/Transforms/FunctionAttrs/internal-noalias.ll
Normal file
49
test/Transforms/FunctionAttrs/internal-noalias.ll
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
; RUN: opt -S -attributor -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=9 < %s | FileCheck %s
|
||||||
|
|
||||||
|
define dso_local i32 @visible(i32* noalias %A, i32* noalias %B) #0 {
|
||||||
|
entry:
|
||||||
|
%call1 = call i32 @noalias_args(i32* %A, i32* %B)
|
||||||
|
%call2 = call i32 @noalias_args_argmem(i32* %A, i32* %B)
|
||||||
|
%add = add nsw i32 %call1, %call2
|
||||||
|
ret i32 %add
|
||||||
|
}
|
||||||
|
|
||||||
|
; FIXME: Should be something like this.
|
||||||
|
; define internal i32 @noalias_args(i32* nocapture readonly %A, i32* noalias nocapture readonly %B)
|
||||||
|
; CHECK: define internal i32 @noalias_args(i32* %A, i32* %B)
|
||||||
|
|
||||||
|
define internal i32 @noalias_args(i32* %A, i32* %B) #0 {
|
||||||
|
entry:
|
||||||
|
%0 = load i32, i32* %A, align 4
|
||||||
|
%1 = load i32, i32* %B, align 4
|
||||||
|
%add = add nsw i32 %0, %1
|
||||||
|
%call = call i32 @noalias_args_argmem(i32* %A, i32* %B)
|
||||||
|
%add2 = add nsw i32 %add, %call
|
||||||
|
ret i32 %add2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
; FIXME: Should be something like this.
|
||||||
|
; define internal i32 @noalias_args_argmem(i32* noalias nocapture readonly %A, i32* noalias nocapture readonly %B)
|
||||||
|
; CHECK: define internal i32 @noalias_args_argmem(i32* %A, i32* %B)
|
||||||
|
;
|
||||||
|
define internal i32 @noalias_args_argmem(i32* %A, i32* %B) #1 {
|
||||||
|
entry:
|
||||||
|
%0 = load i32, i32* %A, align 4
|
||||||
|
%1 = load i32, i32* %B, align 4
|
||||||
|
%add = add nsw i32 %0, %1
|
||||||
|
ret i32 %add
|
||||||
|
}
|
||||||
|
|
||||||
|
define dso_local i32 @visible_local(i32* %A) #0 {
|
||||||
|
entry:
|
||||||
|
%B = alloca i32, align 4
|
||||||
|
store i32 5, i32* %B, align 4
|
||||||
|
%call1 = call i32 @noalias_args(i32* %A, i32* nonnull %B)
|
||||||
|
%call2 = call i32 @noalias_args_argmem(i32* %A, i32* nonnull %B)
|
||||||
|
%add = add nsw i32 %call1, %call2
|
||||||
|
ret i32 %add
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes #0 = { noinline nounwind uwtable willreturn }
|
||||||
|
attributes #1 = { argmemonly noinline nounwind uwtable willreturn}
|
@ -138,3 +138,40 @@ define i8* @test8(i32* %0) nounwind uwtable {
|
|||||||
5: ; preds = %1, %4
|
5: ; preds = %1, %4
|
||||||
ret i8* %2
|
ret i8* %2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; TEST 9
|
||||||
|
; Simple Argument Test
|
||||||
|
define internal void @test9(i8* %a, i8* %b) {
|
||||||
|
; FIXME: missing noalias
|
||||||
|
; CHECK: define internal void @test9(i8* %a, i8* %b)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
define void @test9_helper(i8* %a, i8* %b) {
|
||||||
|
tail call void @test9(i8* noalias %a, i8* %b)
|
||||||
|
tail call void @test9(i8* noalias %b, i8* noalias %a)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
; TEST 10
|
||||||
|
; Simple CallSite Test
|
||||||
|
|
||||||
|
declare void @test10_helper(i8* %a)
|
||||||
|
define void @test10(i8* noalias %a) {
|
||||||
|
; CHECK: define void @test10(i8* noalias %a)
|
||||||
|
; FIXME: missing noalias
|
||||||
|
; CHECK-NEXT: tail call void @test10_helper(i8* %a)
|
||||||
|
tail call void @test10_helper(i8* %a)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; TEST 11
|
||||||
|
; CallSite Test
|
||||||
|
|
||||||
|
declare void @test11_helper(i8* %a, i8 *%b)
|
||||||
|
define void @test11(i8* noalias %a) {
|
||||||
|
; CHECK: define void @test11(i8* noalias %a)
|
||||||
|
; CHECK-NEXT: tail call void @test11_helper(i8* %a, i8* %a)
|
||||||
|
tail call void @test11_helper(i8* %a, i8* %a)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user