Use the Objective-C runtime to unique selectors in JIT'd code.

When generating IR for the JIT, use sel_registerName() to unique the
selector references we generate. Static code doesn't need this
pessimization. Fixes <rdar://problem/12764732>.


Swift SVN r3403
This commit is contained in:
Doug Gregor
2012-12-07 17:13:27 +00:00
parent 1e689a936d
commit 07be3f3e7f
4 changed files with 41 additions and 6 deletions

View File

@@ -56,7 +56,11 @@ public:
/// The optimization level, as in -O2.
unsigned OptLevel : 2;
Options() : OutputKind(OutputKind::LLVMAssembly), Verify(true), OptLevel(0) {}
/// \brief Whether we're generating IR for the JIT.
unsigned UseJIT : 1;
Options() : OutputKind(OutputKind::LLVMAssembly), Verify(true), OptLevel(0),
UseJIT(false) {}
};
} // end namespace irgen

View File

@@ -18,6 +18,7 @@
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "swift/IRGen/Options.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Types.h"
@@ -68,6 +69,17 @@ llvm::Constant *IRGenModule::getObjCMsgSendStretFn() {
return ObjCMsgSendStretFn;
}
llvm::Constant *IRGenModule::getObjCSelRegisterNameFn() {
if (ObjCSelRegisterNameFn) return ObjCSelRegisterNameFn;
// SEL sel_registerName(const char *str);
llvm::Type *argTypes[1] = { Int8PtrTy };
auto fnType = llvm::FunctionType::get(Int8PtrTy, argTypes, false);
ObjCSelRegisterNameFn = createObjCRuntimeFunction(*this, "sel_registerName",
fnType);
return ObjCSelRegisterNameFn;
}
#define DEFINE_OBJC_RUNTIME_FUNCTION(LABEL, NAME, RETTY) \
llvm::Constant *IRGenModule::getObjC##LABEL##Fn() { \
if (ObjC##LABEL##Fn) return ObjC##LABEL##Fn; \
@@ -418,10 +430,24 @@ CallEmission irgen::prepareObjCMethodCall(IRGenFunction &IGF, FuncDecl *method,
selfValues.addUnmanaged(value.getValue());
// Add the selector value.
llvm::Value *selectorV;
Selector selector(method);
auto selectorRef = IGF.IGM.getAddrOfObjCSelectorRef(selector.str());
auto selectorV =
IGF.Builder.CreateLoad(Address(selectorRef, IGF.IGM.getPointerAlignment()));
if (IGF.IGM.Opts.UseJIT) {
// When generating JIT'd code, we need to call sel_registerName() to force
// the runtime to unique the selector.
auto selectorRef = IGF.IGM.getAddrOfObjCSelectorRef(selector.str());
selectorV = IGF.Builder.CreateLoad(Address(selectorRef,
IGF.IGM.getPointerAlignment()));
selectorV = IGF.Builder.CreateCall(IGF.IGM.getObjCSelRegisterNameFn(),
selectorV);
} else {
// When generating statically-compiled code, just build a reference to
// the selector.
auto selectorRef = IGF.IGM.getAddrOfObjCSelectorRef(selector.str());
selectorV = IGF.Builder.CreateLoad(Address(selectorRef,
IGF.IGM.getPointerAlignment()));
}
selfValues.addUnmanaged(selectorV);
// Add that to the emission.

View File

@@ -208,6 +208,8 @@ public:
llvm::Constant *getObjCMsgSendFn();
llvm::Constant *getObjCMsgSendStretFn();
llvm::Constant *getObjCSelRegisterNameFn();
llvm::Constant *getGetFunctionMetadataFn();
llvm::Constant *getGetGenericMetadataFn();
llvm::Constant *getGetMetatypeMetadataFn();
@@ -232,6 +234,7 @@ private:
llvm::Constant *ObjCReleaseFn = nullptr;
llvm::Constant *ObjCMsgSendFn = nullptr;
llvm::Constant *ObjCMsgSendStretFn = nullptr;
llvm::Constant *ObjCSelRegisterNameFn = nullptr;
//--- Generic ---------------------------------------------------------------
public:

View File

@@ -143,6 +143,7 @@ void swift::RunImmediately(TranslationUnit *TU) {
Options.Triple = llvm::sys::getDefaultTargetTriple();
Options.OptLevel = 2;
Options.OutputKind = irgen::OutputKind::Module;
Options.UseJIT = true;
// IRGen the main module.
llvm::LLVMContext LLVMContext;
@@ -299,6 +300,7 @@ void swift::REPL(ASTContext &Context) {
Options.Triple = llvm::sys::getDefaultTargetTriple();
Options.OptLevel = 0;
Options.OutputKind = irgen::OutputKind::Module;
Options.UseJIT = true;
EditLineWrapper e;