if (mf.canFunctionBeEagerlyEvaluated()) {
int nArgs = basicOpExpressions.getNArguments();
int nWHNFArgs = 0;
for (int i = 0; i < nArgs; ++i) {
Expression eArg = basicOpExpressions.getArgument(i);
if (canIgnoreLaziness(eArg, env)) {
nWHNFArgs++;
}
}
if (nArgs == nWHNFArgs) {
// All the args are in WHNF so ideally we can ignore laziness for
// this primitive operation. However, there are some primitive
// ops where an additional condition, that the second argument is
// known to not be zero, is required.
String unqualifiedOpName = opName.getUnqualifiedName();
if (opName.getModuleName().equals(CAL_Prelude.MODULE_NAME) &&
(unqualifiedOpName.equals("divideLong") ||
unqualifiedOpName.equals("remainderLong") ||
unqualifiedOpName.equals("divideInt") ||
unqualifiedOpName.equals("remainderInt") ||
unqualifiedOpName.equals("divideShort") ||
unqualifiedOpName.equals("remainderShort") ||
unqualifiedOpName.equals("divideByte") ||
unqualifiedOpName.equals("remainderByte"))) {
// Check that the second argument is a non zero literal.
Expression arg = basicOpExpressions.getArgument(1);
if (arg.asLiteral() != null) {
if (unqualifiedOpName.equals("divideLong") || unqualifiedOpName.equals("remainderLong")) {
Long l = (Long)arg.asLiteral().getLiteral();
return l.longValue() != 0;
} else if (unqualifiedOpName.equals("divideInt") || unqualifiedOpName.equals("remainderInt")) {
Integer i = (Integer)arg.asLiteral().getLiteral();
return i.intValue() != 0;
} else if (unqualifiedOpName.equals("divideShort") || unqualifiedOpName.equals("remainderShort")) {
Short shortValue = (Short)arg.asLiteral().getLiteral();
return shortValue.shortValue() != 0;
} else if (unqualifiedOpName.equals("divideByte") || unqualifiedOpName.equals("remainderByte")) {
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, env)) {
nWHNFArgs++;
}
}
if (nArgs == nWHNFArgs) {
return true;
}
}
// If e is a fully saturated application of a function tagged for optimization and
// all the arguments are in WHNF or can have laziness ignored we can
// ignore laziness for 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 = currentModule.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 ignore laziness for all the arguments.
if (chain.length - 1 == calledArity) {
int nWHNFArgs = 0;
for (int i = 0; i < calledArity; ++i) {
if (canIgnoreLaziness(chain[i+1], env)) {
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 laziness can be ignored for the data constructor
// expression and the field is strict.
if (e.asDataConsSelection() != null) {
Expression.DataConsSelection dcs = (Expression.DataConsSelection)e;
if (dcs.getDataConstructor().isArgStrict(dcs.getFieldIndex()) && canIgnoreLaziness(dcs.getDCValueExpr(), env)) {
return true;
}
}
// 'if a then b else c' where laziness can be ignore for a, b, and c.
CondTuple conditionExpressions = CondTuple.isCondOp(e);
if (conditionExpressions != null) {
Expression condExpr = conditionExpressions.getConditionExpression();
Expression thenExpr = conditionExpressions.getThenExpression();
Expression elseExpr = conditionExpressions.getElseExpression();
if (canIgnoreLaziness(condExpr, env) &&
canIgnoreLaziness(thenExpr, env) &&
canIgnoreLaziness(elseExpr, env)) {
return true;
}