2 * UnSSA - translate the SSA back to normal form.
4 * For now it's done by replacing to set of copies:
5 * 1) For each phi-node, replace all their phisrc by copies to a common
7 * 2) Replace all the phi-nodes by copies of the temporaries to the phi-node target.
8 * This is node to preserve the semantic of the phi-node (they should all "execute"
9 * simultaneously on entry in the basic block in which they belong).
11 * This is similar to the "Sreedhar method I" except that the copies to the
12 * temporaries are not placed at the end of the predecessor basic blocks, but
13 * at the place where the phi-node operands are defined.
14 * This is particulary easy since these copies are essentialy already present
15 * as the corresponding OP_PHISOURCE.
17 * While very simple this method create a lot more copies that really necessary.
18 * We eliminate some of these copies but most probably most of them are still
20 * Ideally, "Sreedhar method III" should be used:
21 * "Translating Out of Static Single Assignment Form", V. C. Sreedhar, R. D.-C. Ju,
22 * D. M. Gillies and V. Santhanam. SAS'99, Vol. 1694 of Lecture Notes in Computer
23 * Science, Springer-Verlag, pp. 194-210, 1999.
24 * But for this we need precise liveness, on each %phi and not only on OP_PHI's
27 * Copyright (C) 2005 Luc Van Oostenryck
31 #include "linearize.h"
37 static inline int nbr_pseudo_users(pseudo_t p
)
39 return ptr_list_size((struct ptr_list
*)p
->users
);
42 static int simplify_phi_node(struct instruction
*phi
, pseudo_t tmp
)
44 pseudo_t target
= phi
->target
;
45 struct pseudo_user
*pu
;
48 // verify if this phi can be simplified
49 FOR_EACH_PTR(phi
->phi_list
, src
) {
50 struct instruction
*def
= src
->def
;
54 if (def
->bb
== phi
->bb
)
56 } END_FOR_EACH_PTR(src
);
58 // no need to make a copy of this one
59 // -> replace the target pseudo by the tmp
60 FOR_EACH_PTR(target
->users
, pu
) {
61 use_pseudo(pu
->insn
, tmp
, pu
->userp
);
62 } END_FOR_EACH_PTR(pu
);
68 static void replace_phi_node(struct instruction
*phi
)
73 tmp
= alloc_pseudo(NULL
);
74 tmp
->type
= phi
->target
->type
;
75 tmp
->ident
= phi
->target
->ident
;
76 tmp
->def
= NULL
; // defined by all the phisrc
78 // can we avoid to make of copy?
79 simplify_phi_node(phi
, tmp
);
81 // rewrite all it's phi_src to copy to a new tmp
82 FOR_EACH_PTR(phi
->phi_list
, p
) {
83 struct instruction
*def
= p
->def
;
89 assert(def
->opcode
== OP_PHISOURCE
);
91 def
->opcode
= OP_COPY
;
94 // can we eliminate the copy?
96 if (src
->type
!= PSEUDO_REG
)
98 switch (nbr_pseudo_users(src
)) {
99 struct instruction
*insn
;
106 kill_instruction(def
);
109 } END_FOR_EACH_PTR(p
);
114 // rewrite the phi node:
118 phi
->opcode
= OP_COPY
;
119 use_pseudo(phi
, tmp
, &phi
->src
);
122 static void rewrite_phi_bb(struct basic_block
*bb
)
124 struct instruction
*insn
;
126 // Replace all the phi-nodes by copies of a temporary
127 // (which represent the set of all the %phi that feed them).
128 // The target pseudo doesn't change.
129 FOR_EACH_PTR(bb
->insns
, insn
) {
132 if (insn
->opcode
!= OP_PHI
)
134 replace_phi_node(insn
);
135 } END_FOR_EACH_PTR(insn
);
138 int unssa(struct entrypoint
*ep
)
140 struct basic_block
*bb
;
142 FOR_EACH_PTR(ep
->bbs
, bb
) {
144 } END_FOR_EACH_PTR(bb
);