[LLVMdev] Linking modules across contexts crashes
Duncan P. N. Exon Smith
dexonsmith at apple.com
Thu Jun 4 16:20:57 PDT 2015
> 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.
>
> Yuri
I 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.
More information about the llvm-dev
mailing list