This adds remaining gphi * overloads to the GIMPLE_PHI accessors in gimple.h and changes the assert in gimple_phi_arg to only allow access to actual arguments rather than available slots. Accordingly PHI node management needs to be adjusted to avoid touching the unused area apart from memsetting it to zero.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2017-07-20 Richard Biener <rguent...@suse.de> * gimple.h (gimple_phi_result): Add gphi * overload. (gimple_phi_result_ptr): Likewise. (gimple_phi_arg): Likewise. Adjust index assert to only allow actual argument accesses rather than all slots available by capacity. (gimple_phi_arg_def): Add gphi * overload. * tree-phinodes.c (make_phi_node): Initialize only actual arguments. (resize_phi_node): Clear memory not covered by old node, do not initialize excess argument slots. (reserve_phi_args_for_new_edge): Initialize new argument slot completely. Index: gcc/gimple.h =================================================================== --- gcc/gimple.h (revision 250384) +++ gcc/gimple.h (working copy) @@ -4308,19 +4308,31 @@ gimple_phi_num_args (const gimple *gs) /* Return the SSA name created by GIMPLE_PHI GS. */ static inline tree +gimple_phi_result (const gphi *gs) +{ + return gs->result; +} + +static inline tree gimple_phi_result (const gimple *gs) { const gphi *phi_stmt = as_a <const gphi *> (gs); - return phi_stmt->result; + return gimple_phi_result (phi_stmt); } /* Return a pointer to the SSA name created by GIMPLE_PHI GS. */ static inline tree * +gimple_phi_result_ptr (gphi *gs) +{ + return &gs->result; +} + +static inline tree * gimple_phi_result_ptr (gimple *gs) { gphi *phi_stmt = as_a <gphi *> (gs); - return &phi_stmt->result; + return gimple_phi_result_ptr (phi_stmt); } /* Set RESULT to be the SSA name created by GIMPLE_PHI PHI. */ @@ -4338,11 +4350,17 @@ gimple_phi_set_result (gphi *phi, tree r GIMPLE_PHI GS. */ static inline struct phi_arg_d * +gimple_phi_arg (gphi *gs, unsigned index) +{ + gcc_gimple_checking_assert (index < gs->nargs); + return &(gs->args[index]); +} + +static inline struct phi_arg_d * gimple_phi_arg (gimple *gs, unsigned index) { gphi *phi_stmt = as_a <gphi *> (gs); - gcc_gimple_checking_assert (index < phi_stmt->capacity); - return &(phi_stmt->args[index]); + return gimple_phi_arg (phi_stmt, index); } /* Set PHIARG to be the argument corresponding to incoming edge INDEX @@ -4377,6 +4395,12 @@ phi_nodes_ptr (basic_block bb) /* Return the tree operand for argument I of PHI node GS. */ static inline tree +gimple_phi_arg_def (gphi *gs, size_t index) +{ + return gimple_phi_arg (gs, index)->def; +} + +static inline tree gimple_phi_arg_def (gimple *gs, size_t index) { return gimple_phi_arg (gs, index)->def; Index: gcc/tree-phinodes.c =================================================================== --- gcc/tree-phinodes.c (revision 250384) +++ gcc/tree-phinodes.c (working copy) @@ -190,7 +190,7 @@ make_phi_node (tree var, int len) else gimple_phi_set_result (phi, make_ssa_name (var, phi)); - for (i = 0; i < capacity; i++) + for (i = 0; i < len; i++) { use_operand_p imm; @@ -248,6 +248,10 @@ resize_phi_node (gphi *phi, size_t len) new_phi = allocate_phi_node (len); memcpy (new_phi, phi, old_size); + memset ((char *)new_phi + old_size, 0, + (sizeof (struct gphi) + - sizeof (struct phi_arg_d) + + sizeof (struct phi_arg_d) * len) - old_size); for (i = 0; i < gimple_phi_num_args (new_phi); i++) { @@ -260,18 +264,6 @@ resize_phi_node (gphi *phi, size_t len) new_phi->capacity = len; - for (i = gimple_phi_num_args (new_phi); i < len; i++) - { - use_operand_p imm; - - gimple_phi_arg_set_location (new_phi, i, UNKNOWN_LOCATION); - imm = gimple_phi_arg_imm_use_ptr (new_phi, i); - imm->use = gimple_phi_arg_def_ptr (new_phi, i); - imm->prev = NULL; - imm->next = NULL; - imm->loc.stmt = new_phi; - } - return new_phi; } @@ -300,6 +292,8 @@ reserve_phi_args_for_new_edge (basic_blo stmt = new_phi; } + stmt->nargs++; + /* We represent a "missing PHI argument" by placing NULL_TREE in the corresponding slot. If PHI arguments were added immediately after an edge is created, this zeroing would not @@ -307,10 +301,13 @@ reserve_phi_args_for_new_edge (basic_blo example, the loop optimizer duplicates several basic blocks, redirects edges, and then fixes up PHI arguments later in batch. */ + use_operand_p imm = gimple_phi_arg_imm_use_ptr (stmt, len - 1); + imm->use = gimple_phi_arg_def_ptr (stmt, len - 1); + imm->prev = NULL; + imm->next = NULL; + imm->loc.stmt = stmt; SET_PHI_ARG_DEF (stmt, len - 1, NULL_TREE); gimple_phi_arg_set_location (stmt, len - 1, UNKNOWN_LOCATION); - - stmt->nargs++; } }