Print this page
11972 resync smatch

@@ -52,11 +52,11 @@
                         return 0;
                 continue;
 
 found_dominator:
                 br = delete_last_instruction(&parent->insns);
-                phi = alloc_phi(parent, one->target, one->size);
+                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,10 +67,12 @@
         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,11 +97,11 @@
                         unsigned long generation;
 
                         /* Check for illegal offsets.. */
                         check_access(insn);
 
-                        if (insn->type->ctype.modifiers & MOD_VOLATILE)
+                        if (insn->is_volatile)
                                 continue;
 
                         RECURSE_PTR_REVERSE(insn, dom) {
                                 int dominance;
                                 if (!dom->bb)

@@ -125,31 +127,27 @@
                         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));
+                                                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_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) {

@@ -156,12 +154,18 @@
                 if (!insn->bb)
                         continue;
                 if (insn->opcode == OP_STORE) {
                         struct instruction *dom;
                         pseudo_t pseudo = insn->src;
-                        int local = local_pseudo(pseudo);
+                        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,11 +174,11 @@
                                         if (dominance < 0)
                                                 goto next_store;
                                         if (dom->opcode == OP_LOAD)
                                                 goto next_store;
                                         /* Yeehaa! Found one! */
-                                        kill_store(dom);
+                                        kill_instruction_force(dom);
                                 }
                         } END_FOR_EACH_PTR_REVERSE(dom);
 
                         /* OK, we should check the parents now */
                 }

@@ -184,14 +188,26 @@
 }
 
 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);
 }