You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2012/10/03 21:16:20 UTC
svn commit: r1393692 - in
/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward:
analysis/MethodDifferentiator.java instructions/DReturnTransformer.java
Author: luc
Date: Wed Oct 3 19:16:20 2012
New Revision: 1393692
URL: http://svn.apache.org/viewvc?rev=1393692&view=rev
Log:
Leveraged DRETURN handling, suppressing special cases.
Some methods may have code branches like:
if (x < 0) return x else return 0
It is therefore possible that in the same method, some DRETURN
instructions depend on the input parameter while other DRETURN
instructions are independent and therefore must return a constant
converted to a DerivativeStructure. We must handle both cases at the
same time.
Modified:
commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/MethodDifferentiator.java
commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DReturnTransformer.java
Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/MethodDifferentiator.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/MethodDifferentiator.java?rev=1393692&r1=1393691&r2=1393692&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/MethodDifferentiator.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/MethodDifferentiator.java Wed Oct 3 19:16:20 2012
@@ -128,43 +128,17 @@ public class MethodDifferentiator {
frames.put(method.instructions.get(i), array[i]);
}
- // identify the needed changes
- final Set<AbstractInsnNode> changes = identifyChanges(method.instructions);
-
- if (changes.isEmpty()) {
-
- // TODO: merge this case with the general case: DRETURN must always be
- // changed when the function signature changes, and the change is either
- // converting DRETURN to ARETURN, possibly with a prepended call to
- // convertDoubleToDerivativeStructure before the ARETURN when stack0converted
- // is false
-
- // the method does not depend on the parameter at all!
- // we replace all "return d;" by "return new DerivativeStructure(parameters, order, d);"
- for (final Iterator<AbstractInsnNode> i = method.instructions.iterator(); i.hasNext();) {
- final AbstractInsnNode insn = i.next();
- if (insn.getOpcode() == Opcodes.DRETURN) {
- final InsnList list = new DReturnTransformer(false).getReplacement(insn, this, dsIndex);
- method.instructions.insert(insn, list);
- method.instructions.remove(insn);
- }
- }
-
- } else {
-
- // perform the code changes
- for (final AbstractInsnNode insn : changes) {
- method.instructions.insert(insn, getReplacement(insn, method.maxLocals));
- method.instructions.remove(insn);
- }
-
- // trim generated instructions list
- new SwappedDloadTrimmer().trim(method.instructions);
- new SwappedDstoreTrimmer().trim(method.instructions);
- new DLoadPop2Trimmer().trim(method.instructions);
-
+ // perform the code changes
+ for (final AbstractInsnNode insn : identifyChanges(method.instructions, isStatic)) {
+ method.instructions.insert(insn, getReplacement(insn, method.maxLocals));
+ method.instructions.remove(insn);
}
+ // trim generated instructions list
+ new SwappedDloadTrimmer().trim(method.instructions);
+ new SwappedDstoreTrimmer().trim(method.instructions);
+ new DLoadPop2Trimmer().trim(method.instructions);
+
// insert the preservation of the reference derivative structure
method.instructions.insert(preserveReferenceDerivativeStructure(derivedMethodType, isStatic, dsIndex));
@@ -190,12 +164,21 @@ public class MethodDifferentiator {
* the local variables in the initial frame to match the parameters of
* the derivative method, and propagate these variables following the
* instructions path, updating stack cells and local variables as needed.
- * Instructions that must be changed are the ones that consume changed
- * variables or stack cells.</p>
+ * Instructions that must be changed are:
+ * </p>
+ * <ul>
+ * <li>the ones that consume changed variables or stack cells</li>
+ * <li>the GETFIELD/PUTFIELD instruction as they must access the
+ * primitive instance fields</li>
+ * <li>all DRETURN instructions (regardless of the returned value being
+ * converted or not, as in some branch codes the value may return
+ * simple constants like "return 0")</li>
+ * </ul>
* @param instructions instructions of the method
+ * @param isStatic if true, the method is a static method
* @return set containing all the instructions that must be changed
*/
- private Set<AbstractInsnNode> identifyChanges(final InsnList instructions) {
+ private Set<AbstractInsnNode> identifyChanges(final InsnList instructions, final boolean isStatic) {
// the pending set contains the values (local variables or stack cells)
// that have been changed, they will trigger changes on the instructions
@@ -206,8 +189,8 @@ public class MethodDifferentiator {
final Set<AbstractInsnNode> changes = new HashSet<AbstractInsnNode>();
// start by converting the parameter of the method,
- // which is kept in local variable 1 of the initial frame
- final TrackingValue dpParameter = frames.get(instructions.get(0)).getLocal(1);
+ // which is kept in local variable 0 or 1 of the initial frame (depending on the method being static or not)
+ final TrackingValue dpParameter = frames.get(instructions.get(0)).getLocal(isStatic ? 0 : 1);
pending.add(dpParameter);
// propagate the values conversions throughout the method
@@ -243,12 +226,13 @@ public class MethodDifferentiator {
}
}
- // the various GETFIELD/PUTFIELD instructions must also be changed
- // to retrieve the field from the primitive class
+ // the various GETFIELD/PUTFIELD/DRETURN instructions must also be changed
final ListIterator<AbstractInsnNode> iterator = instructions.iterator();
while (iterator.hasNext()) {
final AbstractInsnNode ins = iterator.next();
- if ((ins.getOpcode() == Opcodes.GETFIELD) || (ins.getOpcode() == Opcodes.PUTFIELD)) {
+ if ((ins.getOpcode() == Opcodes.GETFIELD) ||
+ (ins.getOpcode() == Opcodes.PUTFIELD) ||
+ (ins.getOpcode() == Opcodes.DRETURN)) {
changes.add(ins);
}
}
@@ -377,8 +361,7 @@ public class MethodDifferentiator {
case Opcodes.DCMPG :
return new DcmpTransformer().getReplacement(insn, this, dsIndex);
case Opcodes.DRETURN :
- // TODO: the constructor parameter forced to true seems strange...
- return new DReturnTransformer(true).getReplacement(insn, this, dsIndex);
+ return new DReturnTransformer().getReplacement(insn, this, dsIndex);
case Opcodes.GETSTATIC :
// TODO: add support for GETSTATIC differentiation
throw new RuntimeException("GETSTATIC not handled yet");
Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DReturnTransformer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DReturnTransformer.java?rev=1393692&r1=1393691&r2=1393692&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DReturnTransformer.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DReturnTransformer.java Wed Oct 3 19:16:20 2012
@@ -33,16 +33,6 @@ import org.objectweb.asm.tree.InsnNode;
*/
public class DReturnTransformer implements InstructionsTransformer {
- /** Indicator for top stack element conversion. */
- private final boolean stack0Converted;
-
- /** Simple constructor.
- * @param stack0Converted if true, the top level stack element has already been converted
- */
- public DReturnTransformer(final boolean stack0Converted) {
- this.stack0Converted = stack0Converted;
- }
-
/** {@inheritDoc} */
public InsnList getReplacement(final AbstractInsnNode insn,
final MethodDifferentiator methodDifferentiator,
@@ -51,7 +41,7 @@ public class DReturnTransformer implemen
final InsnList list = new InsnList();
- if (!stack0Converted) {
+ if (!methodDifferentiator.stackElementIsConverted(insn, 0)) {
// add conversion for top level stack element
list.add(methodDifferentiator.doubleToDerivativeStructureConversion(dsIndex));
}