For multiple far branches to the same destination, there are chances that some restore blocks could be shared if they clobber the same registers and share the same restore sequence. Since RISCV generates a same restore block consisting only ld s11, 0(sp) for all jumps to one destination (see D130560), deduplicating them would save a few bytes in that case.
This patch stores all restore blocks for a destination in RestoreBlocks in the destination's BasicBlockInfo, allowing the target to call DeduplicateRestoreBB() to find a previously inserted restore block identical to RestoreBB and insert an unconditional branch to it, then BranchRelaxation::fixupUnconditionalBranch() can erase RestoreBB from the function.
Suppose jump .dest is out of range so need a register to jump indirectly in the following code.
.label_0: foo 1 jump .dest .label_1: foo 2 jump .dest .label_2: bar bar bar bar .dest: baz
Without this patch, it will be relaxed to:
.label_0: foo 1 store reg1, (sp) mov reg1, .restore_1 jump reg1 .label_1: foo 2 store reg1, (sp) mov reg1, .restore_2 jump reg1 .label_2: bar bar bar bar .restore_1: load reg1, (sp) jump .dest .restore_2: load reg1, (sp) .dest: baz
With this patch, restore blocks can be deduplicated, thus generating the following code:
.label_0: foo store reg1, (sp) mov reg1, .restore_1 jump reg1 .label_1: foo store reg1, (sp) mov reg1, .restore_1 jump reg1 .label_2: bar bar bar bar .restore_1: load reg1, (sp) .dest: baz
Depends on D131865, which pre-commits the modified test.