[pre-RFC] Name mangling in IRModules

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_hints 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?