I am implementing a compiler for a proprietary language.
The language has one built-in integer type, with unlimited range. Sometimes variables are represented using smaller types, for example if a
and b
are integer variables but b
is only ever assigned the value of the expression a % 100000
or a & 0xFFFFFF
, then b
can be represented as an Int32
instead.
I am considering implementing the following optimization. Suppose it sees the equivalent of this C# method:
public static void Main(string[] args)
{
BigInt i = 0;
while (true)
{
DoStuff(i++);
}
}
Mathematically speaking, transforming into the following is not valid:
public static void Main(string[] args)
{
Int64 i = 0;
while (true)
{
DoStuff(i++);
}
}
Because I have replaced a BigInt
with an Int64
, which will eventually overflow if the loop runs forever. However I suspect I can ignore this possibility because:
i
is initialized to 0 and is modified only by repeatedly adding 1 to it, which means that will take 263 iterations of the loop to make it overflow- If
DoStuff
does any useful work, it will take centuries (extrapolated from my very crude tests) fori
to overflow. The machine the program runs on will not last that long. Not only that but its architecture probably won't last that long either, so I also don't need to worry about it running on a VM that is migrated to new hardware. - If
DoStuff
does not do any useful work, an operator will eventually notice that it is wasting CPU cycles and kill the process
So what scenarios do I need to worry about?
Do any compilers already use this hack?