> 1. How to find all constants in Module? Does this code find all of them, or > they are somewhere else too? > for (GlobalVariable &GV : globals()) { > if (auto C = static_cast<Constant*>(GV.Op<0>().get())) { > ... C is Constant* > } > }Constants are unfortunately part of the Context, not the module :-( Cheers, Rafael
On 06/04/2015 14:29, Rafael Espíndola wrote:> Constants are unfortunately part of the Context, not the moduleBut types are also part of the Context, so I need to re-create these objects in another context. GV.Op<0> = C->changeContext(NewContext); is supposed to replace the old context with the new one inside of the GlobalValue in Module. And same for types in many places. The downside is that the older objects are left in the old context. I actually went through the 80% of the changes, only such complex constants are left. Yuri
Duncan P. N. Exon Smith
2015-Jun-04 23:20 UTC
[LLVMdev] Linking modules across contexts crashes
> On 2015 Jun 4, at 14:58, Yuri <yuri at rawbw.com> wrote: > > On 06/04/2015 14:29, Rafael Espíndola wrote: >> Constants are unfortunately part of the Context, not the module > > But types are also part of the Context, so I need to re-create these objects in another context. > > GV.Op<0> = C->changeContext(NewContext); is supposed to replace the old context with the new one inside of the GlobalValue in Module. > And same for types in many places. > > The downside is that the older objects are left in the old context. > > I actually went through the 80% of the changes, only such complex constants are left. > > YuriI think the other option -- generating a clone of a Module in the new context -- is probably easier, although I'm not sure. Either way, you'll need something like this: class Remapper { DenseMap<Type *, Type *> Types; DenseMap<Constant *, Constant *> Constants; DenseMap<Metadata *, Metadata *> MDs; DenseMap<unsigned, unsigned> AttachmentIDs; /* ... other things stored in the context ... */ LLVMContext &NewContext; public: Type &remapType(Type &OldType); Constant &remapConstant(Constant &OldConstant); Metadata &remapMetadata(Metadata &OldMD); unsigned remapAttachmentID(unsigned OldAttachmentID); /// Map old global value to the new one. void mapGlobal(GlobalValue &OldGV, GlobalValue &NewGV); /* ... more API and internals ... */ }; Where I'm assuming `remapType()` checks for `OldType` in the map, and if it's not there generates the type in `NewContext` (and caches it in the map). Same deal with the other maps. If you go with the "create a new module" approach, I think you basically want to do the following: 1. Create a new module, give it a name, etc. 2. For each global value (for each global and function), create a dummy value, leaving the initializer unset. You'll have to generate types on-demand as you go. Register the new global values in the remapper. 3. Fill in the initializers and function bodies, remapping Values/ Constants/Metadata/Types as you go. 4. Visit the named md nodes, remapping as you go. 5. ...? Note that I don't think this is a small project. I suspect a fair bit of code from the ValueMapper could/should be shared or refactored. I think the "mutate the module" approach would have some interesting corner cases that the "create a new module" approach doesn't, but it's probably doable somehow, and I suspect needs roughly the same algorithm.