import org.objectweb.asm.Label;
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
import org.simantics.scl.compiler.constants.BooleanConstant;
+import org.simantics.scl.compiler.constants.ComparisonFunction;
import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
import org.simantics.scl.compiler.internal.codegen.continuations.ContRef;
+import org.simantics.scl.compiler.internal.codegen.references.BoundVar;
import org.simantics.scl.compiler.internal.codegen.references.Val;
import org.simantics.scl.compiler.internal.codegen.references.ValRef;
import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;
import org.simantics.scl.compiler.internal.codegen.ssa.SSAExit;
import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;
import org.simantics.scl.compiler.internal.codegen.ssa.binders.ValRefBinder;
+import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;
import org.simantics.scl.compiler.internal.codegen.utils.CopyContext;
import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext;
import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;
import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;
+import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor;
import org.simantics.scl.compiler.types.TVar;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.compiler.types.Types;
private ContRef thenTarget;
private ContRef elseTarget;
- public If(ValRef condition, ContRef thenTarget, ContRef elseTarget) {
+ public If(int lineNumber, ValRef condition, ContRef thenTarget, ContRef elseTarget) {
+ super(lineNumber);
setCondition(condition);
setThenTarget(thenTarget);
setElseTarget(elseTarget);
@Override
public void generateCode(MethodBuilder mb) {
+ mb.lineNumber(lineNumber);
+ Val binding = condition.getBinding();
+ simplifyTestCode: if(binding instanceof BoundVar) {
+ BoundVar boundVar = (BoundVar)binding;
+ if(!boundVar.generateOnFly)
+ break simplifyTestCode;
+ LetApply apply = (LetApply)boundVar.getParent();
+ Val function = apply.getFunction().getBinding();
+ if(!(function instanceof ComparisonFunction))
+ break simplifyTestCode;
+
+ Val[] ps = ValRef.getBindings(apply.getParameters());
+ ((ComparisonFunction)function).generateCondition(mb, ps, thenTarget.getBinding(), elseTarget.getBinding());
+ return;
+ }
mb.push(condition.getBinding(), Types.BOOLEAN);
Label elseLabel = mb.getLabel(elseTarget.getBinding());
mb.ifZeroComparisonBranch(elseLabel, "==");
@Override
public SSAExit copy(CopyContext context) {
- return new If(context.copy(condition),
+ If copy = new If(lineNumber,
+ context.copy(condition),
context.copy(thenTarget),
context.copy(elseTarget));
+ return copy;
}
@Override
if(cond instanceof BooleanConstant) {
SSAExit newExit;
if(((BooleanConstant) cond).getValue()) {
- newExit = new Jump(thenTarget);
+ newExit = new Jump(lineNumber, thenTarget);
elseTarget.remove();
}
else {
- newExit = new Jump(elseTarget);
+ newExit = new Jump(lineNumber, elseTarget);
thenTarget.remove();
}
condition.remove();
else if(thenTarget.getBinding() == elseTarget.getBinding()) {
elseTarget.remove();
condition.remove();
- getParent().setExit(new Jump(thenTarget));
+ getParent().setExit(new Jump(lineNumber, thenTarget));
context.markModified("equal-branches-if");
}
}
return SSABlock.EMPTY_ARRAY;
}
}
+
+ @Override
+ public void forValRefs(ValRefVisitor visitor) {
+ visitor.visit(condition);
+ }
+
+ @Override
+ public void cleanup() {
+ condition.remove();
+ }
}