1 bdemsky  1.1.2.1  // LoopOptimize.java, created Thu Jun 24 11:41:44 1999 by bdemsky
   2 bdemsky  1.1.2.1  // Copyright (C) 1999 Brian Demsky <bdemsky@mit.edu>
   3 bdemsky  1.1.2.1  // Licensed under the terms of the GNU GPL; see COPYING for details.
   4 bdemsky  1.1.2.1  package harpoon.Analysis.LowQuad.Loop;
   5 bdemsky  1.1.2.1  
   6 cananian 1.1.2.25 import harpoon.ClassFile.HClass;
   7 cananian 1.1.2.25 import harpoon.ClassFile.HCode;
   8 cananian 1.1.2.25 import harpoon.ClassFile.HCodeElement;
   9 cananian 1.1.2.25 import harpoon.ClassFile.HCodeFactory;
  10 cananian 1.1.2.25 import harpoon.ClassFile.HMethod;
  11 cananian 1.1.2.25 import harpoon.IR.LowQuad.LQop;
  12 cananian 1.1.2.25 import harpoon.IR.LowQuad.LowQuadFactory;
  13 cananian 1.1.2.27 import harpoon.IR.LowQuad.LowQuadSSI;
  14 cananian 1.1.2.25 import harpoon.IR.LowQuad.PAOFFSET;
  15 cananian 1.1.2.25 import harpoon.IR.LowQuad.POPER;
  16 cananian 1.1.2.25 import harpoon.IR.Quads.CONST;
  17 cananian 1.1.2.25 import harpoon.IR.Quads.Edge;
  18 cananian 1.1.2.25 import harpoon.IR.Quads.PHI;
  19 cananian 1.1.2.25 import harpoon.IR.Quads.Qop;
  20 cananian 1.1.2.25 import harpoon.IR.Quads.Quad;
  21 cananian 1.1.2.24 import harpoon.IR.Properties.CFGraphable;
  22 bdemsky  1.1.2.5  import harpoon.Analysis.UseDef;
  23 bdemsky  1.1.2.3  import harpoon.Analysis.Loops.Loops;
  24 bdemsky  1.1.2.1  import harpoon.Analysis.LowQuad.Loop.LoopAnalysis;
  25 bdemsky  1.1.2.15 import harpoon.Analysis.LowQuad.Loop.Induction;
  26 cananian 1.1.2.34 import harpoon.Analysis.Quads.SSIToSSAMap;
  27 bdemsky  1.1.2.6  import harpoon.Analysis.LowQuad.Loop.LoopMap;
  28 bdemsky  1.1.2.3  import harpoon.Analysis.Maps.AllInductionsMap;
  29 bdemsky  1.1.2.3  import harpoon.Analysis.Maps.BasicInductionsMap;
  30 cananian 1.1.2.26 import harpoon.Analysis.Maps.Derivation;
  31 bdemsky  1.1.2.3  import harpoon.Analysis.Maps.InvariantsMap;
  32 bdemsky  1.1.2.1  import harpoon.Util.Util;
  33 cananian 1.5      import net.cscott.jutil.WorkSet;
  34 bdemsky  1.1.2.4  import harpoon.Temp.TempMap;
  35 bdemsky  1.1.2.4  import harpoon.Temp.Temp;
  36 cananian 1.1.2.19 import harpoon.Analysis.Quads.DeadCode;
  37 bdemsky  1.1.2.14 import harpoon.Analysis.LowQuad.Loop.WorkTempMap;
  38 bdemsky  1.1.2.15 import harpoon.Analysis.LowQuad.Loop.MyLowQuadSSI;
  39 bdemsky  1.1.2.3  
  40 bdemsky  1.1.2.3  import java.util.Iterator;
  41 bdemsky  1.1.2.7  import java.util.HashMap;
  42 bdemsky  1.1.2.8  import java.util.Map;
  43 bdemsky  1.1.2.7  import java.util.Set;
  44 bdemsky  1.1.2.1  /**
  45 bdemsky  1.1.2.1   * <code>LoopOptimize</code> optimizes the code after <code>LoopAnalysis</code>.
  46 bdemsky  1.1.2.1   * 
  47 bdemsky  1.1.2.1   * @author  Brian Demsky <bdemsky@mit.edu>
  48 cananian 1.6       * @version $Id: LoopOptimize.java,v 1.6 2004/02/08 05:09:34 cananian Exp $
  49 bdemsky  1.1.2.1   */
  50 bdemsky  1.1.2.1  public final class LoopOptimize {
  51 bdemsky  1.1.2.29 
  52 bdemsky  1.1.2.3      AllInductionsMap aimap;
  53 bdemsky  1.1.2.3      BasicInductionsMap bimap;
  54 bdemsky  1.1.2.3      InvariantsMap invmap;
  55 bdemsky  1.1.2.3      LoopAnalysis loopanal;
  56 bdemsky  1.1.2.4      TempMap ssitossamap;
  57 bdemsky  1.1.2.7      UseDef ud;
  58 bdemsky  1.1.2.29     boolean changed;
  59 bdemsky  1.1.2.4  
  60 bdemsky  1.1.2.1      /** Creates an <code>LoopOptimize</code>. */
  61 bdemsky  1.1.2.4      public LoopOptimize(AllInductionsMap aimap,BasicInductionsMap bimap,InvariantsMap invmap, LoopAnalysis loopanal, TempMap ssitossamap) {
  62 bdemsky  1.1.2.3          this.aimap=aimap;
  63 bdemsky  1.1.2.3          this.bimap=bimap;
  64 bdemsky  1.1.2.3          this.invmap=invmap;
  65 bdemsky  1.1.2.3          this.loopanal=loopanal;
  66 bdemsky  1.1.2.4          this.ssitossamap=ssitossamap;
  67 bdemsky  1.1.2.7          ud=new UseDef();
  68 bdemsky  1.1.2.29         changed=false;
  69 bdemsky  1.1.2.1      }
  70 bdemsky  1.1.2.1  
  71 bdemsky  1.1.2.13     /**<code>LoopOptimize</code> constructor.  Used internally by codeFactory.*/
  72 bdemsky  1.1.2.4      public LoopOptimize(LoopAnalysis lanal, TempMap ssitossamap) {
  73 bdemsky  1.1.2.4          this(lanal,lanal,lanal,lanal, ssitossamap);
  74 bdemsky  1.1.2.3      }
  75 bdemsky  1.1.2.1  
  76 bdemsky  1.1.2.13     /** Returns a <code>HCodeFactory</code> that uses <code>LoopOptimize</code>. */
  77 bdemsky  1.1.2.1      public static HCodeFactory codeFactory(final HCodeFactory parent) {
  78 bdemsky  1.1.2.1          return new HCodeFactory() {
  79 bdemsky  1.1.2.1              public HCode convert(HMethod m) {
  80 bdemsky  1.1.2.1                  HCode hc = parent.convert(m);
  81 bdemsky  1.1.2.1                  if (hc!=null) {
  82 cananian 1.1.2.34                     SSIToSSAMap ssitossa=new SSIToSSAMap(hc);
  83 bdemsky  1.1.2.14                     return (new LoopOptimize(new LoopAnalysis(ssitossa),ssitossa)).optimize(hc);
  84 bdemsky  1.1.2.14                 } else
  85 bdemsky  1.1.2.1                  return hc;
  86 bdemsky  1.1.2.1              }
  87 bdemsky  1.1.2.1              public String getCodeName() { return parent.getCodeName(); }
  88 bdemsky  1.1.2.1              public void clear(HMethod m) { parent.clear(m); }
  89 bdemsky  1.1.2.1          };
  90 bdemsky  1.1.2.1      }
  91 bdemsky  1.1.2.1  
  92 bdemsky  1.1.2.13     /**<code>optimize</code> takes in a <code>HCode</code> and performs loop optimizations on it.
  93 bdemsky  1.1.2.13      * Optimization currently work only on loops with one entrance.   Furthermore, optimizations
  94 bdemsky  1.1.2.13      * currently only work on loops that the header node is a phi function of arity 2 [ie. natural
  95 bdemsky  1.1.2.13      * loops.]  This function really needs code that is passed to it to have been run through 
  96 bdemsky  1.1.2.13      * Deadcode.  Otherwise, it may make some very poor decisions on moving test conditions.
  97 bdemsky  1.1.2.13      */
  98 bdemsky  1.1.2.13 
  99 bdemsky  1.1.2.14     public HCode optimize(final HCode hc) {
 100 bdemsky  1.1.2.1      
 101 bdemsky  1.1.2.10         //Want defmap of temps in my invariants list, not new temps...
 102 bdemsky  1.1.2.10         //Force generation of defmap
 103 bdemsky  1.1.2.10         //Need to fix this!!!
 104 bdemsky  1.1.2.10 
 105 bdemsky  1.1.2.10         Temp []dummy=ud.allTemps(hc);   
 106 bdemsky  1.1.2.10 
 107 bdemsky  1.1.2.30         LowQuadSSI hcnew=new MyLowQuadSSI((LowQuadSSI)hc);
 108 bdemsky  1.1.2.1  
 109 bdemsky  1.1.2.13         // We start at the root loop, and recurse down each of its subloops.
 110 bdemsky  1.1.2.15 
 111 bdemsky  1.1.2.3          Loops lp=loopanal.rootloop(hc);
 112 bdemsky  1.1.2.3          WorkSet kids=(WorkSet) lp.nestedLoops();
 113 bdemsky  1.1.2.3          Iterator iterate=kids.iterator();
 114 bdemsky  1.1.2.35         //hcnew.print(new java.io.PrintWriter(System.out, true));
 115 bdemsky  1.1.2.3          while (iterate.hasNext())
 116 bdemsky  1.1.2.30             recursetree(hc, (MyLowQuadSSI) hcnew, (Loops)iterate.next(), new WorkSet());
 117 bdemsky  1.1.2.29 
 118 bdemsky  1.1.2.31         //hcnew.print(new java.io.PrintWriter(System.out, true));
 119 bdemsky  1.1.2.29         if (changed) {
 120 bdemsky  1.1.2.29             //We've likely broken SSI invariants...EVIL SSI!
 121 bdemsky  1.1.2.29             //Lets fix them...
 122 bdemsky  1.1.2.29             //As soon as someone gives me something to do that...
 123 bdemsky  1.1.2.35             //After doing optimizations we need to clean up any deadcode...
 124 bdemsky  1.1.2.36             
 125 bdemsky  1.1.2.35 
 126 bdemsky  1.1.2.35 
 127 bdemsky  1.1.2.36             MyLowQuadNoSSA hctemp=new MyLowQuadNoSSA(hcnew);
 128 bdemsky  1.1.2.36             hcnew=new LowQuadSSI(hctemp);
 129 bdemsky  1.1.2.36             //DeadCode.optimize(hcnew, null/*throw away AllocationInformation*/);
 130 bdemsky  1.1.2.29         }
 131 bdemsky  1.1.2.13         
 132 bdemsky  1.1.2.35 
 133 bdemsky  1.1.2.31         //hcnew.print(new java.io.PrintWriter(System.out, true));
 134 bdemsky  1.1.2.14         return hcnew;
 135 bdemsky  1.1.2.14     }
 136 bdemsky  1.1.2.14 
 137 bdemsky  1.1.2.14 
 138 bdemsky  1.1.2.13     /** <code>recursetree</code> recurses down the nested loop tree.*/
 139 bdemsky  1.1.2.15     void recursetree(HCode hc, MyLowQuadSSI hcnew, Loops lp, WorkSet usedinvariants) {
 140 bdemsky  1.1.2.13         
 141 bdemsky  1.1.2.13         //We only treat loops with one entrance currently.  We only recognize
 142 bdemsky  1.1.2.13         //loops with one entrance, so this isn't a limitation.
 143 bdemsky  1.1.2.3          if (lp.loopEntrances().size()==1) {
 144 bdemsky  1.1.2.12             Quad header=(Quad)(lp.loopEntrances()).toArray()[0];
 145 bdemsky  1.1.2.12             if (header.prev().length==2) {
 146 bdemsky  1.1.2.13                 //Hoist loop invariants.  The workset usedinvariants
 147 bdemsky  1.1.2.13                 //keeps track of invariants we have moved, so we don't try again.
 148 bdemsky  1.1.2.13 
 149 bdemsky  1.1.2.15                 doLoopinv(hc, hcnew, lp, header, usedinvariants);
 150 bdemsky  1.1.2.13 
 151 bdemsky  1.1.2.13                 //Create induction variables.  Header has to be updated since
 152 bdemsky  1.1.2.13                 //we most likely create new header nodes.
 153 bdemsky  1.1.2.14                 Set newinds=doLoopind(hc, hcnew, lp,header, usedinvariants);
 154 bdemsky  1.1.2.13                 //Move loop test conditions from the original induction variable
 155 bdemsky  1.1.2.13                 //to new ones
 156 bdemsky  1.1.2.22                 doLooptestmove(hc, hcnew, lp, header, newinds, usedinvariants);
 157 bdemsky  1.1.2.3              }
 158 bdemsky  1.1.2.13             else System.out.println("Multiple back edges.");
 159 bdemsky  1.1.2.3          } else
 160 bdemsky  1.1.2.3              System.out.println("Multiple or No  entrance loop in LoopOptimize!");
 161 bdemsky  1.1.2.13 
 162 bdemsky  1.1.2.13         //Look for child loops.  If there are any, recurse to them.
 163 bdemsky  1.1.2.13 
 164 bdemsky  1.1.2.3          WorkSet kids=(WorkSet) lp.nestedLoops();
 165 bdemsky  1.1.2.3          Iterator iterate=kids.iterator();
 166 bdemsky  1.1.2.3          while (iterate.hasNext())
 167 bdemsky  1.1.2.14             recursetree(hc, hcnew, (Loops)iterate.next(),usedinvariants);
 168 bdemsky  1.1.2.3      }
 169 bdemsky  1.1.2.3  
 170 bdemsky  1.1.2.13     /** <code>doLooptest</code> moves test conditions from original induction variables
 171 bdemsky  1.1.2.13      * to new ones whenever possible.*/
 172 bdemsky  1.1.2.13 
 173 bdemsky  1.1.2.22     void doLooptestmove(HCode hc, MyLowQuadSSI hcnew, Loops lp,Quad header, Set newinds, Set usedinvariants) {
 174 bdemsky  1.1.2.13         //Create the set of loop elements
 175 bdemsky  1.1.2.22         Set tests=loopanal.doLooptest(hc, lp);
 176 bdemsky  1.1.2.22         Iterator iterate=tests.iterator();
 177 bdemsky  1.1.2.13 
 178 bdemsky  1.1.2.13         //create sets of loop invariants and map of induction variables
 179 bdemsky  1.1.2.13         //to pass to the visitor
 180 bdemsky  1.1.2.12         Set loopinvars=invmap.invariantsMap(hc,lp);
 181 bdemsky  1.1.2.12         Map allinductions=aimap.allInductionsMap(hc,lp);
 182 bdemsky  1.1.2.12 
 183 bdemsky  1.1.2.22         TestMover mover=new TestMover(newinds, loopinvars, allinductions, header, ssitossamap,hc, hcnew, lp);
 184 bdemsky  1.1.2.13 
 185 bdemsky  1.1.2.13         //visit the nodes
 186 bdemsky  1.1.2.12         while (iterate.hasNext()) {
 187 bdemsky  1.1.2.12             Quad q=(Quad) iterate.next();
 188 bdemsky  1.1.2.13 
 189 bdemsky  1.1.2.13             //make sure that our node hasn't been used...
 190 bdemsky  1.1.2.13             //Isn't required [should be caught by the fact
 191 bdemsky  1.1.2.13             //that loop invariant nodes don't rely on induction variables.]
 192 bdemsky  1.1.2.12             if (!usedinvariants.contains(q))
 193 bdemsky  1.1.2.22                 mover.consider((POPER)q);
 194 bdemsky  1.1.2.12         }
 195 bdemsky  1.1.2.29         if (mover.changed())
 196 bdemsky  1.1.2.29             changed=true;
 197 bdemsky  1.1.2.12     }
 198 bdemsky  1.1.2.12 
 199 bdemsky  1.1.2.13 
 200 bdemsky  1.1.2.22     /**<code>TestMover</code> does all the magic for changing test conditions.*/
 201 bdemsky  1.1.2.13 
 202 bdemsky  1.1.2.22     class TestMover {
 203 bdemsky  1.1.2.12         Set inductvars;
 204 bdemsky  1.1.2.12         Set newinductvars;
 205 bdemsky  1.1.2.12         Set loopinvars;
 206 bdemsky  1.1.2.12         Map allinductions;
 207 bdemsky  1.1.2.12         Quad header;
 208 bdemsky  1.1.2.12         TempMap ssitossamap;
 209 bdemsky  1.1.2.12         Loops lp;
 210 bdemsky  1.1.2.12         HCode hc;
 211 bdemsky  1.1.2.15         MyLowQuadSSI hcnew;
 212 bdemsky  1.1.2.29         boolean changed;
 213 bdemsky  1.1.2.12 
 214 bdemsky  1.1.2.22         //Create TestMover, and inform it of everything.
 215 bdemsky  1.1.2.22         TestMover(Set newinductvars, Set loopinvars, Map allinductions, Quad header, TempMap ssitossamap, HCode hc, MyLowQuadSSI hcnew, Loops lp) {
 216 bdemsky  1.1.2.12             this.newinductvars=newinductvars;
 217 bdemsky  1.1.2.12             this.loopinvars=loopinvars;
 218 bdemsky  1.1.2.12             this.allinductions=allinductions;
 219 bdemsky  1.1.2.12             this.inductvars=allinductions.keySet();
 220 bdemsky  1.1.2.12             this.header=header;
 221 bdemsky  1.1.2.12             this.ssitossamap=ssitossamap;
 222 bdemsky  1.1.2.12             this.hc=hc;
 223 bdemsky  1.1.2.14             this.hcnew=hcnew;
 224 bdemsky  1.1.2.12             this.lp=lp;
 225 bdemsky  1.1.2.29             changed=false;
 226 bdemsky  1.1.2.29         }
 227 bdemsky  1.1.2.29 
 228 bdemsky  1.1.2.29         public boolean changed() {
 229 bdemsky  1.1.2.29             return changed;
 230 bdemsky  1.1.2.12         }
 231 bdemsky  1.1.2.12 
 232 bdemsky  1.1.2.13         //POPER visitor
 233 bdemsky  1.1.2.13         //Only look at ICMPEQ, and ICMPGT
 234 bdemsky  1.1.2.13 
 235 bdemsky  1.1.2.22         public void consider(POPER q) {
 236 bdemsky  1.1.2.23             switch (q.opcode()) {
 237 bdemsky  1.1.2.23             case Qop.ICMPGT:
 238 bdemsky  1.1.2.23             case Qop.ICMPEQ:
 239 bdemsky  1.1.2.12                 POPER replace=lookat(q);
 240 bdemsky  1.1.2.12                 if (replace!=null) {
 241 bdemsky  1.1.2.13                     //Put the new POPER in its place
 242 bdemsky  1.1.2.14                     Quad qnew=hcnew.quadMap(q);
 243 bdemsky  1.1.2.14                     Quad.addEdge(qnew.prev(0), qnew.prevEdge(0).which_succ(), replace,0);
 244 bdemsky  1.1.2.14                     Quad.addEdge(replace, 0, qnew.next(0), qnew.nextEdge(0).which_pred());
 245 bdemsky  1.1.2.29                     changed=true;
 246 bdemsky  1.1.2.12                 }
 247 bdemsky  1.1.2.23                 break;
 248 bdemsky  1.1.2.23             default:
 249 bdemsky  1.1.2.23             }
 250 bdemsky  1.1.2.12         }
 251 bdemsky  1.1.2.12 
 252 bdemsky  1.1.2.13         /**<code>lookat</code> examines a test condition, to see how we should replace it.*/
 253 bdemsky  1.1.2.12         POPER lookat(POPER q) {
 254 bdemsky  1.1.2.12             Temp[] operands=q.operands();
 255 cananian 1.3.2.1              assert operands.length==2;
 256 bdemsky  1.1.2.12             boolean good=true;
 257 bdemsky  1.1.2.12             int flag=-1;
 258 bdemsky  1.1.2.12             POPER newpoper=null;
 259 bdemsky  1.1.2.13 
 260 bdemsky  1.1.2.13             //Loop through the operands
 261 bdemsky  1.1.2.13             //we need one induction variable
 262 bdemsky  1.1.2.13             //and one loop invariant
 263 bdemsky  1.1.2.13 
 264 bdemsky  1.1.2.22             for (int i=0;i<operands.length;i++)
 265 bdemsky  1.1.2.22                 if (inductvars.contains(ssitossamap.tempMap(operands[i])))
 266 bdemsky  1.1.2.22                     flag=i;
 267 bdemsky  1.1.2.13 
 268 bdemsky  1.1.2.13 
 269 bdemsky  1.1.2.13             //if we found these, look for possible replacement induction variables
 270 bdemsky  1.1.2.22  
 271 bdemsky  1.1.2.22             //get the Induction data type for the current induction variable
 272 bdemsky  1.1.2.22             Induction induction=(Induction)allinductions.get(ssitossamap.tempMap(operands[flag]));
 273 bdemsky  1.1.2.22             //Iterate through all of the newly created induction variables
 274 bdemsky  1.1.2.22 
 275 cananian 1.6                  for (Object indvarO : newinductvars) {
 276 cananian 1.6                      Temp indvar = (Temp) indvarO;
 277 bdemsky  1.1.2.22                 Induction t=(Induction) allinductions.get(indvar);
 278 bdemsky  1.1.2.22                 /*Policy for moving:
 279 bdemsky  1.1.2.22                   1) Both have the same base induction variable.
 280 bdemsky  1.1.2.22                   2) The new one isn't used to derive any other induction variables.
 281 bdemsky  1.1.2.22                   Presumably it has a use for being around.
 282 bdemsky  1.1.2.22                   3) If the original test was on a pointer, make sure any new pointer
 283 bdemsky  1.1.2.22                   has the same stride.
 284 bdemsky  1.1.2.22                 */
 285 bdemsky  1.1.2.22                 
 286 bdemsky  1.1.2.22                 if (t.variable()!=induction.variable()) 
 287 bdemsky  1.1.2.22                     continue;
 288 bdemsky  1.1.2.22                 if (t.copied)
 289 bdemsky  1.1.2.22                     continue;
 290 bdemsky  1.1.2.22 
 291 bdemsky  1.1.2.22                 //skipmessy cases
 292 bdemsky  1.1.2.22                 if ((!induction.constant())||(!t.constant()))
 293 bdemsky  1.1.2.22                     continue;
 294 bdemsky  1.1.2.13 
 295 bdemsky  1.1.2.22                 if ((induction.intmultiplier()!=1)&&(induction.intmultiplier()!=-1))
 296 bdemsky  1.1.2.22                     if ((t.intmultiplier()!=induction.intmultiplier())&&(t.intmultiplier()!=-induction.intmultiplier()))
 297 bdemsky  1.1.2.12                         continue;
 298 bdemsky  1.1.2.22                 if (induction.objectsize!=null) {
 299 bdemsky  1.1.2.22                     if ((t.objectsize!=induction.objectsize)||(t.intmultiplier()!=induction.intmultiplier()))
 300 bdemsky  1.1.2.15                         continue;
 301 bdemsky  1.1.2.22                 }
 302 bdemsky  1.1.2.12                     
 303 bdemsky  1.1.2.22                 //Found something that passes the policy
 304 bdemsky  1.1.2.12 
 305 bdemsky  1.1.2.22                 Temp initial=operands[1-flag];
 306 bdemsky  1.1.2.22                 //Call the method to build us a new compare
 307 bdemsky  1.1.2.36                 //System.out.println("Compare statement "+q);
 308 bdemsky  1.1.2.36                 //System.out.println("induction="+induction+"  t="+t);
 309 bdemsky  1.1.2.22                 newpoper=movecompare(hcnew, header, initial, induction, indvar,t,q, flag, new LoopMap(hc,lp,ssitossamap));
 310 bdemsky  1.1.2.22                 break;
 311 bdemsky  1.1.2.12             }
 312 bdemsky  1.1.2.22             
 313 bdemsky  1.1.2.12             return newpoper;
 314 bdemsky  1.1.2.12         }
 315 bdemsky  1.1.2.12     }
 316 bdemsky  1.1.2.12 
 317 bdemsky  1.1.2.15     /** <code>movecompare</code> builds a new compare statement.  The new compared 
 318 bdemsky  1.1.2.15      *  statement uses the derived induction variable t instead of the
 319 bdemsky  1.1.2.15      *  original induction.*/
 320 bdemsky  1.1.2.15 
 321 bdemsky  1.1.2.15     POPER movecompare(MyLowQuadSSI hcnew, Quad oheader, Temp oinitial, Induction induction, Temp oindvar, Induction t, POPER oq, int flag, TempMap loopmap) {
 322 bdemsky  1.1.2.13 
 323 bdemsky  1.1.2.13         //Set up pointers for linking in nodes for providing new test constant
 324 bdemsky  1.1.2.14         Quad header=hcnew.quadMap(oheader);
 325 bdemsky  1.1.2.36         Temp initial=hcnew.tempMap(loopmap.tempMap(oinitial));
 326 bdemsky  1.1.2.14         Temp indvar=hcnew.tempMap(oindvar);
 327 bdemsky  1.1.2.14         POPER q=(POPER)hcnew.quadMap(oq);
 328 bdemsky  1.1.2.14 
 329 bdemsky  1.1.2.14         QuadInserter addquad=new QuadInserter(header.prev(0), header.prevEdge(0).which_succ(),header, 0);
 330 bdemsky  1.1.2.14 
 331 bdemsky  1.1.2.15         if (induction.offset()!=0) {
 332 bdemsky  1.1.2.12             //Add -bc term
 333 bdemsky  1.1.2.12             Quad newquad;
 334 bdemsky  1.1.2.12             Temp newtemp=new Temp(initial.tempFactory(),initial.name());
 335 bdemsky  1.1.2.12             if (induction.objectsize!=null) {
 336 bdemsky  1.1.2.12                 Temp newtempx=new Temp(initial.tempFactory(),initial.name());
 337 bdemsky  1.1.2.15                 newquad=new CONST(header.getFactory(),header, newtempx, 
 338 bdemsky  1.1.2.15                                   new Integer(-induction.offset()), HClass.Int);
 339 bdemsky  1.1.2.14                 hcnew.addType(newtempx, HClass.Int);
 340 bdemsky  1.1.2.14                 addquad.insert(newquad);
 341 bdemsky  1.1.2.15                 newquad=new PAOFFSET(((LowQuadFactory)header.getFactory()),header,
 342 bdemsky  1.1.2.15                                      newtemp,induction.objectsize, newtempx);
 343 bdemsky  1.1.2.14                 hcnew.addType(newtemp, HClass.Int);
 344 bdemsky  1.1.2.14             }
 345 bdemsky  1.1.2.14             else {
 346 bdemsky  1.1.2.15                 newquad=new CONST(header.getFactory(),header, newtemp, 
 347 bdemsky  1.1.2.15                                   new Integer(-induction.offset()), HClass.Int);
 348 bdemsky  1.1.2.14                 hcnew.addType(newtemp, HClass.Int);
 349 bdemsky  1.1.2.12             }
 350 bdemsky  1.1.2.12 
 351 bdemsky  1.1.2.12             Temp newtemp2=new Temp(initial.tempFactory(),initial.name());
 352 bdemsky  1.1.2.12             Temp[] sources=new Temp[2];
 353 bdemsky  1.1.2.12             sources[0]=newtemp;
 354 bdemsky  1.1.2.12             sources[1]=initial;
 355 bdemsky  1.1.2.14             addquad.insert(newquad);
 356 bdemsky  1.1.2.14 
 357 bdemsky  1.1.2.14             if (induction.objectsize==null) {
 358 bdemsky  1.1.2.15                 newquad=new POPER(((LowQuadFactory)header.getFactory()),header,
 359 bdemsky  1.1.2.15                                   Qop.IADD,newtemp2, sources);
 360 bdemsky  1.1.2.14                 hcnew.addType(newtemp2, HClass.Int);
 361 bdemsky  1.1.2.14             }
 362 bdemsky  1.1.2.14             else {
 363 bdemsky  1.1.2.15                 newquad=new POPER(((LowQuadFactory)header.getFactory()),header,
 364 bdemsky  1.1.2.15                                   LQop.PADD,newtemp2, sources);
 365 bdemsky  1.1.2.14                 if (hcnew.derivation(header, initial)==null)
 366 duncan   1.1.2.18                     hcnew.addType(newtemp2, hcnew.typeMap(null,initial));
 367 bdemsky  1.1.2.14                 else
 368 bdemsky  1.1.2.14                     hcnew.addType(newtemp2, 
 369 bdemsky  1.1.2.35                                   null);
 370 bdemsky  1.1.2.14             }
 371 bdemsky  1.1.2.15             hcnew.addDerivation(newtemp2, 
 372 bdemsky  1.1.2.15                                 Derivation.DList.clone(hcnew.derivation(newquad, initial)));
 373 bdemsky  1.1.2.14             addquad.insert(newquad);
 374 bdemsky  1.1.2.12             initial=newtemp2;
 375 bdemsky  1.1.2.12         }
 376 bdemsky  1.1.2.12         
 377 bdemsky  1.1.2.12         
 378 bdemsky  1.1.2.12         if (!induction.pointeroffset.isEmpty()) {
 379 bdemsky  1.1.2.12             Iterator pointers=induction.pointeroffset.iterator();
 380 bdemsky  1.1.2.12             while (pointers.hasNext()) {
 381 bdemsky  1.1.2.15                 Object[] ptrobject=(Object[])pointers.next();
 382 bdemsky  1.1.2.15                 boolean positive=((Boolean)ptrobject[1]).booleanValue();
 383 bdemsky  1.1.2.15                 Temp term=hcnew.tempMap(loopmap.tempMap((Temp) ptrobject[0]));
 384 bdemsky  1.1.2.12                 Temp[] sources=new Temp[1];
 385 bdemsky  1.1.2.15                 Temp newtemp=null;
 386 bdemsky  1.1.2.15                 if (positive) {
 387 bdemsky  1.1.2.15                     sources[0]=term;
 388 bdemsky  1.1.2.15                     newtemp=new Temp(initial.tempFactory(),initial.name());
 389 bdemsky  1.1.2.15                     if (hcnew.derivation(header, term)==null)
 390 duncan   1.1.2.18                         hcnew.addType(newtemp, hcnew.typeMap(null, term));
 391 bdemsky  1.1.2.15                     else
 392 bdemsky  1.1.2.15                         hcnew.addType(newtemp, 
 393 bdemsky  1.1.2.35                                       null);
 394 bdemsky  1.1.2.15                     Quad newquad=new POPER(((LowQuadFactory)header.getFactory()),
 395 bdemsky  1.1.2.15                                            header,LQop.PNEG,newtemp, sources);
 396 bdemsky  1.1.2.15                     hcnew.addDerivation(newtemp, negate(hcnew.derivation(header, term)));
 397 bdemsky  1.1.2.15                     addquad.insert(newquad);
 398 bdemsky  1.1.2.15                 }   else {
 399 bdemsky  1.1.2.15                     newtemp=term;
 400 bdemsky  1.1.2.15                 }
 401 bdemsky  1.1.2.15 
 402 bdemsky  1.1.2.14                 Temp newtemp2=new Temp(initial.tempFactory(),initial.name());
 403 bdemsky  1.1.2.12                 sources=new Temp[2];
 404 bdemsky  1.1.2.14                 sources[0]=newtemp;
 405 bdemsky  1.1.2.12                 sources[1]=initial;
 406 bdemsky  1.1.2.15                 Quad newquad=new POPER(((LowQuadFactory)header.getFactory()),header,LQop.PADD,newtemp2, sources);
 407 bdemsky  1.1.2.14                 Derivation.DList merged=merge(hcnew.derivation(newquad,sources[0]),hcnew.derivation(newquad,sources[1]));
 408 bdemsky  1.1.2.14                 if (merged==null)
 409 bdemsky  1.1.2.14                     hcnew.addType(newtemp2,HClass.Int);
 410 bdemsky  1.1.2.14                 else
 411 bdemsky  1.1.2.14                     hcnew.addType(newtemp2, 
 412 bdemsky  1.1.2.35                                   null);
 413 bdemsky  1.1.2.14                 hcnew.addDerivation(newtemp2, merged);
 414 bdemsky  1.1.2.14                 addquad.insert(newquad);
 415 bdemsky  1.1.2.14                 initial=newtemp2;
 416 bdemsky  1.1.2.12             }
 417 bdemsky  1.1.2.12         }
 418 bdemsky  1.1.2.12         
 419 bdemsky  1.1.2.15         if ((t.intmultiplier()/induction.intmultiplier())!=1) {
 420 bdemsky  1.1.2.12             if (induction.objectsize==null) {
 421 bdemsky  1.1.2.14                 //We have an integer
 422 bdemsky  1.1.2.12                 Temp newtemp=new Temp(initial.tempFactory(),initial.name());
 423 bdemsky  1.1.2.15                 Quad newquad=new CONST(header.getFactory(),header, newtemp,
 424 bdemsky  1.1.2.15                                        new Integer(t.intmultiplier()/induction.intmultiplier()),
 425 bdemsky  1.1.2.15                                        HClass.Int);
 426 bdemsky  1.1.2.14                 hcnew.addType(newtemp, HClass.Int);
 427 bdemsky  1.1.2.14                 addquad.insert(newquad);
 428 bdemsky  1.1.2.12                 Temp[] sources=new Temp[2];
 429 bdemsky  1.1.2.12                 sources[0]=newtemp;
 430 bdemsky  1.1.2.14                 sources[1]=initial;             
 431 bdemsky  1.1.2.14                 Temp newtemp2=new Temp(initial.tempFactory(),initial.name());
 432 bdemsky  1.1.2.15                 newquad=new POPER(((LowQuadFactory)header.getFactory()),header,
 433 bdemsky  1.1.2.15                                   Qop.IMUL,newtemp2, sources);
 434 bdemsky  1.1.2.14                 hcnew.addType(newtemp2, HClass.Int);
 435 bdemsky  1.1.2.14                 addquad.insert(newquad);
 436 bdemsky  1.1.2.12                 initial=newtemp2;
 437 bdemsky  1.1.2.12             } else {
 438 bdemsky  1.1.2.12                 //flip the sign
 439 bdemsky  1.1.2.14                 //the ratio has to be =-1
 440 cananian 1.3.2.1                  assert (t.intmultiplier()/induction.intmultiplier())==-1;
 441 bdemsky  1.1.2.12                 Temp newtemp=new Temp(initial.tempFactory(),initial.name());
 442 bdemsky  1.1.2.12                 Temp[] sources=new Temp[1];
 443 bdemsky  1.1.2.12                 sources[0]=initial;
 444 bdemsky  1.1.2.15                 Quad newquad=new POPER(((LowQuadFactory)header.getFactory()),header,
 445 bdemsky  1.1.2.15                                        LQop.PNEG,newtemp, sources);
 446 bdemsky  1.1.2.14                 if (hcnew.derivation(newquad, initial)==null)
 447 duncan   1.1.2.18                     hcnew.addType(newtemp, hcnew.typeMap(null, initial));
 448 bdemsky  1.1.2.14                 else
 449 bdemsky  1.1.2.14                     hcnew.addType(newtemp, 
 450 bdemsky  1.1.2.35                                   null);
 451 bdemsky  1.1.2.14                 hcnew.addDerivation(newtemp, negate(hcnew.derivation(newquad, initial)));
 452 bdemsky  1.1.2.14                 addquad.insert(newquad);
 453 bdemsky  1.1.2.12                 initial=newtemp;
 454 bdemsky  1.1.2.12             }
 455 bdemsky  1.1.2.12         }
 456 bdemsky  1.1.2.12 
 457 bdemsky  1.1.2.12                     
 458 bdemsky  1.1.2.12         if ((t.objectsize!=null)&&(induction.objectsize==null)) {
 459 bdemsky  1.1.2.12             //Calculate pointer if necessary
 460 bdemsky  1.1.2.12             Temp newtemp=new Temp(initial.tempFactory(),initial.name());
 461 bdemsky  1.1.2.15             Quad newquad=new PAOFFSET(((LowQuadFactory)header.getFactory()),header,
 462 bdemsky  1.1.2.15                                       newtemp,t.objectsize, initial);
 463 bdemsky  1.1.2.14             hcnew.addType(newtemp, HClass.Int);
 464 bdemsky  1.1.2.14             addquad.insert(newquad);
 465 bdemsky  1.1.2.12             initial=newtemp;
 466 bdemsky  1.1.2.12         }
 467 bdemsky  1.1.2.12 
 468 bdemsky  1.1.2.15         if (t.offset()!=0) {
 469 bdemsky  1.1.2.12             if (t.objectsize==null) {
 470 bdemsky  1.1.2.12                 Temp newtemp=new Temp(initial.tempFactory(),initial.name());
 471 bdemsky  1.1.2.15                 Quad newquad=new CONST(header.getFactory(),header, newtemp, 
 472 bdemsky  1.1.2.15                                        new Integer(t.offset()), HClass.Int);
 473 bdemsky  1.1.2.14                 hcnew.addType(newtemp, HClass.Int);
 474 bdemsky  1.1.2.14                 addquad.insert(newquad);
 475 bdemsky  1.1.2.12                 Temp[] sources=new Temp[2];
 476 bdemsky  1.1.2.12                 sources[0]=newtemp;
 477 bdemsky  1.1.2.12                 sources[1]=initial;
 478 bdemsky  1.1.2.14                 Temp newtemp2=new Temp(initial.tempFactory(),initial.name());
 479 bdemsky  1.1.2.14                 hcnew.addType(newtemp2, HClass.Int);
 480 bdemsky  1.1.2.15                 newquad=new POPER(((LowQuadFactory)header.getFactory()),header,
 481 bdemsky  1.1.2.15                                   Qop.IADD,newtemp2, sources);
 482 bdemsky  1.1.2.14                 addquad.insert(newquad);
 483 bdemsky  1.1.2.12                 initial=newtemp2;
 484 bdemsky  1.1.2.12             } else {
 485 bdemsky  1.1.2.14                 //ADD Constant oper
 486 bdemsky  1.1.2.12                 Temp newtemp=new Temp(initial.tempFactory(),initial.name());
 487 bdemsky  1.1.2.14                 hcnew.addType(newtemp, HClass.Int);
 488 bdemsky  1.1.2.15                 Quad newquad=new CONST(header.getFactory(),header, newtemp,
 489 bdemsky  1.1.2.15                                        new Integer(t.offset()), HClass.Int);
 490 bdemsky  1.1.2.14                 addquad.insert(newquad);
 491 bdemsky  1.1.2.14 
 492 bdemsky  1.1.2.14                 //ADD PAOFFSET oper
 493 bdemsky  1.1.2.12                 Temp newtemp2=new Temp(initial.tempFactory(),initial.name());
 494 bdemsky  1.1.2.14                 hcnew.addType(newtemp2, HClass.Int);
 495 bdemsky  1.1.2.15                 newquad=new PAOFFSET(((LowQuadFactory)header.getFactory()),header,
 496 bdemsky  1.1.2.15                                      newtemp2,t.objectsize, newtemp);
 497 bdemsky  1.1.2.14                 addquad.insert(newquad);
 498 bdemsky  1.1.2.14 
 499 bdemsky  1.1.2.14                 //Add PADD oper
 500 bdemsky  1.1.2.12                 Temp[] sources=new Temp[2];
 501 bdemsky  1.1.2.12                 sources[0]=newtemp2;
 502 bdemsky  1.1.2.12                 sources[1]=initial;
 503 bdemsky  1.1.2.14                 Temp newtemp3=new Temp(initial.tempFactory(),initial.name());
 504 bdemsky  1.1.2.14                 if (hcnew.derivation(newquad, newtemp3)==null)
 505 duncan   1.1.2.18                     hcnew.addType(newtemp3, hcnew.typeMap(null,initial));
 506 bdemsky  1.1.2.14                 else
 507 bdemsky  1.1.2.14                     hcnew.addType(newtemp3,
 508 bdemsky  1.1.2.35                                   null);
 509 bdemsky  1.1.2.14                 newquad=new POPER(((LowQuadFactory)header.getFactory()),header,LQop.PADD,newtemp3, sources);
 510 bdemsky  1.1.2.14                 hcnew.addDerivation(newtemp3, hcnew.derivation(newquad, newtemp3));
 511 bdemsky  1.1.2.14                 addquad.insert(newquad);
 512 bdemsky  1.1.2.12                 initial=newtemp3; 
 513 bdemsky  1.1.2.12             }
 514 bdemsky  1.1.2.12         }
 515 bdemsky  1.1.2.12 
 516 bdemsky  1.1.2.12         if (!t.pointeroffset.isEmpty()) {
 517 bdemsky  1.1.2.12             Iterator pointers=t.pointeroffset.iterator();
 518 bdemsky  1.1.2.12             while (pointers.hasNext()) {
 519 bdemsky  1.1.2.15                 Object[] ptrobject=(Object[])pointers.next();
 520 bdemsky  1.1.2.15                 boolean positive=((Boolean)ptrobject[1]).booleanValue();
 521 bdemsky  1.1.2.15                 Temp term=hcnew.tempMap(loopmap.tempMap((Temp) ptrobject[0]));
 522 bdemsky  1.1.2.12                 Temp[] sources=new Temp[2];
 523 bdemsky  1.1.2.15 
 524 bdemsky  1.1.2.15                 if (!positive) {
 525 bdemsky  1.1.2.15                     //have to flip sign
 526 bdemsky  1.1.2.15                     sources[0]=term;
 527 bdemsky  1.1.2.15                     term=new Temp(initial.tempFactory(),initial.name());
 528 bdemsky  1.1.2.15                     if (hcnew.derivation(header, term)==null)
 529 duncan   1.1.2.18                         hcnew.addType(term, hcnew.typeMap(null, sources[0]));
 530 bdemsky  1.1.2.15                     else
 531 bdemsky  1.1.2.15                         hcnew.addType(term, 
 532 bdemsky  1.1.2.35                                       null);
 533 bdemsky  1.1.2.15                     Quad newquad=new POPER(((LowQuadFactory)header.getFactory()),
 534 bdemsky  1.1.2.15                                            header,LQop.PNEG,term, sources);
 535 bdemsky  1.1.2.15                     hcnew.addDerivation(term, negate(hcnew.derivation(header, term)));
 536 bdemsky  1.1.2.15                     addquad.insert(newquad);
 537 bdemsky  1.1.2.15                 }
 538 bdemsky  1.1.2.15 
 539 bdemsky  1.1.2.12                 sources[0]=term;
 540 bdemsky  1.1.2.12                 sources[1]=initial;
 541 bdemsky  1.1.2.14                 Temp newtemp=new Temp(initial.tempFactory(),initial.name());
 542 bdemsky  1.1.2.15                 Quad newquad=new POPER(((LowQuadFactory)header.getFactory()),
 543 bdemsky  1.1.2.15                                        header,LQop.PADD,newtemp, sources);
 544 bdemsky  1.1.2.14 
 545 bdemsky  1.1.2.14                 //Make new derivation list
 546 bdemsky  1.1.2.15                 Derivation.DList merged=merge(hcnew.derivation(newquad,sources[0]),
 547 bdemsky  1.1.2.15                                               hcnew.derivation(newquad,sources[1]));
 548 bdemsky  1.1.2.14                 //Update type info
 549 bdemsky  1.1.2.14                 if (merged==null)
 550 bdemsky  1.1.2.14                     hcnew.addType(newtemp,HClass.Int);
 551 bdemsky  1.1.2.14                 else
 552 bdemsky  1.1.2.14                     hcnew.addType(newtemp, 
 553 bdemsky  1.1.2.35                                   null);
 554 bdemsky  1.1.2.14                 //Update derivation info
 555 bdemsky  1.1.2.14                 hcnew.addDerivation(newtemp, merged);
 556 bdemsky  1.1.2.14                 addquad.insert(newquad);
 557 bdemsky  1.1.2.12                 initial=newtemp;
 558 bdemsky  1.1.2.12             }
 559 bdemsky  1.1.2.12         }
 560 bdemsky  1.1.2.12         int opcode=q.opcode();
 561 bdemsky  1.1.2.12         if (t.objectsize!=null) {
 562 bdemsky  1.1.2.12             if (q.opcode()==Qop.ICMPGT) 
 563 bdemsky  1.1.2.12                 opcode=LQop.PCMPGT;
 564 bdemsky  1.1.2.12             if (q.opcode()==Qop.ICMPEQ)
 565 bdemsky  1.1.2.12                 opcode=LQop.PCMPEQ;
 566 bdemsky  1.1.2.12         }
 567 bdemsky  1.1.2.12         Temp[] sources=new Temp[2];
 568 bdemsky  1.1.2.15         if ((t.intmultiplier()/induction.intmultiplier())>0) {
 569 bdemsky  1.1.2.12             //Keep same order
 570 bdemsky  1.1.2.12             sources[flag]=indvar;
 571 bdemsky  1.1.2.12             sources[1-flag]=initial;
 572 bdemsky  1.1.2.12         } else {
 573 bdemsky  1.1.2.12             //Flip order
 574 bdemsky  1.1.2.12             sources[flag]=initial;
 575 bdemsky  1.1.2.12             sources[1-flag]=indvar;
 576 bdemsky  1.1.2.12         }
 577 bdemsky  1.1.2.29         if (addquad.changed())
 578 bdemsky  1.1.2.29             changed=true;
 579 bdemsky  1.1.2.14         return new POPER(((LowQuadFactory)header.getFactory()),header,opcode,q.dst(), sources);
 580 bdemsky  1.1.2.12     }
 581 bdemsky  1.1.2.12 
 582 bdemsky  1.1.2.14 
 583 bdemsky  1.1.2.15     Set doLoopind(HCode hc, MyLowQuadSSI hcnew, Loops lp,Quad oheader,WorkSet usedinvariants) {
 584 bdemsky  1.1.2.14         Quad header=hcnew.quadMap(oheader);
 585 bdemsky  1.1.2.14 
 586 bdemsky  1.1.2.8          Map basmap=bimap.basicInductionsMap(hc,lp);
 587 bdemsky  1.1.2.8          Map allmap=aimap.allInductionsMap(hc,lp);
 588 bdemsky  1.1.2.7          WorkSet basic=new WorkSet(basmap.keySet());
 589 bdemsky  1.1.2.14         WorkSet complete=new WorkSet(allmap.keySet());
 590 bdemsky  1.1.2.14 
 591 bdemsky  1.1.2.12         //Copy allmap
 592 bdemsky  1.1.2.10         LoopMap loopmap=new LoopMap(hc,lp,ssitossamap);
 593 bdemsky  1.1.2.7          Iterator iterate=complete.iterator();
 594 bdemsky  1.1.2.10 
 595 bdemsky  1.1.2.14         int linkin;
 596 cananian 1.3.2.1          assert ((CFGraphable)header).pred().length==2;
 597 bdemsky  1.1.2.7          //Only worry about headers with two edges
 598 cananian 1.1.2.32         if (lp.loopIncElements().contains(header.prev(0)))
 599 bdemsky  1.1.2.7              linkin=1;
 600 bdemsky  1.1.2.7          else
 601 bdemsky  1.1.2.7              linkin=0;
 602 bdemsky  1.1.2.12 
 603 bdemsky  1.1.2.7  
 604 bdemsky  1.1.2.7          while (iterate.hasNext()) {
 605 bdemsky  1.1.2.7              Temp indvariable=(Temp) iterate.next();
 606 bdemsky  1.1.2.7              Induction induction=(Induction) allmap.get(indvariable);
 607 bdemsky  1.1.2.17             Temp[] headuses=oheader.use();
 608 bdemsky  1.1.2.11             boolean skip=false;
 609 bdemsky  1.1.2.14 
 610 bdemsky  1.1.2.14             //Check to see if this induction is just the next iteration of the basic
 611 bdemsky  1.1.2.14             //induction variable...if so, skip it!
 612 bdemsky  1.1.2.11             for(int l=0;l<headuses.length;l++)
 613 bdemsky  1.1.2.17                 if (ssitossamap.tempMap(headuses[l])==indvariable) {
 614 bdemsky  1.1.2.11                     skip=true;
 615 bdemsky  1.1.2.11                     break;
 616 bdemsky  1.1.2.11                 }
 617 bdemsky  1.1.2.15             if (indvariable==induction.variable())
 618 bdemsky  1.1.2.12                 skip=true;
 619 bdemsky  1.1.2.11 
 620 bdemsky  1.1.2.11             if (induction.pointerindex||skip) {
 621 bdemsky  1.1.2.14                 //Don't deal with induction variables that are already pointers,
 622 bdemsky  1.1.2.7                  iterate.remove();
 623 bdemsky  1.1.2.7              } else {
 624 bdemsky  1.1.2.7                  //Non pointer index...
 625 bdemsky  1.1.2.8                  //We have a derived induction variable...
 626 bdemsky  1.1.2.14 
 627 bdemsky  1.1.2.14                 //Create consttemp with larger scope, so we can use the const Quad twice
 628 bdemsky  1.1.2.15                 Temp[] consttemp=new Temp[induction.depth()];
 629 bdemsky  1.1.2.14 
 630 bdemsky  1.1.2.14                 //Use old header here...
 631 bdemsky  1.1.2.21                 Temp initial=loopanal.initialTemp(hc, induction.variable(), lp);
 632 bdemsky  1.1.2.14                 initial=hcnew.tempMap(initial);
 633 bdemsky  1.1.2.14 
 634 bdemsky  1.1.2.14                 QuadInserter addquad=new QuadInserter(header.prev(linkin), header.prevEdge(linkin).which_succ(), header, linkin);
 635 bdemsky  1.1.2.12 
 636 bdemsky  1.1.2.15                 int count=0;
 637 bdemsky  1.1.2.15                 for (Induction.IntMultAdd integers=induction.bottom();integers!=null;integers=integers.parent()) {
 638 bdemsky  1.1.2.15                     if (integers.intmultiplier()!=1) {
 639 bdemsky  1.1.2.15                         //Add integer multiplication
 640 bdemsky  1.1.2.15                         //Create constant temp with integer
 641 bdemsky  1.1.2.15                         consttemp[count]=new Temp(initial.tempFactory(),initial.name());
 642 bdemsky  1.1.2.15                         hcnew.addType(consttemp[count], HClass.Int);
 643 bdemsky  1.1.2.15                         Quad newquad=new CONST(header.getFactory(),header, consttemp[count], 
 644 bdemsky  1.1.2.15                                                new Integer(integers.intmultiplier()), HClass.Int);
 645 bdemsky  1.1.2.15                         addquad.insert(newquad);
 646 bdemsky  1.1.2.14 
 647 bdemsky  1.1.2.15                         Temp[] sources=new Temp[2];
 648 bdemsky  1.1.2.15                         sources[0]=consttemp[count];
 649 bdemsky  1.1.2.15                         sources[1]=initial;
 650 bdemsky  1.1.2.15                         Temp newtemp=new Temp(initial.tempFactory(),initial.name());
 651 bdemsky  1.1.2.15                         newquad=new POPER(((LowQuadFactory)header.getFactory()),header,Qop.IMUL,
 652 bdemsky  1.1.2.15                                           newtemp, sources);
 653 bdemsky  1.1.2.15                         hcnew.addType(newtemp, HClass.Int);
 654 bdemsky  1.1.2.15                         addquad.insert(newquad);
 655 bdemsky  1.1.2.15                         initial=newtemp;
 656 bdemsky  1.1.2.15                         count++;
 657 bdemsky  1.1.2.15                     }
 658 bdemsky  1.1.2.12                 
 659 bdemsky  1.1.2.15                     if (integers.offset()!=0) {
 660 bdemsky  1.1.2.15                         //Add constant integer offset in
 661 bdemsky  1.1.2.15                         Temp newtemp=new Temp(initial.tempFactory(),initial.name());
 662 bdemsky  1.1.2.15                         hcnew.addType(newtemp, HClass.Int);
 663 bdemsky  1.1.2.15                         Quad newquad=new CONST(header.getFactory(),header,newtemp, 
 664 bdemsky  1.1.2.15                                                new Integer(integers.offset()), HClass.Int);
 665 bdemsky  1.1.2.15                         addquad.insert(newquad);
 666 bdemsky  1.1.2.15                         
 667 bdemsky  1.1.2.15                         //Add in IADD oper
 668 bdemsky  1.1.2.15                         Temp[] sources=new Temp[2];
 669 bdemsky  1.1.2.15                         sources[0]=newtemp;
 670 bdemsky  1.1.2.15                         sources[1]=initial;
 671 bdemsky  1.1.2.15                         Temp newtemp2=new Temp(initial.tempFactory(),initial.name());
 672 bdemsky  1.1.2.15                         newquad=new POPER(((LowQuadFactory)header.getFactory()),header,Qop.IADD,newtemp2, sources);
 673 duncan   1.1.2.18                         hcnew.addType(newtemp2, hcnew.typeMap(null, initial));
 674 bdemsky  1.1.2.15                         addquad.insert(newquad);
 675 bdemsky  1.1.2.15                         initial=newtemp2;
 676 bdemsky  1.1.2.15                     }
 677 bdemsky  1.1.2.15                     if (integers.loopinvariant()!=null) {
 678 bdemsky  1.1.2.15                         Temp operand=integers.loopinvariant();
 679 bdemsky  1.1.2.15                         if (!integers.invariantsign()) {
 680 bdemsky  1.1.2.15                             Temp[] sources=new Temp[1];
 681 bdemsky  1.1.2.16                             sources[0]=hcnew.tempMap(loopmap.tempMap(operand));
 682 bdemsky  1.1.2.15                             Temp newtemp=new Temp(initial.tempFactory(), initial.name());
 683 bdemsky  1.1.2.15                             Quad newquad=new POPER(((LowQuadFactory)header.getFactory()), header, LQop.PNEG, newtemp, sources);
 684 bdemsky  1.1.2.16                             hcnew.addType(newtemp, HClass.Int);
 685 bdemsky  1.1.2.15                             addquad.insert(newquad);
 686 bdemsky  1.1.2.15                             operand=newtemp;
 687 bdemsky  1.1.2.15                         }
 688 bdemsky  1.1.2.15                         Quad newquad=null;
 689 bdemsky  1.1.2.15                         Temp[] sources=new Temp[2];
 690 bdemsky  1.1.2.15                         sources[0]=initial;
 691 bdemsky  1.1.2.15                         sources[1]=operand;
 692 bdemsky  1.1.2.15                         Temp newtemp=new Temp(initial.tempFactory(), initial.name());
 693 bdemsky  1.1.2.15                         if (integers.multiply())
 694 bdemsky  1.1.2.15                             newquad=new POPER(((LowQuadFactory)header.getFactory()), header, LQop.IMUL, newtemp, sources);
 695 bdemsky  1.1.2.15                         else
 696 bdemsky  1.1.2.15                            newquad=new POPER(((LowQuadFactory)header.getFactory()), header, LQop.IADD, newtemp, sources); 
 697 duncan   1.1.2.18                         hcnew.addType(newtemp, hcnew.typeMap(null, initial));
 698 bdemsky  1.1.2.15                         addquad.insert(newquad);
 699 bdemsky  1.1.2.15                         initial=newtemp;
 700 bdemsky  1.1.2.15                     }
 701 bdemsky  1.1.2.8                  }
 702 bdemsky  1.1.2.8  
 703 bdemsky  1.1.2.15 
 704 bdemsky  1.1.2.7                  if (induction.objectsize!=null) {
 705 bdemsky  1.1.2.8                      //add array dereference
 706 bdemsky  1.1.2.14                     Temp newtemp=new Temp(initial.tempFactory(),indvariable.name());
 707 bdemsky  1.1.2.14                     Quad newquad=new PAOFFSET(((LowQuadFactory)header.getFactory()),header,newtemp,induction.objectsize, initial);
 708 bdemsky  1.1.2.14                     hcnew.addType(newtemp, HClass.Int);
 709 bdemsky  1.1.2.14                     addquad.insert(newquad);
 710 bdemsky  1.1.2.8                      initial=newtemp;
 711 bdemsky  1.1.2.8                  }
 712 bdemsky  1.1.2.8  
 713 bdemsky  1.1.2.8                  if (!induction.pointeroffset.isEmpty()) {
 714 bdemsky  1.1.2.8                      Iterator pointers=induction.pointeroffset.iterator();
 715 bdemsky  1.1.2.8                      while (pointers.hasNext()) {
 716 bdemsky  1.1.2.15                         Object[] ptrobject=(Object []) pointers.next();
 717 bdemsky  1.1.2.15                         boolean positive=((Boolean)ptrobject[1]).booleanValue();
 718 bdemsky  1.1.2.15                         Temp term=hcnew.tempMap(loopmap.tempMap((Temp) ptrobject[0]));
 719 bdemsky  1.1.2.15                         Temp[] sources=new Temp[1];
 720 bdemsky  1.1.2.15                         Temp newtemp=null;
 721 bdemsky  1.1.2.15                         if (!positive) {
 722 bdemsky  1.1.2.15                             sources[0]=term;
 723 bdemsky  1.1.2.15                             newtemp=new Temp(initial.tempFactory(),initial.name());
 724 bdemsky  1.1.2.15                             if (hcnew.derivation(header, term)==null)
 725 duncan   1.1.2.18                                 hcnew.addType(newtemp, hcnew.typeMap(null, term));
 726 bdemsky  1.1.2.15                             else
 727 bdemsky  1.1.2.15                                 hcnew.addType(newtemp, 
 728 bdemsky  1.1.2.35                                               null);
 729 bdemsky  1.1.2.15                             Quad newquad=new POPER(((LowQuadFactory)header.getFactory()),
 730 bdemsky  1.1.2.15                                                    header,LQop.PNEG,newtemp, sources);
 731 bdemsky  1.1.2.15                             hcnew.addDerivation(newtemp, negate(hcnew.derivation(header, term)));
 732 bdemsky  1.1.2.15                             addquad.insert(newquad);
 733 bdemsky  1.1.2.15                         }   else {
 734 bdemsky  1.1.2.15                             newtemp=term;
 735 bdemsky  1.1.2.15                         }
 736 bdemsky  1.1.2.15                         sources=new Temp[2];
 737 bdemsky  1.1.2.15                         sources[0]=newtemp;
 738 bdemsky  1.1.2.7                          sources[1]=initial;
 739 bdemsky  1.1.2.15                         newtemp=new Temp(initial.tempFactory(),indvariable.name());
 740 bdemsky  1.1.2.14                         Quad newquad=new POPER(((LowQuadFactory)header.getFactory()),header,LQop.PADD,newtemp, sources);
 741 bdemsky  1.1.2.14 
 742 bdemsky  1.1.2.14                         Derivation.DList merged=merge(hcnew.derivation(newquad,sources[0]),hcnew.derivation(newquad,sources[1]));
 743 bdemsky  1.1.2.14                         if (merged==null)
 744 bdemsky  1.1.2.14                             hcnew.addType(newtemp,HClass.Int);
 745 bdemsky  1.1.2.14                         else
 746 bdemsky  1.1.2.14                             hcnew.addType(newtemp, 
 747 bdemsky  1.1.2.35                                           null);
 748 bdemsky  1.1.2.35                         //System.out.println("Creating derivation: "+newtemp+" : "+merged);
 749 bdemsky  1.1.2.14                         hcnew.addDerivation(newtemp, merged);
 750 bdemsky  1.1.2.14                         addquad.insert(newquad);
 751 bdemsky  1.1.2.8                          initial=newtemp;
 752 bdemsky  1.1.2.7                      }
 753 bdemsky  1.1.2.7                  }
 754 bdemsky  1.1.2.10 
 755 bdemsky  1.1.2.12 
 756 bdemsky  1.1.2.9                  //and calculate the increment size.. [done]
 757 bdemsky  1.1.2.9  
 758 bdemsky  1.1.2.21                 Temp increment=hcnew.tempMap(loopmap.tempMap(loopanal.findIncrement(hc, induction.variable(), lp)));
 759 bdemsky  1.1.2.14 
 760 bdemsky  1.1.2.14 
 761 bdemsky  1.1.2.9                      //Need to do multiply...
 762 bdemsky  1.1.2.15 
 763 bdemsky  1.1.2.15                 count=0;
 764 bdemsky  1.1.2.15                 for (Induction.IntMultAdd integers=induction.bottom();integers!=null;integers=integers.parent()) {
 765 bdemsky  1.1.2.15                     if (integers.intmultiplier()!=1) {
 766 bdemsky  1.1.2.15                         //Add multiplication
 767 bdemsky  1.1.2.15                         Temp[] sources=new Temp[2];
 768 bdemsky  1.1.2.15                         sources[0]=consttemp[count++];
 769 bdemsky  1.1.2.15                         sources[1]=increment;
 770 bdemsky  1.1.2.15                         Temp newtemp=new Temp(increment.tempFactory(),increment.name());
 771 bdemsky  1.1.2.15                         Quad newquad=new POPER(((LowQuadFactory)header.getFactory()),header,Qop.IMUL,newtemp, sources);
 772 bdemsky  1.1.2.15                         hcnew.addType(newtemp,HClass.Int);
 773 bdemsky  1.1.2.15                         addquad.insert(newquad);
 774 bdemsky  1.1.2.15                         increment=newtemp;
 775 bdemsky  1.1.2.15                     }
 776 bdemsky  1.1.2.15 
 777 bdemsky  1.1.2.15                     if ((integers.loopinvariant()!=null)&&(integers.multiply())) {
 778 bdemsky  1.1.2.15                         Temp operand=integers.loopinvariant();
 779 bdemsky  1.1.2.15                         if (!integers.invariantsign()) {
 780 bdemsky  1.1.2.15                             Temp[] sources=new Temp[1];
 781 bdemsky  1.1.2.15                             sources[0]=operand;
 782 bdemsky  1.1.2.15                             Temp newtemp=new Temp(initial.tempFactory(), initial.name());
 783 bdemsky  1.1.2.15                             Quad newquad=new POPER(((LowQuadFactory)header.getFactory()), header, LQop.PNEG, newtemp, sources);
 784 bdemsky  1.1.2.15                             hcnew.addType(newtemp, HClass.Int);
 785 bdemsky  1.1.2.15                             addquad.insert(newquad);
 786 bdemsky  1.1.2.15                             operand=newtemp;
 787 bdemsky  1.1.2.15                         }
 788 bdemsky  1.1.2.15                         Quad newquad=null;
 789 bdemsky  1.1.2.15                         Temp[] sources=new Temp[2];
 790 bdemsky  1.1.2.15                         sources[0]=initial;
 791 bdemsky  1.1.2.15                         sources[1]=operand;
 792 bdemsky  1.1.2.15                         Temp newtemp=new Temp(initial.tempFactory(), initial.name());
 793 bdemsky  1.1.2.15                         if (integers.multiply())
 794 bdemsky  1.1.2.15                             newquad=new POPER(((LowQuadFactory)header.getFactory()), header, LQop.IMUL, newtemp, sources);
 795 bdemsky  1.1.2.15                         else
 796 bdemsky  1.1.2.15                             newquad=new POPER(((LowQuadFactory)header.getFactory()), header, LQop.IADD, newtemp, sources); 
 797 duncan   1.1.2.18                         hcnew.addType(newtemp, hcnew.typeMap(null, initial));
 798 bdemsky  1.1.2.15                         addquad.insert(newquad);
 799 bdemsky  1.1.2.15                         initial=newtemp;
 800 bdemsky  1.1.2.15                     }
 801 bdemsky  1.1.2.12                 }
 802 bdemsky  1.1.2.15 
 803 bdemsky  1.1.2.15 
 804 bdemsky  1.1.2.15 
 805 bdemsky  1.1.2.9                  
 806 bdemsky  1.1.2.9                  if (induction.objectsize!=null) {
 807 bdemsky  1.1.2.9                      //Integer induction variable                    
 808 bdemsky  1.1.2.9                      //add array dereference
 809 bdemsky  1.1.2.9                      Temp newtemp=new Temp(increment.tempFactory(),increment.name());
 810 bdemsky  1.1.2.14                     Quad newquad=new PAOFFSET(((LowQuadFactory)header.getFactory()),header,newtemp,induction.objectsize, increment);
 811 bdemsky  1.1.2.14                     hcnew.addType(newtemp, HClass.Int);
 812 bdemsky  1.1.2.14                     addquad.insert(newquad);
 813 bdemsky  1.1.2.9                      increment=newtemp;
 814 bdemsky  1.1.2.9                  }
 815 bdemsky  1.1.2.10                 
 816 bdemsky  1.1.2.10                 //delete the original definition
 817 bdemsky  1.1.2.10                 HCodeElement[] sources=ud.defMap(hc,indvariable);
 818 cananian 1.3.2.1                  assert sources.length==1;
 819 bdemsky  1.1.2.10                 Quad delquad=(Quad)sources[0];
 820 bdemsky  1.1.2.10 
 821 bdemsky  1.1.2.21                 //Mark it used....wouldn't want to try to hoist this into existance in the future...
 822 bdemsky  1.1.2.10                 usedinvariants.push(delquad);
 823 bdemsky  1.1.2.10 
 824 bdemsky  1.1.2.14                 //Get the right quad
 825 bdemsky  1.1.2.14                 delquad=hcnew.quadMap(delquad);
 826 bdemsky  1.1.2.10                 Quad.addEdge(delquad.prev(0),delquad.prevEdge(0).which_succ(), delquad.next(0), delquad.nextEdge(0).which_pred());
 827 bdemsky  1.1.2.29                 changed=true;
 828 bdemsky  1.1.2.14 
 829 bdemsky  1.1.2.10                 //Now we need to add phi's
 830 bdemsky  1.1.2.10                 Temp addresult=new Temp(initial.tempFactory(), initial.name());
 831 bdemsky  1.1.2.14                 header=handlePHI((PHI) oheader, indvariable,initial, addresult,hc, hcnew, lp);
 832 bdemsky  1.1.2.14                 hcnew.addQuadMapping(oheader,header);
 833 bdemsky  1.1.2.10                 //and add the add operands...
 834 bdemsky  1.1.2.14                 makeADD(induction, addresult, indvariable,increment,hc, hcnew, lp,oheader);
 835 bdemsky  1.1.2.14 
 836 bdemsky  1.1.2.14                 Derivation.DList merged=merge(hcnew.derivation(header,indvariable),hcnew.derivation(header,initial));
 837 bdemsky  1.1.2.14                 if (merged==null)
 838 bdemsky  1.1.2.14                     hcnew.addType(addresult,HClass.Int);
 839 bdemsky  1.1.2.14                 else
 840 bdemsky  1.1.2.14                     hcnew.addType(addresult, 
 841 bdemsky  1.1.2.35                                   null);
 842 bdemsky  1.1.2.35                 //System.out.println("Creating derivation2: "+addresult+" : "+merged);
 843 bdemsky  1.1.2.14                 hcnew.addDerivation(addresult, merged);
 844 bdemsky  1.1.2.36 
 845 bdemsky  1.1.2.36                 //Fix derivation out of phi function...just need to choose one of the branches and we are good...
 846 bdemsky  1.1.2.36                 //System.out.println("Creating derivationX: "+hcnew.tempMap(indvariable)+" : "+merged);
 847 bdemsky  1.1.2.36 
 848 bdemsky  1.1.2.36                 hcnew.addDerivation(hcnew.tempMap(indvariable), Derivation.DList.clone(merged));
 849 bdemsky  1.1.2.29                 if (addquad.changed())
 850 bdemsky  1.1.2.29                     changed=true;
 851 bdemsky  1.1.2.10             }
 852 bdemsky  1.1.2.10         }
 853 bdemsky  1.1.2.14         return complete;
 854 bdemsky  1.1.2.10     }
 855 bdemsky  1.1.2.12 
 856 bdemsky  1.1.2.12 
 857 bdemsky  1.1.2.14     class QuadInserter {
 858 bdemsky  1.1.2.14         Quad loopcaller;
 859 bdemsky  1.1.2.14         int which_succ;
 860 bdemsky  1.1.2.14         Quad successor;
 861 bdemsky  1.1.2.14         int which_pred;
 862 bdemsky  1.1.2.29         boolean changed;
 863 bdemsky  1.1.2.29 
 864 bdemsky  1.1.2.14         QuadInserter(Quad loopcaller, int which_succ, Quad successor, int which_pred) {
 865 bdemsky  1.1.2.14             this.loopcaller=loopcaller;
 866 bdemsky  1.1.2.14             this.which_succ=which_succ;
 867 bdemsky  1.1.2.14             this.successor=successor;
 868 bdemsky  1.1.2.14             this.which_pred=which_pred;
 869 bdemsky  1.1.2.29             changed=false;
 870 bdemsky  1.1.2.29         }
 871 bdemsky  1.1.2.29         public boolean changed() {
 872 bdemsky  1.1.2.29             return changed;
 873 bdemsky  1.1.2.14         }
 874 bdemsky  1.1.2.29 
 875 bdemsky  1.1.2.14         void insert(Quad newquad) {
 876 bdemsky  1.1.2.14             Quad.addEdge(loopcaller, which_succ,newquad,0);
 877 bdemsky  1.1.2.14             loopcaller=newquad; which_succ=0;
 878 bdemsky  1.1.2.14             Quad.addEdge(loopcaller, which_succ, successor, which_pred);        
 879 bdemsky  1.1.2.29             changed=true;
 880 bdemsky  1.1.2.14         }
 881 bdemsky  1.1.2.14     }
 882 bdemsky  1.1.2.14 
 883 bdemsky  1.1.2.9  
 884 bdemsky  1.1.2.15     Quad handlePHI(PHI phi, Temp indvariable, Temp initial, Temp addresult, HCode hc, MyLowQuadSSI hcnew, Loops lp) {
 885 bdemsky  1.1.2.10         //Add phi to PHI that looks like
 886 bdemsky  1.1.2.10         //indvariable=phi(initial, addresult)
 887 bdemsky  1.1.2.14         PHI phin=(PHI) hcnew.quadMap(phi);
 888 bdemsky  1.1.2.14         Temp[][] newsrc=new Temp[phin.numPhis()+1][phin.arity()];
 889 bdemsky  1.1.2.14         Temp[] newdst=new Temp[phin.numPhis()+1];
 890 bdemsky  1.1.2.10         int entrance=-1;
 891 cananian 1.3.2.1          assert phin.arity()==2;
 892 bdemsky  1.1.2.10 
 893 bdemsky  1.1.2.14         for (int i=0;i<phin.arity();i++) 
 894 bdemsky  1.1.2.14             //want old phi here
 895 cananian 1.1.2.32             if (!lp.loopIncElements().contains(phi.prev(i))) {
 896 bdemsky  1.1.2.10                 entrance=i;
 897 bdemsky  1.1.2.10                 break;
 898 bdemsky  1.1.2.7              }
 899 cananian 1.3.2.1          assert entrance!=-1;
 900 bdemsky  1.1.2.14 
 901 bdemsky  1.1.2.14 
 902 bdemsky  1.1.2.14         for (int philoop=0;philoop<phin.numPhis();philoop++) {
 903 bdemsky  1.1.2.14             newdst[philoop]=phin.dst(philoop);
 904 bdemsky  1.1.2.14             for (int arityloop=0;arityloop<phin.arity();arityloop++) {
 905 bdemsky  1.1.2.14                 newsrc[philoop][arityloop]=phin.src(philoop,arityloop);
 906 bdemsky  1.1.2.10             }
 907 bdemsky  1.1.2.10         }
 908 bdemsky  1.1.2.14 
 909 bdemsky  1.1.2.14         newdst[phin.numPhis()]=hcnew.tempMap(indvariable);
 910 bdemsky  1.1.2.14         for (int j=0;j<phin.arity();j++) {
 911 bdemsky  1.1.2.10             if (j==entrance) 
 912 bdemsky  1.1.2.14                 newsrc[phin.numPhis()][j]=initial;
 913 bdemsky  1.1.2.10             else
 914 bdemsky  1.1.2.14                 newsrc[phin.numPhis()][j]=addresult;
 915 bdemsky  1.1.2.10         }
 916 bdemsky  1.1.2.14         PHI newphi=new PHI(phin.getFactory(), phin, newdst, newsrc,phin.arity());
 917 bdemsky  1.1.2.10         //Link our successor in
 918 bdemsky  1.1.2.14         Quad.addEdge(newphi,0,phin.next(0),phin.nextEdge(0).which_pred());
 919 bdemsky  1.1.2.10         //Link our predecessors in
 920 bdemsky  1.1.2.10         for (int k=0;k<phi.arity();k++) {
 921 bdemsky  1.1.2.14             Quad.addEdge(phin.prev(k),phin.prevEdge(k).which_succ(),newphi,k);
 922 bdemsky  1.1.2.7          }
 923 bdemsky  1.1.2.29         changed=true;
 924 bdemsky  1.1.2.10         return newphi;
 925 bdemsky  1.1.2.10     }
 926 bdemsky  1.1.2.10 
 927 bdemsky  1.1.2.15     void makeADD(Induction induction, Temp addresult, Temp indvariable, Temp increment, HCode hc, MyLowQuadSSI hcnew, Loops lp, Quad oheader) {
 928 bdemsky  1.1.2.10         //Build addresult=POPER(add(indvariable, increment))
 929 bdemsky  1.1.2.15         Temp basic=induction.variable();
 930 cananian 1.1.2.32         Quad addposition=hcnew.quadMap(loopanal.addQuad(hc,(PHI) oheader,basic,lp.loopIncElements()));
 931 bdemsky  1.1.2.10 
 932 bdemsky  1.1.2.10         Quad newquad=null;
 933 bdemsky  1.1.2.10         Temp[] sources=new Temp[2];
 934 bdemsky  1.1.2.14         sources[0]=hcnew.tempMap(indvariable);
 935 bdemsky  1.1.2.10         sources[1]=increment;
 936 bdemsky  1.1.2.14 
 937 bdemsky  1.1.2.10         if (induction.objectsize==null) {
 938 bdemsky  1.1.2.10             //need normal add
 939 bdemsky  1.1.2.10             newquad=new POPER(((LowQuadFactory)addposition.getFactory()),addposition,LQop.IADD,addresult, sources);
 940 bdemsky  1.1.2.10         }
 941 bdemsky  1.1.2.10         else {
 942 bdemsky  1.1.2.10             //need pointer add
 943 bdemsky  1.1.2.10             newquad=new POPER(((LowQuadFactory)addposition.getFactory()),addposition,LQop.IADD,addresult, sources);
 944 bdemsky  1.1.2.10         }
 945 bdemsky  1.1.2.14 
 946 bdemsky  1.1.2.14         //link in new add
 947 bdemsky  1.1.2.10         Quad prev=addposition.prev(0);
 948 bdemsky  1.1.2.10         int which_succ=addposition.prevEdge(0).which_succ();
 949 bdemsky  1.1.2.10         Quad successor=addposition;
 950 bdemsky  1.1.2.10         int which_pred=0;
 951 bdemsky  1.1.2.10         Quad.addEdge(prev, which_succ,newquad,0);
 952 bdemsky  1.1.2.10         which_succ=0;
 953 bdemsky  1.1.2.10         Quad.addEdge(newquad, which_succ, successor, which_pred);
 954 bdemsky  1.1.2.29         changed=true;
 955 bdemsky  1.1.2.7      }
 956 bdemsky  1.1.2.14 
 957 bdemsky  1.1.2.7  
 958 bdemsky  1.1.2.21 
 959 bdemsky  1.1.2.13 
 960 bdemsky  1.1.2.14 
 961 bdemsky  1.1.2.14     //**********************************
 962 bdemsky  1.1.2.13     /** <code>doLoopinv</code> hoists loop invariants out of the loop.*/
 963 bdemsky  1.1.2.7  
 964 bdemsky  1.1.2.15     void doLoopinv(HCode hc, MyLowQuadSSI hcnew, Loops lp,Quad oheader, WorkSet usedinvariants) {
 965 bdemsky  1.1.2.4          WorkSet invariants=new WorkSet(invmap.invariantsMap(hc, lp));
 966 bdemsky  1.1.2.4          int linkin;
 967 bdemsky  1.1.2.14         Quad header=hcnew.quadMap(oheader);
 968 bdemsky  1.1.2.4  
 969 cananian 1.3.2.1          assert ((CFGraphable)header).pred().length==2;
 970 bdemsky  1.1.2.4          //Only worry about headers with two edges
 971 cananian 1.1.2.32         if (lp.loopIncElements().contains(header.prev(0)))
 972 bdemsky  1.1.2.4              linkin=1;
 973 bdemsky  1.1.2.5          else
 974 bdemsky  1.1.2.5              linkin=0;
 975 bdemsky  1.1.2.4  
 976 bdemsky  1.1.2.14         QuadInserter addquad=new QuadInserter(header.prev(linkin),header.prevEdge(linkin).which_succ(),header,linkin);
 977 bdemsky  1.1.2.4  
 978 bdemsky  1.1.2.4  
 979 bdemsky  1.1.2.4          while (!invariants.isEmpty()) {
 980 bdemsky  1.1.2.4              Iterator iterate=invariants.iterator();
 981 bdemsky  1.1.2.4              while (iterate.hasNext()) {
 982 bdemsky  1.1.2.4                  Quad q=(Quad)iterate.next();
 983 bdemsky  1.1.2.4                  if (usedinvariants.contains(q)) {
 984 bdemsky  1.1.2.4                      iterate.remove();
 985 bdemsky  1.1.2.4                      break;
 986 bdemsky  1.1.2.4                  }
 987 bdemsky  1.1.2.4                  Temp[] uses=q.use();
 988 bdemsky  1.1.2.4                  boolean okay=true;
 989 bdemsky  1.1.2.4                  for (int i=0;i<uses.length;i++) {
 990 bdemsky  1.1.2.5                      HCodeElement []sources=ud.defMap(hc,ssitossamap.tempMap(uses[i]));
 991 cananian 1.3.2.1                      assert sources.length==1;
 992 bdemsky  1.1.2.5                      if (invariants.contains(sources[0])) {
 993 bdemsky  1.1.2.4                          okay=false;
 994 bdemsky  1.1.2.4                          break;
 995 bdemsky  1.1.2.4                      }
 996 bdemsky  1.1.2.4                  }
 997 bdemsky  1.1.2.4                  if (okay) {
 998 bdemsky  1.1.2.6                      LoopMap loopmap=new LoopMap(hc,lp,ssitossamap);
 999 bdemsky  1.1.2.14                     WorkTempMap worktmp=new WorkTempMap();
1000 bdemsky  1.1.2.14                     Quad newq=hcnew.quadMap(q);
1001 bdemsky  1.1.2.14                     for (int i=0;i<uses.length;i++) {
1002 bdemsky  1.1.2.14                         worktmp.associate(hcnew.tempMap(uses[i]),hcnew.tempMap(loopmap.tempMap(uses[i])));
1003 bdemsky  1.1.2.14                     }
1004 bdemsky  1.1.2.17                     Temp[] def=newq.def();
1005 bdemsky  1.1.2.14                     for (int i=0;i<def.length;i++) {
1006 bdemsky  1.1.2.17                         worktmp.associate(def[i],def[i]);
1007 bdemsky  1.1.2.35                         Derivation.DList parents=((harpoon.IR.LowQuad.Code)hc).getDerivation().derivation(q, q.def()[i]);
1008 bdemsky  1.1.2.35                         //Have to rewrite derivation since we moved quad...SSI..
1009 bdemsky  1.1.2.35                         if (parents!=null) {
1010 bdemsky  1.1.2.35                             Derivation.DList nderiv=Derivation.DList.rename(parents, loopmap);
1011 bdemsky  1.1.2.35                             nderiv=Derivation.DList.rename(nderiv, hcnew.tempMap);
1012 bdemsky  1.1.2.35                             //System.out.println("Rewriting "+q.def()[i]+": "+parents+"->"+nderiv);
1013 bdemsky  1.1.2.35                             hcnew.addDerivation(hcnew.tempMap(q.def()[i]),nderiv);
1014 bdemsky  1.1.2.35                         }
1015 bdemsky  1.1.2.14                     }
1016 bdemsky  1.1.2.14                     Quad newquad=newq.rename(newq.getFactory(), worktmp, worktmp);
1017 bdemsky  1.1.2.4                      //we made a good quad now....
1018 bdemsky  1.1.2.4                      //Toss it  in the pile
1019 bdemsky  1.1.2.14                     addquad.insert(newquad);
1020 bdemsky  1.1.2.4                      //Link the old quad away
1021 bdemsky  1.1.2.14                     Quad.addEdge(newq.prev(0),newq.prevEdge(0).which_succ(), newq.next(0), newq.nextEdge(0).which_pred());
1022 bdemsky  1.1.2.4                      usedinvariants.push(q);
1023 bdemsky  1.1.2.14                     iterate.remove();
1024 bdemsky  1.1.2.29                     changed=true;
1025 bdemsky  1.1.2.4                  }
1026 bdemsky  1.1.2.4              }
1027 bdemsky  1.1.2.4          }
1028 bdemsky  1.1.2.29         if (addquad.changed())
1029 bdemsky  1.1.2.29             changed=true;
1030 bdemsky  1.1.2.14     }
1031 bdemsky  1.1.2.14 
1032 bdemsky  1.1.2.14     private Derivation.DList negate(Derivation.DList dlist) {
1033 bdemsky  1.1.2.14         if (dlist==null) return null;
1034 bdemsky  1.1.2.14         else
1035 bdemsky  1.1.2.14           return new Derivation.DList(dlist.base,
1036 bdemsky  1.1.2.15                            !dlist.sign,
1037 bdemsky  1.1.2.14                            negate(dlist.next));
1038 bdemsky  1.1.2.14     }
1039 bdemsky  1.1.2.14 
1040 bdemsky  1.1.2.14     private Derivation.DList merge(Derivation.DList dlist1, Derivation.DList dlist2) {
1041 bdemsky  1.1.2.14         if (dlist1==null)
1042 bdemsky  1.1.2.14             return dlist2.clone(dlist2);
1043 bdemsky  1.1.2.14         else 
1044 bdemsky  1.1.2.14             return new Derivation.DList(dlist1.base, dlist1.sign, merge(dlist1.next,dlist2));
1045 bdemsky  1.1.2.14     }
1046 cananian 1.2      }