Skip to content

Commit 8ab06d5

Browse files
authored
Merge pull request #579 from apple/eng/PR-58058316-20200108
Relax the rules around objc_alloc and objc_alloc_init optimizations.
2 parents 187f080 + 039b435 commit 8ab06d5

File tree

2 files changed

+29
-22
lines changed

2 files changed

+29
-22
lines changed

clang/lib/CodeGen/CGObjC.cpp

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -461,38 +461,39 @@ tryEmitSpecializedAllocInit(CodeGenFunction &CGF, const ObjCMessageExpr *OME) {
461461
Sel.getNameForSlot(0) != "init")
462462
return None;
463463

464-
// Okay, this is '[receiver init]', check if 'receiver' is '[cls alloc]' or
465-
// we are in an ObjC class method and 'receiver' is '[self alloc]'.
464+
// Okay, this is '[receiver init]', check if 'receiver' is '[cls alloc]'
465+
// with 'cls' a Class.
466466
auto *SubOME =
467467
dyn_cast<ObjCMessageExpr>(OME->getInstanceReceiver()->IgnoreParenCasts());
468468
if (!SubOME)
469469
return None;
470470
Selector SubSel = SubOME->getSelector();
471471

472-
// Check if we are in an ObjC class method and the receiver expression is
473-
// 'self'.
474-
const Expr *SelfInClassMethod = nullptr;
475-
if (const auto *CurMD = dyn_cast_or_null<ObjCMethodDecl>(CGF.CurFuncDecl))
476-
if (CurMD->isClassMethod())
477-
if ((SelfInClassMethod = SubOME->getInstanceReceiver()))
478-
if (!SelfInClassMethod->isObjCSelfExpr())
479-
SelfInClassMethod = nullptr;
480-
481-
if ((SubOME->getReceiverKind() != ObjCMessageExpr::Class &&
482-
!SelfInClassMethod) || !SubOME->getType()->isObjCObjectPointerType() ||
472+
if (!SubOME->getType()->isObjCObjectPointerType() ||
483473
!SubSel.isUnarySelector() || SubSel.getNameForSlot(0) != "alloc")
484474
return None;
485475

486-
llvm::Value *Receiver;
487-
if (SelfInClassMethod) {
488-
Receiver = CGF.EmitScalarExpr(SelfInClassMethod);
489-
} else {
476+
llvm::Value *Receiver = nullptr;
477+
switch (SubOME->getReceiverKind()) {
478+
case ObjCMessageExpr::Instance:
479+
if (!SubOME->getInstanceReceiver()->getType()->isObjCClassType())
480+
return None;
481+
Receiver = CGF.EmitScalarExpr(SubOME->getInstanceReceiver());
482+
break;
483+
484+
case ObjCMessageExpr::Class: {
490485
QualType ReceiverType = SubOME->getClassReceiver();
491486
const ObjCObjectType *ObjTy = ReceiverType->getAs<ObjCObjectType>();
492487
const ObjCInterfaceDecl *ID = ObjTy->getInterface();
493488
assert(ID && "null interface should be impossible here");
494489
Receiver = CGF.CGM.getObjCRuntime().GetClass(CGF, ID);
490+
break;
491+
}
492+
case ObjCMessageExpr::SuperInstance:
493+
case ObjCMessageExpr::SuperClass:
494+
return None;
495495
}
496+
496497
return CGF.EmitObjCAllocInit(Receiver, CGF.ConvertType(OME->getType()));
497498
}
498499

@@ -540,10 +541,7 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E,
540541
switch (E->getReceiverKind()) {
541542
case ObjCMessageExpr::Instance:
542543
ReceiverType = E->getInstanceReceiver()->getType();
543-
if (auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(CurFuncDecl))
544-
if (OMD->isClassMethod())
545-
if (E->getInstanceReceiver()->isObjCSelfExpr())
546-
isClassMessage = true;
544+
isClassMessage = ReceiverType->isObjCClassType();
547545
if (retainSelf) {
548546
TryEmitResult ter = tryEmitARCRetainScalarExpr(*this,
549547
E->getInstanceReceiver());

clang/test/CodeGenObjC/objc-alloc-init.m

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,30 @@ void f() {
2222
}
2323

2424
@interface Y : X
25+
+(Class)class;
2526
+(void)meth;
2627
-(void)instanceMeth;
2728
@end
2829

2930
@implementation Y
31+
+(Class)class {
32+
return self;
33+
}
3034
+(void)meth {
3135
[[self alloc] init];
3236
// OPTIMIZED: call i8* @objc_alloc_init(
3337
// NOT_OPTIMIZED: call i8* @objc_alloc(
3438
}
39+
+ (void)meth2 {
40+
[[[self class] alloc] init];
41+
// OPTIMIZED: call i8* @objc_alloc_init(
42+
// NOT_OPTIMIZED: call i8* @objc_alloc(
43+
}
3544
-(void)instanceMeth {
3645
// EITHER-NOT: call i8* @objc_alloc
3746
// EITHER: call {{.*}} @objc_msgSend
3847
// EITHER: call {{.*}} @objc_msgSend
39-
[[self alloc] init];
48+
[[(id)self alloc] init];
4049
}
4150
@end
4251

0 commit comments

Comments
 (0)