Skip to content

Commit 100f694

Browse files
#53 When a phi goes dead all references to its def in the memoized set of defs must be replaced rather than removed thus avoiding unnecessary future phi creation?
1 parent 86e5dbd commit 100f694

File tree

2 files changed

+94
-126
lines changed

2 files changed

+94
-126
lines changed

optvm/src/main/java/com/compilerprogramming/ezlang/compiler/CompiledFunction.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -965,14 +965,14 @@ private Register addPhiOperands(Register variable, Instruction.Phi phi) {
965965
return tryRemovingPhi(phi);
966966
}
967967

968-
// The Phi's def is dead so we need to remove
969-
// all occurrences of this def from the memoized defs
968+
// The Phi's def was replaced
969+
// We must also replace all occurrences of the phi def from the memoized defs
970970
// per Basic Block
971-
private void clearDefs(Instruction.Phi phi) {
971+
private void replaceDefs(Instruction.Phi phi, Register newValue) {
972972
// TODO rethink the data structure for currentDef
973973
var def = phi.value();
974974
var defs = currentDef.get(def.nonSSAId());
975-
// Make a list of block/reg that we need to delete
975+
// Make a list of block/reg that we need to update
976976
var bbList = new ArrayList<BasicBlock>();
977977
var regList = new ArrayList<Register>();
978978
for (var entries : defs.entrySet()) {
@@ -983,14 +983,15 @@ private void clearDefs(Instruction.Phi phi) {
983983
regList.add(reg);
984984
}
985985
}
986-
// Now delete them
986+
// Now replace the phi def
987987
for (int i = 0; i < bbList.size(); i++) {
988988
var bb = bbList.get(i);
989989
var reg = regList.get(i);
990-
defs.remove(bb, reg);
990+
defs.replace(bb, reg, newValue);
991991
}
992992
}
993993

994+
// reference implementation https://github.com/dibyendumajumdar/libfirm/blob/master/ir/ir/ircons.c#L97
994995
private Register tryRemovingPhi(Instruction.Phi phi) {
995996
Register same = null;
996997
// Check if phi has distinct inputs
@@ -1017,9 +1018,6 @@ private Register tryRemovingPhi(Instruction.Phi phi) {
10171018
// remove all uses of phi to same and remove phi
10181019
replacePhiValueAndUsers(phi, same);
10191020
phi.block.deleteInstruction(phi);
1020-
// Since the phi is dead any references to its def
1021-
// must be removed; this is not mentioned in the paper
1022-
clearDefs(phi);
10231021
// try to recursively remove all phi users, which might have become trivial
10241022
for (var use: users) {
10251023
if (use instanceof Instruction.Phi phiuser)
@@ -1055,6 +1053,9 @@ private void replacePhiValueAndUsers(Instruction.Phi phi, Register newValue) {
10551053
newDefUseChain.useList.addAll(oldDefUseChain.useList);
10561054
oldDefUseChain.useList.clear();
10571055
}
1056+
// Since the phi is replaced by newvalue
1057+
// we must also update the memoized defs
1058+
replaceDefs(phi, newValue);
10581059
}
10591060

10601061
private List<Instruction> getUsesExcept(Instruction.Phi phi) {

optvm/src/test/java/com/compilerprogramming/ezlang/compiler/TestIncrementalSSA.java

Lines changed: 84 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -250,44 +250,32 @@ func example14_66(p: Int,q: Int,r: Int,s: Int,t: Int)
250250
Reg #51 i_5 5
251251
Reg #52 i_6 5
252252
Reg #53 i_7 5
253-
Reg #54 i_8 5
254-
Reg #55 %t55 55
255-
Reg #56 t_1 4
256-
Reg #57 t_2 4
257-
Reg #58 t_3 4
258-
Reg #59 t_4 4
259-
Reg #60 t_5 4
260-
Reg #61 t_6 4
261-
Reg #62 t_7 4
262-
Reg #63 p_2 0
263-
Reg #64 p_3 0
264-
Reg #65 p_4 0
265-
Reg #66 p_5 0
266-
Reg #67 p_6 0
267-
Reg #68 p_7 0
268-
Reg #69 q_2 1
269-
Reg #70 q_3 1
270-
Reg #71 q_4 1
271-
Reg #72 q_5 1
272-
Reg #73 q_6 1
273-
Reg #74 q_7 1
274-
Reg #75 r_6 2
275-
Reg #76 r_7 2
276-
Reg #77 r_8 2
277-
Reg #78 r_9 2
278-
Reg #79 s_6 3
279-
Reg #80 s_7 3
280-
Reg #81 s_8 3
281-
Reg #82 s_9 3
282-
Reg #83 j_5 6
283-
Reg #84 j_6 6
284-
Reg #85 j_7 6
285-
Reg #86 j_8 6
286-
Reg #87 k_6 7
287-
Reg #88 k_7 7
288-
Reg #89 k_8 7
289-
Reg #90 k_9 7
290-
Reg #91 l_9 8
253+
Reg #54 %t54 54
254+
Reg #55 t_1 4
255+
Reg #56 t_2 4
256+
Reg #57 t_3 4
257+
Reg #58 t_4 4
258+
Reg #59 t_5 4
259+
Reg #60 t_6 4
260+
Reg #61 p_2 0
261+
Reg #62 p_3 0
262+
Reg #63 p_4 0
263+
Reg #64 p_5 0
264+
Reg #65 p_6 0
265+
Reg #66 q_2 1
266+
Reg #67 q_3 1
267+
Reg #68 q_4 1
268+
Reg #69 q_5 1
269+
Reg #70 q_6 1
270+
Reg #71 r_6 2
271+
Reg #72 s_6 3
272+
Reg #73 j_5 6
273+
Reg #74 j_6 6
274+
Reg #75 j_7 6
275+
Reg #76 k_6 7
276+
Reg #77 k_7 7
277+
Reg #78 k_8 7
278+
Reg #79 l_9 8
291279
L0:
292280
arg p
293281
arg q
@@ -303,7 +291,7 @@ func example14_66(p: Int,q: Int,r: Int,s: Int,t: Int)
303291
l_5 = phi(l, l_9)
304292
j_4 = phi(j, j_2)
305293
k_2 = phi(k, k_5)
306-
i_1 = phi(i, i_8)
294+
i_1 = phi(i, i_7)
307295
if 1 goto L3 else goto L4
308296
L3:
309297
if p goto L5 else goto L6
@@ -346,9 +334,9 @@ func example14_66(p: Int,q: Int,r: Int,s: Int,t: Int)
346334
L13:
347335
l_9 = phi(l_6, l_8)
348336
%t49 = i_1+6
349-
i_8 = %t49
350-
%t55 = !t
351-
if %t55 goto L18 else goto L19
337+
i_7 = %t49
338+
%t54 = !t
339+
if %t54 goto L18 else goto L19
352340
L18:
353341
goto L4
354342
L4:
@@ -659,17 +647,14 @@ func main()->Int
659647
Reg #25 i_4 1
660648
Reg #26 %t26 26
661649
Reg #27 i_5 1
662-
Reg #28 i_6 1
663-
Reg #29 i_7 1
664-
Reg #30 i_8 1
665650
L0:
666651
a = 0
667652
i = 0
668653
j = 0
669654
goto L2
670655
L2:
671656
a_4 = phi(a, a_1)
672-
i_1 = phi(i, i_8)
657+
i_1 = phi(i, i_5)
673658
%t3 = i_1<3
674659
if %t3 goto L3 else goto L4
675660
L3:
@@ -705,7 +690,7 @@ func main()->Int
705690
goto L10
706691
L7:
707692
%t26 = i_1+1
708-
i_8 = %t26
693+
i_5 = %t26
709694
goto L2
710695
L4:
711696
ret a_4
@@ -863,8 +848,6 @@ func bug(N: Int)
863848
Reg #11 N_3 0
864849
Reg #12 %t12 12
865850
Reg #13 p_5 1
866-
Reg #14 N_4 0
867-
Reg #15 N_5 0
868851
L0:
869852
arg N
870853
p = 2
@@ -1009,52 +992,36 @@ func sieve(N: Int)->[Int]
1009992
Reg #33 p_4 4
1010993
Reg #34 i_2 7
1011994
Reg #35 N_3 0
1012-
Reg #36 ary_4 1
1013-
Reg #37 %t37 37
1014-
Reg #38 p_5 4
1015-
Reg #39 p_6 4
1016-
Reg #40 N_4 0
1017-
Reg #41 ary_5 1
1018-
Reg #42 primes_3 2
1019-
Reg #43 nprimes_4 3
1020-
Reg #44 %t44 44
1021-
Reg #45 p_7 4
1022-
Reg #46 N_5 0
1023-
Reg #47 %t47 47
1024-
Reg #48 ary_6 1
1025-
Reg #49 %t49 49
1026-
Reg #50 primes_4 2
1027-
Reg #51 nprimes_5 3
1028-
Reg #52 %t52 52
1029-
Reg #53 nprimes_6 3
1030-
Reg #54 %t54 54
1031-
Reg #55 p_8 4
1032-
Reg #56 p_9 4
1033-
Reg #57 N_6 0
1034-
Reg #58 N_7 0
1035-
Reg #59 N_8 0
1036-
Reg #60 N_9 0
1037-
Reg #61 ary_7 1
1038-
Reg #62 ary_8 1
1039-
Reg #63 ary_9 1
1040-
Reg #64 ary_10 1
1041-
Reg #65 primes_5 2
1042-
Reg #66 primes_6 2
1043-
Reg #67 primes_7 2
1044-
Reg #68 primes_8 2
1045-
Reg #69 nprimes_7 3
1046-
Reg #70 %t70 70
1047-
Reg #71 %t71 71
1048-
Reg #72 j_1 6
1049-
Reg #73 nprimes_8 3
1050-
Reg #74 %t74 74
1051-
Reg #75 primes_9 2
1052-
Reg #76 rez_1 5
1053-
Reg #77 %t77 77
1054-
Reg #78 j_2 6
1055-
Reg #79 primes_10 2
1056-
Reg #80 primes_11 2
1057-
Reg #81 rez_2 5
995+
Reg #36 %t36 36
996+
Reg #37 p_5 4
997+
Reg #38 primes_3 2
998+
Reg #39 nprimes_4 3
999+
Reg #40 %t40 40
1000+
Reg #41 p_6 4
1001+
Reg #42 N_4 0
1002+
Reg #43 %t43 43
1003+
Reg #44 ary_4 1
1004+
Reg #45 %t45 45
1005+
Reg #46 primes_4 2
1006+
Reg #47 nprimes_5 3
1007+
Reg #48 %t48 48
1008+
Reg #49 nprimes_6 3
1009+
Reg #50 %t50 50
1010+
Reg #51 p_7 4
1011+
Reg #52 p_8 4
1012+
Reg #53 N_5 0
1013+
Reg #54 ary_5 1
1014+
Reg #55 primes_5 2
1015+
Reg #56 nprimes_7 3
1016+
Reg #57 %t57 57
1017+
Reg #58 %t58 58
1018+
Reg #59 j_1 6
1019+
Reg #60 nprimes_8 3
1020+
Reg #61 %t61 61
1021+
Reg #62 primes_6 2
1022+
Reg #63 rez_1 5
1023+
Reg #64 %t64 64
1024+
Reg #65 j_2 6
10581025
L0:
10591026
arg N
10601027
%t8 = New([Int], len=N, initValue=0)
@@ -1067,7 +1034,7 @@ func sieve(N: Int)->[Int]
10671034
goto L2
10681035
L2:
10691036
nprimes_2 = phi(nprimes, nprimes_3)
1070-
p_1 = phi(p, p_6)
1037+
p_1 = phi(p, p_5)
10711038
%t11 = p_1*p_1
10721039
%t13 = %t11<N
10731040
if %t13 goto L3 else goto L4
@@ -1098,44 +1065,44 @@ func sieve(N: Int)->[Int]
10981065
i_2 = %t32
10991066
goto L8
11001067
L10:
1101-
%t37 = p_2+1
1102-
p_6 = %t37
1068+
%t36 = p_2+1
1069+
p_5 = %t36
11031070
goto L2
11041071
L4:
11051072
goto L11
11061073
L11:
11071074
nprimes_5 = phi(nprimes_2, nprimes_7)
1108-
p_7 = phi(p_1, p_9)
1109-
%t44 = p_7<N
1110-
if %t44 goto L12 else goto L13
1075+
p_6 = phi(p_1, p_8)
1076+
%t40 = p_6<N
1077+
if %t40 goto L12 else goto L13
11111078
L12:
1112-
%t47 = ary[p_7]
1113-
%t49 = !%t47
1114-
if %t49 goto L14 else goto L15
1079+
%t43 = ary[p_6]
1080+
%t45 = !%t43
1081+
if %t45 goto L14 else goto L15
11151082
L14:
1116-
primes[nprimes_5] = p_7
1117-
%t52 = nprimes_5+1
1118-
nprimes_6 = %t52
1083+
primes[nprimes_5] = p_6
1084+
%t48 = nprimes_5+1
1085+
nprimes_6 = %t48
11191086
goto L15
11201087
L15:
11211088
nprimes_7 = phi(nprimes_5, nprimes_6)
1122-
%t54 = p_7+1
1123-
p_9 = %t54
1089+
%t50 = p_6+1
1090+
p_8 = %t50
11241091
goto L11
11251092
L13:
1126-
%t70 = New([Int], len=nprimes_5, initValue=0)
1127-
rez = %t70
1093+
%t57 = New([Int], len=nprimes_5, initValue=0)
1094+
rez = %t57
11281095
j = 0
11291096
goto L16
11301097
L16:
11311098
j_1 = phi(j, j_2)
1132-
%t71 = j_1<nprimes_5
1133-
if %t71 goto L17 else goto L18
1099+
%t58 = j_1<nprimes_5
1100+
if %t58 goto L17 else goto L18
11341101
L17:
1135-
%t74 = primes[j_1]
1136-
rez[j_1] = %t74
1137-
%t77 = j_1+1
1138-
j_2 = %t77
1102+
%t61 = primes[j_1]
1103+
rez[j_1] = %t61
1104+
%t64 = j_1+1
1105+
j_2 = %t64
11391106
goto L16
11401107
L18:
11411108
ret rez

0 commit comments

Comments
 (0)