Process one instruction. Meant to be invoked in program order within a block, and ideally in RPO or at least some domtree preorder for maximal reuse.
(
&mut self,
func: &mut Function,
state: &mut LastStores,
inst: Inst,
)
| 291 | /// within a block, and ideally in RPO or at least some domtree |
| 292 | /// preorder for maximal reuse. |
| 293 | pub fn process_inst( |
| 294 | &mut self, |
| 295 | func: &mut Function, |
| 296 | state: &mut LastStores, |
| 297 | inst: Inst, |
| 298 | ) -> OptResult { |
| 299 | trace!( |
| 300 | "alias analysis: scanning at inst{} with state {:?} ({:?})", |
| 301 | inst.index(), |
| 302 | state, |
| 303 | func.dfg.insts[inst], |
| 304 | ); |
| 305 | |
| 306 | let result = if let Some((address, offset, ty)) = inst_addr_offset_type(func, inst) { |
| 307 | let address = func.dfg.resolve_aliases(address); |
| 308 | let opcode = func.dfg.insts[inst].opcode(); |
| 309 | |
| 310 | if opcode.can_store() { |
| 311 | let store_data = inst_store_data(func, inst).unwrap(); |
| 312 | let store_data = func.dfg.resolve_aliases(store_data); |
| 313 | |
| 314 | // Check for idempotent stores, where we are storing the exact |
| 315 | // same value back to a location that already has that value. |
| 316 | let last_store = state.get_last_store(func, inst); |
| 317 | let check_loc = MemoryLoc { |
| 318 | last_store, |
| 319 | address, |
| 320 | offset, |
| 321 | ty, |
| 322 | extending_opcode: get_ext_opcode(opcode), |
| 323 | }; |
| 324 | if let Some((def_inst, known_value)) = self.mem_values.get(&check_loc).cloned() { |
| 325 | if known_value == store_data |
| 326 | && self.domtree.dominates(def_inst, inst, &func.layout) |
| 327 | { |
| 328 | trace!( |
| 329 | "alias analysis: at inst{}: idempotent store of v{} to loc {:?}", |
| 330 | inst.index(), |
| 331 | store_data.index(), |
| 332 | check_loc |
| 333 | ); |
| 334 | return OptResult::IdempotentStore; |
| 335 | } |
| 336 | } |
| 337 | |
| 338 | // Otherwise, update our state to reflect this store. |
| 339 | let mem_loc = MemoryLoc { |
| 340 | last_store: inst.into(), |
| 341 | address, |
| 342 | offset, |
| 343 | ty, |
| 344 | extending_opcode: get_ext_opcode(opcode), |
| 345 | }; |
| 346 | trace!( |
| 347 | "alias analysis: at inst{}: store with data v{} at loc {:?}", |
| 348 | inst.index(), |
| 349 | store_data.index(), |
| 350 | mem_loc |
no test coverage detected