[PATCH] A new HeapToStack allocation promotion pass

David Tweed david.tweed at arm.com
Tue Sep 24 02:39:40 PDT 2013


Hi, this isn't my area of expertise, but doesn't there also need to be handling of truly nasty but "mentioned in the standard as OK" uses of realloc as in

int* p = malloc(<blah>);
<blah>
if (not_big_enough) {
    p = realloc(p,<blah>);
}
<blah>
free(p);

In that case don't you either need to not do the transformation or pick the worst-case size for the stack range? AFAICS extractMalloc is testing with the MallocLike mask only, so I think there ought to be at least some checking that there's no ReallocLike calls to the same variable happening. But I might be missing a subtlety in the code.

Cheers,
Dave

-----Original Message-----
From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-bounces at cs.uiuc.edu] On Behalf Of hfinkel at anl.gov
Sent: 23 September 2013 22:00
To: chandlerc at gmail.com; hfinkel at anl.gov
Cc: llvm-commits at cs.uiuc.edu
Subject: [PATCH] A new HeapToStack allocation promotion pass

Hi chandlerc,

This adds a new optimization pass that can 'promote' malloc'd memory to stack-allocated memory when the lifetime of the allocation can be determined to be bounded by the execution of the function.

To be specific, consider the following three cases:

void bar(int *x);

void foo1() {
  int *x = malloc(16);
  bar(x);
  free(x);
}

In this case the malloc can be replaced by an alloca, and the free removed. Note that this is true even though the pointer 'x' is definitely captured (and may be recorded in global storage, etc.).

The pairing between the malloc and the free need not be 1:1, for example:

void foo2(int a) {
  int *x;

  if (a == 0)
    x = malloc(16);
  else
    x = malloc(32);

  bar(x);
  free(x);
}

where both mallocs and the free can be removed, and, finally, the free might not exclusively be used to free stack-promotable allocations, as in:

void foo3(int *y) {
  if (y == 0)
    y = malloc(48);

  bar(y);
  free(y);
}

to handle this last case, which is referred to as an 'ambiguous' free in the code, a new boolean value is introduced to track the source of the allocation. The malloc is removed, but the free is not. Instead, the pointer passed to the free is conditionally set to null to prevent freeing a stack address.

I talked briefly to Chandler about this offline, and we might want to turn the core functionality here into a utility function so that it can be used directly by SROA. Nevertheless, I think that the basic functionality can be reviewed in this form, and I'd like to discuss any other desired refactoring as part of the review process.

Note: Using this pass causes a miscompile in SingleSource/Benchmarks/Shootout/objinst -- the transformation performed by HeapToStack looks valid, and bugpoint attributes the failure to some combination of later transformations. I'll open a separate bug report to track this issue.

Please review and thanks again!


http://llvm-reviews.chandlerc.com/D1745

Files:
  include/llvm-c/Transforms/Scalar.h
  include/llvm/IR/DataLayout.h
  include/llvm/InitializePasses.h
  include/llvm/LinkAllPasses.h
  include/llvm/Transforms/Scalar.h
  lib/Transforms/IPO/PassManagerBuilder.cpp
  lib/Transforms/Scalar/CMakeLists.txt
  lib/Transforms/Scalar/HeapToStack.cpp
  lib/Transforms/Scalar/Scalar.cpp
  test/Transforms/HeapToStack/basic.ll







More information about the llvm-commits mailing list