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/[email protected]/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
_______________________________________________
llvm-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits