diff options
author | Julien Lerouge <jlerouge@apple.com> | 2011-09-09 22:41:49 +0000 |
---|---|---|
committer | Julien Lerouge <jlerouge@apple.com> | 2011-09-09 22:41:49 +0000 |
commit | 77f68bb90af93b95045fb994e7cd68137adcc132 (patch) | |
tree | 16930a6023a153032d79ad743e75cf1f5d54646f /lib/CodeGen | |
parent | 712f2fcb70ae2eb0cb684d565e7d2cb76881006b (diff) |
Bring llvm.annotation* intrinsics support back to where it was in llvm-gcc: can
annotate global, local variables, struct fields, or arbitrary statements (using
the __builtin_annotation), rdar://8037476.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139423 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGBuiltin.cpp | 11 | ||||
-rw-r--r-- | lib/CodeGen/CGDecl.cpp | 15 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 47 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 17 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 131 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 38 |
7 files changed, 187 insertions, 75 deletions
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 642bf15e1b..18c2bd3fe7 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -991,6 +991,17 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, Value *Result = Builder.CreateICmpSLT(BCArg, ZeroCmp); return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType()))); } + case Builtin::BI__builtin_annotation: { + llvm::Value *AnnVal = EmitScalarExpr(E->getArg(0)); + llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::annotation, + AnnVal->getType()); + + // Get the annotation string, go through casts. Sema requires this to be a + // non-wide string literal, potentially casted, so the cast<> is safe. + const Expr *AnnotationStrExpr = E->getArg(1)->IgnoreParenCasts(); + llvm::StringRef Str = cast<StringLiteral>(AnnotationStrExpr)->getString(); + return RValue::get(EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc())); + } } // If this is an alias for a libm function (e.g. __builtin_sin) turn it into diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 5fa99a513a..9ecc72781c 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -271,13 +271,8 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D, GV->setAlignment(getContext().getDeclAlign(&D).getQuantity()); - // FIXME: Merge attribute handling. - if (const AnnotateAttr *AA = D.getAttr<AnnotateAttr>()) { - SourceManager &SM = CGM.getContext().getSourceManager(); - llvm::Constant *Ann = - CGM.EmitAnnotateAttr(GV, AA, SM.getExpansionLineNumber(D.getLocation())); - CGM.AddAnnotation(Ann); - } + if (D.hasAttr<AnnotateAttr>()) + CGM.AddGlobalAnnotations(&D, GV); if (const SectionAttr *SA = D.getAttr<SectionAttr>()) GV->setSection(SA->getName()); @@ -853,6 +848,9 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { DI->EmitDeclareOfAutoVariable(&D, DeclPtr, Builder); } + if (D.hasAttr<AnnotateAttr>()) + EmitVarAnnotations(&D, emission.Address); + return emission; } @@ -1502,4 +1500,7 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg, // Emit debug info for param declaration. if (CGDebugInfo *DI = getDebugInfo()) DI->EmitDeclareOfArgVariable(&D, DeclPtr, ArgNo, Builder); + + if (D.hasAttr<AnnotateAttr>()) + EmitVarAnnotations(&D, DeclPtr); } diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index daaf7a5887..7ae95331ad 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1875,6 +1875,9 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value *baseAddr, CGM.getTypes().ConvertTypeForMem(type), field->getName()); + if (field->hasAttr<AnnotateAttr>()) + addr = EmitFieldAnnotations(field, addr); + unsigned alignment = getContext().getDeclAlign(field).getQuantity(); LValue LV = MakeAddrLValue(addr, type, alignment); LV.getQuals().addCVRQualifiers(cvr); diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index a16f10e654..b4b2eb16ad 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -1018,3 +1018,50 @@ void CodeGenFunction::unprotectFromPeepholes(PeepholeProtection protection) { // In theory, we could try to duplicate the peepholes now, but whatever. protection.Inst->eraseFromParent(); } + +llvm::Value *CodeGenFunction::EmitAnnotationCall(llvm::Value *AnnotationFn, + llvm::Value *AnnotatedVal, + llvm::StringRef AnnotationStr, + SourceLocation Location) { + llvm::Value *Args[4] = { + AnnotatedVal, + Builder.CreateBitCast(CGM.EmitAnnotationString(AnnotationStr), Int8PtrTy), + Builder.CreateBitCast(CGM.EmitAnnotationUnit(Location), Int8PtrTy), + CGM.EmitAnnotationLineNo(Location) + }; + return Builder.CreateCall(AnnotationFn, Args); +} + +void CodeGenFunction::EmitVarAnnotations(const VarDecl *D, llvm::Value *V) { + assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute"); + // FIXME We create a new bitcast for every annotation because that's what + // llvm-gcc was doing. + for (specific_attr_iterator<AnnotateAttr> + ai = D->specific_attr_begin<AnnotateAttr>(), + ae = D->specific_attr_end<AnnotateAttr>(); ai != ae; ++ai) + EmitAnnotationCall(CGM.getIntrinsic(llvm::Intrinsic::var_annotation), + Builder.CreateBitCast(V, CGM.Int8PtrTy, V->getName()), + (*ai)->getAnnotation(), D->getLocation()); +} + +llvm::Value *CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D, + llvm::Value *V) { + assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute"); + llvm::Type *VTy = V->getType(); + llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation, + CGM.Int8PtrTy); + + for (specific_attr_iterator<AnnotateAttr> + ai = D->specific_attr_begin<AnnotateAttr>(), + ae = D->specific_attr_end<AnnotateAttr>(); ai != ae; ++ai) { + // FIXME Always emit the cast inst so we can differentiate between + // annotation on the first field of a struct and annotation on the struct + // itself. + if (VTy != CGM.Int8PtrTy) + V = Builder.Insert(new llvm::BitCastInst(V, CGM.Int8PtrTy)); + V = EmitAnnotationCall(F, V, (*ai)->getAnnotation(), D->getLocation()); + V = Builder.CreateBitCast(V, VTy); + } + + return V; +} diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 36dcffcd4c..702aca8aca 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -2272,6 +2272,23 @@ public: void EmitCXXThrowExpr(const CXXThrowExpr *E); //===--------------------------------------------------------------------===// + // Annotations Emission + //===--------------------------------------------------------------------===// + + /// Emit an annotation call (intrinsic or builtin). + llvm::Value *EmitAnnotationCall(llvm::Value *AnnotationFn, + llvm::Value *AnnotatedVal, + llvm::StringRef AnnotationStr, + SourceLocation Location); + + /// Emit local annotations for the local variable V, declared by D. + void EmitVarAnnotations(const VarDecl *D, llvm::Value *V); + + /// Emit field annotations for the given field & value. Returns the + /// annotation result. + llvm::Value *EmitFieldAnnotations(const FieldDecl *D, llvm::Value *V); + + //===--------------------------------------------------------------------===// // Internal Helpers //===--------------------------------------------------------------------===// diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 6df03c886f..67757a22c5 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -44,6 +44,8 @@ using namespace clang; using namespace CodeGen; +static const char AnnotationSection[] = "llvm.metadata"; + static CGCXXABI &createCXXABI(CodeGenModule &CGM) { switch (CGM.getContext().getTargetInfo().getCXXABI()) { case CXXABI_ARM: return *CreateARMCXXABI(CGM); @@ -131,7 +133,7 @@ void CodeGenModule::Release() { AddGlobalCtor(ObjCInitFunction); EmitCtorList(GlobalCtors, "llvm.global_ctors"); EmitCtorList(GlobalDtors, "llvm.global_dtors"); - EmitAnnotations(); + EmitGlobalAnnotations(); EmitLLVMUsed(); SimplifyPersonality(); @@ -382,22 +384,6 @@ void CodeGenModule::EmitCtorList(const CtorList &Fns, const char *GlobalName) { } } -void CodeGenModule::EmitAnnotations() { - if (Annotations.empty()) - return; - - // Create a new global variable for the ConstantStruct in the Module. - llvm::Constant *Array = - llvm::ConstantArray::get(llvm::ArrayType::get(Annotations[0]->getType(), - Annotations.size()), - Annotations); - llvm::GlobalValue *gv = - new llvm::GlobalVariable(TheModule, Array->getType(), false, - llvm::GlobalValue::AppendingLinkage, Array, - "llvm.global.annotations"); - gv->setSection("llvm.metadata"); -} - llvm::GlobalValue::LinkageTypes CodeGenModule::getFunctionLinkage(const FunctionDecl *D) { GVALinkage Linkage = getContext().GetGVALinkageForFunction(D); @@ -642,54 +628,78 @@ void CodeGenModule::EmitDeferred() { } } -/// EmitAnnotateAttr - Generate the llvm::ConstantStruct which contains the -/// annotation information for a given GlobalValue. The annotation struct is -/// {i8 *, i8 *, i8 *, i32}. The first field is a constant expression, the -/// GlobalValue being annotated. The second field is the constant string -/// created from the AnnotateAttr's annotation. The third field is a constant -/// string containing the name of the translation unit. The fourth field is -/// the line number in the file of the annotated value declaration. -/// -/// FIXME: this does not unique the annotation string constants, as llvm-gcc -/// appears to. -/// +void CodeGenModule::EmitGlobalAnnotations() { + if (Annotations.empty()) + return; + + // Create a new global variable for the ConstantStruct in the Module. + llvm::Constant *Array = llvm::ConstantArray::get(llvm::ArrayType::get( + Annotations[0]->getType(), Annotations.size()), Annotations); + llvm::GlobalValue *gv = new llvm::GlobalVariable(getModule(), + Array->getType(), false, llvm::GlobalValue::AppendingLinkage, Array, + "llvm.global.annotations"); + gv->setSection(AnnotationSection); +} + +llvm::Constant *CodeGenModule::EmitAnnotationString(llvm::StringRef Str) { + llvm::StringMap<llvm::Constant*>::iterator i = AnnotationStrings.find(Str); + if (i != AnnotationStrings.end()) + return i->second; + + // Not found yet, create a new global. + llvm::Constant *s = llvm::ConstantArray::get(getLLVMContext(), Str, true); + llvm::GlobalValue *gv = new llvm::GlobalVariable(getModule(), s->getType(), + true, llvm::GlobalValue::PrivateLinkage, s, ".str"); + gv->setSection(AnnotationSection); + gv->setUnnamedAddr(true); + AnnotationStrings[Str] = gv; + return gv; +} + +llvm::Constant *CodeGenModule::EmitAnnotationUnit(SourceLocation Loc) { + SourceManager &SM = getContext().getSourceManager(); + PresumedLoc PLoc = SM.getPresumedLoc(Loc); + if (PLoc.isValid()) + return EmitAnnotationString(PLoc.getFilename()); + return EmitAnnotationString(SM.getBufferName(Loc)); +} + +llvm::Constant *CodeGenModule::EmitAnnotationLineNo(SourceLocation L) { + SourceManager &SM = getContext().getSourceManager(); + PresumedLoc PLoc = SM.getPresumedLoc(L); + unsigned LineNo = PLoc.isValid() ? PLoc.getLine() : + SM.getExpansionLineNumber(L); + return llvm::ConstantInt::get(Int32Ty, LineNo); +} + llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV, const AnnotateAttr *AA, - unsigned LineNo) { - llvm::Module *M = &getModule(); - - // get [N x i8] constants for the annotation string, and the filename string - // which are the 2nd and 3rd elements of the global annotation structure. - llvm::Type *SBP = llvm::Type::getInt8PtrTy(VMContext); - llvm::Constant *anno = llvm::ConstantArray::get(VMContext, - AA->getAnnotation(), true); - llvm::Constant *unit = llvm::ConstantArray::get(VMContext, - M->getModuleIdentifier(), - true); - - // Get the two global values corresponding to the ConstantArrays we just - // created to hold the bytes of the strings. - llvm::GlobalValue *annoGV = - new llvm::GlobalVariable(*M, anno->getType(), false, - llvm::GlobalValue::PrivateLinkage, anno, - GV->getName()); - // translation unit name string, emitted into the llvm.metadata section. - llvm::GlobalValue *unitGV = - new llvm::GlobalVariable(*M, unit->getType(), false, - llvm::GlobalValue::PrivateLinkage, unit, - ".str"); - unitGV->setUnnamedAddr(true); + SourceLocation L) { + // Get the globals for file name, annotation, and the line number. + llvm::Constant *AnnoGV = EmitAnnotationString(AA->getAnnotation()), + *UnitGV = EmitAnnotationUnit(L), + *LineNoCst = EmitAnnotationLineNo(L); // Create the ConstantStruct for the global annotation. llvm::Constant *Fields[4] = { - llvm::ConstantExpr::getBitCast(GV, SBP), - llvm::ConstantExpr::getBitCast(annoGV, SBP), - llvm::ConstantExpr::getBitCast(unitGV, SBP), - llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), LineNo) + llvm::ConstantExpr::getBitCast(GV, Int8PtrTy), + llvm::ConstantExpr::getBitCast(AnnoGV, Int8PtrTy), + llvm::ConstantExpr::getBitCast(UnitGV, Int8PtrTy), + LineNoCst }; return llvm::ConstantStruct::getAnon(Fields); } +void CodeGenModule::AddGlobalAnnotations(const ValueDecl *D, + llvm::GlobalValue *GV) { + assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute"); + // Get the struct elements for these annotations. + for (specific_attr_iterator<AnnotateAttr> + ai = D->specific_attr_begin<AnnotateAttr>(), + ae = D->specific_attr_end<AnnotateAttr>(); ai != ae; ++ai) + Annotations.push_back(EmitAnnotateAttr(GV, *ai, D->getLocation())); +} + bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) { // Never defer when EmitAllDecls is specified. if (Features.EmitAllDecls) @@ -1297,11 +1307,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { cast<llvm::GlobalValue>(Entry)->eraseFromParent(); } - if (const AnnotateAttr *AA = D->getAttr<AnnotateAttr>()) { - SourceManager &SM = Context.getSourceManager(); - AddAnnotation(EmitAnnotateAttr( - GV, AA, SM.getExpansionLineNumber(D->getLocation()))); - } + if (D->hasAttr<AnnotateAttr>()) + AddGlobalAnnotations(D, GV); GV->setInitializer(Init); @@ -1530,6 +1537,8 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) { AddGlobalCtor(Fn, CA->getPriority()); if (const DestructorAttr *DA = D->getAttr<DestructorAttr>()) AddGlobalDtor(Fn, DA->getPriority()); + if (D->hasAttr<AnnotateAttr>()) + AddGlobalAnnotations(D, Fn); } void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) { diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 3e5de655ab..7d0d95141a 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -260,8 +260,12 @@ class CodeGenModule : public CodeGenTypeCache { llvm::DenseMap<GlobalDecl, StringRef> MangledDeclNames; llvm::BumpPtrAllocator MangledNamesAllocator; + /// Global annotations. std::vector<llvm::Constant*> Annotations; + /// Map used to get unique annotation strings. + llvm::StringMap<llvm::Constant*> AnnotationStrings; + llvm::StringMap<llvm::Constant*> CFConstantStringMap; llvm::StringMap<llvm::GlobalVariable*> ConstantStringMap; llvm::DenseMap<const Decl*, llvm::Value*> StaticLocalDeclMap; @@ -598,8 +602,6 @@ public: /// metadata global. void AddUsedGlobal(llvm::GlobalValue *GV); - void AddAnnotation(llvm::Constant *C) { Annotations.push_back(C); } - /// AddCXXDtorEntry - Add a destructor and object to add to the C++ global /// destructor function. void AddCXXDtorEntry(llvm::Constant *DtorFn, llvm::Constant *Object) { @@ -643,9 +645,6 @@ public: /// but not always, an LLVM null constant. llvm::Constant *EmitNullConstant(QualType T); - llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV, - const AnnotateAttr *AA, unsigned LineNo); - /// Error - Emit a general error that something can't be done. void Error(SourceLocation loc, StringRef error); @@ -733,6 +732,33 @@ public: std::vector<const CXXRecordDecl*> DeferredVTables; + /// Emit all the global annotations. + void EmitGlobalAnnotations(); + + /// Emit an annotation string. + llvm::Constant *EmitAnnotationString(llvm::StringRef Str); + + /// Emit the annotation's translation unit. + llvm::Constant *EmitAnnotationUnit(SourceLocation Loc); + + /// Emit the annotation line number. + llvm::Constant *EmitAnnotationLineNo(SourceLocation L); + + /// EmitAnnotateAttr - Generate the llvm::ConstantStruct which contains the + /// annotation information for a given GlobalValue. The annotation struct is + /// {i8 *, i8 *, i8 *, i32}. The first field is a constant expression, the + /// GlobalValue being annotated. The second field is the constant string + /// created from the AnnotateAttr's annotation. The third field is a constant + /// string containing the name of the translation unit. The fourth field is + /// the line number in the file of the annotated value declaration. + llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV, + const AnnotateAttr *AA, + SourceLocation L); + + /// Add global annotations that are set on D, for the global GV. Those + /// annotations are emitted during finalization of the LLVM code. + void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV); + private: llvm::GlobalValue *GetGlobalValue(StringRef Ref); @@ -818,8 +844,6 @@ private: /// suitable for use as a LLVM constructor or destructor array. void EmitCtorList(const CtorList &Fns, const char *GlobalName); - void EmitAnnotations(void); - /// EmitFundamentalRTTIDescriptor - Emit the RTTI descriptors for the /// given type. void EmitFundamentalRTTIDescriptor(QualType Type); |