Thanks for raising this @areusch!
Just to clarify the two approaches in my mind here.
RemoveNameCollisions Pass
A Pass
which looks for variables with matching name_hint
s within a module and updates it to remove collisions with any other names in the module. With the additional rule that a global_symbol
which strictly enforce the name, un-resolvable collisions would be an error.
NameSupply Generator
This is similar to our current GetUniqueName
function:
std::string GetUniqueName(std::string name, std::unordered_map<std::string, int>* name_map_);
Except we use it to maintain not only indexes of unique names, but also hold some context of the module and sub-structures. In the case of CMSIS-NN, this means all variables could likely be scoped neatly:
name_supply.FreshGlobalWithPrefix(“ultimate_cat_spotter”, “filter”, “cmsisnn”)
Thoughts
The nice thing about the Pass
approach is that it is essentially magic, a developer doesn’t have to sprinkle GetUniqueName
everywhere as just defining a Var
does that for them. The downside is that the meaning of the names and the rules to generate them are essentially down to whomever defines the Var
so you will likely end up with more nonsensical names? (“constant_0_1_2”, as we keep generating “constant”s for things).
@mbs-octoml, with the NameSupply
, we could create a sub-NameSupply
correct? Something like:
std::string my_module_name = “ultimate_cat_spotter”;
NameSupply module_name_supply(my_module_name);
module_name_supply.FreshGlobal(“constant”); // “tvmgen_ultimate_cat_spotter_constant_0”
NameSupply sub_module_name_supply = module_name_supply.WithPrefix(“sub_module”);
// Send that to some sub-process to generate things
sub_module_name_supply.FreshGlobal(“constant”); // “tvmgen_ultimate_cat_spotter_sub_module_constant_0”
That’d mean for BYOC, we pass it a module and a name supply to use, and we can hierarchically define a prefix? Potentially UniqueGlobal
would instead revert to the central prefix for shared variables.
As far as I can tell, the main difference here is that the NameSupply
approach would give us nicer outputs, with a bit more developer overhead and the Pass
would conversely simplify the developer experience at the expense of the eventual output?