This is an archive of the discontinued LLVM Phabricator instance.

[CFE][Codegen][In-progress] Remove CodeGenFunction::InitTempAlloca()
ClosedPublic

Authored by hsmhsm on Oct 7 2021, 3:04 AM.

Details

Summary

CodeGenFunction::InitTempAlloca() inits the static alloca within the
entry block which may *not* necessarily be correct always.

For example, the current instruction insertion point (pointed by the
instruction builder) could be a program point which is hit multiple
times during the program execution, and it is expected that the static
alloca is initialized every time the program point is hit.

Hence remove CodeGenFunction::InitTempAlloca(), and initialize the
static alloca where the instruction insertion point is at the moment.

This patch, as a starting attempt, removes the calls to
CodeGenFunction::InitTempAlloca() which do not have any side effect on
the lit tests.

Diff Detail

Event Timeline

hsmhsm requested review of this revision.Oct 7 2021, 3:04 AM
hsmhsm created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptOct 7 2021, 3:04 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript

We should take the opportunity to add a test here for the ObjC case. It should be testable with something like this, where you should see the store inside of the loop instead of once in the prologue:

// RUN: %clang_cc1 -triple x86_64-unknown-freebsd -S -emit-llvm -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s

typedef struct {
  int x[12];
} Big;

@protocol P
- (Big) foo;
@end

void test(id<P> p) {
  for (;;) {
    Big big = [p foo];
  }
}

CodeGenFunction::InitTempAlloca() inits the static alloca within the entry block which may *not* necessarily be correct always.

FWIW, for all uses this was correct. The point of the function was exactly to do what you state here as "potentially incorrect".
The documentation explicitly states "and the initializer must be valid in the entry block (i.e. it must either be a constant or an argument value)."
The rest of the reasoning that follows for this patch is consequently mood.

While I don't expect this to have a real negative impact on performance it certainly could if we are somewhat sensitive to the additional stores that
are now executed prior to an event which requires a temporary storage location (in OpenMP).

CodeGenFunction::InitTempAlloca() inits the static alloca within the entry block which may *not* necessarily be correct always.

FWIW, for all uses this was correct. The point of the function was exactly to do what you state here as "potentially incorrect".
The documentation explicitly states "and the initializer must be valid in the entry block (i.e. it must either be a constant or an argument value)."
The rest of the reasoning that follows for this patch is consequently mood.

While I don't expect this to have a real negative impact on performance it certainly could if we are somewhat sensitive to the additional stores that
are now executed prior to an event which requires a temporary storage location (in OpenMP).

It's not potentially incorrect because of dominance problems, it's potentially incorrect because it means the initialization is performed exactly once per call to the enclosing function rather than once per evaluation of the code in question, which generally means it may have been overwritten as part of a prior evaluation. For example, the ObjC code in this patch is trying to zero-initialize a temporary to handle the case where the receiver is nil, but I believe there are situations where that temporary may be modified following the call, and so it's really necessary to zero-initialize prior to each message send, not just once in the prologue. (With that said, what this code is doing with a PHI is silly, and it should just be zeroing the same temporary used for the call return.)

Some of the OpenMP uses seem to be assuming that they're emitting to the start of a function and would be clearer if they just emitted the stores normally. The rest seem to be passing the address of a variable holding i32 0 to a call argument. If all of those calls promise not to modify this argument, we could indeed hoist this store to the prologue. Better yet, we could just pass the address of a constant global variable and not do any stores at all. In either case, having a general InitTempAlloca doesn't seem like the best approach.

hsmhsm updated this revision to Diff 378092.Oct 7 2021, 10:17 PM

Add lit test - CodeGenObjC/static-alloc-init.m

Hmm. I decided the ObjC case needed a more complex change and went ahead and committed that fix here: https://github.com/llvm/llvm-project/commit/5ab6ee75994d. That obviates the need for the new test; sorry for the runaround. Please rebase and I'll review.

hsmhsm updated this revision to Diff 378157.Oct 8 2021, 3:40 AM

Rebase to latest trunk.

rjmccall accepted this revision.Oct 8 2021, 10:52 AM

Patch LGTM, but please remove the test, it's been folded into a test I added in my patch.

This revision is now accepted and ready to land.Oct 8 2021, 10:52 AM
hsmhsm updated this revision to Diff 378408.Oct 8 2021, 8:51 PM

Remove newly added test CodeGenObjC/static-alloc-init.m

This revision was landed with ongoing or failed builds.Oct 8 2021, 8:54 PM
This revision was automatically updated to reflect the committed changes.