1 cananian 1.1.2.12 // CanonicalTreeCode.java, created Mon Mar 29  0:07:41 1999 by duncan
  2 cananian 1.1.2.11 // Copyright (C) 1998 Duncan Bryce <duncan@lcs.mit.edu>
  3 cananian 1.1.2.11 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 duncan   1.1.2.1  package harpoon.IR.Tree;
  5 duncan   1.1.2.1  
  6 cananian 1.1.2.24 import harpoon.Analysis.Tree.Canonicalize;
  7 duncan   1.1.2.1  import harpoon.Backend.Generic.Frame;
  8 duncan   1.1.2.1  import harpoon.ClassFile.HClass;
  9 duncan   1.1.2.1  import harpoon.ClassFile.HCode;
 10 cananian 1.1.2.26 import harpoon.ClassFile.HCodeAndMaps;
 11 duncan   1.1.2.1  import harpoon.ClassFile.HCodeElement;
 12 duncan   1.1.2.1  import harpoon.ClassFile.HCodeFactory;
 13 duncan   1.1.2.1  import harpoon.ClassFile.HMethod;
 14 duncan   1.1.2.3  import harpoon.Temp.CloningTempMap;
 15 duncan   1.1.2.1  import harpoon.Temp.Temp;
 16 duncan   1.1.2.2  import harpoon.Util.Util;
 17 duncan   1.1.2.2  
 18 duncan   1.1.2.4  /**
 19 duncan   1.1.2.4   * The <code>CanonicalTreeCode</code> codeview is the same as 
 20 duncan   1.1.2.4   * the <Code>TreeCode</code> codeview, except for the fact that it 
 21 duncan   1.1.2.4   * does not allow <code>ESEQ</code> objects to be part of its representation.
 22 duncan   1.1.2.4   * There is seldom a compelling reason not to use the canonical tree view,
 23 duncan   1.1.2.4   * as <code>ESEQ</code>s complicate analysis, while providing no real benefits.
 24 duncan   1.1.2.4   *
 25 duncan   1.1.2.4   * The <code>CanonicalTreeCode</code> is based around Andrew Appel's 
 26 duncan   1.1.2.4   * canonical tree form.
 27 duncan   1.1.2.4   * 
 28 duncan   1.1.2.4   * @author   Duncan Bryce <duncan@lcs.mit.edu>
 29 cananian 1.5       * @version  $Id: CanonicalTreeCode.java,v 1.5 2003/03/11 17:24:56 cananian Exp $
 30 duncan   1.1.2.4   * 
 31 duncan   1.1.2.4   */
 32 duncan   1.1.2.1  public class CanonicalTreeCode extends Code {
 33 cananian 1.1.2.25     private final static boolean useOldCanonicalize = false;
 34 cananian 1.1.2.27     /** The <code>getName()</code> method return <code>codename</code>,
 35 cananian 1.1.2.27      *  which is "canonical-tree" for this <code>Code</code>. */
 36 duncan   1.1.2.6      public  static   final String           codename = "canonical-tree";
 37 cananian 1.1.2.21     private          final TreeDerivation   treeDerivation;
 38 duncan   1.1.2.4  
 39 duncan   1.1.2.4      /** Create a new <code>CanonicalTreeCode</code> from a
 40 duncan   1.1.2.4       *  <code>TreeCode</code> object, and a <code>Frame</code>.
 41 duncan   1.1.2.4       */
 42 cananian 1.3.2.2      CanonicalTreeCode(Code code, Frame frame) {
 43 duncan   1.1.2.1          super(code.getMethod(), null, frame);
 44 duncan   1.1.2.1  
 45 cananian 1.1.2.24         if (useOldCanonicalize) {
 46 cananian 1.1.2.24             ToCanonicalTree translator;
 47 cananian 1.1.2.24             translator   = new ToCanonicalTree(this.tf, code);
 48 cananian 1.1.2.24             tree         = translator.getTree();
 49 cananian 1.1.2.24             treeDerivation = translator.getTreeDerivation();
 50 cananian 1.1.2.24         } else {
 51 cananian 1.1.2.24             DerivationGenerator dg = (code.getTreeDerivation()==null) ? null :
 52 cananian 1.1.2.24                 new DerivationGenerator();
 53 cananian 1.1.2.24             tree = Tree.clone(this.tf, code.tree, (dg==null) ? null :
 54 cananian 1.1.2.24                               dg.cloneCallback(code.getTreeDerivation()));
 55 cananian 1.1.2.24             Canonicalize.simplify((Stm)tree, dg, Canonicalize.RULES);
 56 cananian 1.1.2.24             treeDerivation = dg;
 57 cananian 1.1.2.24         }
 58 cananian 1.3.2.1          assert !harpoon.Analysis.Tree.Canonicalize.containsEseq(tree);
 59 duncan   1.1.2.4      }
 60 duncan   1.1.2.6  
 61 duncan   1.1.2.6      /* Copy constructor, should only be called by the clone() method. */
 62 cananian 1.1.2.23     private CanonicalTreeCode(HMethod newMethod, Tree tree, Frame frame,
 63 cananian 1.1.2.23                               TreeDerivation treeDerivation) {
 64 duncan   1.1.2.4          super(newMethod, tree, frame);
 65 cananian 1.1.2.23         this.treeDerivation = treeDerivation;
 66 duncan   1.1.2.6      }
 67 duncan   1.1.2.3  
 68 cananian 1.1.2.21     /** Returns a <code>TreeDerivation</code> object for the
 69 cananian 1.1.2.21      *  generated <code>Tree</code> form. */
 70 cananian 1.1.2.21     public TreeDerivation getTreeDerivation() { return treeDerivation; }
 71 cananian 1.1.2.21 
 72 duncan   1.1.2.6      /** 
 73 duncan   1.1.2.6       * Clone this code representation. The clone has its own
 74 duncan   1.1.2.6       * copy of the tree structure. 
 75 duncan   1.1.2.6       */
 76 cananian 1.5          public HCodeAndMaps<Tree> clone(HMethod newMethod, Frame frame) {
 77 cananian 1.1.2.23         DerivationGenerator dg =
 78 cananian 1.1.2.23             (getTreeDerivation()==null) ? null : new DerivationGenerator();
 79 cananian 1.1.2.23         CanonicalTreeCode tc = new CanonicalTreeCode(newMethod,null,frame,dg);
 80 cananian 1.1.2.26         return cloneHelper(tc, dg);
 81 duncan   1.1.2.1      }
 82 duncan   1.1.2.1  
 83 duncan   1.1.2.4      /**
 84 duncan   1.1.2.4       * Return the name of this code view.
 85 duncan   1.1.2.4       * @return the string <code>"canonical-tree"</code>.
 86 duncan   1.1.2.4       */
 87 duncan   1.1.2.1      public String getName() { return codename; }
 88 duncan   1.1.2.1  
 89 duncan   1.1.2.4      /** @return true */
 90 duncan   1.1.2.4      public boolean isCanonical() { return true; } 
 91 duncan   1.1.2.4  
 92 duncan   1.1.2.1      /**
 93 duncan   1.1.2.4       * Return a code factory for <code>CanonicalTreeCode</code>, given a 
 94 pnkfelix 1.1.2.9       * code factory for <code>TreeCode</code>.
 95 pnkfelix 1.1.2.9       * <BR> <B>effects:</B> if <code>hcf</code> is a code factory for
 96 pnkfelix 1.1.2.9       *      <code>TreeCode</code>, then creates and returns a code
 97 pnkfelix 1.1.2.9       *      factory for <code>CanonicalTreeCode</code>.  Else passes
 98 pnkfelix 1.1.2.9       *      <code>hcf</code> to
 99 pnkfelix 1.1.2.9       *      <code>TreeCode.codeFactory()</code>, and reattempts to
100 pnkfelix 1.1.2.9       *      create a code factory for <code>CanonicalTreeCode</code> from the
101 pnkfelix 1.1.2.9       *      code factory returned by <code>TreeCode</code>.
102 pnkfelix 1.1.2.10      * @see TreeCode#codeFactory(HCodeFactory, Frame)
103 duncan   1.1.2.1       */
104 duncan   1.1.2.1      public static HCodeFactory codeFactory(final HCodeFactory hcf, 
105 duncan   1.1.2.1                                             final Frame frame) {
106 duncan   1.1.2.1          if (hcf.getCodeName().equals(TreeCode.codename)) {
107 cananian 1.1.2.13             // note that result will not be serializable unless frame is.
108 cananian 1.1.2.13             return new harpoon.ClassFile.SerializableCodeFactory() { 
109 duncan   1.1.2.1                  public HCode convert(HMethod m) { 
110 duncan   1.1.2.1                      HCode c = hcf.convert(m);
111 duncan   1.1.2.1                      return (c==null) ? null :
112 cananian 1.3.2.2                          new CanonicalTreeCode((Code)c, frame);
113 duncan   1.1.2.1                  }
114 duncan   1.1.2.1                  public void clear(HMethod m) { hcf.clear(m); }
115 duncan   1.1.2.1                  public String getCodeName() { return codename; }
116 duncan   1.1.2.1              };
117 pnkfelix 1.1.2.8          } else {
118 pnkfelix 1.1.2.8              HCodeFactory treeCodeHCF=TreeCode.codeFactory(hcf, frame);
119 pnkfelix 1.1.2.8              return codeFactory( treeCodeHCF, frame );
120 duncan   1.1.2.1          }
121 duncan   1.1.2.1      }
122 duncan   1.1.2.1    
123 duncan   1.1.2.1      /**
124 duncan   1.1.2.4       * Return a code factory for <code>CanonicalTreeCode</code>, 
125 duncan   1.1.2.4       * using the default code factory for <code>TreeCode</code>
126 duncan   1.1.2.1       */
127 duncan   1.1.2.1      public static HCodeFactory codeFactory(final Frame frame) {  
128 duncan   1.1.2.1          return codeFactory(TreeCode.codeFactory(frame), frame);
129 duncan   1.1.2.1      }
130 duncan   1.1.2.1  }
131 duncan   1.1.2.3  
132 duncan   1.1.2.3  
133 duncan   1.1.2.3  
134 duncan   1.1.2.3  
135 duncan   1.1.2.3  
136 duncan   1.1.2.3  
137 duncan   1.1.2.3  
138 duncan   1.1.2.3  
139 cananian 1.2