Skip to content

Commit e16715e

Browse files
authored
Merge pull request #580 from apple/eng/PR-58058316-20190619
Relax the rules around objc_alloc and objc_alloc_init optimizations.
2 parents 968b251 + 142ddd1 commit e16715e

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
@@ -460,38 +460,39 @@ tryEmitSpecializedAllocInit(CodeGenFunction &CGF, const ObjCMessageExpr *OME) {
460460
Sel.getNameForSlot(0) != "init")
461461
return None;
462462

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

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

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

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