Single Static Assignment
When a computer executes code one of the most important things it must do is figure out how to turn the human-meaningful variable names into computer-meaningful memory accesses. Some variables cannot be statically allocated at the creation of the stack frame and must go on the heap and others never need to hit main memory and may live in registers for their entire life.
The compiler must do bookkeeping while parsing the code to figure out the most optimal arrangement possible for it. Anything allocated dynamically must go on the heap, obviously, but some memory allocations can be determined statically and converted into stack allocations if they also pass other heuristics like Escape Analysis. Conversely, if a function operates by constantly updating one or two variables (imagine you're summing up 2D vectors, for instance; you might want to read the X and Y variables into registers, load the other components in a loop, and only write X and Y back to memory at the end. This is why, on older architectures, the main register was called the Accumulator.) In fact, the preference for keeping variables in registers is so strong that some languages have a keyword to indicate that a variable has to be written back to memory or read from memory on every access. Otherwise, multithreading code running on other processors will never see changes to it!
One of the techniques for tracking variable assignment is Single Static Assignment. With this, if a variable X is used and then re-used it is tracked internally as X1 and X2. At the point that X2 is created it's clear that X1 won't be accessed again and so it may be forgotten! This intermediate form lets the compiler apply other optimizations that might be ambiguous or require a lot more complicated reasoning to prove that they're correct and safe. Dead code elimination is trivial, if X2 is never read from then it's creation can be elided, so long as the functions used in its creation are still invoked to get any side-effects. If X1 depends entirely on values known at compile time then it's creation, too, can be removed and statically inlined in its place.
Wikipedia says SSA was developed at IBM in the 80's. I think they're off by 140 years.
In 1840 Charles Babbage gave his only public explanation of the Analytical Engine, what would have been a mechanical computer if assembled. An Italian mathematician took notes on this in French and Ada Lovelace was invited by Charles to translate them and add her own appendices and explanations. These were labeled Notes A-G and the last, Note G, was a completed program to compute Bernoulli numbers

There's a lot to unpack here but columns 3-6 are the ones I want to pay attention to.
The variables are all called V followed by a subscript number indicating what it's index in memory is. Lovelace's arrays, evidently, are 1-indexed. The first operation is a bit tricky to write in a more conventional notation because the result of V2 * V3 is assigned to V4, V5, and V6. The next line is much easier, V4 = V4 - V1. And proceeding on the next two lines, V5 = V5 + V1 and V11 = V5 / V4.
The column for the "Statement of Results" should be thought of as comments. While they don't explain why she's doing the particular operations they do try to explain the bigger picture of where we are in the computation. They even reveal a (the) bug in the code. It says V5 / V4 but then shows 2n-1 / 2n+1 when V5 is given the value 2n+1 and V4 is 2n-1.
Bug aside there's an even more interesting observation here. See how each V in her note is also prefaced by a superscript number? What's that supposed to mean? Observe Operation 2 and Operation 3, where the "Variable receiving results" is 2V4 and 2V5, respectively. They each were assigned for the first time in Operation 1, where they're noted 1V. The preceeding subscript number is which iteration this is assigning the variable!
She used this format to keep track of how the variables were mutated as the program ran. This is, effectively, SSA.