diff mbox

[13/29] add insert_phi_node()

Message ID 20170816153455.97693-14-luc.vanoostenryck@gmail.com (mailing list archive)
State Changes Requested, archived
Headers show

Commit Message

Luc Van Oostenryck Aug. 16, 2017, 3:34 p.m. UTC
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.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 linearize.c | 22 ++++++++++++++++++++++
 linearize.h |  1 +
 2 files changed, 23 insertions(+)

Comments

Christopher Li Aug. 18, 2017, 8:39 p.m. UTC | #1
On Wed, Aug 16, 2017 at 11:34 AM, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
>
> +pseudo_t insert_phi_node(struct basic_block *bb, struct symbol *type)
> +{
> +       struct instruction *phi_node = alloc_typed_instruction(OP_PHI, type);
> +       struct instruction *insn;
> +       pseudo_t phi;
> +
> +       phi = alloc_pseudo(phi_node);
> +       phi_node->target = phi;
> +       phi_node->bb = bb;
> +
> +       FOR_EACH_PTR(bb->insns, insn) {
> +               enum opcode op = insn->opcode;
> +               if (op == OP_ENTRY || op == OP_PHI)
> +                       continue;
> +               INSERT_CURRENT(phi_node, insn);

You do need to preserve the order of the phi node, right?
At first I was thinking always insert the phi at the first instruction.
Then I realized that, it is possible some phi node use some other
phi node as source in case of a loop. So the order does need
to be preserved some how.

> +               return phi;
> +       } END_FOR_EACH_PTR(insn);
> +
> +       add_instruction(&bb->insns, phi_node);
> +       return phi;
> +}
> +


Chris
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Luc Van Oostenryck Aug. 18, 2017, 8:52 p.m. UTC | #2
On Fri, Aug 18, 2017 at 10:39 PM, Christopher Li <sparse@chrisli.org> wrote:
>
> You do need to preserve the order of the phi node, right?
> At first I was thinking always insert the phi at the first instruction.
> Then I realized that, it is possible some phi node use some other
> phi node as source in case of a loop. So the order does need
> to be preserved some how.

It's not needed because:
1) phi-nodes need to have 'parallel-assignment' semantics anyway
    like in languages where you can write 'a, b = b, a' to exchange
    two variables. In other words, if the order would matter it would
    be a bug.
2) you can never have (the target of) a phi-node (OP_PHI)
    as another phi-node' source because all such sources are
    created by OP_PHISOURCEs.

-- Luc
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Christopher Li Aug. 18, 2017, 9:17 p.m. UTC | #3
On Fri, Aug 18, 2017 at 4:52 PM, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
> On Fri, Aug 18, 2017 at 10:39 PM, Christopher Li <sparse@chrisli.org> wrote:
>>
>
> It's not needed because:
> 1) phi-nodes need to have 'parallel-assignment' semantics anyway
>     like in languages where you can write 'a, b = b, a' to exchange
>     two variables. In other words, if the order would matter it would
>     be a bug.

I need to think more about that.

> 2) you can never have (the target of) a phi-node (OP_PHI)
>     as another phi-node' source because all such sources are
>     created by OP_PHISOURCEs.

I see. So that means you can just insert into the first instruction?

Chris
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Luc Van Oostenryck Aug. 18, 2017, 9:43 p.m. UTC | #4
On Fri, Aug 18, 2017 at 11:17 PM, Christopher Li <sparse@chrisli.org> wrote:

>> 2) you can never have (the target of) a phi-node (OP_PHI)
>>     as another phi-node' source because all such sources are
>>     created by OP_PHISOURCEs.
>
> I see. So that means you can just insert into the first instruction?

Yes, you would also, for example, add a list in the BB and just add
them in this list in any order. They are not really instructions, the best
way to see them in the see them in a kind of BB prologue where they
(virtually) select the value for their target pseudo (and if you know for
 sure from which patch the BB will always come, you can remove them
completely.On the other hand, it' an error when merging BB to leave
a phi-node in the middle of the new bigger BB, it needs special care
but also often it doesn't matter).

-- Luc
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/linearize.c b/linearize.c
index 3d14892cd..0af92a08e 100644
--- a/linearize.c
+++ b/linearize.c
@@ -852,6 +852,28 @@  pseudo_t alloc_phi(struct basic_block *source, pseudo_t pseudo, struct symbol *t
 	return phi;
 }
 
+pseudo_t insert_phi_node(struct basic_block *bb, struct symbol *type)
+{
+	struct instruction *phi_node = alloc_typed_instruction(OP_PHI, type);
+	struct instruction *insn;
+	pseudo_t phi;
+
+	phi = alloc_pseudo(phi_node);
+	phi_node->target = phi;
+	phi_node->bb = bb;
+
+	FOR_EACH_PTR(bb->insns, insn) {
+		enum opcode op = insn->opcode;
+		if (op == OP_ENTRY || op == OP_PHI)
+			continue;
+		INSERT_CURRENT(phi_node, insn);
+		return phi;
+	} END_FOR_EACH_PTR(insn);
+
+	add_instruction(&bb->insns, phi_node);
+	return phi;
+}
+
 /*
  * 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 060d5f327..a67f5b3e7 100644
--- a/linearize.h
+++ b/linearize.h
@@ -332,6 +332,7 @@  struct entrypoint {
 extern void insert_select(struct basic_block *bb, struct instruction *br, struct instruction *phi, pseudo_t if_true, pseudo_t if_false);
 extern void insert_branch(struct basic_block *bb, struct instruction *br, struct basic_block *target);
 
+pseudo_t insert_phi_node(struct basic_block *bb, struct symbol *type);
 pseudo_t alloc_phi(struct basic_block *source, pseudo_t pseudo, struct symbol *type);
 pseudo_t alloc_pseudo(struct instruction *def);
 pseudo_t value_pseudo(long long val);