<div dir="ltr"><div dir="ltr">Hi Dibyendu,<div><br></div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">My point was that suppose whether I added the module or not in the way<br>you suggest, I still need to know which value of they VModuleKey is<br>'invalid'. In the example assume that CODLayer.addModule() is never<br>called sometimes. So how do you know whether to call removeModule()?</blockquote></div><div><br></div><div>That's definitely up to the client to track. E.g. if you want to make removal generic.</div><div><br></div><div><font face="monospace">enum class RemoveFrom { None, OptimizeLayer, CODLayer };</font></div><div><font face="monospace"><br></font></div><div><font face="monospace">struct ModuleInfo {</font></div><div><font face="monospace">  VModuleKey Key;</font></div><div><font face="monospace">  RemoveFrom ToRemove;</font></div><div><font face="monospace">};<br></font></div><div><br></div><div>When adding to the CODLayer:</div><div><br></div><div>  <font face="monospace">ModuleInfo MInfo;</font></div><div><font face="monospace">  MInfo.Key = ES.allocateVModule();</font></div><div><font face="monospace">  MInfo.ToRemove = RemoveFrom::CODLayer;</font></div><div><font face="monospace">  CODLayer.add(MInfo.Key, std::move(M));</font></div><div><br></div><div>When removing code:</div><div><br></div><div><font face="monospace">void removeModule(ModuleInfo &MInfo) {</font></div><div><font face="monospace">  switch (MInfo.ToRemove) {</font></div><div><font face="monospace">  case RemoveFrom::None:</font></div><div><font face="monospace">    break;</font></div><div><font face="monospace">  case RemoveFrom::OptimizeLayer:</font></div><div><font face="monospace">    OptLayer.removeModule(MInfo.Key);</font></div><div><font face="monospace">    break;</font></div><div><font face="monospace">  case RemovFrom::CODLayer:</font></div><div><font face="monospace">    CODLayer.removeModule(MInfo.Key);</font></div><div><font face="monospace">    break;</font></div><div><font face="monospace">  }</font></div><div><font face="monospace">}</font></div><div><br></div><div>At the moment removal is simpler in my prototype for removable code in ORCv2: You still create and hold a VModuleKey yourself, but it's an object that knows how to remove the code for you, so removal looks more like:</div><div><br></div><div><font face="monospace">auto Key = ES.allocateVModule();</font></div><div><font face="monospace">CODLayer.add(Key, std::move(M));</font></div><div><font face="monospace">// Do stuff.</font></div><div><font face="monospace"><br></font></div><div><font face="monospace">// Later.</font></div><div><font face="monospace">Key.remove();</font></div><div><br></div><div>Hopefully I can keep it that simple, but there's still a lot of work to do on this prototype.</div><div><br></div><div>Cheers,</div><div>Lang.</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Aug 13, 2019 at 3:17 PM Dibyendu Majumdar <<a href="mailto:mobile@majumdar.org.uk">mobile@majumdar.org.uk</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">Hi Lang,<br>
<br>
On Tue, 13 Aug 2019 at 23:04, Lang Hames <<a href="mailto:lhames@gmail.com" target="_blank">lhames@gmail.com</a>> wrote:<br>
><br>
>> Yes indeed that is what happened. So to prevent that I need to check<br>
>> if VModuleKey was ever initialized ... how do I do that? I would have<br>
>> to have to add another flag to track the initialized state.<br>
>> The reason for it not being initialized is that sometimes I cannot<br>
>> generate JIT code because some bytecode is not yet supported.<br>
><br>
><br>
> I'm not sure I follow. In ORCv1 VModuleKeys are just integers: initialization is up to you, and the standard way to get a unique key is to always initialize keys by calling ExecutionSession::allocateVModuleKey(). The intent is that you should use a unique key for each module that you add, and keep a copy of the key if it is associated with a module if you want to be able to remove that module later. E.g.<br>
><br>
> // Module that I will never want to remove:<br>
> CODLayer.addModule(ES.createVModuleKey(), std::move(M)); // unique throwaway key.<br>
><br>
> // Module that I want to be able to remove later:<br>
> auto TemporaryModuleKey = ES.createVModuleKey();<br>
> CODLayer.addModule(TemporaryModuleKey, std::move(M));<br>
> // Do stuff.<br>
> CODLayer.removeModule(TemporaryModuleKey);<br>
><br>
> The main use cases of removable modules that I'm aware of are: (1) temporary expressions in REPLs, and (2) lower-optimized modules in re-optimizing JITs. In the former case you can usually name the key individually (as above). In the latter case you usually want to stash it in a map or context object somewhere and remove it after you've replaced the low-optimization-level code with a higher optimization level.<br>
><br>
<br>
Okay maybe I am doing something wrong. I am using:<br>
<br>
llvm::orc::VModuleKey K = ES->allocateVModule();<br>
<br>
My point was that suppose whether I added the module or not in the way<br>
you suggest, I still need to know which value of they VModuleKey is<br>
'invalid'. In the example assume that CODLayer.addModule() is never<br>
called sometimes. So how do you know whether to call removeModule()?<br>
<br>
<br>
Regards<br>
Dibyendu<br>
</blockquote></div>