aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-12-07 14:08:47 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:05:35 -0700
commit2d8d9bda591831a9d0acc478f7d3b8fa35032b6e (patch)
tree3d14bcc9b65c1f94ad0036d45668ba9f89801862
parentDon't output code for static/toplevel symbols. (diff)
downloadsparse-2d8d9bda591831a9d0acc478f7d3b8fa35032b6e.tar.gz
sparse-2d8d9bda591831a9d0acc478f7d3b8fa35032b6e.tar.bz2
sparse-2d8d9bda591831a9d0acc478f7d3b8fa35032b6e.zip
Make OP_PHISOURCE track the OP_PHI instructions that it defines.
This allows us to always see which pseudos are nonlocally affected by the phi source. We can only do this after the instruction flow is fixed, together with the OP_DEATHNOTE phase.
-rw-r--r--cse.c6
-rw-r--r--lib.h2
-rw-r--r--linearize.c13
-rw-r--r--linearize.h4
-rw-r--r--liveness.c17
-rw-r--r--simplify.c2
6 files changed, 34 insertions, 10 deletions
diff --git a/cse.c b/cse.c
index 47cd78f..6835aac 100644
--- a/cse.c
+++ b/cse.c
@@ -20,8 +20,6 @@
#define INSN_HASH_SIZE 65536
static struct instruction_list *insn_hash_table[INSN_HASH_SIZE];
-#define hashval(x) ((unsigned long)(x))
-
int repeat_phase, merge_phi_sources;
static int phi_compare(pseudo_t phi1, pseudo_t phi2)
@@ -96,7 +94,7 @@ static void clean_up_one_instruction(struct basic_block *bb, struct instruction
}
case OP_PHISOURCE:
- hash += hashval(insn->src1);
+ hash += hashval(insn->phi_src);
hash += hashval(insn->bb);
break;
@@ -209,7 +207,7 @@ static int insn_compare(const void *_i1, const void *_i2)
return phi_list_compare(i1->phi_list, i2->phi_list);
case OP_PHISOURCE:
- if (i1->src1 != i2->src1)
+ if (i1->phi_src != i2->phi_src)
return i1->src1 < i2->src1 ? -1 : 1;
if (i1->bb != i2->bb)
return i1->bb < i2->bb ? -1 : 1;
diff --git a/lib.h b/lib.h
index 5493980..ea04cf8 100644
--- a/lib.h
+++ b/lib.h
@@ -406,4 +406,6 @@ extern void pack_ptr_list(struct ptr_list **);
#define PACK_PTR_LIST(x) pack_ptr_list((struct ptr_list **)(x))
+#define hashval(x) ((unsigned long)(x))
+
#endif
diff --git a/linearize.c b/linearize.c
index f3cd174..f5c08d7 100644
--- a/linearize.c
+++ b/linearize.c
@@ -336,9 +336,14 @@ void show_instruction(struct instruction *insn)
break;
}
- case OP_PHISOURCE:
- buf += sprintf(buf, "%s <- %s", show_pseudo(insn->target), show_pseudo(insn->src1));
+ case OP_PHISOURCE: {
+ struct instruction *phi;
+ buf += sprintf(buf, "%s <- %s ", show_pseudo(insn->target), show_pseudo(insn->phi_src));
+ FOR_EACH_PTR(insn->phi_users, phi) {
+ buf += sprintf(buf, " (%s)", show_pseudo(phi->target));
+ } END_FOR_EACH_PTR(phi);
break;
+ }
case OP_PHI: {
pseudo_t phi;
@@ -427,7 +432,7 @@ void show_instruction(struct instruction *insn)
printf("%s\n", buffer);
}
-static void show_bb(struct basic_block *bb)
+void show_bb(struct basic_block *bb)
{
struct instruction *insn;
@@ -771,7 +776,7 @@ pseudo_t alloc_phi(struct basic_block *source, pseudo_t pseudo, int size)
phi->nr = ++nr;
phi->def = insn;
- use_pseudo(pseudo, &insn->src1);
+ use_pseudo(pseudo, &insn->phi_src);
insn->bb = source;
insn->target = phi;
add_instruction(&source->insns, insn);
diff --git a/linearize.h b/linearize.h
index 7ae3b2e..0398456 100644
--- a/linearize.h
+++ b/linearize.h
@@ -57,6 +57,10 @@ struct instruction {
struct /* phi_node */ {
struct pseudo_list *phi_list;
};
+ struct /* phi source */ {
+ pseudo_t phi_src;
+ struct instruction_list *phi_users;
+ };
struct /* unops */ {
pseudo_t src;
struct symbol *orig_type; /* casts */
diff --git a/liveness.c b/liveness.c
index 2ae6f11..4424cb3 100644
--- a/liveness.c
+++ b/liveness.c
@@ -92,7 +92,7 @@ static void track_instruction_usage(struct basic_block *bb, struct instruction *
* We don't care about the phi-source define, they get set
* up and expanded by the OP_PHI
*/
- USES(src1);
+ USES(phi_src);
break;
case OP_CAST:
@@ -272,6 +272,19 @@ static void merge_pseudo_list(struct pseudo_list *src, struct pseudo_list **dest
} END_FOR_EACH_PTR(pseudo);
}
+static void track_phi_uses(struct instruction *insn)
+{
+ pseudo_t phi;
+ FOR_EACH_PTR(insn->phi_list, phi) {
+ struct instruction *def;
+ if (phi == VOID || !phi->def)
+ continue;
+ def = phi->def;
+ assert(def->opcode == OP_PHISOURCE);
+ add_ptr_list(&def->phi_users, insn);
+ } END_FOR_EACH_PTR(phi);
+}
+
static struct pseudo_list **live_list;
static struct pseudo_list *dead_list;
@@ -301,6 +314,8 @@ static void track_pseudo_death_bb(struct basic_block *bb)
FOR_EACH_PTR_REVERSE(bb->insns, insn) {
if (!insn->bb)
continue;
+ if (insn->opcode == OP_PHI)
+ track_phi_uses(insn);
dead_list = NULL;
track_instruction_usage(bb, insn, death_def, death_use);
if (dead_list) {
diff --git a/simplify.c b/simplify.c
index 2d14b9d..2b4b3e2 100644
--- a/simplify.c
+++ b/simplify.c
@@ -662,7 +662,7 @@ int simplify_instruction(struct instruction *insn)
}
return clean_up_phi(insn);
case OP_PHISOURCE:
- if (dead_insn(insn, &insn->src1, NULL, NULL))
+ if (dead_insn(insn, &insn->phi_src, NULL, NULL))
return REPEAT_CSE;
break;
case OP_SEL: