Is there some reason that RefineAbstractType doesn't recurse down DerivedTypes and further resolve abstract types? In Fortran it is possible to have a routine that takes a function pointer to a routine with the same signature. This is not possible to express in C/C++. I'm not sure it's possible to express in LLVM either without using varargs (opinions welcome). In a simpler C++ example, we end upcreating a function pointer type: void (...) * (opaque *) We want to resolve "opaque" to be void (...) Note that this isn't the same issue as in Fortran (it's not a recursive type) but it serves the purpose for this question. Unfortunately, calling FunctionType::refineAbstractType(opaque, void (...)) doesn't work because RefineAbstractType doesn't recurse down into the pointee types. It ends up giving back void (...) * (opaque *) so it didn't resolve anything. It's not clear how to fix this without a core LLVM change because the pointee depth could be arbitrary (pointer to pointer to pointer...). Thoughts? -Dave
On Nov 12, 2008, at 2:59 PM, David Greene wrote:> Is there some reason that RefineAbstractType doesn't recurse down > DerivedTypes > and further resolve abstract types?Because that would resolve two different types. RefineAbstractType just refines the one type you request, and further uniques types based on it. In fact, I strongly suspect that RefineAbstractType doesn't work if you give it something that isn't Opaque. I'd recommend only using it on Opaque, not random abstract types.> In Fortran it is possible to have a routine that takes a function > pointer to a > routine with the same signature. This is not possible to express in > C/C++. > I'm not sure it's possible to express in LLVM either without using > varargs > (opinions welcome).Sure, LLVM is more general than C. In LLVM, you can have a pointer that points to itself, for example: %t = type %t* which is "\1*" if you like up references. I'm not sure what a function pointer that takes a pointer to itself has to do with opaque types, but you'd write it like this: %t = type void (%t)* or if you want the function: %t = type void (%t*)> Unfortunately, calling FunctionType::refineAbstractType(opaque, void > (...)) > doesn't work because RefineAbstractType doesn't recurse down into the > pointee types.What types are you starting out with? If you had the equivalent of: %t1 = type opaque %t2 = type void(%t1*) and you refine t1 -> t2, it should work. -Chris
On Wednesday 12 November 2008 17:29, Chris Lattner wrote:> In fact, I strongly suspect that RefineAbstractType doesn't work if > you give it something that isn't Opaque. I'd recommend only using it > on Opaque, not random abstract types.Ok.> Sure, LLVM is more general than C. In LLVM, you can have a pointer > that points to itself, for example: > > %t = type %t* > > which is "\1*" if you like up references. > > I'm not sure what a function pointer that takes a pointer to itself > has to do with opaque types, but you'd write it like this:It has to do with the way we're processing things right now. We have to break the processing recursion so we create an Opaque type as a stand-in for the (yet-to-be-completed) FunctionType when we encounter an argument referencing the (yet-to-be-completed) FunctionType. We want to resolve those OpaqueTypes once we have the FunctionType constructed.> > %t = type void (%t)* > > or if you want the function: > > %t = type void (%t*)Cool.> > Unfortunately, calling FunctionType::refineAbstractType(opaque, void > > (...)) > > doesn't work because RefineAbstractType doesn't recurse down into the > > pointee types. > > What types are you starting out with? If you had the equivalent of: > > %t1 = type opaque > %t2 = type void(%t1*) > > and you refine t1 -> t2, it should work.I'm not sure it will. %t1* is the "contained" type inside the FunctionType. RefineAbstractTypes expects the OldType (%t1 in this case) to be in the contained type set. Since a _pointer_ to %t1 is in the contained set, it doesn't see it. -Dave