Your hunch is correct, many modern compilers use flow analysis to rename variables so that each variable is unique. The resulting form is called "single static assignment" or SSA for short.
Input:
B = 2
B = B + 5
B = J + B
Output:
B1 = 2
B2 = B1 + 5
B3 = J + B2
There are additional parts to this for working with branches and loops, such as:
Input:
if X < 5
B = Y + Z
else
B = 2
B = B + 1
Output:
if X < 5:
B1 = Y + Z
else
B2 = 2
B3 = phi(B1, B2)
B4 = B3 + 1
The "phi" function selects whichever of its inputs is live.
This is NOT done during preprocessing, it is done after the code is compiled to some IR, usually consisting of basic blocks. It is NOT similar to macro-expansion.