Le 15 juin 2010 à 21:14, Chris Lattner a écrit :> > On Jun 15, 2010, at 11:51 AM, Stéphane Letz wrote: > >>> Nope, types are immutable once created. The only thing you can do is "refine" opaque types to other types. There is a section in the programmer's manual on this: >>> http://llvm.org/docs/ProgrammersManual.html#TypeResolve >>> >>> -Chris >> >> >> So I succeeded in using a "PATypeHolder" for the "opaque" type, define a Type* with PointerType::getUnqual, prepare a field, then use " refineAbstractTypeTo " to built the real type with this added field. >> >> The thing is that I would need to do that repeatedly, that is progressively adding fields, generates code that access those ready fields, and "refine" the type step by step. >> >> Is that even possible? > > It would work, but sounds really inefficient. What are you really trying to do here? > > -Chrisinefficient : do you mean because all users of the refined type would have to be "notified" ? The reason is that our code generator generates a struct (progressively adding fields) and generates code that access this struct (that is : the fields that are already added). If we cannot create the struct progressively, then we have to define a pass to build the complete struct, then define a second pass to generate the code. If we can simply create the struct progressively at LLVM level, then it make our code simpler. Thanks Stéphane Letz
On Jun 15, 2010, at 12:45 PM, Stéphane Letz wrote:>>> >>> Is that even possible? >> >> It would work, but sounds really inefficient. What are you really trying to do here? >> >> -Chris > > > inefficient : do you mean because all users of the refined type would have to be "notified" ?Yes.> The reason is that our code generator generates a struct (progressively adding fields) and generates code that access this struct (that is : the fields that are already added). If we cannot create the struct progressively, then we have to define a pass to build the complete struct, then define a second pass to generate the code. If we can simply create the struct progressively at LLVM level, then it make our code simpler.LLVM doesn't support this sort of thing. Is two passes really that bad? -Chris
Le 15 juin 2010 à 23:05, Chris Lattner a écrit :> > On Jun 15, 2010, at 12:45 PM, Stéphane Letz wrote: >>>> >>>> Is that even possible? >>> >>> It would work, but sounds really inefficient. What are you really trying to do here? >>> >>> -Chris >> >> >> inefficient : do you mean because all users of the refined type would have to be "notified" ? > > Yes.Thanks for clarifying.> >> The reason is that our code generator generates a struct (progressively adding fields) and generates code that access this struct (that is : the fields that are already added). If we cannot create the struct progressively, then we have to define a pass to build the complete struct, then define a second pass to generate the code. If we can simply create the struct progressively at LLVM level, then it make our code simpler. > > LLVM doesn't support this sort of thing. Is two passes really that bad? > > -ChrisWe'll do a two passes model. Thanks again. Stéphane Letz
Hi Stéphane,> The reason is that our code generator generates a struct (progressively adding fields) and generates code that access this struct (that is : the fields that are already added). If we cannot create the struct progressively, then we have to define a pass to build the complete struct, then define a second pass to generate the code. If we can simply create the struct progressively at LLVM level, then it make our code simpler.to access struct fields you don't necessarily need the struct type. For example, rather than passing around a pointer to your struct type, you can use an i8*. Suppose you add a new integer (i32) field to your struct, offset N bytes from the start and want to generate code to load it. Then you can use a GEP (or ptrtoint, add, inttoptr combination) to offset the pointer by N bytes, and then load an i32 from this pointer. So I'm suggesting that you can generate *code* progressively as fields are added without ever explicitly defining the struct type. Once you have generated all fields, you can then replace all these i8* with a (bitcast of) the final "struct type"*, and the optimizers should then clean everything up. Ciao, Duncan.