On Fri, Apr 10, 2020 at 10:29:29AM +0200, Martin Liška wrote:
> +/* Valid pairs of new and delete operators for DCE. */
> +static hash_set<nofree_string_hash> *valid_pairs = NULL;
> +
> +/* Return that NEW_CALL and DELETE_CALL are a valid pair of new
> + and delete operators. */
> +
> +static bool
> +valid_new_delete_pair_p (gimple *new_call, gimple *delete_call)
> +{
> + const char *new_name
> + = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (gimple_call_fndecl
> (new_call)));
> + const char *delete_name
> + = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (gimple_call_fndecl
> (delete_call)));
> +
> + if (new_name[0] == '_' and new_name[1] == '_')
> + ++new_name;
> + if (delete_name[0] == '_' and delete_name[1] == '_')
> + ++delete_name;
> +
> + char *needle = concat (new_name, ":", delete_name, NULL);
> +
> + if (valid_pairs == NULL)
> + {
> + valid_pairs = new hash_set<nofree_string_hash> ();
> + /* Invalid pairs:
> + non-[] and []
> + aligned and non-aligned
> + */
> +
> + const char *pairs[] = {
> + /* non-[] operators. */
> + "_Znwm:_ZdlPv" ,
> + "_Znwm:_ZdlPvm" ,
Formatting, I think the /* and "_Z should be two columns from const char,
and no space before ,
Not sure I like using the : and using a hash table looks like an overkill to
me, don't we have only 8 options, and most of them with different identifier
lengths? The concat itself will take a while...
And, what's worse, the m in there is really different on different targets.
It can be j, m or y depending on what fundamental type size_t is.
So why not (completely untested):
static bool
valid_new_delete_pair_p (gimple *new_call, gimple *delete_call)
{
tree new_asm = DECL_ASSEMBLER_NAME (gimple_call_fndecl (new_call));
tree delete_asm = DECL_ASSEMBLER_NAME (gimple_call_fndecl (delete_call));
const char *new_name = IDENTIFIER_POINTER (new_asm);
const char *delete_name = IDENTIFIER_POINTER (delete_asm);
unsigned int new_len = IDENTIFIER_LENGTH (mew_asm);
unsigned int delete_len = IDENTIFIER_LENGTH (delete_asm);
if (new_name < 5 || delete_len < 6)
return false;
if (new_name[0] == '_')
++new_name, --new_len;
if (new_name[0] == '_')
++new_name, --new_len;
if (delete_name[0] == '_')
++delete_name, --delete_len;
if (delete_name[0] == '_')
++delete_name, --delete_len;
if (new_len < 4 || delete_len < 5)
return false;
/* *_len is now just the length after initial underscores. */
if (new_name[0] != 'Z' || new_name[1] != 'n')
return false;
if (delete_name[0] != 'Z' || delete_name[1] != 'd')
return false;
/* _Znw must match _Zdl, _Zna must match _Zda. */
if ((new_name[2] != 'w' || delete_name[2] != 'l')
&& (new_name[2] != 'a' || delete_name[2] != 'a'))
return false;
if (new_name[3] != 'j' && new_name[3] != 'm' && new_name[3] != 'y')
return false;
if (delete_name[3] != 'P' || delete_name[4] != 'v')
return false;
if (new_len == 4
|| (new_len == 18 && !memcmp (new_name + 4, "RKSt9nothrow_t", 14)))
{
/* _ZnXY or _ZnXYRKSt9nothrow_t matches
_ZdXPv, _ZdXPvY and _ZdXPvRKSt9nothrow_t. */
if (delete_len == 5)
return true;
if (delete_len == 6 && delete_name[5] == new_name[3])
return true;
if (delete_len == 19 && !memcmp (delete_name + 5, "RKSt9nothrow_t", 14))
return true;
}
else if ((new_len == 19 && !memcmp (new_name + 4, "St11align_val_t", 15))
|| (new_len == 33
&& !memcmp (new_name + 4, "St11align_val_tRKSt9nothrow_t", 29)))
{
/* _ZnXYSt11align_val_t or _ZnXYSt11align_val_tRKSt9nothrow_t matches
_ZdXPvSt11align_val_t or _ZdXPvYSt11align_val_t or or
_ZdXPvSt11align_val_tRKSt9nothrow_t. */
if (delete_len == 20 && !memcmp (delete_name + 5, "St11align_val_t", 15))
return true;
if (delete_len == 21
&& delete_name[5] == new_name[3]
&& !memcmp (delete_name + 6, "St11align_val_t", 15))
return true;
if (delete_len == 34
&& !memcmp (delete_name + 5, "St11align_val_tRKSt9nothrow_t", 29))
return true;
}
return false;
}
Jakub