MachineFunction mf = module.getFunction(opName);
if (mf != null && mf.canFunctionBeEagerlyEvaluated()) {
int nArgs = basicOpExpressions.getNArguments();
int nWHNFArgs = 0;
for (int i = 0; i < nArgs; ++i) {
Expression eArg = basicOpExpressions.getArgument(i);
if (canIgnoreLaziness(eArg, variableContext)) {
nWHNFArgs++;
}
}
if (nArgs == nWHNFArgs) {
String unqualifiedOpName = opName.getUnqualifiedName();
if (opName.getModuleName().equals(CAL_Prelude.MODULE_NAME) &&
(unqualifiedOpName.equals(CAL_Prelude_internal.Functions.divideLong.getUnqualifiedName()) ||
unqualifiedOpName.equals(CAL_Prelude_internal.Functions.remainderLong.getUnqualifiedName()) ||
unqualifiedOpName.equals(CAL_Prelude_internal.Functions.divideInt.getUnqualifiedName()) ||
unqualifiedOpName.equals(CAL_Prelude_internal.Functions.remainderInt.getUnqualifiedName()) ||
unqualifiedOpName.equals(CAL_Prelude_internal.Functions.divideShort.getUnqualifiedName()) ||
unqualifiedOpName.equals(CAL_Prelude_internal.Functions.remainderShort.getUnqualifiedName()) ||
unqualifiedOpName.equals(CAL_Prelude_internal.Functions.divideByte.getUnqualifiedName()) ||
unqualifiedOpName.equals(CAL_Prelude_internal.Functions.remainderByte.getUnqualifiedName()))) {
// Check that the second argument is a non zero literal.
Expression arg = basicOpExpressions.getArgument(1);
if (arg.asLiteral() != null) {
if (unqualifiedOpName.equals(CAL_Prelude_internal.Functions.divideLong.getUnqualifiedName()) ||
unqualifiedOpName.equals(CAL_Prelude_internal.Functions.remainderLong.getUnqualifiedName())) {
Long l = (Long)arg.asLiteral().getLiteral();
return l.longValue() != 0;
} else if (unqualifiedOpName.equals(CAL_Prelude_internal.Functions.divideInt.getUnqualifiedName()) ||
unqualifiedOpName.equals(CAL_Prelude_internal.Functions.remainderInt.getUnqualifiedName())) {
Integer i = (Integer)arg.asLiteral().getLiteral();
return i.intValue() != 0;
} else if (unqualifiedOpName.equals(CAL_Prelude_internal.Functions.divideShort.getUnqualifiedName()) ||
unqualifiedOpName.equals(CAL_Prelude_internal.Functions.remainderShort.getUnqualifiedName())) {
Short shortValue = (Short)arg.asLiteral().getLiteral();
return shortValue.shortValue() != 0;
} else if (unqualifiedOpName.equals(CAL_Prelude_internal.Functions.divideByte.getUnqualifiedName()) ||
unqualifiedOpName.equals(CAL_Prelude_internal.Functions.remainderByte.getUnqualifiedName())) {
Byte byteValue = (Byte)arg.asLiteral().getLiteral();
return byteValue.byteValue() != 0;
} else {
throw new IllegalStateException();
}
} else {
return false;
}
} else {
return true;
}
} else {
return false;
}
}
}
basicOpExpressions = BasicOpTuple.isAndOr (e);
if (basicOpExpressions != null) {
// Code a basic operation
int nArgs = basicOpExpressions.getNArguments ();
int nWHNFArgs = 0;
for (int i = 0; i < nArgs; ++i) {
Expression eArg = basicOpExpressions.getArgument(i);
if (canIgnoreLaziness(eArg, variableContext)) {
nWHNFArgs++;
}
}
if (nArgs == nWHNFArgs) {
return true;
}
}
// If e is a fully saturated application of a function tagged for optimization and
// all the arguments can be shortcutted we can shortcut the application.
if (e.asAppl() != null) {
Expression[] chain = appChain(e.asAppl());
if (chain[0].asVar() != null) {
// Get the supercombinator on the left end of the chain.
Expression.Var scVar = chain[0].asVar();
if (scVar != null) {
// Check if this supercombinator is one we should try to optimize.
MachineFunction mf = module.getFunction(scVar.getName());
if (mf != null && mf.canFunctionBeEagerlyEvaluated()) {
// Now determine the arity of the SC.
int calledArity = mf.getArity();
// Check to see if we can shortcut all the arguments.
if (chain.length - 1 == calledArity) {
int nWHNFArgs = 0;
for (int i = 0; i < calledArity; ++i) {
if (canIgnoreLaziness(chain[i+1], variableContext)) {
nWHNFArgs++;
}
}
if (nWHNFArgs == calledArity) {
return true;
}
}
}
}
}
}
// Is e an application of a zero arity constructor.
if (ConstructorOpTuple.isConstructorOp(e, true) != null) {
ConstructorOpTuple constructorOpExpressions = ConstructorOpTuple.isConstructorOp(e, false);
DataConstructor dc = constructorOpExpressions.getDataConstructor ();
if (dc.getArity() == 0){
return true;
}
}
// Is e a DataConsFieldSelection where the data constructor expression can be shortcutted and
// the field is strict.
if (e.asDataConsSelection() != null) {
Expression.DataConsSelection dcs = (Expression.DataConsSelection)e;
if (dcs.getDataConstructor().isArgStrict(dcs.getFieldIndex()) && canIgnoreLaziness(dcs.getDCValueExpr(), variableContext)) {
return true;
}
}
// 'if a then b else c' where a, b, and c can all be shortcut.
CondTuple conditionExpressions = CondTuple.isCondOp(e);
if (conditionExpressions != null) {
Expression condExpr = conditionExpressions.getConditionExpression();
Expression thenExpr = conditionExpressions.getThenExpression();
Expression elseExpr = conditionExpressions.getElseExpression();
if (canIgnoreLaziness(condExpr, variableContext) &&
canIgnoreLaziness(thenExpr, variableContext) &&
canIgnoreLaziness(elseExpr, variableContext)) {
return true;
}