1 cananian 1.1.2.14 // TreeCode.java, created Mon Feb 15 12:53:14 1999 by duncan
  2 cananian 1.1.2.35 // Copyright (C) 1998 Duncan Bryce <duncan@lcs.mit.edu>
  3 cananian 1.1.2.13 // 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.23 import harpoon.Analysis.Maps.Derivation;
  7 cananian 1.1.2.23 import harpoon.Analysis.Maps.Derivation.DList;
  8 duncan   1.1.2.1  import harpoon.Analysis.Maps.TypeMap;
  9 duncan   1.1.2.1  import harpoon.Backend.Generic.Frame;
 10 duncan   1.1.2.1  import harpoon.ClassFile.HClass;
 11 duncan   1.1.2.1  import harpoon.ClassFile.HCode;
 12 cananian 1.1.2.33 import harpoon.ClassFile.HCodeAndMaps;
 13 duncan   1.1.2.1  import harpoon.ClassFile.HCodeElement;
 14 duncan   1.1.2.1  import harpoon.ClassFile.HCodeFactory;
 15 duncan   1.1.2.1  import harpoon.ClassFile.HMethod;
 16 duncan   1.1.2.1  import harpoon.IR.LowQuad.LowQuadNoSSA;
 17 cananian 1.1.2.32 import harpoon.IR.LowQuad.LowQuadSSA;
 18 cananian 1.1.2.31 import harpoon.IR.LowQuad.LowQuadSSI;
 19 cananian 1.1.2.30 import harpoon.IR.Properties.CFGrapher;
 20 cananian 1.1.2.30 import harpoon.IR.Properties.UseDefer;
 21 duncan   1.1.2.7  import harpoon.Temp.CloningTempMap;
 22 duncan   1.1.2.1  import harpoon.Temp.Temp;
 23 duncan   1.1.2.9  import harpoon.Util.Util;
 24 duncan   1.1.2.1  
 25 duncan   1.1.2.7  /*
 26 duncan   1.1.2.7   * The <code>TreeCode</code> codeview exposes a tree-based representation.
 27 duncan   1.1.2.7   * This codeview serves primarily as an intermediate translation phase between 
 28 duncan   1.1.2.7   * <code>LowQuadNoSSA</code> and <code>CanonicalTreeCode</code>.  
 29 duncan   1.1.2.7   * In general, most analyses will be simpler in <code>CanonicalTreeCode</code>
 30 duncan   1.1.2.7   * because it has no <code>ESEQ</code>s.  
 31 duncan   1.1.2.7   * 
 32 duncan   1.1.2.7   * The tree form is based around Andrew Appel's tree form.  
 33 duncan   1.1.2.7   *
 34 cananian 1.1.2.35  * @author  Duncan Bryce <duncan@lcs.mit.edu>
 35 cananian 1.4       * @version $Id: TreeCode.java,v 1.4 2002/09/01 07:47:33 cananian Exp $
 36 duncan   1.1.2.7   * 
 37 duncan   1.1.2.7   */
 38 duncan   1.1.2.5  public class TreeCode extends Code {
 39 cananian 1.1.2.34     /** The <code>getName()</code> method return <code>codename</code>,
 40 cananian 1.1.2.34      *  which is "tree" for this <code>Code</code>. */
 41 duncan   1.1.2.7      public  static   final   String     codename = "tree";
 42 cananian 1.1.2.29     private final    TreeDerivation     treeDerivation;
 43 duncan   1.1.2.1    
 44 duncan   1.1.2.7      /** Create a new <code>TreeCode</code> from a
 45 duncan   1.1.2.7       *  <code>LowQuadNoSSA</code> object, and a <code>Frame</code>.
 46 duncan   1.1.2.7       */
 47 duncan   1.1.2.5      TreeCode(LowQuadNoSSA code, Frame topframe) {
 48 duncan   1.1.2.5          super(code.getMethod(), null, topframe);
 49 duncan   1.1.2.5  
 50 duncan   1.1.2.5          ToTree translator;
 51 duncan   1.1.2.5  
 52 duncan   1.1.2.5          translator = new ToTree(this.tf, code);
 53 duncan   1.1.2.5          tree       = translator.getTree();
 54 cananian 1.1.2.24         treeDerivation = translator.getTreeDerivation();
 55 duncan   1.1.2.5      }
 56 cananian 1.1.2.25     /** Create a new <code>TreeCode</code> from a
 57 cananian 1.1.2.32      *  <code>LowQuadSSA</code> object, and a <code>Frame</code>.
 58 cananian 1.1.2.32      */
 59 cananian 1.1.2.32     TreeCode(LowQuadSSA code, Frame topframe) {
 60 cananian 1.1.2.32         super(code.getMethod(), null, topframe);
 61 cananian 1.1.2.32 
 62 cananian 1.1.2.32         ToTree translator;
 63 cananian 1.1.2.32 
 64 cananian 1.1.2.32         translator = new ToTree(this.tf, code);
 65 cananian 1.1.2.32         tree       = translator.getTree();
 66 cananian 1.1.2.32         treeDerivation = translator.getTreeDerivation();
 67 cananian 1.1.2.32     }
 68 cananian 1.1.2.32     /** Create a new <code>TreeCode</code> from a
 69 cananian 1.1.2.31      *  <code>LowQuadSSI</code> object, and a <code>Frame</code>.
 70 cananian 1.1.2.25      */
 71 cananian 1.1.2.31     TreeCode(LowQuadSSI code, Frame topframe) {
 72 cananian 1.1.2.25         super(code.getMethod(), null, topframe);
 73 cananian 1.1.2.25 
 74 cananian 1.1.2.25         ToTree translator;
 75 cananian 1.1.2.25 
 76 cananian 1.1.2.25         translator = new ToTree(this.tf, code);
 77 cananian 1.1.2.25         tree       = translator.getTree();
 78 cananian 1.1.2.25         treeDerivation = translator.getTreeDerivation();
 79 cananian 1.1.2.25     }
 80 duncan   1.1.2.5  
 81 cananian 1.1.2.29     // copy constructor.  should only be called by the clone() method
 82 cananian 1.1.2.26     protected TreeCode(HMethod newMethod, Tree tree, Frame topframe,
 83 cananian 1.1.2.26                        TreeDerivation treeDerivation) {
 84 duncan   1.1.2.5          super(newMethod, tree, topframe);
 85 cananian 1.1.2.26         this.treeDerivation = treeDerivation;
 86 duncan   1.1.2.5      }
 87 duncan   1.1.2.5  
 88 cananian 1.1.2.24     public TreeDerivation getTreeDerivation() { return treeDerivation; }
 89 cananian 1.1.2.24 
 90 duncan   1.1.2.7      /** 
 91 duncan   1.1.2.7       * Clone this code representation. The clone has its own
 92 duncan   1.1.2.7       * copy of the tree structure. 
 93 duncan   1.1.2.7       */
 94 cananian 1.4          public HCodeAndMaps<Tree> clone(HMethod newMethod, Frame frame) {
 95 cananian 1.1.2.29         DerivationGenerator  dg  =
 96 cananian 1.1.2.29             (getTreeDerivation()==null) ? null : new DerivationGenerator();
 97 cananian 1.1.2.29         TreeCode             tc  = new TreeCode(newMethod, null, frame, dg); 
 98 cananian 1.1.2.33         return cloneHelper(tc, dg);
 99 duncan   1.1.2.5      }
100 duncan   1.1.2.5  
101 duncan   1.1.2.7      /**
102 duncan   1.1.2.7       * Return the name of this code view.
103 duncan   1.1.2.7       * @return the string <code>"tree"</code>.
104 duncan   1.1.2.7       */
105 duncan   1.1.2.5      public String getName() { return codename; }
106 duncan   1.1.2.5  
107 duncan   1.1.2.7      /** @return false */
108 duncan   1.1.2.7      public boolean isCanonical() { return false; } 
109 cananian 1.1.2.30     /** <code>CFGrapher</code> not valid for non-canonical trees. 
110 cananian 1.1.2.30      * @return null */
111 cananian 1.2.2.1      public CFGrapher<Tree> getGrapher() { return null; }
112 cananian 1.1.2.30     /** <code>UseDefer</code> not valid for non-canonical trees. 
113 cananian 1.1.2.30      * @return null */
114 cananian 1.2.2.1      public UseDefer<Tree> getUseDefer() { return null; }
115 duncan   1.1.2.7  
116 duncan   1.1.2.7      /** 
117 duncan   1.1.2.7       * This operation is not supported in non-canonical tree forms.
118 duncan   1.1.2.7       * @exception UnsupportedOperationException always.
119 duncan   1.1.2.7       */
120 duncan   1.1.2.7      public void recomputeEdges() { throw new UnsupportedOperationException(); }
121 duncan   1.1.2.7  
122 duncan   1.1.2.5      /**
123 pnkfelix 1.1.2.11      * Returns a code factory for <code>TreeCode</code>, given a 
124 cananian 1.1.2.31      * code factory for <code>LowQuadNoSSA</code> or <code>LowQuadSSI</code>.
125 pnkfelix 1.1.2.11      * <BR> <B>effects:</B> if <code>hcf</code> is a code factory for
126 cananian 1.1.2.31      *      <code>LowQuadNoSSA</code> or <code>LowQuadSSI</code>, then
127 cananian 1.1.2.25      *      creates and returns a code
128 pnkfelix 1.1.2.11      *      factory for <code>TreeCode</code>.  Else passes
129 pnkfelix 1.1.2.11      *      <code>hcf</code> to
130 cananian 1.1.2.31      *      <code>LowQuadSSI.codeFactory()</code>, and reattempts to
131 pnkfelix 1.1.2.11      *      create a code factory for <code>TreeCode</code> from the
132 cananian 1.1.2.31      *      code factory returned by <code>LowQuadSSI</code>.
133 cananian 1.1.2.31      * @see LowQuadSSI#codeFactory(HCodeFactory)
134 duncan   1.1.2.5       */
135 duncan   1.1.2.5      public static HCodeFactory codeFactory(final HCodeFactory hcf, 
136 duncan   1.1.2.5                                             final Frame frame) {
137 cananian 1.1.2.31         if (hcf.getCodeName().equals(LowQuadSSI.codename)) {
138 cananian 1.1.2.25             // note that result will not be serializable unless frame is.
139 cananian 1.1.2.25             return new harpoon.ClassFile.SerializableCodeFactory() { 
140 cananian 1.1.2.25                 public HCode convert(HMethod m) { 
141 cananian 1.1.2.25                     HCode c = hcf.convert(m);
142 cananian 1.1.2.25                     return (c==null) ? null :
143 cananian 1.1.2.31                         new TreeCode((LowQuadSSI)c, frame);
144 cananian 1.1.2.32                 }
145 cananian 1.1.2.32                 public void clear(HMethod m) { hcf.clear(m); }
146 cananian 1.1.2.32                 public String getCodeName() { return codename; }
147 cananian 1.1.2.32             };
148 cananian 1.1.2.32         } else if (hcf.getCodeName().equals(LowQuadSSA.codename)) {
149 cananian 1.1.2.32             // note that result will not be serializable unless frame is.
150 cananian 1.1.2.32             return new harpoon.ClassFile.SerializableCodeFactory() { 
151 cananian 1.1.2.32                 public HCode convert(HMethod m) { 
152 cananian 1.1.2.32                     HCode c = hcf.convert(m);
153 cananian 1.1.2.32                     return (c==null) ? null :
154 cananian 1.1.2.32                         new TreeCode((LowQuadSSA)c, frame);
155 cananian 1.1.2.25                 }
156 cananian 1.1.2.25                 public void clear(HMethod m) { hcf.clear(m); }
157 cananian 1.1.2.25                 public String getCodeName() { return codename; }
158 cananian 1.1.2.25             };
159 cananian 1.1.2.25         } else if (hcf.getCodeName().equals(LowQuadNoSSA.codename)) {
160 cananian 1.1.2.15             // note that result will not be serializable unless frame is.
161 cananian 1.1.2.15             return new harpoon.ClassFile.SerializableCodeFactory() { 
162 duncan   1.1.2.5                  public HCode convert(HMethod m) { 
163 duncan   1.1.2.5                      HCode c = hcf.convert(m);
164 duncan   1.1.2.5                      return (c==null) ? null :
165 duncan   1.1.2.5                          new TreeCode((LowQuadNoSSA)c, frame);
166 duncan   1.1.2.5                  }
167 duncan   1.1.2.5                  public void clear(HMethod m) { hcf.clear(m); }
168 duncan   1.1.2.5                  public String getCodeName() { return codename; }
169 duncan   1.1.2.5              };
170 pnkfelix 1.1.2.10         } else {
171 pnkfelix 1.1.2.10             //   throw new Error("don't know how to make " + codename +
172 pnkfelix 1.1.2.10             //      " from " + hcf.getCodeName());
173 cananian 1.1.2.31             HCodeFactory lqnossaHCF = LowQuadSSI.codeFactory(hcf);
174 pnkfelix 1.1.2.10             return codeFactory(lqnossaHCF, frame);
175 duncan   1.1.2.1          }
176 duncan   1.1.2.1      }
177 duncan   1.1.2.1    
178 duncan   1.1.2.5      /**
179 cananian 1.1.2.27      * Return a code factory for <code>TreeCode</code>, using the default
180 cananian 1.1.2.31      * code factory for <code>LowQuadSSI</code>
181 duncan   1.1.2.5       */
182 duncan   1.1.2.5      public static HCodeFactory codeFactory(final Frame frame) {  
183 cananian 1.1.2.31         return codeFactory(LowQuadSSI.codeFactory(), frame);
184 duncan   1.1.2.5      }
185 cananian 1.2      }