Print this page
new smatch
        
*** 52,62 ****
                          return 0;
                  continue;
  
  found_dominator:
                  br = delete_last_instruction(&parent->insns);
!                 phi = alloc_phi(parent, one->target, one->size);
                  phi->ident = phi->ident ? : one->target->ident;
                  add_instruction(&parent->insns, br);
                  use_pseudo(insn, phi, add_pseudo(dominators, phi));
          } END_FOR_EACH_PTR(parent);
          return 1;
--- 52,62 ----
                          return 0;
                  continue;
  
  found_dominator:
                  br = delete_last_instruction(&parent->insns);
!                 phi = alloc_phi(parent, one->target, one->type);
                  phi->ident = phi->ident ? : one->target->ident;
                  add_instruction(&parent->insns, br);
                  use_pseudo(insn, phi, add_pseudo(dominators, phi));
          } END_FOR_EACH_PTR(parent);
          return 1;
*** 67,76 ****
--- 67,78 ----
          struct pseudo_user *pu;
          FOR_EACH_PTR(pseudo->users, pu) {
                  struct instruction *insn = pu->insn;
                  if (insn->bb && (insn->opcode != OP_LOAD && insn->opcode != OP_STORE))
                          return 1;
+                 if (pu->userp != &insn->src)
+                         return 1;
          } END_FOR_EACH_PTR(pu);
          return 0;
  }
  
  static int local_pseudo(pseudo_t pseudo)
*** 95,105 ****
                          unsigned long generation;
  
                          /* Check for illegal offsets.. */
                          check_access(insn);
  
!                         if (insn->type->ctype.modifiers & MOD_VOLATILE)
                                  continue;
  
                          RECURSE_PTR_REVERSE(insn, dom) {
                                  int dominance;
                                  if (!dom->bb)
--- 97,107 ----
                          unsigned long generation;
  
                          /* Check for illegal offsets.. */
                          check_access(insn);
  
!                         if (insn->is_volatile)
                                  continue;
  
                          RECURSE_PTR_REVERSE(insn, dom) {
                                  int dominance;
                                  if (!dom->bb)
*** 125,155 ****
                          if (find_dominating_parents(pseudo, insn, bb, generation, &dominators, local)) {
                                  /* This happens with initial assignments to structures etc.. */
                                  if (!dominators) {
                                          if (local) {
                                                  assert(pseudo->type != PSEUDO_ARG);
!                                                 convert_load_instruction(insn, value_pseudo(insn->type, 0));
                                          }
                                          goto next_load;
                                  }
                                  rewrite_load_instruction(insn, dominators);
                          }
                  }
  next_load:
                  /* Do the next one */;
          } END_FOR_EACH_PTR_REVERSE(insn);
  }
  
- static void kill_store(struct instruction *insn)
- {
-         if (insn) {
-                 insn->bb = NULL;
-                 insn->opcode = OP_SNOP;
-                 kill_use(&insn->target);
-         }
- }
- 
  static void kill_dominated_stores(struct basic_block *bb)
  {
          struct instruction *insn;
  
          FOR_EACH_PTR_REVERSE(bb->insns, insn) {
--- 127,153 ----
                          if (find_dominating_parents(pseudo, insn, bb, generation, &dominators, local)) {
                                  /* This happens with initial assignments to structures etc.. */
                                  if (!dominators) {
                                          if (local) {
                                                  assert(pseudo->type != PSEUDO_ARG);
!                                                 convert_load_instruction(insn, value_pseudo(0));
                                          }
                                          goto next_load;
                                  }
                                  rewrite_load_instruction(insn, dominators);
+                         } else {        // cleanup pending phi-sources
+                                 pseudo_t phi;
+                                 FOR_EACH_PTR(dominators, phi) {
+                                         kill_instruction(phi->def);
+                                 } END_FOR_EACH_PTR(phi);
                          }
                  }
  next_load:
                  /* Do the next one */;
          } END_FOR_EACH_PTR_REVERSE(insn);
  }
  
  static void kill_dominated_stores(struct basic_block *bb)
  {
          struct instruction *insn;
  
          FOR_EACH_PTR_REVERSE(bb->insns, insn) {
*** 156,167 ****
                  if (!insn->bb)
                          continue;
                  if (insn->opcode == OP_STORE) {
                          struct instruction *dom;
                          pseudo_t pseudo = insn->src;
!                         int local = local_pseudo(pseudo);
  
                          RECURSE_PTR_REVERSE(insn, dom) {
                                  int dominance;
                                  if (!dom->bb)
                                          continue;
                                  dominance = dominates(pseudo, insn, dom, local);
--- 154,171 ----
                  if (!insn->bb)
                          continue;
                  if (insn->opcode == OP_STORE) {
                          struct instruction *dom;
                          pseudo_t pseudo = insn->src;
!                         int local;
  
+                         if (!insn->type)
+                                 continue;
+                         if (insn->is_volatile)
+                                 continue;
+ 
+                         local = local_pseudo(pseudo);
                          RECURSE_PTR_REVERSE(insn, dom) {
                                  int dominance;
                                  if (!dom->bb)
                                          continue;
                                  dominance = dominates(pseudo, insn, dom, local);
*** 170,180 ****
                                          if (dominance < 0)
                                                  goto next_store;
                                          if (dom->opcode == OP_LOAD)
                                                  goto next_store;
                                          /* Yeehaa! Found one! */
!                                         kill_store(dom);
                                  }
                          } END_FOR_EACH_PTR_REVERSE(dom);
  
                          /* OK, we should check the parents now */
                  }
--- 174,184 ----
                                          if (dominance < 0)
                                                  goto next_store;
                                          if (dom->opcode == OP_LOAD)
                                                  goto next_store;
                                          /* Yeehaa! Found one! */
!                                         kill_instruction_force(dom);
                                  }
                          } END_FOR_EACH_PTR_REVERSE(dom);
  
                          /* OK, we should check the parents now */
                  }
*** 184,197 ****
--- 188,213 ----
  }
  
  void simplify_memops(struct entrypoint *ep)
  {
          struct basic_block *bb;
+         pseudo_t pseudo;
  
          FOR_EACH_PTR_REVERSE(ep->bbs, bb) {
                  simplify_loads(bb);
          } END_FOR_EACH_PTR_REVERSE(bb);
  
          FOR_EACH_PTR_REVERSE(ep->bbs, bb) {
                  kill_dominated_stores(bb);
          } END_FOR_EACH_PTR_REVERSE(bb);
+ 
+         FOR_EACH_PTR(ep->accesses, pseudo) {
+                 struct symbol *var = pseudo->sym;
+                 unsigned long mod;
+                 if (!var)
+                         continue;
+                 mod = var->ctype.modifiers;
+                 if (mod & (MOD_VOLATILE | MOD_NONLOCAL | MOD_STATIC))
+                         continue;
+                 kill_dead_stores(ep, pseudo, local_pseudo(pseudo));
+         } END_FOR_EACH_PTR(pseudo);
  }