@@ -13,21 +13,32 @@
#include "flow.h"
static void phi_defines(struct instruction * phi_node, pseudo_t target,
- void (*defines)(struct basic_block *, struct instruction *, pseudo_t))
+ void (*defines)(struct basic_block *, struct instruction *, pseudo_t),
+ unsigned long generation)
{
pseudo_t phi;
FOR_EACH_PTR(phi_node->phi_list, phi) {
- struct instruction *def;
if (phi == VOID)
continue;
- def = phi->def;
- if (!def || !def->bb)
- continue;
- if (def->opcode == OP_PHI) {
- phi_defines(def, target, defines);
+ if (!phi->def || !phi->def->bb)
continue;
+
+ /*
+ * In case of "(PHISOURCE->PHI->)+ PHISOURCE->PHI" chain, move
+ * "defines" information upstream to BBs of very initial PHISOURCEs;
+ * recursion guarded by generation marking of PHI instructions BBs.
+ */
+ pseudo_t src_pseudo = phi->def->phi_src;
+ if (src_pseudo->type == PSEUDO_REG
+ && src_pseudo->def->opcode == OP_PHI) {
+ phi_node->bb->generation = generation;
+ if (src_pseudo->def->bb->generation != generation) {
+ phi_defines(src_pseudo->def, target, defines, generation);
+ continue;
+ }
}
- defines(def->bb, phi->def, target);
+
+ defines(phi->def->bb, phi->def, target);
} END_FOR_EACH_PTR(phi);
}
@@ -103,7 +114,7 @@ static void track_instruction_usage(struct basic_block *bb, struct instruction *
/* Other */
case OP_PHI:
/* Phi-nodes are "backwards" nodes. Their def doesn't matter */
- phi_defines(insn, insn->target, def);
+ phi_defines(insn, insn->target, def, ++bb_generation);
break;
case OP_PHISOURCE:
Reformulated comment to better describe what it does. (Sorry for inconvenience) Signed-off-by: Jan Pokorny <pokorny_jan@seznam.cz> --- liveness.c | 29 ++++++++++++++++++++--------- 1 files changed, 20 insertions(+), 9 deletions(-)