aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorJulien Lerouge <jlerouge@apple.com>2011-09-09 22:41:49 +0000
committerJulien Lerouge <jlerouge@apple.com>2011-09-09 22:41:49 +0000
commit77f68bb90af93b95045fb994e7cd68137adcc132 (patch)
tree16930a6023a153032d79ad743e75cf1f5d54646f /lib/CodeGen
parent712f2fcb70ae2eb0cb684d565e7d2cb76881006b (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.cpp11
-rw-r--r--lib/CodeGen/CGDecl.cpp15
-rw-r--r--lib/CodeGen/CGExpr.cpp3
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp47
-rw-r--r--lib/CodeGen/CodeGenFunction.h17
-rw-r--r--lib/CodeGen/CodeGenModule.cpp131
-rw-r--r--lib/CodeGen/CodeGenModule.h38
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);