Print this page
11972 resync smatch


  37                         if (dominance < 0) {
  38                                 if (one->opcode == OP_LOAD)
  39                                         continue;
  40                                 return 0;
  41                         }
  42                         if (!dominance)
  43                                 continue;
  44                         goto found_dominator;
  45                 } END_FOR_EACH_PTR_REVERSE(one);
  46 no_dominance:
  47                 if (parent->generation == generation)
  48                         continue;
  49                 parent->generation = generation;
  50 
  51                 if (!find_dominating_parents(pseudo, insn, parent, generation, dominators, local))
  52                         return 0;
  53                 continue;
  54 
  55 found_dominator:
  56                 br = delete_last_instruction(&parent->insns);
  57                 phi = alloc_phi(parent, one->target, one->size);
  58                 phi->ident = phi->ident ? : one->target->ident;
  59                 add_instruction(&parent->insns, br);
  60                 use_pseudo(insn, phi, add_pseudo(dominators, phi));
  61         } END_FOR_EACH_PTR(parent);
  62         return 1;
  63 }               
  64 
  65 static int address_taken(pseudo_t pseudo)
  66 {
  67         struct pseudo_user *pu;
  68         FOR_EACH_PTR(pseudo->users, pu) {
  69                 struct instruction *insn = pu->insn;
  70                 if (insn->bb && (insn->opcode != OP_LOAD && insn->opcode != OP_STORE))
  71                         return 1;


  72         } END_FOR_EACH_PTR(pu);
  73         return 0;
  74 }
  75 
  76 static int local_pseudo(pseudo_t pseudo)
  77 {
  78         return pseudo->type == PSEUDO_SYM
  79                 && !(pseudo->sym->ctype.modifiers & (MOD_STATIC | MOD_NONLOCAL))
  80                 && !address_taken(pseudo);
  81 }
  82 
  83 static void simplify_loads(struct basic_block *bb)
  84 {
  85         struct instruction *insn;
  86 
  87         FOR_EACH_PTR_REVERSE(bb->insns, insn) {
  88                 if (!insn->bb)
  89                         continue;
  90                 if (insn->opcode == OP_LOAD) {
  91                         struct instruction *dom;
  92                         pseudo_t pseudo = insn->src;
  93                         int local = local_pseudo(pseudo);
  94                         struct pseudo_list *dominators;
  95                         unsigned long generation;
  96 
  97                         /* Check for illegal offsets.. */
  98                         check_access(insn);
  99 
 100                         if (insn->type->ctype.modifiers & MOD_VOLATILE)
 101                                 continue;
 102 
 103                         RECURSE_PTR_REVERSE(insn, dom) {
 104                                 int dominance;
 105                                 if (!dom->bb)
 106                                         continue;
 107                                 dominance = dominates(pseudo, insn, dom, local);
 108                                 if (dominance) {
 109                                         /* possible partial dominance? */
 110                                         if (dominance < 0)  {
 111                                                 if (dom->opcode == OP_LOAD)
 112                                                         continue;
 113                                                 goto next_load;
 114                                         }
 115                                         /* Yeehaa! Found one! */
 116                                         convert_load_instruction(insn, dom->target);
 117                                         goto next_load;
 118                                 }
 119                         } END_FOR_EACH_PTR_REVERSE(dom);
 120 
 121                         /* OK, go find the parents */
 122                         generation = ++bb_generation;
 123                         bb->generation = generation;
 124                         dominators = NULL;
 125                         if (find_dominating_parents(pseudo, insn, bb, generation, &dominators, local)) {
 126                                 /* This happens with initial assignments to structures etc.. */
 127                                 if (!dominators) {
 128                                         if (local) {
 129                                                 assert(pseudo->type != PSEUDO_ARG);
 130                                                 convert_load_instruction(insn, value_pseudo(insn->type, 0));
 131                                         }
 132                                         goto next_load;
 133                                 }
 134                                 rewrite_load_instruction(insn, dominators);





 135                         }
 136                 }
 137 next_load:
 138                 /* Do the next one */;
 139         } END_FOR_EACH_PTR_REVERSE(insn);
 140 }
 141 
 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 static void kill_dominated_stores(struct basic_block *bb)
 152 {
 153         struct instruction *insn;
 154 
 155         FOR_EACH_PTR_REVERSE(bb->insns, insn) {
 156                 if (!insn->bb)
 157                         continue;
 158                 if (insn->opcode == OP_STORE) {
 159                         struct instruction *dom;
 160                         pseudo_t pseudo = insn->src;
 161                         int local = local_pseudo(pseudo);
 162 






 163                         RECURSE_PTR_REVERSE(insn, dom) {
 164                                 int dominance;
 165                                 if (!dom->bb)
 166                                         continue;
 167                                 dominance = dominates(pseudo, insn, dom, local);
 168                                 if (dominance) {
 169                                         /* possible partial dominance? */
 170                                         if (dominance < 0)
 171                                                 goto next_store;
 172                                         if (dom->opcode == OP_LOAD)
 173                                                 goto next_store;
 174                                         /* Yeehaa! Found one! */
 175                                         kill_store(dom);
 176                                 }
 177                         } END_FOR_EACH_PTR_REVERSE(dom);
 178 
 179                         /* OK, we should check the parents now */
 180                 }
 181 next_store:
 182                 /* Do the next one */;
 183         } END_FOR_EACH_PTR_REVERSE(insn);
 184 }
 185 
 186 void simplify_memops(struct entrypoint *ep)
 187 {
 188         struct basic_block *bb;

 189 
 190         FOR_EACH_PTR_REVERSE(ep->bbs, bb) {
 191                 simplify_loads(bb);
 192         } END_FOR_EACH_PTR_REVERSE(bb);
 193 
 194         FOR_EACH_PTR_REVERSE(ep->bbs, bb) {
 195                 kill_dominated_stores(bb);
 196         } END_FOR_EACH_PTR_REVERSE(bb);











 197 }


  37                         if (dominance < 0) {
  38                                 if (one->opcode == OP_LOAD)
  39                                         continue;
  40                                 return 0;
  41                         }
  42                         if (!dominance)
  43                                 continue;
  44                         goto found_dominator;
  45                 } END_FOR_EACH_PTR_REVERSE(one);
  46 no_dominance:
  47                 if (parent->generation == generation)
  48                         continue;
  49                 parent->generation = generation;
  50 
  51                 if (!find_dominating_parents(pseudo, insn, parent, generation, dominators, local))
  52                         return 0;
  53                 continue;
  54 
  55 found_dominator:
  56                 br = delete_last_instruction(&parent->insns);
  57                 phi = alloc_phi(parent, one->target, one->type);
  58                 phi->ident = phi->ident ? : one->target->ident;
  59                 add_instruction(&parent->insns, br);
  60                 use_pseudo(insn, phi, add_pseudo(dominators, phi));
  61         } END_FOR_EACH_PTR(parent);
  62         return 1;
  63 }               
  64 
  65 static int address_taken(pseudo_t pseudo)
  66 {
  67         struct pseudo_user *pu;
  68         FOR_EACH_PTR(pseudo->users, pu) {
  69                 struct instruction *insn = pu->insn;
  70                 if (insn->bb && (insn->opcode != OP_LOAD && insn->opcode != OP_STORE))
  71                         return 1;
  72                 if (pu->userp != &insn->src)
  73                         return 1;
  74         } END_FOR_EACH_PTR(pu);
  75         return 0;
  76 }
  77 
  78 static int local_pseudo(pseudo_t pseudo)
  79 {
  80         return pseudo->type == PSEUDO_SYM
  81                 && !(pseudo->sym->ctype.modifiers & (MOD_STATIC | MOD_NONLOCAL))
  82                 && !address_taken(pseudo);
  83 }
  84 
  85 static void simplify_loads(struct basic_block *bb)
  86 {
  87         struct instruction *insn;
  88 
  89         FOR_EACH_PTR_REVERSE(bb->insns, insn) {
  90                 if (!insn->bb)
  91                         continue;
  92                 if (insn->opcode == OP_LOAD) {
  93                         struct instruction *dom;
  94                         pseudo_t pseudo = insn->src;
  95                         int local = local_pseudo(pseudo);
  96                         struct pseudo_list *dominators;
  97                         unsigned long generation;
  98 
  99                         /* Check for illegal offsets.. */
 100                         check_access(insn);
 101 
 102                         if (insn->is_volatile)
 103                                 continue;
 104 
 105                         RECURSE_PTR_REVERSE(insn, dom) {
 106                                 int dominance;
 107                                 if (!dom->bb)
 108                                         continue;
 109                                 dominance = dominates(pseudo, insn, dom, local);
 110                                 if (dominance) {
 111                                         /* possible partial dominance? */
 112                                         if (dominance < 0)  {
 113                                                 if (dom->opcode == OP_LOAD)
 114                                                         continue;
 115                                                 goto next_load;
 116                                         }
 117                                         /* Yeehaa! Found one! */
 118                                         convert_load_instruction(insn, dom->target);
 119                                         goto next_load;
 120                                 }
 121                         } END_FOR_EACH_PTR_REVERSE(dom);
 122 
 123                         /* OK, go find the parents */
 124                         generation = ++bb_generation;
 125                         bb->generation = generation;
 126                         dominators = NULL;
 127                         if (find_dominating_parents(pseudo, insn, bb, generation, &dominators, local)) {
 128                                 /* This happens with initial assignments to structures etc.. */
 129                                 if (!dominators) {
 130                                         if (local) {
 131                                                 assert(pseudo->type != PSEUDO_ARG);
 132                                                 convert_load_instruction(insn, value_pseudo(0));
 133                                         }
 134                                         goto next_load;
 135                                 }
 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);
 142                         }
 143                 }
 144 next_load:
 145                 /* Do the next one */;
 146         } END_FOR_EACH_PTR_REVERSE(insn);
 147 }
 148 









 149 static void kill_dominated_stores(struct basic_block *bb)
 150 {
 151         struct instruction *insn;
 152 
 153         FOR_EACH_PTR_REVERSE(bb->insns, insn) {
 154                 if (!insn->bb)
 155                         continue;
 156                 if (insn->opcode == OP_STORE) {
 157                         struct instruction *dom;
 158                         pseudo_t pseudo = insn->src;
 159                         int local;
 160 
 161                         if (!insn->type)
 162                                 continue;
 163                         if (insn->is_volatile)
 164                                 continue;
 165 
 166                         local = local_pseudo(pseudo);
 167                         RECURSE_PTR_REVERSE(insn, dom) {
 168                                 int dominance;
 169                                 if (!dom->bb)
 170                                         continue;
 171                                 dominance = dominates(pseudo, insn, dom, local);
 172                                 if (dominance) {
 173                                         /* possible partial dominance? */
 174                                         if (dominance < 0)
 175                                                 goto next_store;
 176                                         if (dom->opcode == OP_LOAD)
 177                                                 goto next_store;
 178                                         /* Yeehaa! Found one! */
 179                                         kill_instruction_force(dom);
 180                                 }
 181                         } END_FOR_EACH_PTR_REVERSE(dom);
 182 
 183                         /* OK, we should check the parents now */
 184                 }
 185 next_store:
 186                 /* Do the next one */;
 187         } END_FOR_EACH_PTR_REVERSE(insn);
 188 }
 189 
 190 void simplify_memops(struct entrypoint *ep)
 191 {
 192         struct basic_block *bb;
 193         pseudo_t pseudo;
 194 
 195         FOR_EACH_PTR_REVERSE(ep->bbs, bb) {
 196                 simplify_loads(bb);
 197         } END_FOR_EACH_PTR_REVERSE(bb);
 198 
 199         FOR_EACH_PTR_REVERSE(ep->bbs, bb) {
 200                 kill_dominated_stores(bb);
 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);
 213 }