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

Chris Lattner clattner at apple.com
Fri Sep 21 10:24:48 PDT 2007


>> 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

I don't think so: the patch makes it so that llvm.gcroot *doesn't*  
implicitly null out the root.  This means the front-end *does* need  
to explicitly emit the null init if it wants it, right?

> 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.

I don't think the collector wants to be in the business of nulling  
out pointers.  The important thing is that when the collector runs,  
it doesn't want a root with garbage in it.

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

Even if the language doesn't require it, for GC roots, it seems very  
dangerous to hand the collector a root with random garbage in it, agree?

> +// 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>*).

Actually no, I need to update the langref.html document to make this  
explicit, thanks for reminding me.  The issue is that if you link two  
modules with different <ty>'s, the two different intrinsics would  
have to be merged somehow.  By forcing the intrinsic to a specific  
type this problem doesn't happen.

-Chris

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


More information about the llvm-commits mailing list