Mercurial > hg > truffle
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 -> duplicate) | 1014 * @return the map of duplicated nodes (original -> 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 */ |