1
1
2
-
3
-
4
2
function uniquearrayrefs_csesummary (ls:: LoopSet )
5
3
uniquerefs = ArrayReferenceMeta[]
6
4
# each `Vector{Tuple{Int,Int}}` has the same name
@@ -195,43 +193,83 @@ function substitute_ops_all!(
195
193
end
196
194
end
197
195
end
198
- function normalize_offsets! (
199
- ls:: LoopSet , i:: Int , allarrayrefs:: Vector{ArrayReferenceMeta} ,
200
- array_refs_with_same_name:: Vector{Int} , arrayref_to_name_op_collection:: Vector{Vector{Tuple{Int,Int,Int}}}
201
- )
202
- ops = operations (ls)
203
- length (ops) > 128 && return 0
204
- minoffset:: Int8 = typemax (Int8)
205
- maxoffset:: Int8 = typemin (Int8)
206
- # we want to store the offsets, because we don't want to require that the `offset` vectors of the variaous `ArrayReferenceMeta`s don't alias
207
- offsets:: Base.RefValue{NTuple{128,Int8}} = Base. RefValue {NTuple{128,Int8}} ();
208
- GC. @preserve offsets begin
209
- poffsets = Base. unsafe_convert (Ptr{Int8}, offsets)
210
- for j ∈ array_refs_with_same_name
211
- arrayref_to_name_op = arrayref_to_name_op_collection[j]
212
- for (_,__,opid) ∈ arrayref_to_name_op
213
- op = ops[opid]
214
- off = getoffsets (op. ref)[i]
215
- off == zero (Int8) && return 0
216
- minoffset = min (off, minoffset)
217
- maxoffset = max (off, maxoffset)
218
- unsafe_store! (poffsets, off, opid)
219
- end
220
- end
221
- # reaching here means none of the offsets contain `0`
222
- # we won't bother if difference between offsets is >127
223
- # we don't want `maxoffset` to overflow when subtracting `minoffset`
224
- # so we check if it's safe, and give up if it isn't
225
- (Int (maxoffset) - Int (minoffset)) > 127 && return 0
226
- for j ∈ array_refs_with_same_name
227
- arrayref_to_name_op = arrayref_to_name_op_collection[j]
228
- for (_,__,opid) ∈ arrayref_to_name_op
229
- getoffsets (ops[opid]. ref)[i] = unsafe_load (poffsets, opid) - minoffset
230
- end
231
- end
232
- end
233
- return Int (minoffset)
234
- end
196
+ # function normalize_offsets!(
197
+ # ls::LoopSet, i::Int, allarrayrefs::Vector{ArrayReferenceMeta},
198
+ # array_refs_with_same_name::Vector{Int}, arrayref_to_name_op_collection::Vector{Vector{Tuple{Int,Int,Int}}}
199
+ # )
200
+ # ops = operations(ls)
201
+ # length(ops) > 256 && return 0
202
+ # minoffset::Int8 = typemax(Int8)
203
+ # maxoffset::Int8 = typemin(Int8)
204
+ # # we want to store the offsets, because we don't want to require that the `offset` vectors of the variaous `ArrayReferenceMeta`s don't alias
205
+ # # loopsym = Symbol("##DUMMY##NOT#REALLY#A#LOOP##")
206
+ # # stride::Int = typemin(Int)
207
+ # # thereiszerooffset::Bool = false
208
+ # # offsets::Base.RefValue{NTuple{128,Int8}} = Base.RefValue{NTuple{128,Int8}}();
209
+ # # GC.@preserve offsets begin
210
+ # # poffsets = Base.unsafe_convert(Ptr{Int8}, offsets)
211
+ # for j ∈ array_refs_with_same_name
212
+ # arrayref_to_name_op = arrayref_to_name_op_collection[j]
213
+ # for (_,__,opid) ∈ arrayref_to_name_op
214
+ # op = ops[opid]
215
+ # opref = op.ref
216
+ # off = getoffsets(opref)[i]
217
+ # # thereiszerooffset |= off == zero(Int8)
218
+ # # off == zero(Int8) && return 0
219
+ # minoffset = min(off, minoffset)
220
+ # maxoffset = max(off, maxoffset)
221
+ # # unsafe_store!(poffsets, off, opid)
222
+ # # if loopsym ≢ Symbol("##DUMMY##NOT#REALLY#A#LOOP##")
223
+ # # stride = Int(getstrides(opref)[i])
224
+ # # if opref.loopedindex[i]
225
+ # # loopsym = getindicesonly(op)[i]
226
+ # # else
227
+ # # loopsym = Symbol("##NOT#A#LOOP##")
228
+ # # end
229
+ # # end
230
+ # end
231
+ # end
232
+ # # reaching here means none of the offsets contain `0`
233
+ # # we won't bother if difference between offsets is >127
234
+ # # we don't want `maxoffset` to overflow when subtracting `minoffset`
235
+ # # so we check if it's safe, and give up if it isn't
236
+ # minoffsetint = Int(minoffset)
237
+ # return (((Int(maxoffset) - minoffsetint) > 127)) ? 0 : minoffsetint
238
+
239
+ # # # if loopsym ≢ Symbol("##DUMMY##NOT#REALLY#A#LOOP##")
240
+ # # # loop = getloop(ls, loopsym)
241
+ # # # if minstride ≠ maxstride
242
+ # # # @assert isknown(first(loop)) "Currently, if the same index is used for the same array with different multiples (e.g., `x[i]` and `x[2*i]`), then the start of that loop range must be known at compile time."
243
+ # # # end
244
+ # # # stride_offset = 1 - gethint(first(loop))
245
+ # # # else
246
+ # # # loop = first(ls.loops)
247
+ # # # end
248
+ # # offset_adjust = Int(minoffset)
249
+ # # if (loopsym ≢ Symbol("##DUMMY##NOT#REALLY#A#LOOP##")) && (loopsym ≢ Symbol("##NOT#A#LOOP##"))
250
+ # # loopstart = first(getloop(ls, loopsym))
251
+ # # if isknown(loopstart)
252
+ # # loopstartval = gethint(loopstart)
253
+ # # offset_adjust = loopstartval*(stride - 1)
254
+ # # if offset_adjust + Int(maxoffset) ≤ typemax(Int8)
255
+ # # minoffset -= Int8(offset_adjust)
256
+ # # stride = 1
257
+ # # end
258
+ # # end
259
+ # # end
260
+ # # for j ∈ array_refs_with_same_name
261
+ # # arrayref_to_name_op = arrayref_to_name_op_collection[j]
262
+ # # for (_,__,opid) ∈ arrayref_to_name_op
263
+ # # new_offset = unsafe_load(poffsets, opid) - minoffset
264
+ # # old_offset = getoffsets(ops[opid].ref)[i]
265
+ # # @show new_offset, old_offset
266
+ # # getoffsets(ops[opid].ref)[i] = new_offset
267
+ # # # getoffsets(ops[opid].ref)[i] = unsafe_load(poffsets, opid) - minoffset
268
+ # # end
269
+ # # end
270
+ # # end
271
+ # # return @show offset_adjust, stride
272
+ # end
235
273
function isloopvalue (ls:: LoopSet , ind:: Symbol , isrooted:: Union{Nothing,Vector{Bool}} = nothing )
236
274
for (i,op) ∈ enumerate (operations (ls))
237
275
if (isrooted ≢ nothing )
@@ -260,7 +298,7 @@ function cse_constant_offsets!(
260
298
strides = getstrides (ar)
261
299
offset = first (indices) === DISCONTIGUOUS
262
300
# gespindoffsets = fill(Symbol(""), length(li))
263
- gespindsummary = Vector {Tuple{ Symbol,Int} } (undef, length (li))
301
+ gespindsummary = Vector {Symbol} (undef, length (li))
264
302
for i ∈ eachindex (li)
265
303
gespsymbol:: Symbol = Symbol (" " )
266
304
ii = i + offset
@@ -377,9 +415,9 @@ function cse_constant_offsets!(
377
415
end
378
416
end
379
417
end
380
- constoffset = normalize_offsets! (ls, i, allarrayrefs, array_refs_with_same_name, arrayref_to_name_op_collection)
381
- gespindsummary[i] = (gespsymbol, constoffset)
382
- # pushgespind!(gespinds, ls, gespsymbol, constoffset, ind, li, i, check_shouldindbyind(ls, ind, shouldindbyind), true)
418
+ # constoffset = normalize_offsets!(ls, i, allarrayrefs, array_refs_with_same_name, arrayref_to_name_op_collection)
419
+ # gespindsummary[i] = (gespsymbol, constoffset)
420
+ gespindsummary[i] = gespsymbol
383
421
end
384
422
return gespindsummary
385
423
end
@@ -400,20 +438,97 @@ end
400
438
# end
401
439
# return nothing
402
440
# end
403
- function calcgespinds (ls:: LoopSet , ar:: ArrayReferenceMeta , gespindsummary:: Vector{Tuple{Symbol,Int}} , shouldindbyind:: Vector{Bool} )
441
+ function adjust_offsets! (
442
+ ls:: LoopSet , i:: Int ,
443
+ array_refs_with_same_name:: Vector{Int} , arrayref_to_name_op_collection:: Vector{Vector{Tuple{Int,Int,Int}}}
444
+ )
445
+ ops = operations (ls)
446
+ @assert length (ops) ≤ 256
447
+ offsets:: Base.RefValue{NTuple{256,Int8}} = Base. RefValue {NTuple{256,Int8}} ();
448
+ GC. @preserve offsets begin
449
+ poffsets = Base. unsafe_convert (Ptr{Int8}, offsets)
450
+ minoffset = typemax (Int8)
451
+ maxoffset = typemin (Int8)
452
+ # stridesunequal = false
453
+ for j ∈ array_refs_with_same_name
454
+ arrayref_to_name_op = arrayref_to_name_op_collection[j]
455
+ for (_,__,opid) ∈ arrayref_to_name_op
456
+ opref = ops[opid]. ref
457
+ off = getoffsets (opref)[i]
458
+ minoffset = min (off, minoffset)
459
+ maxoffset = max (off, maxoffset)
460
+ unsafe_store! (poffsets, off, opid)
461
+ # stridesunequal |= (stride ≠ getstrides(opref)[i])
462
+ end
463
+ end
464
+ constoffset = Int (minoffset)
465
+ constoffset = Core. ifelse (Int (maxoffset) - constoffset > 127 , 0 , constoffset)
466
+ if constoffset ≠ 0
467
+ for j ∈ array_refs_with_same_name
468
+ arrayref_to_name_op = arrayref_to_name_op_collection[j]
469
+ for (_,__,opid) ∈ arrayref_to_name_op
470
+ opref = ops[opid]. ref
471
+ newoffset = unsafe_load (poffsets, opid) - constoffset
472
+ # if stridesunequal
473
+ # stride = getstrides(opref)[i]
474
+ # newoffsetint = Int(newoffset) + (Int(stride) - 1)
475
+ # # @assert typemin(Int8) ≤ newoffsetint ≤ typemax(Int8)
476
+ # newoffset = Int8(newoffsetint)
477
+ # end
478
+ getoffsets (ops[opid]. ref)[i] = newoffset
479
+ end
480
+ end
481
+ end
482
+ end
483
+ constoffset# , Core.ifelse(stridesunequal, 1, Int(stride))
484
+ end
485
+
486
+ function calcgespinds (
487
+ ls:: LoopSet , ar:: ArrayReferenceMeta , gespindsummary:: Vector{Symbol} , shouldindbyind:: Vector{Bool} ,
488
+ array_refs_with_same_name:: Vector{Int} , arrayref_to_name_op_collection:: Vector{Vector{Tuple{Int,Int,Int}}}
489
+ )
404
490
gespinds = Expr (:tuple )
405
491
li = ar. loopedindex
406
492
indices = getindicesonly (ar)
493
+ # offsets = getoffsets(ar)
494
+ strides = getstrides (ar)
407
495
for i ∈ eachindex (li)
408
496
ind = indices[i]
409
- gespsymbol, constoffset = gespindsummary[i]
410
- pushgespind! (gespinds, ls, gespsymbol, constoffset, ind, li[i], check_shouldindbyind (ls, ind, shouldindbyind), true )
497
+ isli = li[i]
498
+ gespsymbol = gespindsummary[i]
499
+ # if isli & (!index_by_index) && (length(operations(ls)) ≤ 256)
500
+ # ops = operations(ls)
501
+ # loopfirst = first(getloop(ls, ind))
502
+ # if isknown(loopfirst)
503
+ # # copy in case of aliasing
504
+ # end
505
+ # end
506
+ # constoffset ≠ 0 &&
507
+ constoffset = adjust_offsets! (ls, i, array_refs_with_same_name, arrayref_to_name_op_collection)
508
+ index_by_index = isli ? check_shouldindbyind (ls, ind, shouldindbyind) : true
509
+ # (stridesunequal & isli) && (@assert isknown(first(getloop(ls, ind))))
510
+
511
+ # end
512
+ # stride = strides[i]
513
+ # if stride ≠ 1
514
+ # loop = getloop(ls, ind)
515
+ # if isknown(first(loop))
516
+ # offsets[i] -= gethint(first(loop))
517
+ # end
518
+ # end
519
+ # # for op ∈ operations(ls)
520
+ # # accesses_memory(op) || continue
521
+ # # sameref(op.ref, ref) || continue
522
+ # # getstrides(op)
523
+ # # end
524
+ # end
525
+ pushgespind! (gespinds, ls, gespsymbol, constoffset, Int (strides[i]), ind, isli, index_by_index, true )
411
526
end
412
527
gespinds
413
528
end
414
529
415
530
function pushgespind! (
416
- gespinds:: Expr , ls:: LoopSet , gespsymbol:: Symbol , constoffset:: Int , ind:: Symbol , isli:: Bool , index_by_index:: Bool , fromgsp:: Bool
531
+ gespinds:: Expr , ls:: LoopSet , gespsymbol:: Symbol , constoffset:: Int , stride :: Int , ind:: Symbol , isli:: Bool , index_by_index:: Bool , fromgsp:: Bool
417
532
)
418
533
if isli
419
534
if ind === CONSTANTZEROINDEX
@@ -453,21 +568,32 @@ function pushgespind!(
453
568
loop = getloop (ls, ind)
454
569
if gespsymbol === Symbol (" " )
455
570
if isknown (first (loop))
456
- push! (gespinds. args, staticexpr (constoffset + gethint (first (loop))))
571
+ # @show constoffset, gethint(first(loop))
572
+ push! (gespinds. args, staticexpr (constoffset + stride* gethint (first (loop))))
457
573
elseif constoffset == 0
458
- push! (gespinds. args, getsym (first (loop)))
459
- else
574
+ if stride == 1
575
+ push! (gespinds. args, getsym (first (loop)))
576
+ else
577
+ push! (gespinds. args, mulexpr (getsym (first (loop)), stride))
578
+ end
579
+ elseif stride == 1
460
580
push! (gespinds. args, addexpr (getsym (first (loop)), constoffset))
581
+ else
582
+ push! (gespinds. args, addexpr (mulexpr (getsym (first (loop)), stride), constoffset))
461
583
end
462
584
elseif isknown (first (loop))
463
- loopfirst = gethint (first (loop)) + constoffset
585
+ loopfirst = gethint (first (loop))* stride + constoffset
464
586
if loopfirst == 0
465
587
push! (gespinds. args, gespsymbol)
466
588
else
467
589
push! (gespinds. args, Expr (:call , GlobalRef (Base, :(+ )), gespsymbol, staticexpr (loopfirst)))
468
590
end
469
591
else
470
- addedstarts = Expr (:call , GlobalRef (Base, :(+ )), gespsymbol, getsym (first (loop)))
592
+ addedstarts = if stride == 1
593
+ Expr (:call , GlobalRef (Base, :(+ )), gespsymbol, getsym (first (loop)))
594
+ else
595
+ Expr (:call , GlobalRef (Base, :(+ )), mulexpr (stride, gespsymbol), getsym (first (loop)))
596
+ end
471
597
if constoffset == 0
472
598
push! (gespinds. args, addedstarts)
473
599
else
@@ -563,25 +689,25 @@ function use_loop_induct_var!(
563
689
if ! li[i] # if it wasn't set
564
690
uliv[i] = 0
565
691
push! (offsetprecalc_descript. args, 0 )
566
- Wisz || pushgespind! (gespinds, ls, Symbol (" " ), 0 , ind, isli, true , false )
692
+ Wisz || pushgespind! (gespinds, ls, Symbol (" " ), 0 , 1 , ind, isli, true , false )
567
693
elseif ind === CONSTANTZEROINDEX
568
694
uliv[i] = 0
569
695
push! (offsetprecalc_descript. args, 0 )
570
- Wisz || pushgespind! (gespinds, ls, Symbol (" " ), 0 , ind, isli, true , false )
696
+ Wisz || pushgespind! (gespinds, ls, Symbol (" " ), 0 , 1 , ind, isli, true , false )
571
697
elseif isbroadcast ||
572
698
((isone (ii) && (last (looporder) === ind)) && ! (otherindexunrolled (ls, ind, ar)) ||
573
699
multiple_with_name (vptrar, allarrayrefs)) ||
574
700
(iszero (ls. vector_width) && isstaticloop (getloop (ls, ind)))# ||
575
701
# Not doing normal offset indexing
576
702
uliv[i] = - findfirst (Base. Fix2 (=== ,ind), looporder):: Int
577
703
push! (offsetprecalc_descript. args, 0 ) # not doing offset indexing, so push 0
578
- Wisz || pushgespind! (gespinds, ls, Symbol (" " ), 0 , ind, isli, true , false )
704
+ Wisz || pushgespind! (gespinds, ls, Symbol (" " ), 0 , 1 , ind, isli, true , false )
579
705
else
580
706
uliv[i] = findfirst (Base. Fix2 (=== ,ind), looporder):: Int
581
707
loop = getloop (ls, ind)
582
708
push! (offsetprecalc_descript. args, max (5 ,us. u₁+ 1 ,us. u₂+ 1 ))
583
709
use_offsetprecalc = true
584
- Wisz || pushgespind! (gespinds, ls, Symbol (" " ), 0 , ind, isli, false , false )
710
+ Wisz || pushgespind! (gespinds, ls, Symbol (" " ), 0 , 1 , ind, isli, false , false )
585
711
end
586
712
# cases for pushgespind! and loopval!
587
713
# if !isloopval, same as before
0 commit comments