MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / collect_block_call

Method collect_block_call

cranelift/codegen/src/machinst/lower.rs:1054–1113  ·  view source on GitHub ↗

Collect the outgoing block-call arguments for a given edge out of a lowered block.

(
        &mut self,
        block: BlockIndex,
        succ_idx: usize,
        buffer: &'a mut SmallVec<[Reg; 16]>,
    )

Source from the content-addressed store, hash-verified

1052 /// Collect the outgoing block-call arguments for a given edge out
1053 /// of a lowered block.
1054 fn collect_block_call<'a>(
1055 &mut self,
1056 block: BlockIndex,
1057 succ_idx: usize,
1058 buffer: &'a mut SmallVec<[Reg; 16]>,
1059 ) -> (BlockIndex, &'a [Reg]) {
1060 let block_order = self.vcode.block_order();
1061 let (_, succs) = block_order.succ_indices(block);
1062 let succ = succs[succ_idx];
1063 let this_lb = block_order.lowered_order()[block.index()];
1064 let succ_lb = block_order.lowered_order()[succ.index()];
1065
1066 let (branch_inst, succ_idx) = match (this_lb, succ_lb) {
1067 (_, LoweredBlock::CriticalEdge { .. }) => {
1068 // The successor is a split-critical-edge block. In this
1069 // case, this block-call has no arguments, and the
1070 // arguments go on the critical edge block's unconditional
1071 // branch instead.
1072 return (succ, &[]);
1073 }
1074 (LoweredBlock::CriticalEdge { pred, succ_idx, .. }, _) => {
1075 // This is a split-critical-edge block. In this case, our
1076 // block-call has the arguments that in the CLIF appear in
1077 // the predecessor's branch to this edge.
1078 let branch_inst = self.f.layout.last_inst(pred).unwrap();
1079 (branch_inst, succ_idx as usize)
1080 }
1081
1082 (this, _) => {
1083 let block = this.orig_block().unwrap();
1084 // Ordinary block, with an ordinary block as
1085 // successor. Take the arguments from the branch.
1086 let branch_inst = self.f.layout.last_inst(block).unwrap();
1087 (branch_inst, succ_idx)
1088 }
1089 };
1090
1091 let block_call = self.f.dfg.insts[branch_inst]
1092 .branch_destination(&self.f.dfg.jump_tables, &self.f.dfg.exception_tables)[succ_idx];
1093 for arg in block_call.args(&self.f.dfg.value_lists) {
1094 match arg {
1095 BlockArg::Value(arg) => {
1096 debug_assert!(self.f.dfg.value_is_real(arg));
1097 let regs = self.put_value_in_regs(arg);
1098 buffer.extend_from_slice(regs.regs());
1099 }
1100 BlockArg::TryCallRet(i) => {
1101 let regs = self.try_call_rets.get(&branch_inst).unwrap()[i as usize]
1102 .map(|r| r.to_reg());
1103 buffer.extend_from_slice(regs.regs());
1104 }
1105 BlockArg::TryCallExn(i) => {
1106 let reg =
1107 self.try_call_payloads.get(&branch_inst).unwrap()[i as usize].to_reg();
1108 buffer.push(reg);
1109 }
1110 }
1111 }

Callers 1

Calls 15

block_orderMethod · 0.80
succ_indicesMethod · 0.80
lowered_orderMethod · 0.80
last_instMethod · 0.80
orig_blockMethod · 0.80
branch_destinationMethod · 0.80
put_value_in_regsMethod · 0.80
to_regMethod · 0.80
indexMethod · 0.45
unwrapMethod · 0.45
argsMethod · 0.45
regsMethod · 0.45

Tested by

no test coverage detected