Only read-after-write (RAW) is a true data dependency. Write-after-write (WAW) and write-after-read (WAR) are name collisions on a reused logical register, not data flow.
Renaming removes the false ones. Each write allocates a fresh physical register, so independent writes never collide.
Type | Example | True flow? | Handling |
|---|---|---|---|
RAW | ADD r2 <- r1, after LD r1 | Yes | Wait for the operand; forward or bypass when ready |
WAW | Two writes to r1 with no read between | No | Give each write its own physical register |
WAR | Write to r4 after a read of r4 | No | Read keeps the old physical register; write takes a new one |
A rename map records the current physical register for each logical one. A free list holds unallocated physical registers for new writes.
On commit, the overwritten physical register returns to the free list. On a mispredict, the map is restored from the checkpoint or rebuilt at the ROB tail.
Step | Instruction | Rename map for r1 | Note |
|---|---|---|---|
Start | - | r1 -> p10 | Reader of r1 uses p10 |
Rename | ADD r1 <- r2 + r3 | r1 -> p14 | Fresh p14 from the free list; p10 kept for older readers |
Rename | ADD r1 <- r4 + r5 | r1 -> p21 | WAW avoided: the two writes target p14 and p21 |
Commit | First ADD commits | r1 -> p21 | p10 returns to the free list when no reader remains |
The pool must cover every live value: all architectural registers plus every in-flight write. A full rename stage with no free register stalls dispatch even when execution units are idle.
The example below uses stated parameters, not a product figure.
32 architectural registers, 64-entry instruction window (stated example)
in-flight writes at most = window size = 64
physical registers needed >= 32 + 64 = 96
choice with margin: 128 physical registersNo. Each write takes a fresh physical register, so the WAW name collision is gone and they execute independently.
The free list: with no physical register for the next write, rename cannot proceed.