aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-04-15 13:38:59 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-07-01 00:18:44 +0200
commitaa4bd0297606ed5c6803a8149bff0a38d8a89827 (patch)
tree7fbaa4a31793614add6cf255e417e750c390e681
parent8cb5317fa01679fd8b2b30ffbf8dec13ae71c98d (diff)
downloadsparse-dev-aa4bd0297606ed5c6803a8149bff0a38d8a89827.tar.gz
add insert_phi_node()
This helper is used later during the SSA construction and is, as its name suggest, used to insert phi-nodes in the instruction stream. More exactly, the phi-node will be put at the begining of the specified BB, just after the others phi-nodes but before any other instructions, as required for their semantics (although, it's less important for sparse since each operand correspond first to a phi-source, so no phi-node directly depending on themselves in sparse). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--linearize.c36
-rw-r--r--linearize.h3
2 files changed, 39 insertions, 0 deletions
diff --git a/linearize.c b/linearize.c
index 7aecc9af..19e06af8 100644
--- a/linearize.c
+++ b/linearize.c
@@ -881,6 +881,42 @@ pseudo_t alloc_phi(struct basic_block *source, pseudo_t pseudo, struct symbol *t
return insn->target;
}
+struct instruction *alloc_phi_node(struct basic_block *bb, struct symbol *type, struct ident *ident)
+{
+ struct instruction *phi_node = alloc_typed_instruction(OP_PHI, type);
+ pseudo_t phi;
+
+ phi = alloc_pseudo(phi_node);
+ phi->ident = ident;
+ phi->def = phi_node;
+ phi_node->target = phi;
+ phi_node->bb = bb;
+ return phi_node;
+}
+
+void add_phi_node(struct basic_block *bb, struct instruction *phi_node)
+{
+ struct instruction *insn;
+
+ FOR_EACH_PTR(bb->insns, insn) {
+ enum opcode op = insn->opcode;
+ if (op == OP_PHI)
+ continue;
+ INSERT_CURRENT(phi_node, insn);
+ return;
+ } END_FOR_EACH_PTR(insn);
+
+ // FIXME
+ add_instruction(&bb->insns, phi_node);
+}
+
+struct instruction *insert_phi_node(struct basic_block *bb, struct symbol *var)
+{
+ struct instruction *phi_node = alloc_phi_node(bb, var, var->ident);
+ add_phi_node(bb, phi_node);
+ return phi_node;
+}
+
/*
* We carry the "access_data" structure around for any accesses,
* which simplifies things a lot. It contains all the access
diff --git a/linearize.h b/linearize.h
index c30c826d..3cce3656 100644
--- a/linearize.h
+++ b/linearize.h
@@ -385,6 +385,9 @@ extern void insert_select(struct basic_block *bb, struct instruction *br, struct
extern void insert_branch(struct basic_block *bb, struct instruction *br, struct basic_block *target);
struct instruction *alloc_phisrc(pseudo_t pseudo, struct symbol *type);
+struct instruction *alloc_phi_node(struct basic_block *bb, struct symbol *type, struct ident *ident);
+struct instruction *insert_phi_node(struct basic_block *bb, struct symbol *var);
+void add_phi_node(struct basic_block *bb, struct instruction *phi_node);
pseudo_t alloc_phi(struct basic_block *source, pseudo_t pseudo, struct symbol *type);
pseudo_t alloc_pseudo(struct instruction *def);