What is Delayed Branching ?
One way to maximize the use of the pipeline, is to find an instruction that can be safely executed whether the branch is taken or not, and execute that instruction. So, when a branch instruction is encountered, the hardware puts the instruction following the branch into the pipe and begins executing it, just as in predict-not-taken. However, unlike in predict-not-taken, we do not need to worry about whether the branch is taken or not, we do not need to clear the pipe because no matter whether the branch is taken or not, we know the instruction is safe to execute.
Moving $I_1$ after branch
- $I1$ is updating the value of $R2$
- $R2$ which is used to determine branch condition $R1$
- Value of $R2$ is available after branch
$\Rightarrow$ Cannot be moved
Moving $I_3$ after branch
- value of $R1$ is computed in this instruction
- $R1$ is the branch condition
$\Rightarrow$ Cannot be moved
Moving $I_4$ after branch
Moving $I_2$ after branch
- It update the memory location to place the storing of conditional branch instruction $R1$
- If moved after branch , when compiler reaches $I4$ program execution will stop
$\Rightarrow $ Cannot be moved
Hence, option D is answer.