@@ -33,22 +33,6 @@ function extreme_var(var_to_diff, v, level = nothing, ::Val{descend} = Val(true)
33
33
level === nothing ? v : (v => level)
34
34
end
35
35
36
- function walk_to_root! (relative_level, iag, v:: Integer , level = 0 )
37
- brs = neighbors (iag, v)
38
- min_var_level = v => level
39
- for (x, lv′) in brs
40
- lv = lv′ + level
41
- x, lv = walk_to_root! (relative_level, iag, x, lv)
42
- relative_level[x] = lv
43
- if min_var_level[2 ] > lv
44
- min_var_level = x => lv
45
- end
46
- end
47
- x, lv = extreme_var (iag. var_to_diff, min_var_level... )
48
- relative_level[x] = lv
49
- return x => lv
50
- end
51
-
52
36
function alias_elimination (sys)
53
37
state = TearingState (sys; quick_cancel = true )
54
38
Main. _state[] = state
@@ -92,39 +76,29 @@ function alias_elimination(sys)
92
76
processed = falses (nvars)
93
77
# iag = InducedAliasGraph(ag, invag, var_to_diff, processed)
94
78
iag = InducedAliasGraph (ag, invag, var_to_diff)
95
- relative_level = BitDict (nvars)
96
79
newag = AliasGraph (nvars)
97
80
for (v, dv) in enumerate (var_to_diff)
98
81
processed[v] && continue
99
82
(dv === nothing && diff_to_var[v] === nothing ) && continue
100
83
101
- # TODO : use an iterator, and get a relative level vector for `processed`
102
- # variabels.
103
- # Note that `rootlv` is non-positive
104
- r, rootlv = walk_to_root! (relative_level, iag, v)
105
- fill! (iag. visited, false )
84
+ r, _ = find_root! (iag, v)
106
85
let
107
86
sv = fullvars[v]
108
87
root = fullvars[r]
109
- @info " Found root $r " sv=> root level= rootlv
110
- for vv in relative_level
111
- @show fullvars[vv[1 ]]
112
- end
88
+ @info " Found root $r " sv=> root
113
89
end
114
90
level_to_var = Int[]
115
91
extreme_var (var_to_diff, r, nothing , Val (false ), callback = Base. Fix1 (push!, level_to_var))
116
92
nlevels = length (level_to_var)
117
93
current_level = Ref (0 )
118
- add_alias! = let current_level = current_level, level_to_var = level_to_var, newag = newag
94
+ add_alias! = let current_level = current_level, level_to_var = level_to_var, newag = newag, processed = processed
119
95
v -> begin
120
96
level = current_level[]
121
- # FIXME : only alias variables in the reachable set
122
97
if level + 1 <= length (level_to_var)
123
98
# TODO : make sure the coefficient is 1
124
99
av = level_to_var[level + 1 ]
125
100
if v != av # if the level_to_var isn't from the root branch
126
101
newag[v] = 1 => av
127
- # @info "create alias" fullvars[v] => fullvars[level_to_var[level + 1]]
128
102
end
129
103
else
130
104
@assert length (level_to_var) == level
@@ -134,13 +108,18 @@ function alias_elimination(sys)
134
108
current_level[] += 1
135
109
end
136
110
end
137
- for (v, rl) in pairs (relative_level)
138
- @assert diff_to_var[v] === nothing
111
+ for (lv, t) in StatefulBFS (RootedAliasTree (iag, r))
112
+ v = nodevalue (t)
113
+ processed[v] = true
139
114
v == r && continue
140
- current_level[] = rl - rootlv
115
+ if lv < length (level_to_var)
116
+ if level_to_var[lv + 1 ] == v
117
+ continue
118
+ end
119
+ end
120
+ current_level[] = lv
141
121
extreme_var (var_to_diff, v, nothing , Val (false ), callback = add_alias!)
142
122
end
143
- empty! (relative_level)
144
123
if nlevels < (new_nlevels = length (level_to_var))
145
124
@assert ! (D isa Nothing)
146
125
for i in (nlevels + 1 ): new_nlevels
@@ -384,6 +363,7 @@ struct IAGNeighbors
384
363
end
385
364
386
365
function Base. iterate (it:: IAGNeighbors , state = nothing )
366
+ Main. _a[] = it, state
387
367
@unpack ag, invag, var_to_diff, visited = it. iag
388
368
callback! = let visited = visited
389
369
var -> visited[var] = true
@@ -424,22 +404,42 @@ function Base.iterate(it::IAGNeighbors, state = nothing)
424
404
end
425
405
end
426
406
visited[v] = true
427
- (v′ = var_to_diff[v]) === nothing && return nothing
428
- v:: Int = v′
407
+ (v = var_to_diff[v]) === nothing && return nothing
429
408
level += 1
430
409
used_ag = false
431
410
end
432
411
end
433
412
434
413
Graphs. neighbors (iag:: InducedAliasGraph , v:: Integer ) = IAGNeighbors (iag, v)
435
414
415
+ function _find_root! (iag:: InducedAliasGraph , v:: Integer , level = 0 )
416
+ brs = neighbors (iag, v)
417
+ min_var_level = v => level
418
+ for (x, lv′) in brs
419
+ lv = lv′ + level
420
+ x, lv = _find_root! (iag, x, lv)
421
+ if min_var_level[2 ] > lv
422
+ min_var_level = x => lv
423
+ end
424
+ end
425
+ x, lv = extreme_var (iag. var_to_diff, min_var_level... )
426
+ return x => lv
427
+ end
428
+
429
+ function find_root! (iag:: InducedAliasGraph , v:: Integer )
430
+ ret = _find_root! (iag, v)
431
+ fill! (iag. visited, false )
432
+ ret
433
+ end
434
+
436
435
struct RootedAliasTree
437
436
iag:: InducedAliasGraph
438
437
root:: Int
439
438
end
440
439
441
440
AbstractTrees. childtype (:: Type{<:RootedAliasTree} ) = Union{RootedAliasTree, Int}
442
441
AbstractTrees. children (rat:: RootedAliasTree ) = RootedAliasChildren (rat)
442
+ AbstractTrees. nodetype (:: Type{<:RootedAliasTree} ) = Int
443
443
AbstractTrees. nodevalue (rat:: RootedAliasTree ) = rat. root
444
444
AbstractTrees. shouldprintkeys (rat:: RootedAliasTree ) = false
445
445
has_fast_reverse (:: Type{<:AbstractSimpleTreeIter{<:RootedAliasTree}} ) = false
0 commit comments