Lower the function.
(
mut self,
backend: &B,
ctrl_plane: &mut ControlPlane,
)
| 1114 | |
| 1115 | /// Lower the function. |
| 1116 | pub fn lower<B: LowerBackend<MInst = I>>( |
| 1117 | mut self, |
| 1118 | backend: &B, |
| 1119 | ctrl_plane: &mut ControlPlane, |
| 1120 | ) -> CodegenResult<VCode<I>> { |
| 1121 | trace!("about to lower function: {:?}", self.f); |
| 1122 | |
| 1123 | self.vcode.init_retval_area(&mut self.vregs)?; |
| 1124 | |
| 1125 | // Get the pinned reg here (we only parameterize this function on `B`, |
| 1126 | // not the whole `Lower` impl). |
| 1127 | self.pinned_reg = backend.maybe_pinned_reg(); |
| 1128 | |
| 1129 | self.vcode.set_entry(BlockIndex::new(0)); |
| 1130 | |
| 1131 | // Reused vectors for branch lowering. |
| 1132 | let mut targets: SmallVec<[MachLabel; 2]> = SmallVec::new(); |
| 1133 | |
| 1134 | // get a copy of the lowered order; we hold this separately because we |
| 1135 | // need a mut ref to the vcode to mutate it below. |
| 1136 | let lowered_order: SmallVec<[LoweredBlock; 64]> = self |
| 1137 | .vcode |
| 1138 | .block_order() |
| 1139 | .lowered_order() |
| 1140 | .iter() |
| 1141 | .cloned() |
| 1142 | .collect(); |
| 1143 | |
| 1144 | // Main lowering loop over lowered blocks. |
| 1145 | for (bindex, lb) in lowered_order.iter().enumerate().rev() { |
| 1146 | let bindex = BlockIndex::new(bindex); |
| 1147 | |
| 1148 | // Lower the block body in reverse order (see comment in |
| 1149 | // `lower_clif_block()` for rationale). |
| 1150 | |
| 1151 | // End branch. |
| 1152 | if let Some(bb) = lb.orig_block() { |
| 1153 | if let Some(branch) = self.collect_branch_and_targets(bindex, bb, &mut targets) { |
| 1154 | let branch_start = self.vcode.vcode.num_insts(); |
| 1155 | self.lower_clif_branch(backend, bindex, bb, branch, &targets)?; |
| 1156 | self.finish_ir_inst(self.srcloc(branch)); |
| 1157 | |
| 1158 | // Branch instructions like try_call can also be safepoints |
| 1159 | // that need stack maps. Forward the stack map from the CLIF |
| 1160 | // branch to the VCode safepoint, just like we do for |
| 1161 | // non-branch instructions in `lower_clif_block`. |
| 1162 | if let Some(entries) = self.f.dfg.user_stack_map_entries(branch) { |
| 1163 | let branch_end = self.vcode.vcode.num_insts(); |
| 1164 | for i in branch_start..branch_end { |
| 1165 | let iix = InsnIndex::new(i); |
| 1166 | if self.vcode.vcode[iix].is_safepoint() { |
| 1167 | self.vcode.add_user_stack_map( |
| 1168 | BackwardsInsnIndex::new(iix.index()), |
| 1169 | entries, |
| 1170 | ); |
| 1171 | break; |
| 1172 | } |
| 1173 | } |
no test coverage detected