1*1f5207b7SJohn Levon /* 2*1f5207b7SJohn Levon * CSE - walk the linearized instruction flow, and 3*1f5207b7SJohn Levon * see if we can simplify it and apply CSE on it. 4*1f5207b7SJohn Levon * 5*1f5207b7SJohn Levon * Copyright (C) 2004 Linus Torvalds 6*1f5207b7SJohn Levon */ 7*1f5207b7SJohn Levon 8*1f5207b7SJohn Levon #include <string.h> 9*1f5207b7SJohn Levon #include <stdarg.h> 10*1f5207b7SJohn Levon #include <stdlib.h> 11*1f5207b7SJohn Levon #include <stdio.h> 12*1f5207b7SJohn Levon #include <stddef.h> 13*1f5207b7SJohn Levon #include <assert.h> 14*1f5207b7SJohn Levon 15*1f5207b7SJohn Levon #include "parse.h" 16*1f5207b7SJohn Levon #include "expression.h" 17*1f5207b7SJohn Levon #include "linearize.h" 18*1f5207b7SJohn Levon #include "flow.h" 19*1f5207b7SJohn Levon 20*1f5207b7SJohn Levon #define INSN_HASH_SIZE 256 21*1f5207b7SJohn Levon static struct instruction_list *insn_hash_table[INSN_HASH_SIZE]; 22*1f5207b7SJohn Levon 23*1f5207b7SJohn Levon int repeat_phase; 24*1f5207b7SJohn Levon 25*1f5207b7SJohn Levon static int phi_compare(pseudo_t phi1, pseudo_t phi2) 26*1f5207b7SJohn Levon { 27*1f5207b7SJohn Levon const struct instruction *def1 = phi1->def; 28*1f5207b7SJohn Levon const struct instruction *def2 = phi2->def; 29*1f5207b7SJohn Levon 30*1f5207b7SJohn Levon if (def1->src1 != def2->src1) 31*1f5207b7SJohn Levon return def1->src1 < def2->src1 ? -1 : 1; 32*1f5207b7SJohn Levon if (def1->bb != def2->bb) 33*1f5207b7SJohn Levon return def1->bb < def2->bb ? -1 : 1; 34*1f5207b7SJohn Levon return 0; 35*1f5207b7SJohn Levon } 36*1f5207b7SJohn Levon 37*1f5207b7SJohn Levon 38*1f5207b7SJohn Levon static void clean_up_one_instruction(struct basic_block *bb, struct instruction *insn) 39*1f5207b7SJohn Levon { 40*1f5207b7SJohn Levon unsigned long hash; 41*1f5207b7SJohn Levon 42*1f5207b7SJohn Levon if (!insn->bb) 43*1f5207b7SJohn Levon return; 44*1f5207b7SJohn Levon assert(insn->bb == bb); 45*1f5207b7SJohn Levon repeat_phase |= simplify_instruction(insn); 46*1f5207b7SJohn Levon if (!insn->bb) 47*1f5207b7SJohn Levon return; 48*1f5207b7SJohn Levon hash = (insn->opcode << 3) + (insn->size >> 3); 49*1f5207b7SJohn Levon switch (insn->opcode) { 50*1f5207b7SJohn Levon case OP_SEL: 51*1f5207b7SJohn Levon hash += hashval(insn->src3); 52*1f5207b7SJohn Levon /* Fall through */ 53*1f5207b7SJohn Levon 54*1f5207b7SJohn Levon /* Binary arithmetic */ 55*1f5207b7SJohn Levon case OP_ADD: case OP_SUB: 56*1f5207b7SJohn Levon case OP_MULU: case OP_MULS: 57*1f5207b7SJohn Levon case OP_DIVU: case OP_DIVS: 58*1f5207b7SJohn Levon case OP_MODU: case OP_MODS: 59*1f5207b7SJohn Levon case OP_SHL: 60*1f5207b7SJohn Levon case OP_LSR: case OP_ASR: 61*1f5207b7SJohn Levon case OP_AND: case OP_OR: 62*1f5207b7SJohn Levon 63*1f5207b7SJohn Levon /* Binary logical */ 64*1f5207b7SJohn Levon case OP_XOR: case OP_AND_BOOL: 65*1f5207b7SJohn Levon case OP_OR_BOOL: 66*1f5207b7SJohn Levon 67*1f5207b7SJohn Levon /* Binary comparison */ 68*1f5207b7SJohn Levon case OP_SET_EQ: case OP_SET_NE: 69*1f5207b7SJohn Levon case OP_SET_LE: case OP_SET_GE: 70*1f5207b7SJohn Levon case OP_SET_LT: case OP_SET_GT: 71*1f5207b7SJohn Levon case OP_SET_B: case OP_SET_A: 72*1f5207b7SJohn Levon case OP_SET_BE: case OP_SET_AE: 73*1f5207b7SJohn Levon hash += hashval(insn->src2); 74*1f5207b7SJohn Levon /* Fall through */ 75*1f5207b7SJohn Levon 76*1f5207b7SJohn Levon /* Unary */ 77*1f5207b7SJohn Levon case OP_NOT: case OP_NEG: 78*1f5207b7SJohn Levon hash += hashval(insn->src1); 79*1f5207b7SJohn Levon break; 80*1f5207b7SJohn Levon 81*1f5207b7SJohn Levon case OP_SETVAL: 82*1f5207b7SJohn Levon hash += hashval(insn->val); 83*1f5207b7SJohn Levon break; 84*1f5207b7SJohn Levon 85*1f5207b7SJohn Levon case OP_SYMADDR: 86*1f5207b7SJohn Levon hash += hashval(insn->symbol); 87*1f5207b7SJohn Levon break; 88*1f5207b7SJohn Levon 89*1f5207b7SJohn Levon case OP_CAST: 90*1f5207b7SJohn Levon case OP_SCAST: 91*1f5207b7SJohn Levon case OP_PTRCAST: 92*1f5207b7SJohn Levon /* 93*1f5207b7SJohn Levon * This is crap! Many "orig_types" are the 94*1f5207b7SJohn Levon * same as far as casts go, we should generate 95*1f5207b7SJohn Levon * some kind of "type hash" that is identical 96*1f5207b7SJohn Levon * for identical casts 97*1f5207b7SJohn Levon */ 98*1f5207b7SJohn Levon hash += hashval(insn->orig_type); 99*1f5207b7SJohn Levon hash += hashval(insn->src); 100*1f5207b7SJohn Levon break; 101*1f5207b7SJohn Levon 102*1f5207b7SJohn Levon /* Other */ 103*1f5207b7SJohn Levon case OP_PHI: { 104*1f5207b7SJohn Levon pseudo_t phi; 105*1f5207b7SJohn Levon FOR_EACH_PTR(insn->phi_list, phi) { 106*1f5207b7SJohn Levon struct instruction *def; 107*1f5207b7SJohn Levon if (phi == VOID || !phi->def) 108*1f5207b7SJohn Levon continue; 109*1f5207b7SJohn Levon def = phi->def; 110*1f5207b7SJohn Levon hash += hashval(def->src1); 111*1f5207b7SJohn Levon hash += hashval(def->bb); 112*1f5207b7SJohn Levon } END_FOR_EACH_PTR(phi); 113*1f5207b7SJohn Levon break; 114*1f5207b7SJohn Levon } 115*1f5207b7SJohn Levon 116*1f5207b7SJohn Levon default: 117*1f5207b7SJohn Levon /* 118*1f5207b7SJohn Levon * Nothing to do, don't even bother hashing them, 119*1f5207b7SJohn Levon * we're not going to try to CSE them 120*1f5207b7SJohn Levon */ 121*1f5207b7SJohn Levon return; 122*1f5207b7SJohn Levon } 123*1f5207b7SJohn Levon hash += hash >> 16; 124*1f5207b7SJohn Levon hash &= INSN_HASH_SIZE-1; 125*1f5207b7SJohn Levon add_instruction(insn_hash_table + hash, insn); 126*1f5207b7SJohn Levon } 127*1f5207b7SJohn Levon 128*1f5207b7SJohn Levon static void clean_up_insns(struct entrypoint *ep) 129*1f5207b7SJohn Levon { 130*1f5207b7SJohn Levon struct basic_block *bb; 131*1f5207b7SJohn Levon 132*1f5207b7SJohn Levon FOR_EACH_PTR(ep->bbs, bb) { 133*1f5207b7SJohn Levon struct instruction *insn; 134*1f5207b7SJohn Levon FOR_EACH_PTR(bb->insns, insn) { 135*1f5207b7SJohn Levon clean_up_one_instruction(bb, insn); 136*1f5207b7SJohn Levon } END_FOR_EACH_PTR(insn); 137*1f5207b7SJohn Levon } END_FOR_EACH_PTR(bb); 138*1f5207b7SJohn Levon } 139*1f5207b7SJohn Levon 140*1f5207b7SJohn Levon /* Compare two (sorted) phi-lists */ 141*1f5207b7SJohn Levon static int phi_list_compare(struct pseudo_list *l1, struct pseudo_list *l2) 142*1f5207b7SJohn Levon { 143*1f5207b7SJohn Levon pseudo_t phi1, phi2; 144*1f5207b7SJohn Levon 145*1f5207b7SJohn Levon PREPARE_PTR_LIST(l1, phi1); 146*1f5207b7SJohn Levon PREPARE_PTR_LIST(l2, phi2); 147*1f5207b7SJohn Levon for (;;) { 148*1f5207b7SJohn Levon int cmp; 149*1f5207b7SJohn Levon 150*1f5207b7SJohn Levon while (phi1 && (phi1 == VOID || !phi1->def)) 151*1f5207b7SJohn Levon NEXT_PTR_LIST(phi1); 152*1f5207b7SJohn Levon while (phi2 && (phi2 == VOID || !phi2->def)) 153*1f5207b7SJohn Levon NEXT_PTR_LIST(phi2); 154*1f5207b7SJohn Levon 155*1f5207b7SJohn Levon if (!phi1) 156*1f5207b7SJohn Levon return phi2 ? -1 : 0; 157*1f5207b7SJohn Levon if (!phi2) 158*1f5207b7SJohn Levon return phi1 ? 1 : 0; 159*1f5207b7SJohn Levon cmp = phi_compare(phi1, phi2); 160*1f5207b7SJohn Levon if (cmp) 161*1f5207b7SJohn Levon return cmp; 162*1f5207b7SJohn Levon NEXT_PTR_LIST(phi1); 163*1f5207b7SJohn Levon NEXT_PTR_LIST(phi2); 164*1f5207b7SJohn Levon } 165*1f5207b7SJohn Levon /* Not reached, but we need to make the nesting come out right */ 166*1f5207b7SJohn Levon FINISH_PTR_LIST(phi2); 167*1f5207b7SJohn Levon FINISH_PTR_LIST(phi1); 168*1f5207b7SJohn Levon } 169*1f5207b7SJohn Levon 170*1f5207b7SJohn Levon static int insn_compare(const void *_i1, const void *_i2) 171*1f5207b7SJohn Levon { 172*1f5207b7SJohn Levon const struct instruction *i1 = _i1; 173*1f5207b7SJohn Levon const struct instruction *i2 = _i2; 174*1f5207b7SJohn Levon 175*1f5207b7SJohn Levon if (i1->opcode != i2->opcode) 176*1f5207b7SJohn Levon return i1->opcode < i2->opcode ? -1 : 1; 177*1f5207b7SJohn Levon 178*1f5207b7SJohn Levon switch (i1->opcode) { 179*1f5207b7SJohn Levon 180*1f5207b7SJohn Levon /* commutative binop */ 181*1f5207b7SJohn Levon case OP_ADD: 182*1f5207b7SJohn Levon case OP_MULU: case OP_MULS: 183*1f5207b7SJohn Levon case OP_AND_BOOL: case OP_OR_BOOL: 184*1f5207b7SJohn Levon case OP_AND: case OP_OR: 185*1f5207b7SJohn Levon case OP_XOR: 186*1f5207b7SJohn Levon case OP_SET_EQ: case OP_SET_NE: 187*1f5207b7SJohn Levon if (i1->src1 == i2->src2 && i1->src2 == i2->src1) 188*1f5207b7SJohn Levon return 0; 189*1f5207b7SJohn Levon goto case_binops; 190*1f5207b7SJohn Levon 191*1f5207b7SJohn Levon case OP_SEL: 192*1f5207b7SJohn Levon if (i1->src3 != i2->src3) 193*1f5207b7SJohn Levon return i1->src3 < i2->src3 ? -1 : 1; 194*1f5207b7SJohn Levon /* Fall-through to binops */ 195*1f5207b7SJohn Levon 196*1f5207b7SJohn Levon /* Binary arithmetic */ 197*1f5207b7SJohn Levon case OP_SUB: 198*1f5207b7SJohn Levon case OP_DIVU: case OP_DIVS: 199*1f5207b7SJohn Levon case OP_MODU: case OP_MODS: 200*1f5207b7SJohn Levon case OP_SHL: 201*1f5207b7SJohn Levon case OP_LSR: case OP_ASR: 202*1f5207b7SJohn Levon 203*1f5207b7SJohn Levon /* Binary comparison */ 204*1f5207b7SJohn Levon case OP_SET_LE: case OP_SET_GE: 205*1f5207b7SJohn Levon case OP_SET_LT: case OP_SET_GT: 206*1f5207b7SJohn Levon case OP_SET_B: case OP_SET_A: 207*1f5207b7SJohn Levon case OP_SET_BE: case OP_SET_AE: 208*1f5207b7SJohn Levon case_binops: 209*1f5207b7SJohn Levon if (i1->src2 != i2->src2) 210*1f5207b7SJohn Levon return i1->src2 < i2->src2 ? -1 : 1; 211*1f5207b7SJohn Levon /* Fall through to unops */ 212*1f5207b7SJohn Levon 213*1f5207b7SJohn Levon /* Unary */ 214*1f5207b7SJohn Levon case OP_NOT: case OP_NEG: 215*1f5207b7SJohn Levon if (i1->src1 != i2->src1) 216*1f5207b7SJohn Levon return i1->src1 < i2->src1 ? -1 : 1; 217*1f5207b7SJohn Levon break; 218*1f5207b7SJohn Levon 219*1f5207b7SJohn Levon case OP_SYMADDR: 220*1f5207b7SJohn Levon if (i1->symbol != i2->symbol) 221*1f5207b7SJohn Levon return i1->symbol < i2->symbol ? -1 : 1; 222*1f5207b7SJohn Levon break; 223*1f5207b7SJohn Levon 224*1f5207b7SJohn Levon case OP_SETVAL: 225*1f5207b7SJohn Levon if (i1->val != i2->val) 226*1f5207b7SJohn Levon return i1->val < i2->val ? -1 : 1; 227*1f5207b7SJohn Levon break; 228*1f5207b7SJohn Levon 229*1f5207b7SJohn Levon /* Other */ 230*1f5207b7SJohn Levon case OP_PHI: 231*1f5207b7SJohn Levon return phi_list_compare(i1->phi_list, i2->phi_list); 232*1f5207b7SJohn Levon 233*1f5207b7SJohn Levon case OP_CAST: 234*1f5207b7SJohn Levon case OP_SCAST: 235*1f5207b7SJohn Levon case OP_PTRCAST: 236*1f5207b7SJohn Levon /* 237*1f5207b7SJohn Levon * This is crap! See the comments on hashing. 238*1f5207b7SJohn Levon */ 239*1f5207b7SJohn Levon if (i1->orig_type != i2->orig_type) 240*1f5207b7SJohn Levon return i1->orig_type < i2->orig_type ? -1 : 1; 241*1f5207b7SJohn Levon if (i1->src != i2->src) 242*1f5207b7SJohn Levon return i1->src < i2->src ? -1 : 1; 243*1f5207b7SJohn Levon break; 244*1f5207b7SJohn Levon 245*1f5207b7SJohn Levon default: 246*1f5207b7SJohn Levon warning(i1->pos, "bad instruction on hash chain"); 247*1f5207b7SJohn Levon } 248*1f5207b7SJohn Levon if (i1->size != i2->size) 249*1f5207b7SJohn Levon return i1->size < i2->size ? -1 : 1; 250*1f5207b7SJohn Levon return 0; 251*1f5207b7SJohn Levon } 252*1f5207b7SJohn Levon 253*1f5207b7SJohn Levon static void sort_instruction_list(struct instruction_list **list) 254*1f5207b7SJohn Levon { 255*1f5207b7SJohn Levon sort_list((struct ptr_list **)list , insn_compare); 256*1f5207b7SJohn Levon } 257*1f5207b7SJohn Levon 258*1f5207b7SJohn Levon static struct instruction * cse_one_instruction(struct instruction *insn, struct instruction *def) 259*1f5207b7SJohn Levon { 260*1f5207b7SJohn Levon convert_instruction_target(insn, def->target); 261*1f5207b7SJohn Levon 262*1f5207b7SJohn Levon kill_instruction(insn); 263*1f5207b7SJohn Levon repeat_phase |= REPEAT_CSE; 264*1f5207b7SJohn Levon return def; 265*1f5207b7SJohn Levon } 266*1f5207b7SJohn Levon 267*1f5207b7SJohn Levon /* 268*1f5207b7SJohn Levon * Does "bb1" dominate "bb2"? 269*1f5207b7SJohn Levon */ 270*1f5207b7SJohn Levon static int bb_dominates(struct entrypoint *ep, struct basic_block *bb1, struct basic_block *bb2, unsigned long generation) 271*1f5207b7SJohn Levon { 272*1f5207b7SJohn Levon struct basic_block *parent; 273*1f5207b7SJohn Levon 274*1f5207b7SJohn Levon /* Nothing dominates the entrypoint.. */ 275*1f5207b7SJohn Levon if (bb2 == ep->entry->bb) 276*1f5207b7SJohn Levon return 0; 277*1f5207b7SJohn Levon FOR_EACH_PTR(bb2->parents, parent) { 278*1f5207b7SJohn Levon if (parent == bb1) 279*1f5207b7SJohn Levon continue; 280*1f5207b7SJohn Levon if (parent->generation == generation) 281*1f5207b7SJohn Levon continue; 282*1f5207b7SJohn Levon parent->generation = generation; 283*1f5207b7SJohn Levon if (!bb_dominates(ep, bb1, parent, generation)) 284*1f5207b7SJohn Levon return 0; 285*1f5207b7SJohn Levon } END_FOR_EACH_PTR(parent); 286*1f5207b7SJohn Levon return 1; 287*1f5207b7SJohn Levon } 288*1f5207b7SJohn Levon 289*1f5207b7SJohn Levon static struct basic_block *trivial_common_parent(struct basic_block *bb1, struct basic_block *bb2) 290*1f5207b7SJohn Levon { 291*1f5207b7SJohn Levon struct basic_block *parent; 292*1f5207b7SJohn Levon 293*1f5207b7SJohn Levon if (bb_list_size(bb1->parents) != 1) 294*1f5207b7SJohn Levon return NULL; 295*1f5207b7SJohn Levon parent = first_basic_block(bb1->parents); 296*1f5207b7SJohn Levon if (bb_list_size(bb2->parents) != 1) 297*1f5207b7SJohn Levon return NULL; 298*1f5207b7SJohn Levon if (first_basic_block(bb2->parents) != parent) 299*1f5207b7SJohn Levon return NULL; 300*1f5207b7SJohn Levon return parent; 301*1f5207b7SJohn Levon } 302*1f5207b7SJohn Levon 303*1f5207b7SJohn Levon static inline void remove_instruction(struct instruction_list **list, struct instruction *insn, int count) 304*1f5207b7SJohn Levon { 305*1f5207b7SJohn Levon delete_ptr_list_entry((struct ptr_list **)list, insn, count); 306*1f5207b7SJohn Levon } 307*1f5207b7SJohn Levon 308*1f5207b7SJohn Levon static void add_instruction_to_end(struct instruction *insn, struct basic_block *bb) 309*1f5207b7SJohn Levon { 310*1f5207b7SJohn Levon struct instruction *br = delete_last_instruction(&bb->insns); 311*1f5207b7SJohn Levon insn->bb = bb; 312*1f5207b7SJohn Levon add_instruction(&bb->insns, insn); 313*1f5207b7SJohn Levon add_instruction(&bb->insns, br); 314*1f5207b7SJohn Levon } 315*1f5207b7SJohn Levon 316*1f5207b7SJohn Levon static struct instruction * try_to_cse(struct entrypoint *ep, struct instruction *i1, struct instruction *i2) 317*1f5207b7SJohn Levon { 318*1f5207b7SJohn Levon struct basic_block *b1, *b2, *common; 319*1f5207b7SJohn Levon 320*1f5207b7SJohn Levon /* 321*1f5207b7SJohn Levon * OK, i1 and i2 are the same instruction, modulo "target". 322*1f5207b7SJohn Levon * We should now see if we can combine them. 323*1f5207b7SJohn Levon */ 324*1f5207b7SJohn Levon b1 = i1->bb; 325*1f5207b7SJohn Levon b2 = i2->bb; 326*1f5207b7SJohn Levon 327*1f5207b7SJohn Levon /* 328*1f5207b7SJohn Levon * Currently we only handle the uninteresting degenerate case where 329*1f5207b7SJohn Levon * the CSE is inside one basic-block. 330*1f5207b7SJohn Levon */ 331*1f5207b7SJohn Levon if (b1 == b2) { 332*1f5207b7SJohn Levon struct instruction *insn; 333*1f5207b7SJohn Levon FOR_EACH_PTR(b1->insns, insn) { 334*1f5207b7SJohn Levon if (insn == i1) 335*1f5207b7SJohn Levon return cse_one_instruction(i2, i1); 336*1f5207b7SJohn Levon if (insn == i2) 337*1f5207b7SJohn Levon return cse_one_instruction(i1, i2); 338*1f5207b7SJohn Levon } END_FOR_EACH_PTR(insn); 339*1f5207b7SJohn Levon warning(b1->pos, "Whaa? unable to find CSE instructions"); 340*1f5207b7SJohn Levon return i1; 341*1f5207b7SJohn Levon } 342*1f5207b7SJohn Levon if (bb_dominates(ep, b1, b2, ++bb_generation)) 343*1f5207b7SJohn Levon return cse_one_instruction(i2, i1); 344*1f5207b7SJohn Levon 345*1f5207b7SJohn Levon if (bb_dominates(ep, b2, b1, ++bb_generation)) 346*1f5207b7SJohn Levon return cse_one_instruction(i1, i2); 347*1f5207b7SJohn Levon 348*1f5207b7SJohn Levon /* No direct dominance - but we could try to find a common ancestor.. */ 349*1f5207b7SJohn Levon common = trivial_common_parent(b1, b2); 350*1f5207b7SJohn Levon if (common) { 351*1f5207b7SJohn Levon i1 = cse_one_instruction(i2, i1); 352*1f5207b7SJohn Levon remove_instruction(&b1->insns, i1, 1); 353*1f5207b7SJohn Levon add_instruction_to_end(i1, common); 354*1f5207b7SJohn Levon } 355*1f5207b7SJohn Levon 356*1f5207b7SJohn Levon return i1; 357*1f5207b7SJohn Levon } 358*1f5207b7SJohn Levon 359*1f5207b7SJohn Levon void cleanup_and_cse(struct entrypoint *ep) 360*1f5207b7SJohn Levon { 361*1f5207b7SJohn Levon int i; 362*1f5207b7SJohn Levon 363*1f5207b7SJohn Levon simplify_memops(ep); 364*1f5207b7SJohn Levon repeat: 365*1f5207b7SJohn Levon repeat_phase = 0; 366*1f5207b7SJohn Levon clean_up_insns(ep); 367*1f5207b7SJohn Levon if (repeat_phase & REPEAT_CFG_CLEANUP) 368*1f5207b7SJohn Levon kill_unreachable_bbs(ep); 369*1f5207b7SJohn Levon for (i = 0; i < INSN_HASH_SIZE; i++) { 370*1f5207b7SJohn Levon struct instruction_list **list = insn_hash_table + i; 371*1f5207b7SJohn Levon if (*list) { 372*1f5207b7SJohn Levon if (instruction_list_size(*list) > 1) { 373*1f5207b7SJohn Levon struct instruction *insn, *last; 374*1f5207b7SJohn Levon 375*1f5207b7SJohn Levon sort_instruction_list(list); 376*1f5207b7SJohn Levon 377*1f5207b7SJohn Levon last = NULL; 378*1f5207b7SJohn Levon FOR_EACH_PTR(*list, insn) { 379*1f5207b7SJohn Levon if (!insn->bb) 380*1f5207b7SJohn Levon continue; 381*1f5207b7SJohn Levon if (last) { 382*1f5207b7SJohn Levon if (!insn_compare(last, insn)) 383*1f5207b7SJohn Levon insn = try_to_cse(ep, last, insn); 384*1f5207b7SJohn Levon } 385*1f5207b7SJohn Levon last = insn; 386*1f5207b7SJohn Levon } END_FOR_EACH_PTR(insn); 387*1f5207b7SJohn Levon } 388*1f5207b7SJohn Levon free_ptr_list((struct ptr_list **)list); 389*1f5207b7SJohn Levon } 390*1f5207b7SJohn Levon } 391*1f5207b7SJohn Levon 392*1f5207b7SJohn Levon if (repeat_phase & REPEAT_SYMBOL_CLEANUP) 393*1f5207b7SJohn Levon simplify_memops(ep); 394*1f5207b7SJohn Levon 395*1f5207b7SJohn Levon if (repeat_phase & REPEAT_CSE) 396*1f5207b7SJohn Levon goto repeat; 397*1f5207b7SJohn Levon } 398