[llvm-commits] [patch] add gcroot attribute, test

Gordon Henriksen gordonhenriksen at mac.com
Fri Sep 21 07:49:33 PDT 2007


Hi Eric,

On Sep 21, 2007, at 04:49, Eric Christopher wrote:

> Here are a pair of patches to add an attribute to automatically  
> gcroot things based on type. It currently works for pointers to  
> structures only because a) that's all I need, and b) I think that's  
> all that makes sense really. I could remove the restriction if  
> someone can come up with a good use case for other types.

Very cool.

> Note that we're also zeroing out automatic variables as well so if  
> we do a collection before they're initialized we don't end up  
> following garbage.

@@ -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))
+      && TYPE_GCROOT(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)) {

This is redundant; LLVM does it for you. See thread starting here:

   http://www.mail-archive.com/llvm-commits@cs.uiuc.edu/msg23987.html

The upshot is that the collector knows whether it is necessary to  
initialize roots or not, and does so on the program's behalf iff  
necessary.

However, if the source language requires null initialization  
semantics, then the front-end should emit explicit null initializers  
(as the variable comes into scope).


+// 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");

The llvm.gcroot intrinsic can be declared to take any types you care  
to give it in the module, so long as its eventual type is like void 
(<ty>**, <ty2>*).

But since you don't have a parent type to use, what you've done  
probably makes as much sense as anything.

— Gordon

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20070921/a227703e/attachment.html>


More information about the llvm-commits mailing list