forked from JuliaSIMD/LoopVectorization.jl
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtransforms.jl
More file actions
141 lines (132 loc) · 4.26 KB
/
Copy pathtransforms.jl
File metadata and controls
141 lines (132 loc) · 4.26 KB
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
# file for misc loopset transforms
function hoist_constant_memory_accesses!(ls::LoopSet)
hoist_stores = false
for op ∈ operations(ls)
if isload(op)
length(getindicesonly(op)) == 0 && hoist_constant_vload!(ls, op)
elseif isstore(op) && iszero(length(getindicesonly(op)))
hoist_stores = true
end
end
hoist_stores && return hoist_constant_memory_accesses_nocheck!(ls)
ls.preamble
end
function hoist_constant_memory_accesses_nocheck!(ls::LoopSet)
post = Expr(:block)
for op ∈ operations(ls)
if isstore(op) && length(getindicesonly(op)) == 0
hoist_constant_store!(post, ls, op)
end
end
post
end
function hoist_constant_vload!(ls::LoopSet, op::Operation)
op.instr = LOOPCONSTANT
op.node_type = constant
add_constant_vload!(
ls,
op,
ArrayReferenceMetaPosition(
op.ref,
parents(op),
loopdependencies(op),
reduceddependencies(op),
name(op),
),
elementbytes,
)
end
function return_empty_reductinit(op::Operation, var::Symbol)
for opp ∈ parents(op)
if (name(opp) === var) &&
(length(reduceddependencies(opp)) == 0) &&
(length(loopdependencies(opp)) == 0) &&
(length(children(opp)) == 1)
return opp
end
opcheck = return_empty_reductinit(opp, var)
opcheck === opp || return opcheck
end
return op
end
function constant_symbol!(ls::LoopSet, op::Operation)
# hack
# relowers, but should make it work
# TODO: DRY with `lower_licm_constants!` from `src/codegen/lower_constants.jl`
skip_constant(instruction(op)) || return instruction(op).instr
idcheck = identifier(op)
symname = constantopname(op)
for (id, sym) ∈ ls.preamble_symsym
(idcheck ≢ nothing) && ((idcheck == id) && continue)
pushpreamble!(ls, Expr(:(=), symname, sym))
return symname
# setconstantop!(ls, op, sym)
# setconstantop!(ls, op, Expr(:call, lv(:maybeconvert), ls.T, sym))
end
for (id, (intval, intsz, signed)) ∈ ls.preamble_symint
(idcheck ≢ nothing) && ((idcheck == id) && continue)
if intsz == 1
pushpreamble!(ls, Expr(:(=), symname, intval % Bool))
else
pushpreamble!(ls, Expr(:(=), symname, sizeequivalent_symint_expr(intval, signed)))
end
return symname
end
for (id, floatval) ∈ ls.preamble_symfloat
(idcheck ≢ nothing) && ((idcheck == id) && continue)
pushpreamble!(
ls,
Expr(:(=), symname, Expr(:call, lv(:sizeequivalentfloat), ELTYPESYMBOL, floatval)),
)
return symname
end
for (id, typ) ∈ ls.preamble_zeros
(idcheck ≢ nothing) && ((idcheck == id) && continue)
instruction(op) === LOOPCONSTANT || continue
if typ == IntOrFloat
pushpreamble!(ls, Expr(:(=), symname, Expr(:call, :zero, ELTYPESYMBOL)))
elseif typ == HardInt
pushpreamble!(ls, Expr(:(=), symname, Expr(:call, lv(:zerointeger), ELTYPESYMBOL)))
else#if typ == HardFloat
pushpreamble!(ls, Expr(:(=), symname, Expr(:call, lv(:zerofloat), ELTYPESYMBOL)))
end
return symname
end
for (id, f) ∈ ls.preamble_funcofeltypes
(idcheck ≢ nothing) && ((idcheck == id) && continue)
pushpreamble!(ls, Expr(:(=), symname, Expr(:call, reduction_zero(f), ELTYPESYMBOL)))
return symname
end
throw("Constant operation symbol not found.")
end
function hoist_constant_store!(q::Expr, ls::LoopSet, op::Operation)
op.instruction = DROPPEDCONSTANT
op.node_type = constant
opr = only(parents(op))
while opr.instruction.instr === :identity
opr.instruction = DROPPEDCONSTANT
opr.node_type = constant
opr = only(parents(opr))
end
push!(ls.outer_reductions, identifier(opr))
initop = return_empty_reductinit(opr, name(opr))
# @show last(ls.preamble.args)
init = constant_symbol!(ls, initop)
# @show last(ls.preamble.args)
pushpreamble!(
ls,
Expr(:(=), outer_reduct_init_typename(opr), Expr(:call, lv(:typeof), init)),
)
qpre = Expr(:block)
push!(
q.args,
Expr(
:call,
lv(:unsafe_store!),
Expr(:call, lv(:pointer), op.ref.ptr),
outer_reduction_to_scalar_reduceq!(qpre, opr, init),
),
)
length(qpre.args) == 0 || pushpreamble!(ls, qpre) # creating `Expr` and pushing because `outer_reduction_to_scalar_reduceq!` uses `pushfirst!(q.args`, and we don't want it at the start of the preamble
return nothing
end