зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
a96698e935
Коммит
c6cd5fd3ea
|
@ -55,6 +55,7 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
|
||||||
CGObjCRuntime &Runtime = CGM.getObjCRuntime();
|
CGObjCRuntime &Runtime = CGM.getObjCRuntime();
|
||||||
bool isSuperMessage = false;
|
bool isSuperMessage = false;
|
||||||
bool isClassMessage = false;
|
bool isClassMessage = false;
|
||||||
|
ObjCInterfaceDecl *OID = 0;
|
||||||
// Find the receiver
|
// Find the receiver
|
||||||
llvm::Value *Receiver = 0;
|
llvm::Value *Receiver = 0;
|
||||||
switch (E->getReceiverKind()) {
|
switch (E->getReceiverKind()) {
|
||||||
|
@ -65,8 +66,9 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
|
||||||
case ObjCMessageExpr::Class: {
|
case ObjCMessageExpr::Class: {
|
||||||
const ObjCInterfaceType *IFace
|
const ObjCInterfaceType *IFace
|
||||||
= E->getClassReceiver()->getAs<ObjCInterfaceType>();
|
= E->getClassReceiver()->getAs<ObjCInterfaceType>();
|
||||||
|
OID = IFace->getDecl();
|
||||||
assert(IFace && "Invalid Objective-C class message send");
|
assert(IFace && "Invalid Objective-C class message send");
|
||||||
Receiver = Runtime.GetClass(Builder, IFace->getDecl());
|
Receiver = Runtime.GetClass(Builder, OID);
|
||||||
isClassMessage = true;
|
isClassMessage = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +103,7 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return Runtime.GenerateMessageSend(*this, E->getType(), E->getSelector(),
|
return Runtime.GenerateMessageSend(*this, E->getType(), E->getSelector(),
|
||||||
Receiver, isClassMessage, Args,
|
Receiver, Args, OID,
|
||||||
E->getMethodDecl());
|
E->getMethodDecl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,7 +455,7 @@ RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp) {
|
||||||
return CGM.getObjCRuntime().
|
return CGM.getObjCRuntime().
|
||||||
GenerateMessageSend(*this, Exp->getType(), S,
|
GenerateMessageSend(*this, Exp->getType(), S,
|
||||||
EmitScalarExpr(E->getBase()),
|
EmitScalarExpr(E->getBase()),
|
||||||
false, CallArgList());
|
CallArgList());
|
||||||
} else {
|
} else {
|
||||||
const ObjCImplicitSetterGetterRefExpr *KE =
|
const ObjCImplicitSetterGetterRefExpr *KE =
|
||||||
cast<ObjCImplicitSetterGetterRefExpr>(Exp);
|
cast<ObjCImplicitSetterGetterRefExpr>(Exp);
|
||||||
|
@ -469,7 +471,7 @@ RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp) {
|
||||||
return CGM.getObjCRuntime().
|
return CGM.getObjCRuntime().
|
||||||
GenerateMessageSend(*this, Exp->getType(), S,
|
GenerateMessageSend(*this, Exp->getType(), S,
|
||||||
Receiver,
|
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()));
|
Args.push_back(std::make_pair(Src, E->getType()));
|
||||||
CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
|
CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
|
||||||
EmitScalarExpr(E->getBase()),
|
EmitScalarExpr(E->getBase()),
|
||||||
false, Args);
|
Args);
|
||||||
} else if (const ObjCImplicitSetterGetterRefExpr *E =
|
} else if (const ObjCImplicitSetterGetterRefExpr *E =
|
||||||
dyn_cast<ObjCImplicitSetterGetterRefExpr>(Exp)) {
|
dyn_cast<ObjCImplicitSetterGetterRefExpr>(Exp)) {
|
||||||
Selector S = E->getSetterMethod()->getSelector();
|
Selector S = E->getSetterMethod()->getSelector();
|
||||||
|
@ -523,7 +525,7 @@ void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp,
|
||||||
Args.push_back(std::make_pair(Src, E->getType()));
|
Args.push_back(std::make_pair(Src, E->getType()));
|
||||||
CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
|
CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
|
||||||
Receiver,
|
Receiver,
|
||||||
E->getInterfaceDecl() != 0, Args);
|
Args, E->getInterfaceDecl());
|
||||||
} else
|
} else
|
||||||
assert (0 && "bad expression node in EmitObjCPropertySet");
|
assert (0 && "bad expression node in EmitObjCPropertySet");
|
||||||
}
|
}
|
||||||
|
@ -591,7 +593,7 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
|
||||||
CGM.getObjCRuntime().GenerateMessageSend(*this,
|
CGM.getObjCRuntime().GenerateMessageSend(*this,
|
||||||
getContext().UnsignedLongTy,
|
getContext().UnsignedLongTy,
|
||||||
FastEnumSel,
|
FastEnumSel,
|
||||||
Collection, false, Args);
|
Collection, Args);
|
||||||
|
|
||||||
llvm::Value *LimitPtr = CreateMemTemp(getContext().UnsignedLongTy,
|
llvm::Value *LimitPtr = CreateMemTemp(getContext().UnsignedLongTy,
|
||||||
"limit.ptr");
|
"limit.ptr");
|
||||||
|
@ -716,7 +718,7 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
|
||||||
CGM.getObjCRuntime().GenerateMessageSend(*this,
|
CGM.getObjCRuntime().GenerateMessageSend(*this,
|
||||||
getContext().UnsignedLongTy,
|
getContext().UnsignedLongTy,
|
||||||
FastEnumSel,
|
FastEnumSel,
|
||||||
Collection, false, Args);
|
Collection, Args);
|
||||||
Builder.CreateStore(CountRV.getScalarVal(), LimitPtr);
|
Builder.CreateStore(CountRV.getScalarVal(), LimitPtr);
|
||||||
Limit = Builder.CreateLoad(LimitPtr);
|
Limit = Builder.CreateLoad(LimitPtr);
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include "llvm/Intrinsics.h"
|
#include "llvm/Intrinsics.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
|
#include "llvm/LLVMContext.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/StringMap.h"
|
#include "llvm/ADT/StringMap.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
|
@ -81,6 +82,8 @@ private:
|
||||||
llvm::Constant *Zeros[2];
|
llvm::Constant *Zeros[2];
|
||||||
llvm::Constant *NULLPtr;
|
llvm::Constant *NULLPtr;
|
||||||
llvm::LLVMContext &VMContext;
|
llvm::LLVMContext &VMContext;
|
||||||
|
/// Metadata kind used to tie method lookups to message sends.
|
||||||
|
unsigned msgSendMDKind;
|
||||||
private:
|
private:
|
||||||
llvm::Constant *GenerateIvarList(
|
llvm::Constant *GenerateIvarList(
|
||||||
const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
|
const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
|
||||||
|
@ -142,8 +145,8 @@ public:
|
||||||
QualType ResultType,
|
QualType ResultType,
|
||||||
Selector Sel,
|
Selector Sel,
|
||||||
llvm::Value *Receiver,
|
llvm::Value *Receiver,
|
||||||
bool IsClassMessage,
|
|
||||||
const CallArgList &CallArgs,
|
const CallArgList &CallArgs,
|
||||||
|
const ObjCInterfaceDecl *Class,
|
||||||
const ObjCMethodDecl *Method);
|
const ObjCMethodDecl *Method);
|
||||||
virtual CodeGen::RValue
|
virtual CodeGen::RValue
|
||||||
GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
|
GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
|
||||||
|
@ -236,6 +239,9 @@ static std::string SymbolNameForMethod(const std::string &ClassName, const
|
||||||
CGObjCGNU::CGObjCGNU(CodeGen::CodeGenModule &cgm)
|
CGObjCGNU::CGObjCGNU(CodeGen::CodeGenModule &cgm)
|
||||||
: CGM(cgm), TheModule(CGM.getModule()), ClassPtrAlias(0),
|
: CGM(cgm), TheModule(CGM.getModule()), ClassPtrAlias(0),
|
||||||
MetaClassPtrAlias(0), VMContext(cgm.getLLVMContext()) {
|
MetaClassPtrAlias(0), VMContext(cgm.getLLVMContext()) {
|
||||||
|
|
||||||
|
msgSendMDKind = VMContext.getMDKindID("GNUObjCMessageSend");
|
||||||
|
|
||||||
IntTy = cast<llvm::IntegerType>(
|
IntTy = cast<llvm::IntegerType>(
|
||||||
CGM.getTypes().ConvertType(CGM.getContext().IntTy));
|
CGM.getTypes().ConvertType(CGM.getContext().IntTy));
|
||||||
LongTy = cast<llvm::IntegerType>(
|
LongTy = cast<llvm::IntegerType>(
|
||||||
|
@ -542,8 +548,8 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
|
||||||
QualType ResultType,
|
QualType ResultType,
|
||||||
Selector Sel,
|
Selector Sel,
|
||||||
llvm::Value *Receiver,
|
llvm::Value *Receiver,
|
||||||
bool IsClassMessage,
|
|
||||||
const CallArgList &CallArgs,
|
const CallArgList &CallArgs,
|
||||||
|
const ObjCInterfaceDecl *Class,
|
||||||
const ObjCMethodDecl *Method) {
|
const ObjCMethodDecl *Method) {
|
||||||
// Strip out message sends to retain / release in GC mode
|
// Strip out message sends to retain / release in GC mode
|
||||||
if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
|
if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
|
||||||
|
@ -642,9 +648,16 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
|
||||||
LookupFn->setDoesNotCapture(1);
|
LookupFn->setDoesNotCapture(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Value *slot =
|
llvm::Instruction *slot =
|
||||||
Builder.CreateCall3(lookupFunction, ReceiverPtr, cmd, self);
|
Builder.CreateCall3(lookupFunction, ReceiverPtr, cmd, self);
|
||||||
imp = Builder.CreateLoad(Builder.CreateStructGEP(slot, 4));
|
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 lookup function may have changed the receiver, so make sure we use
|
||||||
// the new one.
|
// the new one.
|
||||||
ActualArgs[0] =
|
ActualArgs[0] =
|
||||||
|
@ -660,7 +673,6 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
|
||||||
|
|
||||||
imp = Builder.CreateCall2(lookupFunction, Receiver, cmd);
|
imp = Builder.CreateCall2(lookupFunction, Receiver, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
RValue msgRet =
|
RValue msgRet =
|
||||||
CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs);
|
CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs);
|
||||||
|
|
||||||
|
|
|
@ -1129,8 +1129,8 @@ public:
|
||||||
QualType ResultType,
|
QualType ResultType,
|
||||||
Selector Sel,
|
Selector Sel,
|
||||||
llvm::Value *Receiver,
|
llvm::Value *Receiver,
|
||||||
bool IsClassMessage,
|
|
||||||
const CallArgList &CallArgs,
|
const CallArgList &CallArgs,
|
||||||
|
const ObjCInterfaceDecl *Class,
|
||||||
const ObjCMethodDecl *Method);
|
const ObjCMethodDecl *Method);
|
||||||
|
|
||||||
virtual CodeGen::RValue
|
virtual CodeGen::RValue
|
||||||
|
@ -1357,8 +1357,8 @@ public:
|
||||||
QualType ResultType,
|
QualType ResultType,
|
||||||
Selector Sel,
|
Selector Sel,
|
||||||
llvm::Value *Receiver,
|
llvm::Value *Receiver,
|
||||||
bool IsClassMessage,
|
|
||||||
const CallArgList &CallArgs,
|
const CallArgList &CallArgs,
|
||||||
|
const ObjCInterfaceDecl *Class,
|
||||||
const ObjCMethodDecl *Method);
|
const ObjCMethodDecl *Method);
|
||||||
|
|
||||||
virtual CodeGen::RValue
|
virtual CodeGen::RValue
|
||||||
|
@ -1577,8 +1577,8 @@ CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
|
||||||
QualType ResultType,
|
QualType ResultType,
|
||||||
Selector Sel,
|
Selector Sel,
|
||||||
llvm::Value *Receiver,
|
llvm::Value *Receiver,
|
||||||
bool IsClassMessage,
|
|
||||||
const CallArgList &CallArgs,
|
const CallArgList &CallArgs,
|
||||||
|
const ObjCInterfaceDecl *Class,
|
||||||
const ObjCMethodDecl *Method) {
|
const ObjCMethodDecl *Method) {
|
||||||
return EmitLegacyMessageSend(CGF, ResultType,
|
return EmitLegacyMessageSend(CGF, ResultType,
|
||||||
EmitSelector(CGF.Builder, Sel),
|
EmitSelector(CGF.Builder, Sel),
|
||||||
|
@ -5214,8 +5214,8 @@ CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
|
||||||
QualType ResultType,
|
QualType ResultType,
|
||||||
Selector Sel,
|
Selector Sel,
|
||||||
llvm::Value *Receiver,
|
llvm::Value *Receiver,
|
||||||
bool IsClassMessage,
|
|
||||||
const CallArgList &CallArgs,
|
const CallArgList &CallArgs,
|
||||||
|
const ObjCInterfaceDecl *Class,
|
||||||
const ObjCMethodDecl *Method) {
|
const ObjCMethodDecl *Method) {
|
||||||
return LegacyDispatchedSelector(Sel)
|
return LegacyDispatchedSelector(Sel)
|
||||||
? EmitLegacyMessageSend(CGF, ResultType, EmitSelector(CGF.Builder, Sel),
|
? EmitLegacyMessageSend(CGF, ResultType, EmitSelector(CGF.Builder, Sel),
|
||||||
|
|
|
@ -122,8 +122,8 @@ public:
|
||||||
QualType ResultType,
|
QualType ResultType,
|
||||||
Selector Sel,
|
Selector Sel,
|
||||||
llvm::Value *Receiver,
|
llvm::Value *Receiver,
|
||||||
bool IsClassMessage,
|
|
||||||
const CallArgList &CallArgs,
|
const CallArgList &CallArgs,
|
||||||
|
const ObjCInterfaceDecl *Class = 0,
|
||||||
const ObjCMethodDecl *Method = 0) = 0;
|
const ObjCMethodDecl *Method = 0) = 0;
|
||||||
|
|
||||||
/// Generate an Objective-C message send operation to the super
|
/// Generate an Objective-C message send operation to the super
|
||||||
|
|
Загрузка…
Ссылка в новой задаче