This is an archive of the discontinued LLVM Phabricator instance.

[ObjCARC] Replace parts of ObjCARCAA with intrinsic attributes
Needs ReviewPublic

Authored by nikic on Oct 31 2022, 8:02 AM.

Details

Summary

ObjCARCAliasAnalysis implements custom getMemoryEffects/getModRefInfo for a few objc intrinsics. However, this is not necessary, as these intrinsics can be described using ordinary readnone/inaccessiblememonly intrinsic attributes. Do that, and drop the special handling from the AA pass.

Diff Detail

Event Timeline

nikic created this revision.Oct 31 2022, 8:02 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 31 2022, 8:02 AM
nikic requested review of this revision.Oct 31 2022, 8:02 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 31 2022, 8:02 AM

I think Akira needs to review this.

ahatanak added inline comments.Nov 13 2022, 8:35 PM
llvm/lib/Analysis/ObjCARCAliasAnalysis.cpp
123

The comment below doesn't seem correct as I think these functions can indirectly cause a memory location that is visible to the compiler to be modified.

For example, in the code below, method retain, which gets called when an object of type C is passed to objc_retain, modifies cnt.

@interface C : NSObject {
  @public unsigned cnt;
}
- (instancetype)retain;
@end

@implementation C
- (instancetype)retain {
  ++cnt;
  return [super retain];
}

cnt can easily be accessed by the code generated by the compiler. For example:

void test(C *c) {
  c->cnt = 0;
}

John, does ARC assume that objc_retain doesn't access any memory visible to the compiler?

The ARC spec describes the semantic restrictions on retain/release implementations:

https://clang.llvm.org/docs/AutomaticReferenceCounting.html#arc-objects-retains

Those semantics do not forbid changing visible memory, they just permit retains and releases to be moved regardless of their impact on visible memory. This is in keeping with the very operational definition of ObjC ARC optimization. There's an implicit assumption here that moving retains and releases won't make other optimizations unsound, which I think can most easily be satisfied by not moving retains and releases to places where there aren't already retains and releases of that object.

nikic added a comment.Dec 5 2022, 12:39 AM

Thanks for the comments. I'm a bit unclear on what the right way forward here is. It sounds like the existing behavior is already incorrect (I think reporting NoModRef allows transforms that are not equivalent to a move of retain/release) and the correct action here would be to drop ARCInstKind::Retain and a few others from the getModRefInfo() implementation instead?