Added dead code elimination survival facility
authorSebastian Hack <hack@ipd.info.uni-karlsruhe.de>
Mon, 6 Mar 2006 15:16:38 +0000 (15:16 +0000)
committerSebastian Hack <hack@ipd.info.uni-karlsruhe.de>
Mon, 6 Mar 2006 15:16:38 +0000 (15:16 +0000)
[r7417]

ir/common/survive_dce.c [new file with mode: 0644]
ir/common/survive_dce.h [new file with mode: 0644]

diff --git a/ir/common/survive_dce.c b/ir/common/survive_dce.c
new file mode 100644 (file)
index 0000000..37a83f7
--- /dev/null
@@ -0,0 +1,76 @@
+
+#include "pmap.h"
+
+#include "irnode_t.h"
+#include "irhooks.h"
+#include "irgwalk.h"
+
+#include "survive_dce.h"
+
+struct _survive_dce_t {
+       pmap *places;
+       pmap *new_places;
+       hook_entry_t dead_node_elim;
+       hook_entry_t dead_node_elim_subst;
+};
+
+static void dead_node_hook(void *context, ir_graph *irg, int start)
+{
+       survive_dce_t *sd = context;
+
+       /* Create a new map before the dead node elimination is performed. */
+       if(start) {
+               sd->new_places = pmap_create_ex(pmap_count(sd->places));
+       }
+
+       /* Patch back all nodes if dead node elimination is over and something is to be done. */
+       else {
+               pmap_destroy(sd->places);
+               sd->places     = sd->new_places;
+               sd->new_places = NULL;
+       }
+}
+
+static void dead_node_subst_hook(void *context, ir_graph *irg, ir_node *old, ir_node *nw)
+{
+       survive_dce_t *sd = context;
+       ir_node **place    = (ir_node **) pmap_get(sd->places, old);
+
+       /* If the node is to be patched back, do it. */
+       if(place) {
+               *place = nw;
+               pmap_insert(sd->new_places, nw, (void *) place);
+       }
+}
+
+survive_dce_t *new_survive_dce(void)
+{
+       survive_dce_t *res = xmalloc(sizeof(res[0]));
+       res->places     = pmap_create();
+       res->new_places = NULL;
+
+       res->dead_node_elim.hook._hook_dead_node_elim = dead_node_hook;
+       res->dead_node_elim.context                   = res;
+       res->dead_node_elim.next                      = NULL;
+
+       res->dead_node_elim_subst.hook._hook_dead_node_elim_subst = dead_node_subst_hook;
+       res->dead_node_elim_subst.context = res;
+       res->dead_node_elim_subst.next    = NULL;
+
+       register_hook(hook_dead_node_elim, &res->dead_node_elim);
+       register_hook(hook_dead_node_elim_subst, &res->dead_node_elim_subst);
+       return res;
+}
+
+void free_survive_dce(survive_dce_t *sd)
+{
+       pmap_destroy(sd->places);
+       unregister_hook(hook_dead_node_elim, &sd->dead_node_elim);
+       unregister_hook(hook_dead_node_elim_subst, &sd->dead_node_elim_subst);
+       free(sd);
+}
+
+void survive_dce_register_irn(survive_dce_t *sd, ir_node **place)
+{
+       pmap_insert(sd->places, *place, (void *) place);
+}
diff --git a/ir/common/survive_dce.h b/ir/common/survive_dce.h
new file mode 100644 (file)
index 0000000..3c0c205
--- /dev/null
@@ -0,0 +1,29 @@
+/**
+ * A facility for nodes to "survive" the dead code elimination.
+ */
+
+#ifndef _FIRM_SURVIVE_DCE_H
+#define _FIRM_SURVIVE_DCE_H
+
+typedef struct _survive_dce_t survive_dce_t;
+
+/**
+ * Make a new dead code survive instance.
+ */
+survive_dce_t *new_survive_dce(void);
+
+/**
+ * Free a dead node survive instance.
+ */
+void           free_survive_dce(survive_dce_t *sd);
+
+/**
+ * Register a storage place for a node.
+ * @param sd The survive dead code private data.
+ * @param place A pointer to a node pointer which shall be actualized.
+ * The location given by <code>place</code> will be updated with the substitute
+ * of the node it is currently pointing to after dead node elimination.
+ */
+void survive_dce_register_irn(survive_dce_t *sd, ir_node **place);
+
+#endif