Changed signature of GenerateMessageSend() function to pass the ObjCInterfaceDecl for class messages and removed the boolean IsClassMessage argument, which wasn't used anywhere.
Emitted some metadata on message sends to allow a later pass to do some speculative inlining of class methods (GNU runtime). Speculative inlining of instance methods requires type feedback to be useful (work in progress), but for class methods it works quite nicely.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102514 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 1ff30f2..3c1dca0 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -55,6 +55,7 @@
CGObjCRuntime &Runtime = CGM.getObjCRuntime();
bool isSuperMessage = false;
bool isClassMessage = false;
+ ObjCInterfaceDecl *OID = 0;
// Find the receiver
llvm::Value *Receiver = 0;
switch (E->getReceiverKind()) {
@@ -65,8 +66,9 @@
case ObjCMessageExpr::Class: {
const ObjCInterfaceType *IFace
= E->getClassReceiver()->getAs<ObjCInterfaceType>();
+ OID = IFace->getDecl();
assert(IFace && "Invalid Objective-C class message send");
- Receiver = Runtime.GetClass(Builder, IFace->getDecl());
+ Receiver = Runtime.GetClass(Builder, OID);
isClassMessage = true;
break;
}
@@ -101,7 +103,7 @@
}
return Runtime.GenerateMessageSend(*this, E->getType(), E->getSelector(),
- Receiver, isClassMessage, Args,
+ Receiver, Args, OID,
E->getMethodDecl());
}
@@ -453,7 +455,7 @@
return CGM.getObjCRuntime().
GenerateMessageSend(*this, Exp->getType(), S,
EmitScalarExpr(E->getBase()),
- false, CallArgList());
+ CallArgList());
} else {
const ObjCImplicitSetterGetterRefExpr *KE =
cast<ObjCImplicitSetterGetterRefExpr>(Exp);
@@ -469,7 +471,7 @@
return CGM.getObjCRuntime().
GenerateMessageSend(*this, Exp->getType(), S,
Receiver,
- KE->getInterfaceDecl() != 0, CallArgList());
+ CallArgList(), KE->getInterfaceDecl());
}
}
@@ -506,7 +508,7 @@
Args.push_back(std::make_pair(Src, E->getType()));
CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
EmitScalarExpr(E->getBase()),
- false, Args);
+ Args);
} else if (const ObjCImplicitSetterGetterRefExpr *E =
dyn_cast<ObjCImplicitSetterGetterRefExpr>(Exp)) {
Selector S = E->getSetterMethod()->getSelector();
@@ -523,7 +525,7 @@
Args.push_back(std::make_pair(Src, E->getType()));
CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
Receiver,
- E->getInterfaceDecl() != 0, Args);
+ Args, E->getInterfaceDecl());
} else
assert (0 && "bad expression node in EmitObjCPropertySet");
}
@@ -591,7 +593,7 @@
CGM.getObjCRuntime().GenerateMessageSend(*this,
getContext().UnsignedLongTy,
FastEnumSel,
- Collection, false, Args);
+ Collection, Args);
llvm::Value *LimitPtr = CreateMemTemp(getContext().UnsignedLongTy,
"limit.ptr");
@@ -716,7 +718,7 @@
CGM.getObjCRuntime().GenerateMessageSend(*this,
getContext().UnsignedLongTy,
FastEnumSel,
- Collection, false, Args);
+ Collection, Args);
Builder.CreateStore(CountRV.getScalarVal(), LimitPtr);
Limit = Builder.CreateLoad(LimitPtr);
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 0a97351..0f4354c 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -26,6 +26,7 @@
#include "llvm/Intrinsics.h"
#include "llvm/Module.h"
+#include "llvm/LLVMContext.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Compiler.h"
@@ -81,6 +82,8 @@
llvm::Constant *Zeros[2];
llvm::Constant *NULLPtr;
llvm::LLVMContext &VMContext;
+ /// Metadata kind used to tie method lookups to message sends.
+ unsigned msgSendMDKind;
private:
llvm::Constant *GenerateIvarList(
const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
@@ -142,8 +145,8 @@
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
- bool IsClassMessage,
const CallArgList &CallArgs,
+ const ObjCInterfaceDecl *Class,
const ObjCMethodDecl *Method);
virtual CodeGen::RValue
GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
@@ -236,6 +239,9 @@
CGObjCGNU::CGObjCGNU(CodeGen::CodeGenModule &cgm)
: CGM(cgm), TheModule(CGM.getModule()), ClassPtrAlias(0),
MetaClassPtrAlias(0), VMContext(cgm.getLLVMContext()) {
+
+ msgSendMDKind = VMContext.getMDKindID("GNUObjCMessageSend");
+
IntTy = cast<llvm::IntegerType>(
CGM.getTypes().ConvertType(CGM.getContext().IntTy));
LongTy = cast<llvm::IntegerType>(
@@ -542,8 +548,8 @@
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
- bool IsClassMessage,
const CallArgList &CallArgs,
+ const ObjCInterfaceDecl *Class,
const ObjCMethodDecl *Method) {
// Strip out message sends to retain / release in GC mode
if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
@@ -642,9 +648,16 @@
LookupFn->setDoesNotCapture(1);
}
- llvm::Value *slot =
+ llvm::Instruction *slot =
Builder.CreateCall3(lookupFunction, ReceiverPtr, cmd, self);
imp = Builder.CreateLoad(Builder.CreateStructGEP(slot, 4));
+ llvm::Value *impMD[] = {
+ llvm::MDString::get(VMContext, Sel.getAsString()),
+ llvm::MDString::get(VMContext, Class ? Class->getNameAsString() :""),
+ };
+ llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD, 2);
+ cast<llvm::Instruction>(imp)->setMetadata(msgSendMDKind, node);
+
// The lookup function may have changed the receiver, so make sure we use
// the new one.
ActualArgs[0] =
@@ -660,7 +673,6 @@
imp = Builder.CreateCall2(lookupFunction, Receiver, cmd);
}
-
RValue msgRet =
CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs);
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 3905bd4..429b13c 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -1129,8 +1129,8 @@
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
- bool IsClassMessage,
const CallArgList &CallArgs,
+ const ObjCInterfaceDecl *Class,
const ObjCMethodDecl *Method);
virtual CodeGen::RValue
@@ -1357,8 +1357,8 @@
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
- bool IsClassMessage,
const CallArgList &CallArgs,
+ const ObjCInterfaceDecl *Class,
const ObjCMethodDecl *Method);
virtual CodeGen::RValue
@@ -1577,8 +1577,8 @@
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
- bool IsClassMessage,
const CallArgList &CallArgs,
+ const ObjCInterfaceDecl *Class,
const ObjCMethodDecl *Method) {
return EmitLegacyMessageSend(CGF, ResultType,
EmitSelector(CGF.Builder, Sel),
@@ -5214,8 +5214,8 @@
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
- bool IsClassMessage,
const CallArgList &CallArgs,
+ const ObjCInterfaceDecl *Class,
const ObjCMethodDecl *Method) {
return LegacyDispatchedSelector(Sel)
? EmitLegacyMessageSend(CGF, ResultType, EmitSelector(CGF.Builder, Sel),
diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h
index 64e6808..654ad0a 100644
--- a/lib/CodeGen/CGObjCRuntime.h
+++ b/lib/CodeGen/CGObjCRuntime.h
@@ -122,8 +122,8 @@
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
- bool IsClassMessage,
const CallArgList &CallArgs,
+ const ObjCInterfaceDecl *Class = 0,
const ObjCMethodDecl *Method = 0) = 0;
/// Generate an Objective-C message send operation to the super