Print this page
new smatch

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/memops.c
          +++ new/usr/src/tools/smatch/src/memops.c
↓ open down ↓ 46 lines elided ↑ open up ↑
  47   47                  if (parent->generation == generation)
  48   48                          continue;
  49   49                  parent->generation = generation;
  50   50  
  51   51                  if (!find_dominating_parents(pseudo, insn, parent, generation, dominators, local))
  52   52                          return 0;
  53   53                  continue;
  54   54  
  55   55  found_dominator:
  56   56                  br = delete_last_instruction(&parent->insns);
  57      -                phi = alloc_phi(parent, one->target, one->size);
       57 +                phi = alloc_phi(parent, one->target, one->type);
  58   58                  phi->ident = phi->ident ? : one->target->ident;
  59   59                  add_instruction(&parent->insns, br);
  60   60                  use_pseudo(insn, phi, add_pseudo(dominators, phi));
  61   61          } END_FOR_EACH_PTR(parent);
  62   62          return 1;
  63   63  }               
  64   64  
  65   65  static int address_taken(pseudo_t pseudo)
  66   66  {
  67   67          struct pseudo_user *pu;
  68   68          FOR_EACH_PTR(pseudo->users, pu) {
  69   69                  struct instruction *insn = pu->insn;
  70   70                  if (insn->bb && (insn->opcode != OP_LOAD && insn->opcode != OP_STORE))
  71   71                          return 1;
       72 +                if (pu->userp != &insn->src)
       73 +                        return 1;
  72   74          } END_FOR_EACH_PTR(pu);
  73   75          return 0;
  74   76  }
  75   77  
  76   78  static int local_pseudo(pseudo_t pseudo)
  77   79  {
  78   80          return pseudo->type == PSEUDO_SYM
  79   81                  && !(pseudo->sym->ctype.modifiers & (MOD_STATIC | MOD_NONLOCAL))
  80   82                  && !address_taken(pseudo);
  81   83  }
↓ open down ↓ 8 lines elided ↑ open up ↑
  90   92                  if (insn->opcode == OP_LOAD) {
  91   93                          struct instruction *dom;
  92   94                          pseudo_t pseudo = insn->src;
  93   95                          int local = local_pseudo(pseudo);
  94   96                          struct pseudo_list *dominators;
  95   97                          unsigned long generation;
  96   98  
  97   99                          /* Check for illegal offsets.. */
  98  100                          check_access(insn);
  99  101  
 100      -                        if (insn->type->ctype.modifiers & MOD_VOLATILE)
      102 +                        if (insn->is_volatile)
 101  103                                  continue;
 102  104  
 103  105                          RECURSE_PTR_REVERSE(insn, dom) {
 104  106                                  int dominance;
 105  107                                  if (!dom->bb)
 106  108                                          continue;
 107  109                                  dominance = dominates(pseudo, insn, dom, local);
 108  110                                  if (dominance) {
 109  111                                          /* possible partial dominance? */
 110  112                                          if (dominance < 0)  {
↓ open down ↓ 9 lines elided ↑ open up ↑
 120  122  
 121  123                          /* OK, go find the parents */
 122  124                          generation = ++bb_generation;
 123  125                          bb->generation = generation;
 124  126                          dominators = NULL;
 125  127                          if (find_dominating_parents(pseudo, insn, bb, generation, &dominators, local)) {
 126  128                                  /* This happens with initial assignments to structures etc.. */
 127  129                                  if (!dominators) {
 128  130                                          if (local) {
 129  131                                                  assert(pseudo->type != PSEUDO_ARG);
 130      -                                                convert_load_instruction(insn, value_pseudo(insn->type, 0));
      132 +                                                convert_load_instruction(insn, value_pseudo(0));
 131  133                                          }
 132  134                                          goto next_load;
 133  135                                  }
 134  136                                  rewrite_load_instruction(insn, dominators);
      137 +                        } else {        // cleanup pending phi-sources
      138 +                                pseudo_t phi;
      139 +                                FOR_EACH_PTR(dominators, phi) {
      140 +                                        kill_instruction(phi->def);
      141 +                                } END_FOR_EACH_PTR(phi);
 135  142                          }
 136  143                  }
 137  144  next_load:
 138  145                  /* Do the next one */;
 139  146          } END_FOR_EACH_PTR_REVERSE(insn);
 140  147  }
 141  148  
 142      -static void kill_store(struct instruction *insn)
 143      -{
 144      -        if (insn) {
 145      -                insn->bb = NULL;
 146      -                insn->opcode = OP_SNOP;
 147      -                kill_use(&insn->target);
 148      -        }
 149      -}
 150      -
 151  149  static void kill_dominated_stores(struct basic_block *bb)
 152  150  {
 153  151          struct instruction *insn;
 154  152  
 155  153          FOR_EACH_PTR_REVERSE(bb->insns, insn) {
 156  154                  if (!insn->bb)
 157  155                          continue;
 158  156                  if (insn->opcode == OP_STORE) {
 159  157                          struct instruction *dom;
 160  158                          pseudo_t pseudo = insn->src;
 161      -                        int local = local_pseudo(pseudo);
      159 +                        int local;
 162  160  
      161 +                        if (!insn->type)
      162 +                                continue;
      163 +                        if (insn->is_volatile)
      164 +                                continue;
      165 +
      166 +                        local = local_pseudo(pseudo);
 163  167                          RECURSE_PTR_REVERSE(insn, dom) {
 164  168                                  int dominance;
 165  169                                  if (!dom->bb)
 166  170                                          continue;
 167  171                                  dominance = dominates(pseudo, insn, dom, local);
 168  172                                  if (dominance) {
 169  173                                          /* possible partial dominance? */
 170  174                                          if (dominance < 0)
 171  175                                                  goto next_store;
 172  176                                          if (dom->opcode == OP_LOAD)
 173  177                                                  goto next_store;
 174  178                                          /* Yeehaa! Found one! */
 175      -                                        kill_store(dom);
      179 +                                        kill_instruction_force(dom);
 176  180                                  }
 177  181                          } END_FOR_EACH_PTR_REVERSE(dom);
 178  182  
 179  183                          /* OK, we should check the parents now */
 180  184                  }
 181  185  next_store:
 182  186                  /* Do the next one */;
 183  187          } END_FOR_EACH_PTR_REVERSE(insn);
 184  188  }
 185  189  
 186  190  void simplify_memops(struct entrypoint *ep)
 187  191  {
 188  192          struct basic_block *bb;
      193 +        pseudo_t pseudo;
 189  194  
 190  195          FOR_EACH_PTR_REVERSE(ep->bbs, bb) {
 191  196                  simplify_loads(bb);
 192  197          } END_FOR_EACH_PTR_REVERSE(bb);
 193  198  
 194  199          FOR_EACH_PTR_REVERSE(ep->bbs, bb) {
 195  200                  kill_dominated_stores(bb);
 196  201          } END_FOR_EACH_PTR_REVERSE(bb);
      202 +
      203 +        FOR_EACH_PTR(ep->accesses, pseudo) {
      204 +                struct symbol *var = pseudo->sym;
      205 +                unsigned long mod;
      206 +                if (!var)
      207 +                        continue;
      208 +                mod = var->ctype.modifiers;
      209 +                if (mod & (MOD_VOLATILE | MOD_NONLOCAL | MOD_STATIC))
      210 +                        continue;
      211 +                kill_dead_stores(ep, pseudo, local_pseudo(pseudo));
      212 +        } END_FOR_EACH_PTR(pseudo);
 197  213  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX