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

Method insert_pure_enode

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

Optimization of a single instruction. This does a few things: - Looks up the instruction in the GVN deduplication map. If we already have the same instruction somewhere else, with the same args, then we can alias the original instruction's results and omit this instruction entirely. - If the instruction is "new" (not deduplicated), then apply optimization rules: - All of the mid-end rules written

(&mut self, inst: NewOrExistingInst)

Source from the content-addressed store, hash-verified

196 /// - Update the value-to-opt-value map, and update the eclass
197 /// union-find, if we rewrote the value to different form(s).
198 pub(crate) fn insert_pure_enode(&mut self, inst: NewOrExistingInst) -> Value {
199 // Create the external context for looking up and updating the
200 // GVN map. This is necessary so that instructions themselves
201 // do not have to carry all the references or data for a full
202 // `Eq` or `Hash` impl.
203 let gvn_context = GVNContext {
204 value_lists: &self.func.dfg.value_lists,
205 };
206
207 self.stats.pure_inst += 1;
208 if let NewOrExistingInst::New(..) = inst {
209 self.stats.new_inst += 1;
210 }
211
212 // Does this instruction already exist? If so, add entries to
213 // the value-map to rewrite uses of its results to the results
214 // of the original (existing) instruction. If not, optimize
215 // the new instruction.
216 if let Some(&Some(orig_result)) = self
217 .gvn_map
218 .get(&gvn_context, &inst.get_inst_key(&self.func.dfg))
219 {
220 self.stats.pure_inst_deduped += 1;
221 if let NewOrExistingInst::Existing(inst) = inst {
222 debug_assert_eq!(self.func.dfg.inst_results(inst).len(), 1);
223 let result = self.func.dfg.first_result(inst);
224 self.value_to_opt_value[result] = orig_result;
225 self.available_block[result] = self.available_block[orig_result];
226 }
227 orig_result
228 } else {
229 // Now actually insert the InstructionData and attach
230 // result value (exactly one).
231 let (inst, result, ty) = match inst {
232 NewOrExistingInst::New(data, typevar) => {
233 self.stats.pure_inst_insert_new += 1;
234 let inst = self.func.dfg.make_inst(data);
235 // TODO: reuse return value?
236 self.func.dfg.make_inst_results(inst, typevar);
237 let result = self.func.dfg.first_result(inst);
238 // New inst. We need to do the analysis of its result.
239 (inst, result, typevar)
240 }
241 NewOrExistingInst::Existing(inst) => {
242 self.stats.pure_inst_insert_orig += 1;
243 let result = self.func.dfg.first_result(inst);
244 let ty = self.func.dfg.ctrl_typevar(inst);
245 (inst, result, ty)
246 }
247 };
248
249 self.available_block[result] = self.get_available_block(inst);
250 let opt_value = self.optimize_pure_enode(inst);
251 log::trace!("optimizing inst {inst} orig result {result} gave {opt_value}");
252
253 let gvn_context = GVNContext {
254 value_lists: &self.func.dfg.value_lists,
255 };

Callers 2

make_inst_ctorMethod · 0.80

Calls 10

get_inst_keyMethod · 0.80
first_resultMethod · 0.80
make_instMethod · 0.80
make_inst_resultsMethod · 0.80
ctrl_typevarMethod · 0.80
get_available_blockMethod · 0.80
optimize_pure_enodeMethod · 0.80
insert_with_depthMethod · 0.80
getMethod · 0.45

Tested by

no test coverage detected