Revision: 128471 Author: lattner Date: 2007-06-15 14:02:55 -0700 (Fri, 15 Jun 2007)
Log Message: ----------- Add annotate attribute. Modified Paths: -------------- apple-local/branches/llvm/gcc/c-common.c apple-local/branches/llvm/gcc/llvm-backend.cpp apple-local/branches/llvm/gcc/llvm-convert.cpp apple-local/branches/llvm/gcc/llvm-internal.h Modified: apple-local/branches/llvm/gcc/c-common.c =================================================================== --- apple-local/branches/llvm/gcc/c-common.c 2007-06-15 20:34:18 UTC (rev 128470) +++ apple-local/branches/llvm/gcc/c-common.c 2007-06-15 21:02:55 UTC (rev 128471) @@ -660,6 +660,12 @@ bool *); static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *); +/* APPLE LOCAL begin LLVM */ +#ifdef ENABLE_LLVM +static tree handle_annotate_attribute (tree*, tree, tree, int, bool *); +#endif +/* APPLE LOCAL end LLVM */ + static void check_function_nonnull (tree, tree); static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT); static bool nonnull_check_p (tree, unsigned HOST_WIDE_INT); @@ -747,6 +753,12 @@ handle_warn_unused_result_attribute }, { "sentinel", 0, 1, false, true, true, handle_sentinel_attribute }, + /* APPLE LOCAL begin LLVM */ + #ifdef ENABLE_LLVM + { "annotate", 0, -1, true, false, false, + handle_annotate_attribute }, + #endif + /* APPLE LOCAL end LLVM */ { NULL, 0, 0, false, false, false, NULL } }; @@ -5758,6 +5770,39 @@ return NULL_TREE; } +/* APPLE LOCAL begin LLVM */ +#ifdef ENABLE_LLVM +/* Handle "annotate" attribute */ +static tree +handle_annotate_attribute (tree *node, tree name, tree args, + int ARG_UNUSED (flags), bool *no_add_attrs) +{ + tree id; + id = TREE_VALUE (args); + + if (TREE_CODE (*node) == FUNCTION_DECL || + TREE_CODE (*node) == VAR_DECL || TREE_CODE (*node) == PARM_DECL) + { + + /* Arg must be a string and node must be a var or function decl */ + if (TREE_CODE (id) != STRING_CST) + { + error ("%qs attribute arg is required to be a string", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + } + else + { + warning ("%qs attribute ignored", IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + + return NULL_TREE; +} +#endif +/* APPLE LOCAL end LLVM */ + /* Check for valid arguments being passed to a function. */ void check_function_arguments (tree attrs, tree params) Modified: apple-local/branches/llvm/gcc/llvm-backend.cpp =================================================================== --- apple-local/branches/llvm/gcc/llvm-backend.cpp 2007-06-15 20:34:18 UTC (rev 128470) +++ apple-local/branches/llvm/gcc/llvm-backend.cpp 2007-06-15 21:02:55 UTC (rev 128471) @@ -81,6 +81,7 @@ std::vector<std::pair<Function*, int> > StaticCtors, StaticDtors; std::vector<Constant*> AttributeUsedGlobals; std::vector<Constant*> AttributeNoinlineFunctions; +std::vector<std::pair<Constant*, Constant*> > AttributeAnnotateGlobals; /// PerFunctionPasses - This is the list of cleanup passes run per-function /// as each is compiled. In cases where we are not doing IPO, it includes the @@ -489,6 +490,26 @@ AttributeNoinlineFunctions.clear(); } + // Add llvm.global.annotations + if (!AttributeAnnotateGlobals.empty()) { + std::vector<Constant*> AttrList; + + for (unsigned i = 0, e = AttributeAnnotateGlobals.size(); i != e; ++i) { + Constant *Elts[2] = {AttributeAnnotateGlobals[i].first, + AttributeAnnotateGlobals[i].second }; + AttrList.push_back(ConstantStruct::get(Elts, 2, false)); + } + + Constant *Array = + ConstantArray::get(ArrayType::get(AttrList[0]->getType(), AttrList.size()), + AttrList); + GlobalValue *gv = new GlobalVariable(Array->getType(), false, + GlobalValue::AppendingLinkage, Array, + "llvm.global.annotations", TheModule); + gv->setSection("llvm.metadata"); + + } + // Finish off the per-function pass. if (PerFunctionPasses) PerFunctionPasses->doFinalization(); @@ -650,7 +671,47 @@ return; } +/// AddAnnotateAttrsToGlobal - Adds decls that have a +/// annotate attribute to a vector to be emitted later. +void AddAnnotateAttrsToGlobal(GlobalValue *GV, tree decl) { + // Handle annotate attribute on global. + tree annotateAttr = lookup_attribute("annotate", DECL_ATTRIBUTES (decl)); + if (!annotateAttr) + return; + + // There may be multiple annotate attributes. Pass return of lookup_attr + // to successive lookups. + while (annotateAttr) { + + // Each annotate attribute is a tree list. + // Get value of list which is our linked list of args. + tree args = TREE_VALUE(annotateAttr); + + // Each annotate attribute may have multiple args. + // Treat each arg as if it were a separate annotate attribute. + for (tree a = args; a; a = TREE_CHAIN(a)) { + // Each element of the arg list is a tree list, so get value + tree val = TREE_VALUE(a); + + // Assert its a string, and then get that string. + assert(TREE_CODE(val) == STRING_CST && + "Annotate attribute arg should always be a string"); + Constant *strGV = TreeConstantToLLVM::EmitLV_STRING_CST(val); + const Type *SBP= PointerType::get(Type::Int8Ty); + AttributeAnnotateGlobals.push_back( + std::make_pair(ConstantExpr::getBitCast(GV,SBP), + ConstantExpr::getBitCast(strGV,SBP))); + } + + // Get next annotate attribute. + annotateAttr = TREE_CHAIN(annotateAttr); + if (annotateAttr) + annotateAttr = lookup_attribute("annotate", annotateAttr); + } +} + + /// emit_global_to_llvm - Emit the specified VAR_DECL or aggregate CONST_DECL to /// LLVM as a global variable. This function implements the end of /// assemble_variable. @@ -762,6 +823,10 @@ const Type *SBP= PointerType::get(Type::Int8Ty); AttributeUsedGlobals.push_back(ConstantExpr::getBitCast(GV, SBP)); } + + // Add annotate attributes for globals + if (DECL_ATTRIBUTES(decl)) + AddAnnotateAttrsToGlobal(GV, decl); } if (TheDebugInfo) TheDebugInfo->EmitGlobalVariable(GV, decl); Modified: apple-local/branches/llvm/gcc/llvm-convert.cpp =================================================================== --- apple-local/branches/llvm/gcc/llvm-convert.cpp 2007-06-15 20:34:18 UTC (rev 128470) +++ apple-local/branches/llvm/gcc/llvm-convert.cpp 2007-06-15 21:02:55 UTC (rev 128471) @@ -600,6 +600,10 @@ AttributeNoinlineFunctions.push_back(ConstantExpr::getBitCast(Fn,SBP)); } + // Handle annotate attributes + if (DECL_ATTRIBUTES(FnDecl)) + AddAnnotateAttrsToGlobal(Fn, FnDecl); + // Create a new basic block for the function. Builder.SetInsertPoint(new BasicBlock("entry", Fn)); @@ -645,6 +649,10 @@ Builder.GetInsertBlock()); } + // Emit annotate intrinsic if arg has annotate attr + if (DECL_ATTRIBUTES(Args)) + EmitAnnotateIntrinsic(Tmp, Args); + Client.setName(Name); Client.setLocation(Tmp); ABIConverter.HandleArgument(TREE_TYPE(Args)); @@ -1392,6 +1400,52 @@ BranchFixups.push_back(BranchFixup(BI, isExceptionEdge)); } +// Emits annotate intrinsic if the decl has the annotate attribute set. +void TreeToLLVM::EmitAnnotateIntrinsic(Value *V, tree decl) { + + // Handle annotate attribute on global. + tree annotateAttr = lookup_attribute("annotate", DECL_ATTRIBUTES (decl)); + + if (!annotateAttr) + return; + + Function *annotateFun = Intrinsic::getDeclaration(TheModule, + Intrinsic::var_annotation); + + // There may be multiple annotate attributes. Pass return of lookup_attr + // to successive lookups. + while (annotateAttr) { + + // Each annotate attribute is a tree list. + // Get value of list which is our linked list of args. + tree args = TREE_VALUE(annotateAttr); + + // Each annotate attribute may have multiple args. + // Treat each arg as if it were a separate annotate attribute. + for (tree a = args; a; a = TREE_CHAIN(a)) { + // Each element of the arg list is a tree list, so get value + tree val = TREE_VALUE(a); + + // Assert its a string, and then get that string. + assert(TREE_CODE(val) == STRING_CST && + "Annotate attribute arg should always be a string"); + const Type *SBP = PointerType::get(Type::Int8Ty); + Constant *strGV = TreeConstantToLLVM::EmitLV_STRING_CST(val); + Value *Ops[2] = { + BitCastToType(V, SBP), + BitCastToType(strGV, SBP) + }; + + Builder.CreateCall(annotateFun, Ops, 2); + } + + // Get next annotate attribute. + annotateAttr = TREE_CHAIN(annotateAttr); + if (annotateAttr) + annotateAttr = lookup_attribute("annotate", annotateAttr); + } +} + //===----------------------------------------------------------------------===// // ... Basic Lists and Binding Scopes ... //===----------------------------------------------------------------------===// @@ -1493,9 +1547,13 @@ } AI->setAlignment(Alignment); - + SET_DECL_LLVM(decl, AI); + // Handle annotate attributes + if (DECL_ATTRIBUTES(decl)) + EmitAnnotateIntrinsic(AI, decl); + if (TheDebugInfo) { if (DECL_NAME(decl)) { TheDebugInfo->EmitDeclare(decl, llvm::dwarf::DW_TAG_auto_variable, Modified: apple-local/branches/llvm/gcc/llvm-internal.h =================================================================== --- apple-local/branches/llvm/gcc/llvm-internal.h 2007-06-15 20:34:18 UTC (rev 128470) +++ apple-local/branches/llvm/gcc/llvm-internal.h 2007-06-15 21:02:55 UTC (rev 128471) @@ -92,6 +92,10 @@ /// marked attribute(noinline) extern std::vector<Constant*> AttributeNoinlineFunctions; +/// AddAnnotateAttrsToGlobal - Adds decls that have a +/// annotate attribute to a vector to be emitted later. +extern void AddAnnotateAttrsToGlobal(GlobalValue *GV, union tree_node* decl); + void changeLLVMValue(Value *Old, Value *New); void readLLVMTypesStringTable(); void writeLLVMTypesStringTable(); @@ -444,6 +448,10 @@ static bool isNoopCast(Value *V, const Type *Ty); void HandleMultiplyDefinedGCCTemp(tree_node *var); + + /// EmitAnnotateIntrinsic - Emits call to annotate attr intrinsic + void EmitAnnotateIntrinsic(Value *V, tree_node *decl); + private: /// GatherTypeInfo - Walk through the expression gathering all the /// typeinfos that are used. _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits