Skip to content

Commit

Permalink
Bring llvm.annotation* intrinsics support back to where it was in llv…
Browse files Browse the repository at this point in the history
…m-gcc: can

annotate global, local variables, struct fields, or arbitrary statements (using
the __builtin_annotation), rdar://8037476.

llvm-svn: 139423
  • Loading branch information
Julien Lerouge committed Sep 9, 2011
1 parent 5bfb0e0 commit 5a6b698
Show file tree
Hide file tree
Showing 21 changed files with 401 additions and 88 deletions.
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def AnalyzerNoReturn : InheritableAttr {
let Spellings = ["analyzer_noreturn"];
}

def Annotate : InheritableAttr {
def Annotate : InheritableParamAttr {
let Spellings = ["annotate"];
let Args = [StringArgument<"Annotation">];
}
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/Builtins.def
Original file line number Diff line number Diff line change
Expand Up @@ -741,5 +741,8 @@ LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", "Blocks.h", ALL_LANGUAGES)
LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES)
// FIXME: Also declare NSConcreteGlobalBlock and NSConcreteStackBlock.

// Annotation function
BUILTIN(__builtin_annotation, "UiUicC*", "nc")

#undef BUILTIN
#undef LIBBUILTIN
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -4420,6 +4420,9 @@ def err_return_in_block_expression : Error<
def err_block_returning_array_function : Error<
"block cannot return %select{array|function}0 type %1">;

// Builtin annotation string.
def err_builtin_annotation_not_string_constant : Error<
"__builtin_annotation requires a non wide string constant">;

// CFString checking
def err_cfstring_literal_not_string_constant : Error<
Expand Down
11 changes: 11 additions & 0 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 8 additions & 7 deletions clang/lib/CodeGen/CGDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -853,6 +848,9 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
DI->EmitDeclareOfAutoVariable(&D, DeclPtr, Builder);
}

if (D.hasAttr<AnnotateAttr>())
EmitVarAnnotations(&D, emission.Address);

return emission;
}

Expand Down Expand Up @@ -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);
}
3 changes: 3 additions & 0 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
47 changes: 47 additions & 0 deletions clang/lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
17 changes: 17 additions & 0 deletions clang/lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -2271,6 +2271,23 @@ class CodeGenFunction : public CodeGenTypeCache {

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
//===--------------------------------------------------------------------===//
Expand Down
131 changes: 70 additions & 61 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -131,7 +133,7 @@ void CodeGenModule::Release() {
AddGlobalCtor(ObjCInitFunction);
EmitCtorList(GlobalCtors, "llvm.global_ctors");
EmitCtorList(GlobalDtors, "llvm.global_dtors");
EmitAnnotations();
EmitGlobalAnnotations();
EmitLLVMUsed();

SimplifyPersonality();
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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) {
Expand Down
Loading

0 comments on commit 5a6b698

Please sign in to comment.