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