On Wed, Nov 29, 2017 at 8:15 AM, David Malcolm <dmalc...@redhat.com> wrote: > On Wed, 2017-11-29 at 08:56 -0700, Martin Sebor wrote: >> On 11/29/2017 01:30 AM, Jakub Jelinek wrote: >> > On Tue, Nov 28, 2017 at 09:11:00PM -0700, Martin Sebor wrote: >> > > On 11/27/2017 02:22 AM, Dominik Inführ wrote: >> > > > Thanks for all the reviews! I’ve revised the patch, the >> > > > operator_delete_flag is now stored in tree_decl_with_vis (there >> > > > already seem to be some FUNCTION_DECL-flags in there). I’ve >> > > > also added the option -fallocation-dce to disable this >> > > > optimization. It bootstraps and no regressions on aarch64 and >> > > > x86_64. >> > > > >> > > >> > > It's great to be able to eliminate pairs of these calls. For >> > > unpaired calls, though, I think it would be even more useful to >> > > also issue a warning. Otherwise the elimination will mask bugs >> > >> > ?? I hope you're only talking about allocation where the returned >> > pointer can't leak elsewhere, doing allocation in one function >> > (e.g. constructor, or whatever other function) and deallocation in >> > some >> > other one is so common such a warning would be not just useless, >> > but >> > harmful with almost all occurrences being false positives. >> > >> > Warning on malloc/standard operator new or malloc/realloc-like >> > function >> > when the return pointer can't escape the current function is >> > reasonable. >> >> Yes, warn for leaks, or for calls to delete/free with no matching >> new/malloc (when they can be detected). >> >> From the test case included in the patch, warn on the first two >> of the following three functions: >> >> +++ b/gcc/testsuite/g++.dg/cpp1y/new1.C >> @@ -0,0 +1,65 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-O2 -fdump-tree-cddce-details" } */ >> + >> +#include <stdlib.h> >> + >> +void >> +new_without_use() { >> + int *x = new int; >> +} >> + >> +void >> +new_array_without_use() { >> + int *x = new int[5]; >> +} >> + >> +void >> +new_primitive() { >> + int *x = new int; >> + delete x; >> +} >> >> An obvious extension to such a checker would then be to also detect >> possible invalid deallocations, as in: >> >> void f (unsigned n) >> { >> void *p = n < 256 ? alloca (n) : malloc (n); >> // ... >> free (p); >> } >> >> David Malcolm was working on something like that earlier this year >> so he might have some thoughts on this as well. > > I was experimenting with optimizing away matching malloc/free pairs, > moving the allocation to either the stack, or to a thread-local > obstack, under certain conditions, or to hoist allocations out of > loops. > > I didn't get any significant wins, but much of this was due to my lack > of experience with the middle-end, and being drawn back to front- > end/diagnostic improvements. > > Issues I ran into included: > > * wrapper functions like "Perl_malloc" which require LTO for the > optimization to be able to see the allocations > > * 435.gromacs has this "interesting" function:
It is still in the upstream sources too: https://sourcecodebrowser.com/gromacs/3.3.1/smalloc_8h.html#a776f070172af6850dda887c7358fa630 Thanks, Andrew Pinski > > unsigned maxavail(void) > { > char *ptr; > unsigned low,high,size; > > low=0; > high=256e6; > while ((high-low) > 4) { > size=(high+low)/2; > if ((ptr=malloc((size_t)size))==NULL) > high=size; > else { > free(ptr); > low=size; > } > } > return low; > } > > i.e. a loop which attempts a binary search of malloc calls to try to > find a threshold at which they fail. > > > Dave