aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Chisnall <csdavec@swan.ac.uk>2010-04-28 19:33:36 +0000
committerDavid Chisnall <csdavec@swan.ac.uk>2010-04-28 19:33:36 +0000
commitc6cd5fd3eae71f8841504a396563343cfaaf503e (patch)
tree3560e86c568d422b2bc2283e8cad343628544b97
parenta96698e9358c00c269b96ad4d8b27da8a8273086 (diff)
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
-rw-r--r--lib/CodeGen/CGObjC.cpp18
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp20
-rw-r--r--lib/CodeGen/CGObjCMac.cpp8
-rw-r--r--lib/CodeGen/CGObjCRuntime.h2
4 files changed, 31 insertions, 17 deletions
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 1ff30f2634..3c1dca01e1 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -55,6 +55,7 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
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 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
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 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
}
return Runtime.GenerateMessageSend(*this, E->getType(), E->getSelector(),
- Receiver, isClassMessage, Args,
+ Receiver, Args, OID,
E->getMethodDecl());
}
@@ -453,7 +455,7 @@ RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp) {
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 @@ RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp) {
return CGM.getObjCRuntime().
GenerateMessageSend(*this, Exp->getType(), S,
Receiver,
- KE->getInterfaceDecl() != 0, CallArgList());
+ CallArgList(), KE->getInterfaceDecl());
}
}
@@ -506,7 +508,7 @@ void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp,
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 @@ void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp,
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 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
CGM.getObjCRuntime().GenerateMessageSend(*this,
getContext().UnsignedLongTy,
FastEnumSel,
- Collection, false, Args);
+ Collection, Args);
llvm::Value *LimitPtr = CreateMemTemp(getContext().UnsignedLongTy,
"limit.ptr");
@@ -716,7 +718,7 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
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 0a973512c8..0f4354c75a 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 @@ private:
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 @@ public:
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 @@ static std::string SymbolNameForMethod(const std::string &ClassName, const
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 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
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 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
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 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
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 3905bd4f3d..429b13c50a 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -1129,8 +1129,8 @@ public:
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 @@ public:
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 @@ CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
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 @@ CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
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 64e68083c0..654ad0a4bf 100644
--- a/lib/CodeGen/CGObjCRuntime.h
+++ b/lib/CodeGen/CGObjCRuntime.h
@@ -122,8 +122,8 @@ public:
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