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);
}