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 {
|
||||
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(...).
|
||||
ChangeStatus updateImpl(Attributor &A) override {
|
||||
// TODO: Implement this.
|
||||
@ -1572,14 +1578,10 @@ struct AANoAliasFloating final : AANoAliasImpl {
|
||||
};
|
||||
|
||||
/// NoAlias attribute for an argument.
|
||||
struct AANoAliasArgument final : AANoAliasImpl {
|
||||
AANoAliasArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
|
||||
|
||||
/// See AbstractAttribute::updateImpl(...).
|
||||
ChangeStatus updateImpl(Attributor &A) override {
|
||||
// TODO: Implement this.
|
||||
return indicatePessimisticFixpoint();
|
||||
}
|
||||
struct AANoAliasArgument final
|
||||
: AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
|
||||
AANoAliasArgument(const IRPosition &IRP)
|
||||
: AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>(IRP) {}
|
||||
|
||||
/// See AbstractAttribute::trackStatistics()
|
||||
void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
|
||||
@ -1588,6 +1590,12 @@ struct AANoAliasArgument final : AANoAliasImpl {
|
||||
struct AANoAliasCallSiteArgument final : AANoAliasImpl {
|
||||
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(...).
|
||||
ChangeStatus updateImpl(Attributor &A) override {
|
||||
// TODO: Implement this.
|
||||
@ -2814,6 +2822,9 @@ void Attributor::identifyDefaultAbstractAttributes(
|
||||
// Every argument with pointer type might be marked nonnull.
|
||||
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.
|
||||
checkAndRegisterAA<AADereferenceableArgument>(ArgPos, *this, Whitelist);
|
||||
|
||||
@ -2879,6 +2890,10 @@ void Attributor::identifyDefaultAbstractAttributes(
|
||||
checkAndRegisterAA<AANonNullCallSiteArgument>(CSArgPos, *this,
|
||||
Whitelist);
|
||||
|
||||
// Call site argument attribute "no-alias".
|
||||
checkAndRegisterAA<AANoAliasCallSiteArgument>(CSArgPos, *this,
|
||||
Whitelist);
|
||||
|
||||
// Call site argument attribute "dereferenceable".
|
||||
checkAndRegisterAA<AADereferenceableCallSiteArgument>(CSArgPos, *this,
|
||||
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
|
||||
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