[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