GCC carefully packs these bitfields so that there are exactly 32 of
them. With this addition, you'll push over and require an extra
word for every tree. Would it be possible to record the gcroot flag
in the attributes list somehow? This tradeoff seems worthwhile,
because almost no structs will be marked as GCable.
Sure. Here's the new patch. I removed any dependence on RECORD_TYPE,
but make sure we have a pointer at least to gcroot from.
-eric
Index: gcc/llvm-convert.cpp
===================================================================
--- gcc/llvm-convert.cpp (revision 42184)
+++ gcc/llvm-convert.cpp (working copy)
@@ -655,6 +655,11 @@ void TreeToLLVM::StartFunctionBody() {
// Emit annotate intrinsic if arg has annotate attr
if (DECL_ATTRIBUTES(Args))
EmitAnnotateIntrinsic(Tmp, Args);
+
+ // Emit gcroot intrinsic if arg has attribute
+ if (POINTER_TYPE_P(TREE_TYPE(Args))
+ && lookup_attribute ("gcroot", TYPE_ATTRIBUTES(TREE_TYPE(Args))))
+ EmitTypeGcroot(Tmp, Args);
Client.setName(Name);
Client.setLocation(Tmp);
@@ -1420,6 +1425,25 @@ void TreeToLLVM::AddBranchFixup(BranchIn
BranchFixups.push_back(BranchFixup(BI, isExceptionEdge));
}
+// Emits code to do something for a type attribute
+void TreeToLLVM::EmitTypeGcroot(Value *V, tree decl) {
+
+ Function *gcrootFun = Intrinsic::getDeclaration(TheModule,
+ Intrinsic::gcroot);
+
+ // The idea is that it's a pointer to type "Value"
+ // which is opaque* but the routine expects i8** and i8*.
+ const PointerType *Ty = PointerType::get(Type::Int8Ty);
+ V = Builder.CreateBitCast(V, PointerType::get(Ty), "tmp");
+
+ Value *Ops[2] = {
+ V,
+ ConstantPointerNull::get(Ty)
+ };
+
+ Builder.CreateCall(gcrootFun, Ops, Ops+2);
+}
+
// Emits annotate intrinsic if the decl has the annotate attribute set.
void TreeToLLVM::EmitAnnotateIntrinsic(Value *V, tree decl) {
@@ -1581,6 +1605,17 @@ void TreeToLLVM::EmitAutomaticVariableDe
// Handle annotate attributes
if (DECL_ATTRIBUTES(decl))
EmitAnnotateIntrinsic(AI, decl);
+
+ // Handle gcroot attribute
+ if (POINTER_TYPE_P(TREE_TYPE (decl))
+ && lookup_attribute("gcroot", TYPE_ATTRIBUTES(TREE_TYPE (decl))))
+ {
+ // We should null out local variables so that a stack crawl
+ // before initialization doesn't get garbage results to follow.
+ const Type *T = cast<PointerType>(AI->getType())->getElementType();
+ EmitTypeGcroot(AI, decl);
+ Builder.CreateStore(Constant::getNullValue(T), AI);
+ }
if (TheDebugInfo) {
if (DECL_NAME(decl)) {
Index: gcc/llvm-internal.h
===================================================================
--- gcc/llvm-internal.h (revision 42184)
+++ gcc/llvm-internal.h (working copy)
@@ -472,7 +472,9 @@ private:
/// EmitAnnotateIntrinsic - Emits call to annotate attr intrinsic
void EmitAnnotateIntrinsic(Value *V, tree_node *decl);
-
+
+ /// EmitTypeGcroot - Emits call to make type a gcroot
+ void EmitTypeGcroot(Value *V, tree_node *decl);
private:
/// GatherTypeInfo - Walk through the expression gathering all the
/// typeinfos that are used.
Index: gcc/c-common.c
===================================================================
--- gcc/c-common.c (revision 42184)
+++ gcc/c-common.c (working copy)
@@ -663,6 +663,7 @@ static tree handle_sentinel_attribute (t
/* APPLE LOCAL begin LLVM */
#ifdef ENABLE_LLVM
static tree handle_annotate_attribute (tree*, tree, tree, int, bool *);
+static tree handle_gcroot_attribute (tree *, tree, tree, int, bool *);
#endif
/* APPLE LOCAL end LLVM */
@@ -757,6 +758,8 @@ const struct attribute_spec c_common_att
#ifdef ENABLE_LLVM
{ "annotate", 0, -1, true, false, false,
handle_annotate_attribute },
+ { "gcroot", 0, 0, false, true, false,
+ handle_gcroot_attribute },
#endif
/* APPLE LOCAL end LLVM */
{ NULL, 0, 0, false, false, false, NULL }
@@ -5812,6 +5815,21 @@ handle_annotate_attribute (tree *node, t
return NULL_TREE;
}
+
+/* Handle the "gcroot" attribute */
+static tree
+handle_gcroot_attribute (tree *node, tree name, tree ARG_UNUSED(args),
+ int ARG_UNUSED(flags), bool *ARG_UNUSED(no_add_attrs))
+{
+ if (!TYPE_P (*node)
+ || !POINTER_TYPE_P (*node))
+ {
+ warning ("%qs attribute ignored", IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ }
+
+ return NULL_TREE;
+}
#endif
/* APPLE LOCAL end LLVM */
Index: test/CFrontend/2007-09-20-GcrootAttribute.c
===================================================================
--- test/CFrontend/2007-09-20-GcrootAttribute.c (revision 0)
+++ test/CFrontend/2007-09-20-GcrootAttribute.c (revision 0)
@@ -0,0 +1,28 @@
+// RUN: %llvmgxx -c -emit-llvm %s -o - | grep llvm.gcroot
+// RUN: %llvmgxx -c -emit-llvm %s -o - | grep llvm.gcroot | count 6
+
+typedef struct foo_s
+{
+ int a;
+} foo, __attribute__ ((gcroot)) *foo_p;
+
+foo my_foo;
+
+int alpha ()
+{
+ foo my_foo2 = my_foo;
+
+ return my_foo2.a;
+}
+
+int bar (foo a)
+{
+ foo_p b;
+ return b->a;
+}
+
+foo_p baz (foo_p a, foo_p b, foo_p *c)
+{
+ a = b = *c;
+ return a;
+}
_______________________________________________
llvm-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits