diff options
author | dim <dim@FreeBSD.org> | 2011-12-09 22:23:45 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-12-09 22:23:45 +0000 |
commit | 0a8d9e83286f1e0207031442c8c9b143758a0a75 (patch) | |
tree | 9f786c58105dd9ad2fee073528a513777fea3e3c /contrib/llvm/tools/clang/lib/CodeGen | |
parent | 1003872b67ebc3af8b693420f84097716d3b8395 (diff) | |
download | FreeBSD-src-0a8d9e83286f1e0207031442c8c9b143758a0a75.zip FreeBSD-src-0a8d9e83286f1e0207031442c8c9b143758a0a75.tar.gz |
Upgrade our copy of llvm/clang to 3.0 release. Release notes can be
found at: http://llvm.org/releases/3.0/docs/ReleaseNotes.html
MFC after: 1 week
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CGObjCGNU.cpp | 42 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp | 59 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h | 2 |
3 files changed, 79 insertions, 24 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGObjCGNU.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGObjCGNU.cpp index d3da649..688e992 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGObjCGNU.cpp @@ -538,11 +538,12 @@ protected: llvm::Value *cmd, llvm::MDNode *node) { CGBuilderTy &Builder = CGF.Builder; - llvm::Value *imp = Builder.CreateCall2(MsgLookupFn, - EnforceType(Builder, Receiver, IdTy), - EnforceType(Builder, cmd, SelectorTy)); - cast<llvm::CallInst>(imp)->setMetadata(msgSendMDKind, node); - return imp; + llvm::Value *args[] = { + EnforceType(Builder, Receiver, IdTy), + EnforceType(Builder, cmd, SelectorTy) }; + llvm::CallSite imp = CGF.EmitCallOrInvoke(MsgLookupFn, args); + imp->setMetadata(msgSendMDKind, node); + return imp.getInstruction(); } virtual llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, llvm::Value *ObjCSuper, @@ -597,16 +598,17 @@ class CGObjCGNUstep : public CGObjCGNU { // The lookup function is guaranteed not to capture the receiver pointer. LookupFn->setDoesNotCapture(1); - llvm::CallInst *slot = - Builder.CreateCall3(LookupFn, - EnforceType(Builder, ReceiverPtr, PtrToIdTy), - EnforceType(Builder, cmd, SelectorTy), - EnforceType(Builder, self, IdTy)); - slot->setOnlyReadsMemory(); + llvm::Value *args[] = { + EnforceType(Builder, ReceiverPtr, PtrToIdTy), + EnforceType(Builder, cmd, SelectorTy), + EnforceType(Builder, self, IdTy) }; + llvm::CallSite slot = CGF.EmitCallOrInvoke(LookupFn, args); + slot.setOnlyReadsMemory(); slot->setMetadata(msgSendMDKind, node); // Load the imp from the slot - llvm::Value *imp = Builder.CreateLoad(Builder.CreateStructGEP(slot, 4)); + llvm::Value *imp = + Builder.CreateLoad(Builder.CreateStructGEP(slot.getInstruction(), 4)); // The lookup function may have changed the receiver, so make sure we use // the new one. @@ -1361,8 +1363,8 @@ llvm::Constant *CGObjCGNU::GenerateClassStructure( LongTy, // abi_version IvarOffsets->getType(), // ivar_offsets Properties->getType(), // properties - Int64Ty, // strong_pointers - Int64Ty, // weak_pointers + IntPtrTy, // strong_pointers + IntPtrTy, // weak_pointers NULL); llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0); // Fill in the structure @@ -1723,12 +1725,14 @@ void CGObjCGNU::GenerateProtocolHolderCategory(void) { /// bitfield / with the 63rd bit set will be 1<<64. llvm::Constant *CGObjCGNU::MakeBitField(llvm::SmallVectorImpl<bool> &bits) { int bitCount = bits.size(); - if (bitCount < 64) { + int ptrBits = + (TheModule.getPointerSize() == llvm::Module::Pointer32) ? 32 : 64; + if (bitCount < ptrBits) { uint64_t val = 1; for (int i=0 ; i<bitCount ; ++i) { if (bits[i]) val |= 1ULL<<(i+1); } - return llvm::ConstantInt::get(Int64Ty, val); + return llvm::ConstantInt::get(IntPtrTy, val); } llvm::SmallVector<llvm::Constant*, 8> values; int v=0; @@ -1748,8 +1752,6 @@ llvm::Constant *CGObjCGNU::MakeBitField(llvm::SmallVectorImpl<bool> &bits) { llvm::Constant *GS = MakeGlobal(llvm::StructType::get(Int32Ty, arrayTy, NULL), fields); llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy); - if (IntPtrTy != Int64Ty) - ptr = llvm::ConstantExpr::getZExt(ptr, Int64Ty); return ptr; } @@ -2073,12 +2075,12 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { } ++ivarIndex; } - llvm::Constant *Zero64 = llvm::ConstantInt::get(Int64Ty, 0); + llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0); //Generate metaclass for class methods llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr, NULLPtr, 0x12L, ClassName.c_str(), 0, Zeros[0], GenerateIvarList( empty, empty, empty), ClassMethodList, NULLPtr, - NULLPtr, NULLPtr, Zero64, Zero64, true); + NULLPtr, NULLPtr, ZeroPtr, ZeroPtr, true); // Generate the class structure llvm::Constant *ClassStruct = diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp index 924ec84..275045c 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp @@ -29,6 +29,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Mangle.h" #include "clang/AST/RecordLayout.h" +#include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" @@ -858,6 +859,59 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { } } +namespace { + struct FunctionIsDirectlyRecursive : + public RecursiveASTVisitor<FunctionIsDirectlyRecursive> { + const StringRef Name; + bool Result; + FunctionIsDirectlyRecursive(const FunctionDecl *F) : + Name(F->getName()), Result(false) { + } + typedef RecursiveASTVisitor<FunctionIsDirectlyRecursive> Base; + + bool TraverseCallExpr(CallExpr *E) { + const Decl *D = E->getCalleeDecl(); + if (!D) + return true; + AsmLabelAttr *Attr = D->getAttr<AsmLabelAttr>(); + if (!Attr) + return true; + if (Name == Attr->getLabel()) { + Result = true; + return false; + } + return true; + } + }; +} + +// isTriviallyRecursiveViaAsm - Check if this function calls another +// decl that, because of the asm attribute, ends up pointing to itself. +bool +CodeGenModule::isTriviallyRecursiveViaAsm(const FunctionDecl *F) { + if (getCXXABI().getMangleContext().shouldMangleDeclName(F)) + return false; + + FunctionIsDirectlyRecursive Walker(F); + Walker.TraverseFunctionDecl(const_cast<FunctionDecl*>(F)); + return Walker.Result; +} + +bool +CodeGenModule::shouldEmitFunction(const FunctionDecl *F) { + if (getFunctionLinkage(F) != llvm::Function::AvailableExternallyLinkage) + return true; + if (CodeGenOpts.OptimizationLevel == 0 && + !F->hasAttr<AlwaysInlineAttr>()) + return false; + // PR9614. Avoid cases where the source code is lying to us. An available + // externally function should have an equivalent function somewhere else, + // but a function that calls itself is clearly not equivalent to the real + // implementation. + // This happens in glibc's btowc and in some configure checks. + return !isTriviallyRecursiveViaAsm(F); +} + void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) { const ValueDecl *D = cast<ValueDecl>(GD.getDecl()); @@ -868,10 +922,7 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) { if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { // At -O0, don't generate IR for functions with available_externally // linkage. - if (CodeGenOpts.OptimizationLevel == 0 && - !Function->hasAttr<AlwaysInlineAttr>() && - getFunctionLinkage(Function) - == llvm::Function::AvailableExternallyLinkage) + if (!shouldEmitFunction(Function)) return; if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) { diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h index 8e38a89..dbc6a87 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h +++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h @@ -324,6 +324,8 @@ class CodeGenModule : public CodeGenTypeCache { void createOpenCLRuntime(); void createCUDARuntime(); + bool isTriviallyRecursiveViaAsm(const FunctionDecl *F); + bool shouldEmitFunction(const FunctionDecl *F); llvm::LLVMContext &VMContext; /// @name Cache for Blocks Runtime Globals |