001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.nabla.algorithmic.forward.analysis; 018 019 import java.util.HashSet; 020 import java.util.Set; 021 022 import org.objectweb.asm.tree.AbstractInsnNode; 023 import org.objectweb.asm.tree.analysis.BasicValue; 024 import org.objectweb.asm.tree.analysis.Value; 025 026 /** A value that keep track of both instructions producing and consuming it. 027 */ 028 public class TrackingValue implements Value { 029 030 /** Special value for uninitialized values. */ 031 public static final TrackingValue UNINITIALIZED_VALUE = 032 new TrackingValue((BasicValue) BasicValue.UNINITIALIZED_VALUE); 033 034 /** Underlying value. */ 035 private final BasicValue value; 036 037 /** Instructions that consume this value. */ 038 private Set<AbstractInsnNode> consumers; 039 040 /** Instructions that produce this value. */ 041 private Set<AbstractInsnNode> producers; 042 043 /** Values that are merged with this value. */ 044 private Set<TrackingValue> merged; 045 046 /** Build a new value without any link to instructions. 047 * @param value wrapped {@link BasicValue} value 048 */ 049 public TrackingValue(final BasicValue value) { 050 this.value = value; 051 consumers = new HashSet<AbstractInsnNode>(); 052 producers = new HashSet<AbstractInsnNode>(); 053 merged = new HashSet<TrackingValue>(); 054 } 055 056 /** Get the wrapped {@link BasicValue}. 057 * @return wrapped {@link BasicValue} 058 */ 059 public BasicValue getValue() { 060 return value; 061 } 062 063 /** {@inheritDoc} */ 064 public int getSize() { 065 return value.getSize(); 066 } 067 068 /** Add a consumer for this value. 069 * @param consumer consumer for this value 070 */ 071 public void addConsumer(final AbstractInsnNode consumer) { 072 consumers.add(consumer); 073 } 074 075 /** Get the consumers for this value and all values it is merged with. 076 * @return the instructions consuming either this value or the values 077 * it has been merged with 078 */ 079 public Set<AbstractInsnNode> getConsumers() { 080 return consumers; 081 } 082 083 /** Add a producer for this value. 084 * @param producer producer for this value 085 */ 086 public void addProducer(final AbstractInsnNode producer) { 087 producers.add(producer); 088 } 089 090 /** Get the producers for this value and all values it is merged with. 091 * @return the instructions producing either this value or the values 092 * it has been merged with 093 */ 094 public Set<AbstractInsnNode> getProducers() { 095 return producers; 096 } 097 098 /** Merge two instances. 099 * <p>Once merged, values share the same producers and consumers sets.</p> 100 * @param value1 first value to merge 101 * @param value2 second value to merge 102 */ 103 public static void merge(final TrackingValue value1, 104 final TrackingValue value2) { 105 106 // merge the sets 107 value1.consumers.addAll(value2.consumers); 108 value1.producers.addAll(value2.producers); 109 value1.merged.addAll(value2.merged); 110 111 // share the merged sets 112 for (TrackingValue value : value2.merged) { 113 value.consumers = value1.consumers; 114 value.producers = value1.producers; 115 value.merged = value1.merged; 116 } 117 value2.consumers = value1.consumers; 118 value2.producers = value1.producers; 119 value2.merged = value1.merged; 120 121 } 122 123 }