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

Method optimize_skeleton_inst

cranelift/codegen/src/egraph/mod.rs:470–574  ·  view source on GitHub ↗

Optimize a "skeleton" instruction. Returns an optional command of how to continue processing the optimized instruction (e.g. removing it or replacing it with a new instruction).

(
        &mut self,
        inst: Inst,
        block: Block,
    )

Source from the content-addressed store, hash-verified

468 /// Returns an optional command of how to continue processing the optimized
469 /// instruction (e.g. removing it or replacing it with a new instruction).
470 fn optimize_skeleton_inst(
471 &mut self,
472 inst: Inst,
473 block: Block,
474 ) -> Option<SkeletonInstSimplification> {
475 self.stats.skeleton_inst += 1;
476
477 // If we have a rewrite rule for this instruction, do that first, so
478 // that GVN and alias analysis only see simplified skeleton
479 // instructions.
480 if let Some(cmd) = self.simplify_skeleton_inst(inst) {
481 self.stats.skeleton_inst_simplified += 1;
482 return Some(cmd);
483 }
484
485 // First, can we try to deduplicate? We need to keep some copy
486 // of the instruction around because it's side-effecting, but
487 // we may be able to reuse an earlier instance of it.
488 if is_mergeable_for_egraph(self.func, inst) {
489 let result = self.func.dfg.inst_results(inst).get(0).copied();
490 trace!(" -> mergeable side-effecting op {}", inst);
491
492 // Does this instruction already exist? If so, add entries to
493 // the value-map to rewrite uses of its results to the results
494 // of the original (existing) instruction. If not, optimize
495 // the new instruction.
496 //
497 // Note that the GVN map is scoped, which is important
498 // here: because effectful ops are not removed from the
499 // skeleton (`Layout`), we need to be mindful of whether
500 // our current position is dominated by an instance of the
501 // instruction. (See #5796 for details.)
502 let ty = self.func.dfg.ctrl_typevar(inst);
503 match self
504 .gvn_map
505 .entry(&NullCtx, (ty, self.func.dfg.insts[inst]))
506 {
507 ScopedEntry::Occupied(o) => {
508 let orig_result = *o.get();
509 match (result, orig_result) {
510 (Some(result), Some(orig_result)) => {
511 // Hit in GVN map -- reuse value.
512 self.stats.skeleton_inst_gvn += 1;
513 self.value_to_opt_value[result] = orig_result;
514 self.available_block[result] = self.available_block[orig_result];
515 trace!(" -> merges result {} to {}", result, orig_result);
516 }
517 (None, None) => {
518 // Hit in the GVN map, but the instruction doesn't
519 // produce results, only side effects. Nothing else
520 // to do here.
521 self.stats.skeleton_inst_gvn += 1;
522 trace!(" -> merges with dominating instruction");
523 }
524 (_, _) => unreachable!(),
525 }
526 Some(SkeletonInstSimplification::Remove)
527 }

Callers 1

Calls 10

is_mergeable_for_egraphFunction · 0.85
copiedMethod · 0.80
ctrl_typevarMethod · 0.80
process_instMethod · 0.80
first_resultMethod · 0.80
getMethod · 0.45
inst_resultsMethod · 0.45
entryMethod · 0.45
insertMethod · 0.45

Tested by

no test coverage detected