@@ -269,6 +269,16 @@ pub trait LowerBackend {
269269 fn maybe_pinned_reg ( & self ) -> Option < Reg > {
270270 None
271271 }
272+
273+ /// Generate the instructions that must appear at the beginning of a basic
274+ /// block, if any.
275+ fn start_block < C : LowerCtx < I = Self :: MInst > > (
276+ & self ,
277+ _is_indirect_branch_target : bool ,
278+ _ctx : & mut C ,
279+ ) -> CodegenResult < ( ) > {
280+ Ok ( ( ) )
281+ }
272282}
273283
274284/// Machine-independent lowering driver / machine-instruction container. Maintains a correspondence
@@ -1093,12 +1103,13 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
10931103 // Main lowering loop over lowered blocks.
10941104 for ( bindex, lb) in lowered_order. iter ( ) . enumerate ( ) . rev ( ) {
10951105 let bindex = BlockIndex :: new ( bindex) ;
1106+ let orig_block = lb. orig_block ( ) ;
10961107
10971108 // Lower the block body in reverse order (see comment in
10981109 // `lower_clif_block()` for rationale).
10991110
11001111 // End branches.
1101- if let Some ( bb) = lb . orig_block ( ) {
1112+ if let Some ( bb) = orig_block {
11021113 self . collect_branches_and_targets ( bindex, bb, & mut branches, & mut targets) ;
11031114 if branches. len ( ) > 0 {
11041115 self . lower_clif_branches ( backend, bindex, bb, & branches, & targets) ?;
@@ -1134,7 +1145,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
11341145 }
11351146
11361147 // Original block body.
1137- if let Some ( bb) = lb . orig_block ( ) {
1148+ if let Some ( bb) = orig_block {
11381149 self . lower_clif_block ( backend, bb) ?;
11391150 self . emit_value_label_markers_for_block_args ( bb) ;
11401151 }
@@ -1143,6 +1154,15 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
11431154 // Set up the function with arg vreg inits.
11441155 self . gen_arg_setup ( ) ;
11451156 self . finish_ir_inst ( SourceLoc :: default ( ) ) ;
1157+ } else {
1158+ let is_indirect_branch_target = if let Some ( bb) = orig_block {
1159+ self . vcode . block_order ( ) . is_indirect_branch_target ( bb)
1160+ } else {
1161+ false
1162+ } ;
1163+
1164+ backend. start_block ( is_indirect_branch_target, & mut self ) ?;
1165+ self . finish_ir_inst ( SourceLoc :: default ( ) ) ;
11461166 }
11471167
11481168 self . finish_bb ( ) ;
@@ -1493,26 +1513,32 @@ impl<'func, I: VCodeInst> LowerCtx for Lower<'func, I> {
14931513}
14941514
14951515/// Visit all successors of a block with a given visitor closure.
1496- pub ( crate ) fn visit_block_succs < F : FnMut ( Inst , Block ) > ( f : & Function , block : Block , mut visit : F ) {
1516+ pub ( crate ) fn visit_block_succs < F : FnMut ( Inst , Block , bool ) > (
1517+ f : & Function ,
1518+ block : Block ,
1519+ mut visit : F ,
1520+ ) {
14971521 for inst in f. layout . block_likely_branches ( block) {
14981522 if f. dfg [ inst] . opcode ( ) . is_branch ( ) {
14991523 visit_branch_targets ( f, inst, & mut visit) ;
15001524 }
15011525 }
15021526}
15031527
1504- fn visit_branch_targets < F : FnMut ( Inst , Block ) > ( f : & Function , inst : Inst , visit : & mut F ) {
1528+ fn visit_branch_targets < F : FnMut ( Inst , Block , bool ) > ( f : & Function , inst : Inst , visit : & mut F ) {
15051529 match f. dfg [ inst] . analyze_branch ( & f. dfg . value_lists ) {
15061530 BranchInfo :: NotABranch => { }
15071531 BranchInfo :: SingleDest ( dest, _) => {
1508- visit ( inst, dest) ;
1532+ visit ( inst, dest, false ) ;
15091533 }
15101534 BranchInfo :: Table ( table, maybe_dest) => {
15111535 if let Some ( dest) = maybe_dest {
1512- visit ( inst, dest) ;
1536+ // The default block is reached via a direct conditional branch,
1537+ // so it is not part of the table.
1538+ visit ( inst, dest, false ) ;
15131539 }
15141540 for & dest in f. jump_tables [ table] . as_slice ( ) {
1515- visit ( inst, dest) ;
1541+ visit ( inst, dest, true ) ;
15161542 }
15171543 }
15181544 }
0 commit comments