1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
|
; RUN: opt %loadPolly -basic-aa -polly-scops -analyze < %s | FileCheck %s
; RUN: opt %loadPolly -basic-aa -polly-function-scops -analyze < %s | FileCheck %s
; ModuleID = 'scalar_to_array.ll'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
@A = common global [1024 x float] zeroinitializer, align 8
; Terminating loops without side-effects will be optimzied away, hence
; detecting a scop would be pointless.
; CHECK-NOT: Function: empty
; Function Attrs: nounwind
define i32 @empty() #0 {
entry:
fence seq_cst
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
%exitcond = icmp ne i64 %indvar, 1024
br i1 %exitcond, label %for.body, label %return
for.body: ; preds = %for.cond
br label %for.inc
for.inc: ; preds = %for.body
%indvar.next = add i64 %indvar, 1
br label %for.cond
return: ; preds = %for.cond
fence seq_cst
ret i32 0
}
; CHECK-LABEL: Function: array_access
; Function Attrs: nounwind
define i32 @array_access() #0 {
entry:
fence seq_cst
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
%exitcond = icmp ne i64 %indvar, 1024
br i1 %exitcond, label %for.body, label %return
for.body: ; preds = %for.cond
%arrayidx = getelementptr [1024 x float], [1024 x float]* @A, i64 0, i64 %indvar
%float = uitofp i64 %indvar to float
store float %float, float* %arrayidx
br label %for.inc
; CHECK: Stmt_for_body
; CHECK-NOT: ReadAccess
; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_for_body[i0] -> MemRef_A[i0] };
for.inc: ; preds = %for.body
%indvar.next = add i64 %indvar, 1
br label %for.cond
return: ; preds = %for.cond
fence seq_cst
ret i32 0
}
; Function Attrs: nounwind
; CHECK-LABEL: Function: intra_scop_dep
define i32 @intra_scop_dep() #0 {
entry:
fence seq_cst
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
%exitcond = icmp ne i64 %indvar, 1024
br i1 %exitcond, label %for.body.a, label %return
for.body.a: ; preds = %for.cond
%arrayidx = getelementptr [1024 x float], [1024 x float]* @A, i64 0, i64 %indvar
%scalar = load float, float* %arrayidx
br label %for.body.b
; CHECK: Stmt_for_body_a
; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_for_body_a[i0] -> MemRef_A[i0] };
; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: { Stmt_for_body_a[i0] -> MemRef_scalar[] };
for.body.b: ; preds = %for.body.a
%arrayidx2 = getelementptr [1024 x float], [1024 x float]* @A, i64 0, i64 %indvar
%float = uitofp i64 %indvar to float
%sum = fadd float %scalar, %float
store float %sum, float* %arrayidx2
br label %for.inc
; CHECK: Stmt_for_body_b
; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: { Stmt_for_body_b[i0] -> MemRef_scalar[] };
; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_for_body_b[i0] -> MemRef_A[i0] };
for.inc: ; preds = %for.body.b
%indvar.next = add i64 %indvar, 1
br label %for.cond
return: ; preds = %for.cond
fence seq_cst
ret i32 0
}
; It is not possible to have a scop which accesses a scalar element that is
; a global variable. All global variables are pointers containing possibly
; a single element. Hence they do not need to be handled anyways.
; Please note that this is still required when scalar to array rewritting is
; disabled.
; CHECK-LABEL: Function: use_after_scop
; Function Attrs: nounwind
define i32 @use_after_scop() #0 {
entry:
%scalar.s2a = alloca float
fence seq_cst
br label %for.head
for.head: ; preds = %for.inc, %entry
%indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
br label %for.body
for.body: ; preds = %for.head
%arrayidx = getelementptr [1024 x float], [1024 x float]* @A, i64 0, i64 %indvar
%scalar = load float, float* %arrayidx
store float %scalar, float* %scalar.s2a
; Escaped uses are still required to be rewritten to stack variable.
; CHECK: Stmt_for_body
; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_for_body[i0] -> MemRef_A[i0] };
; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_for_body[i0] -> MemRef_scalar_s2a[0] };
br label %for.inc
for.inc: ; preds = %for.body
%indvar.next = add i64 %indvar, 1
%exitcond = icmp ne i64 %indvar.next, 1024
br i1 %exitcond, label %for.head, label %for.after
for.after: ; preds = %for.inc
%scalar.loadoutside = load float, float* %scalar.s2a
fence seq_cst
%return_value = fptosi float %scalar.loadoutside to i32
br label %return
return: ; preds = %for.after
ret i32 %return_value
}
; We currently do not transform scalar references, that have only read accesses
; in the scop. There are two reasons for this:
;
; o We don't introduce additional memory references which may yield to compile
; time overhead.
; o For integer values, such a translation may block the use of scalar
; evolution on those values.
;
; CHECK-LABEL: Function: before_scop
; Function Attrs: nounwind
define i32 @before_scop() #0 {
entry:
br label %preheader
preheader: ; preds = %entry
%scalar = fadd float 4.000000e+00, 5.000000e+00
fence seq_cst
br label %for.cond
for.cond: ; preds = %for.inc, %preheader
%indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %preheader ]
%exitcond = icmp ne i64 %indvar, 1024
br i1 %exitcond, label %for.body, label %return
for.body: ; preds = %for.cond
%arrayidx = getelementptr [1024 x float], [1024 x float]* @A, i64 0, i64 %indvar
store float %scalar, float* %arrayidx
br label %for.inc
; CHECK: Stmt_for_body
; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_for_body[i0] -> MemRef_A[i0] };
for.inc: ; preds = %for.body
%indvar.next = add i64 %indvar, 1
br label %for.cond
return: ; preds = %for.cond
fence seq_cst
ret i32 0
}
attributes #0 = { nounwind }
|