comparison graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java @ 15003:4b1f128a3d45

create memory anchor for snippet StartNodes
author Lukas Stadler <lukas.stadler@oracle.com>
date Mon, 07 Apr 2014 11:32:08 +0200
parents e302df8bf51c
children c8e575742f36
comparison
equal deleted inserted replaced
15002:06e50d290784 15003:4b1f128a3d45
59 import com.oracle.graal.word.*; 59 import com.oracle.graal.word.*;
60 60
61 /** 61 /**
62 * A snippet template is a graph created by parsing a snippet method and then specialized by binding 62 * A snippet template is a graph created by parsing a snippet method and then specialized by binding
63 * constants to the snippet's {@link ConstantParameter} parameters. 63 * constants to the snippet's {@link ConstantParameter} parameters.
64 * 64 *
65 * Snippet templates can be managed in a cache maintained by {@link AbstractTemplates}. 65 * Snippet templates can be managed in a cache maintained by {@link AbstractTemplates}.
66 */ 66 */
67 public class SnippetTemplate { 67 public class SnippetTemplate {
68 68
69 /** 69 /**
77 protected final boolean[] constantParameters; 77 protected final boolean[] constantParameters;
78 protected final boolean[] varargsParameters; 78 protected final boolean[] varargsParameters;
79 79
80 /** 80 /**
81 * Times instantiations of all templates derived form this snippet. 81 * Times instantiations of all templates derived form this snippet.
82 * 82 *
83 * @see SnippetTemplate#instantiationTimer 83 * @see SnippetTemplate#instantiationTimer
84 */ 84 */
85 private final DebugTimer instantiationTimer; 85 private final DebugTimer instantiationTimer;
86 86
87 /** 87 /**
88 * Counts instantiations of all templates derived from this snippet. 88 * Counts instantiations of all templates derived from this snippet.
89 * 89 *
90 * @see SnippetTemplate#instantiationCounter 90 * @see SnippetTemplate#instantiationCounter
91 */ 91 */
92 private final DebugMetric instantiationCounter; 92 private final DebugMetric instantiationCounter;
93 93
94 /** 94 /**
625 625
626 assert checkAllVarargPlaceholdersAreDeleted(parameterCount, placeholders); 626 assert checkAllVarargPlaceholdersAreDeleted(parameterCount, placeholders);
627 627
628 new FloatingReadPhase(FloatingReadPhase.ExecutionMode.ANALYSIS_ONLY).apply(snippetCopy); 628 new FloatingReadPhase(FloatingReadPhase.ExecutionMode.ANALYSIS_ONLY).apply(snippetCopy);
629 629
630 MemoryAnchorNode memoryAnchor = snippetCopy.add(new MemoryAnchorNode());
631 snippetCopy.start().replaceAtUsages(InputType.Memory, memoryAnchor);
632 if (memoryAnchor.usages().isEmpty()) {
633 memoryAnchor.safeDelete();
634 } else {
635 snippetCopy.addAfterFixed(snippetCopy.start(), memoryAnchor);
636 }
637
630 this.snippet = snippetCopy; 638 this.snippet = snippetCopy;
639
640 Debug.dump(snippet, "SnippetTemplate after fixing memory anchoring");
641
631 List<ReturnNode> returnNodes = new ArrayList<>(4); 642 List<ReturnNode> returnNodes = new ArrayList<>(4);
632 List<MemoryMapNode> memMaps = new ArrayList<>(4); 643 List<MemoryMapNode> memMaps = new ArrayList<>(4);
633 StartNode entryPointNode = snippet.start(); 644 StartNode entryPointNode = snippet.start();
634 for (ReturnNode retNode : snippet.getNodes(ReturnNode.class)) { 645 for (ReturnNode retNode : snippet.getNodes(ReturnNode.class)) {
635 MemoryMapNode memMap = retNode.getMemoryMap(); 646 MemoryMapNode memMap = retNode.getMemoryMap();
647 memMap.replaceLastLocationAccess(snippetCopy.start(), memoryAnchor);
636 memMaps.add(memMap); 648 memMaps.add(memMap);
637 retNode.setMemoryMap(null); 649 retNode.setMemoryMap(null);
638 returnNodes.add(retNode); 650 returnNodes.add(retNode);
639 if (memMap.usages().isEmpty()) { 651 if (memMap.usages().isEmpty()) {
640 memMap.safeDelete(); 652 memMap.safeDelete();
748 */ 760 */
749 private final MemoryMapNode memoryMap; 761 private final MemoryMapNode memoryMap;
750 762
751 /** 763 /**
752 * Times instantiations of this template. 764 * Times instantiations of this template.
753 * 765 *
754 * @see SnippetInfo#instantiationTimer 766 * @see SnippetInfo#instantiationTimer
755 */ 767 */
756 private final DebugTimer instantiationTimer; 768 private final DebugTimer instantiationTimer;
757 769
758 /** 770 /**
759 * Counts instantiations of this template. 771 * Counts instantiations of this template.
760 * 772 *
761 * @see SnippetInfo#instantiationCounter 773 * @see SnippetInfo#instantiationCounter
762 */ 774 */
763 private final DebugMetric instantiationCounter; 775 private final DebugMetric instantiationCounter;
764 776
765 /** 777 /**
766 * Gets the instantiation-time bindings to this template's parameters. 778 * Gets the instantiation-time bindings to this template's parameters.
767 * 779 *
768 * @return the map that will be used to bind arguments to parameters when inlining this template 780 * @return the map that will be used to bind arguments to parameters when inlining this template
769 */ 781 */
770 private IdentityHashMap<Node, Node> bind(StructuredGraph replaceeGraph, MetaAccessProvider metaAccess, Arguments args) { 782 private IdentityHashMap<Node, Node> bind(StructuredGraph replaceeGraph, MetaAccessProvider metaAccess, Arguments args) {
771 IdentityHashMap<Node, Node> replacements = new IdentityHashMap<>(); 783 IdentityHashMap<Node, Node> replacements = new IdentityHashMap<>();
772 assert args.info.getParameterCount() == parameters.length : "number of args (" + args.info.getParameterCount() + ") != number of parameters (" + parameters.length + ")"; 784 assert args.info.getParameterCount() == parameters.length : "number of args (" + args.info.getParameterCount() + ") != number of parameters (" + parameters.length + ")";
819 831
820 /** 832 /**
821 * Converts a Java boxed value to a {@link Constant} of the right kind. This adjusts for the 833 * Converts a Java boxed value to a {@link Constant} of the right kind. This adjusts for the
822 * limitation that a {@link Local}'s kind is a {@linkplain Kind#getStackKind() stack kind} and 834 * limitation that a {@link Local}'s kind is a {@linkplain Kind#getStackKind() stack kind} and
823 * so cannot be used for re-boxing primitives smaller than an int. 835 * so cannot be used for re-boxing primitives smaller than an int.
824 * 836 *
825 * @param argument a Java boxed value 837 * @param argument a Java boxed value
826 * @param localKind the kind of the {@link Local} to which {@code argument} will be bound 838 * @param localKind the kind of the {@link Local} to which {@code argument} will be bound
827 */ 839 */
828 protected Constant forBoxed(Object argument, Kind localKind) { 840 protected Constant forBoxed(Object argument, Kind localKind) {
829 assert localKind == localKind.getStackKind(); 841 assert localKind == localKind.getStackKind();
927 939
928 if (replacee instanceof MemoryCheckpoint.Single) { 940 if (replacee instanceof MemoryCheckpoint.Single) {
929 // check if some node in snippet graph also kills the same location 941 // check if some node in snippet graph also kills the same location
930 LocationIdentity locationIdentity = ((MemoryCheckpoint.Single) replacee).getLocationIdentity(); 942 LocationIdentity locationIdentity = ((MemoryCheckpoint.Single) replacee).getLocationIdentity();
931 if (locationIdentity == ANY_LOCATION) { 943 if (locationIdentity == ANY_LOCATION) {
932 assert !(memoryMap.getLastLocationAccess(ANY_LOCATION) instanceof StartNode) : replacee + " kills ANY_LOCATION, but snippet does not"; 944 assert !(memoryMap.getLastLocationAccess(ANY_LOCATION) instanceof MemoryAnchorNode) : replacee + " kills ANY_LOCATION, but snippet does not";
933 } 945 }
934 assert kills.contains(locationIdentity) : replacee + " kills " + locationIdentity + ", but snippet doesn't contain a kill to this location"; 946 assert kills.contains(locationIdentity) : replacee + " kills " + locationIdentity + ", but snippet doesn't contain a kill to this location";
935 return true; 947 return true;
936 } 948 }
937 assert !(replacee instanceof MemoryCheckpoint.Multi) : replacee + " multi not supported (yet)"; 949 assert !(replacee instanceof MemoryCheckpoint.Multi) : replacee + " multi not supported (yet)";
938 950
939 Debug.log("WARNING: %s is not a MemoryCheckpoint, but the snippet graph contains kills (%s). You might want %s to be a MemoryCheckpoint", replacee, kills, replacee); 951 Debug.log("WARNING: %s is not a MemoryCheckpoint, but the snippet graph contains kills (%s). You might want %s to be a MemoryCheckpoint", replacee, kills, replacee);
940 952
941 // remove ANY_LOCATION if it's just a kill by the start node 953 // remove ANY_LOCATION if it's just a kill by the start node
942 if (memoryMap.getLastLocationAccess(ANY_LOCATION) instanceof StartNode) { 954 if (memoryMap.getLastLocationAccess(ANY_LOCATION) instanceof MemoryAnchorNode) {
943 kills.remove(ANY_LOCATION); 955 kills.remove(ANY_LOCATION);
944 } 956 }
945 957
946 // node can only lower to a ANY_LOCATION kill if the replacee also kills ANY_LOCATION 958 // node can only lower to a ANY_LOCATION kill if the replacee also kills ANY_LOCATION
947 assert !kills.contains(ANY_LOCATION) : "snippet graph contains a kill to ANY_LOCATION, but replacee (" + replacee + ") doesn't kill ANY_LOCATION. kills: " + kills; 959 assert !kills.contains(ANY_LOCATION) : "snippet graph contains a kill to ANY_LOCATION, but replacee (" + replacee + ") doesn't kill ANY_LOCATION. kills: " + kills;
983 995
984 @Override 996 @Override
985 public Set<LocationIdentity> getLocations() { 997 public Set<LocationIdentity> getLocations() {
986 return memoryMap.getLocations(); 998 return memoryMap.getLocations();
987 } 999 }
1000
1001 @Override
1002 public void replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode) {
1003 throw GraalInternalError.shouldNotReachHere();
1004 }
988 } 1005 }
989 1006
990 /** 1007 /**
991 * Replaces a given fixed node with this specialized snippet. 1008 * Replaces a given fixed node with this specialized snippet.
992 * 1009 *
993 * @param metaAccess 1010 * @param metaAccess
994 * @param replacee the node that will be replaced 1011 * @param replacee the node that will be replaced
995 * @param replacer object that replaces the usages of {@code replacee} 1012 * @param replacer object that replaces the usages of {@code replacee}
996 * @param args the arguments to be bound to the flattened positional parameters of the snippet 1013 * @param args the arguments to be bound to the flattened positional parameters of the snippet
997 * @return the map of duplicated nodes (original -&gt; duplicate) 1014 * @return the map of duplicated nodes (original -&gt; duplicate)
1138 return snippet.copy(); 1155 return snippet.copy();
1139 } 1156 }
1140 1157
1141 /** 1158 /**
1142 * Replaces a given floating node with this specialized snippet. 1159 * Replaces a given floating node with this specialized snippet.
1143 * 1160 *
1144 * @param metaAccess 1161 * @param metaAccess
1145 * @param replacee the node that will be replaced 1162 * @param replacee the node that will be replaced
1146 * @param replacer object that replaces the usages of {@code replacee} 1163 * @param replacer object that replaces the usages of {@code replacee}
1147 * @param args the arguments to be bound to the flattened positional parameters of the snippet 1164 * @param args the arguments to be bound to the flattened positional parameters of the snippet
1148 */ 1165 */