MCPcopy Create free account
hub / github.com/Amanieu/regalloc3 / gen_cfg_skeleton

Method gen_cfg_skeleton

src/debug_utils/generic_function/arbitrary.rs:225–314  ·  view source on GitHub ↗

Generates a function skeleton with a randomly generated CFG. These blocks do not contain any instructions yet.

(&mut self)

Source from the content-addressed store, hash-verified

223 ///
224 /// These blocks do not contain any instructions yet.
225 fn gen_cfg_skeleton(&mut self) -> Result<()> {
226 // To avoid critical edges, we need to ensure that blocks with multiple
227 // successors only jump to blocks with a single predecessors, and that
228 // blocks with multiple predecessors are only jumped to from blocks with
229 // a single successor.
230 let mut can_add_succ = vec![];
231 let mut can_add_pred = vec![];
232
233 // Create the entry points.
234 let num_entries = self
235 .u
236 .int_in_range(self.config.entry_points.clone())?
237 .max(1);
238 for _ in 0..num_entries {
239 let entry_frequency = self.block_frequency()?;
240 let entry = self.func.blocks.push(BlockData {
241 insts: InstRange::new(Inst::new(0), Inst::new(0)),
242 preds: vec![],
243 succs: vec![],
244 block_params_in: vec![],
245 block_params_out: vec![],
246 immediate_dominator: None.into(),
247 frequency: entry_frequency,
248 is_critical_edge: false,
249 });
250 self.func.entry_points.push(entry);
251 can_add_succ.push(entry);
252 }
253
254 // Repeatedly add edges to the CFG, either to a new block, or to an
255 // existing block.
256 for _ in 0..self.u.int_in_range(self.config.cfg_edges.clone())? {
257 if can_add_succ.is_empty() {
258 break;
259 }
260
261 let from = *self.u.choose(&can_add_succ)?;
262 let mut to = None;
263
264 // If the chosen block has no successors, try linking it to an
265 // existing block that accepts predecessors.
266 if !can_add_pred.is_empty()
267 && self.func.blocks[from].succs.is_empty()
268 && self.u.arbitrary()?
269 {
270 to = Some(*self.u.choose(&can_add_pred)?);
271 }
272
273 if let Some(to) = to {
274 // Create an edge to an existing block.
275 self.func.blocks[from].succs.push(to);
276 self.func.blocks[to].preds.push(from);
277
278 // If the `to` block now has multiple predecessors, prevent
279 // adding new successors to them.
280 if self.func.blocks[to].preds.len() > 1 {
281 can_add_succ.retain(|b| !self.func.blocks[to].preds.contains(b));
282 }

Callers 1

arbitrary_with_configMethod · 0.80

Calls 8

cloneMethod · 0.80
pushMethod · 0.80
retainMethod · 0.80
block_frequencyMethod · 0.45
is_emptyMethod · 0.45
arbitraryMethod · 0.45
lenMethod · 0.45
containsMethod · 0.45

Tested by

no test coverage detected