private void doTransformOptimizations(CompilerMessageLogger logger) throws Packager.PackagerException, UnableToResolveForeignEntityException {
// First build up a list of functions that haven't already been optimized.
List<MachineFunction> functionsList = new ArrayList<MachineFunction>();
Module m = getCurrentModule();
for (final MachineFunction mf : m.getFunctions()) {
if (!mf.isOptimized()) {
functionsList.add (mf);
}
}
// Run the CAL optimizer on the functions before other optimization are
// performed.
if (optimizer_executor != null) {
Iterator<MachineFunction> functions = functionsList.iterator();
List<MachineFunction> moreFunctions = new LinkedList<MachineFunction>();
// List of modules used by the module. Inlining expression can cause name from
// non-imported module to be used. The type info has to be updated with these new
// modules.
Set<ModuleName> moreModules = new HashSet<ModuleName>();
int skipped_otherCounter = 0;
int skipped_tooManyHelperFunctionsCounter = 0;
int skipped_unsupportedExpressionType = 0;
int skipped_hasBadStructure = 0;
int skipped_tooDeep = 0;
int skipped_tooMuchTime = 0;
int changedCounter = 0;
while (functions.hasNext()) {
MachineFunctionImpl cl = (MachineFunctionImpl) functions.next();
CoreFunction coreFunction = cl.getCoreFunction();
if (cl.getExpressionForm() instanceof Expression.PackCons) {
continue; // can't be optimized so skip these
}
if (cl.getName().startsWith("$")) {
continue; // skip compiler generated helper functions
}
try {
Expression newBody = applyCALOptimizer(cl.getTimeStamp(), coreFunction, moreFunctions);
if (!newBody.toString().equals(cl.getExpressionForm().toString())) {
++changedCounter;
}
modules(newBody, moreModules);
cl.setExpression(newBody);
} catch(TooManyHelperFunctionsException e){
skipped_tooManyHelperFunctionsCounter++;
} catch (OptimizerHelper.UnsupportedExpressionTypeException e) {
skipped_unsupportedExpressionType++;
} catch (HasBadStructureException e){
skipped_hasBadStructure++;
} catch (TooDeepException e){
skipped_tooDeep++;
} catch (TooMuchTimeException e){
skipped_tooMuchTime++;
} catch (IllegalStateException e) {
// TODO fix this so all the types of expressions are
// handled.
skipped_otherCounter++;
} catch (UnsupportedOperationException e){
skipped_unsupportedExpressionType++;
} catch (IllegalArgumentException e) {
// TODO figure out why this is happening and fix it.
skipped_otherCounter++;
} catch (Throwable e) {
// TODO figure out why this is happening and fix it.
skipped_otherCounter++;
}
}
if (moreFunctions.size() > 0 ||
skipped_otherCounter > 0 ||
skipped_hasBadStructure > 0 ||
skipped_tooDeep > 0 ||
skipped_tooMuchTime > 0 ||
skipped_tooManyHelperFunctionsCounter > 0 ||
skipped_unsupportedExpressionType > 0 ||
changedCounter > 0) {
System.out.print(m.getName());
System.out.println(": ");
if (moreFunctions.size() > 0) {
System.out.println(" Added " + moreFunctions.size()
+ " more functions.");
}
if (changedCounter > 0) {
System.out.println(" Changed " + changedCounter + " of "
+ functionsList.size() + " expressions.");
}
if (
skipped_unsupportedExpressionType > 0 ||
skipped_tooManyHelperFunctionsCounter > 0 ||
skipped_hasBadStructure > 0 ||
skipped_tooDeep > 0 ||
skipped_tooMuchTime > 0 ||
skipped_otherCounter > 0) {
System.out.println(" Skipped " + (skipped_hasBadStructure + skipped_otherCounter + skipped_tooManyHelperFunctionsCounter + skipped_unsupportedExpressionType) + " of " + functionsList.size() + " expressions.");
if (skipped_tooManyHelperFunctionsCounter > 0) {
System.out.println(" Too many helpers " + skipped_tooManyHelperFunctionsCounter + " of " + functionsList.size() + " expressions.");
}
if (skipped_unsupportedExpressionType > 0) {
System.out.println(" Unsupported expression types " + skipped_unsupportedExpressionType + " of " + functionsList.size() + " expressions.");
}
if (skipped_hasBadStructure > 0) {
System.out.println(" Incomplete optimization " + skipped_hasBadStructure + " of " + functionsList.size() + " expressions.");
}
if (skipped_tooDeep > 0) {
System.out.println(" Optimization too deep " + skipped_tooDeep + " of " + functionsList.size() + " expressions.");
}
if (skipped_tooMuchTime > 0) {
System.out.println(" Too much time " + skipped_tooMuchTime + " of " + functionsList.size() + " expressions.");
}
if (skipped_otherCounter > 0) {
System.out.println(" Other " + skipped_otherCounter + " of " + functionsList.size() + " expressions.");
}
}
}
// add the helper functions to the list of functions for the module.
{
for (final MachineFunction mf : moreFunctions) {
m.addFunction(mf);
functionsList.add(mf);
}
}
}
Iterator<MachineFunction> functions = functionsList.iterator();
Map<String, Expression> nameToExpressionMap = new HashMap<String, Expression>();
while (functions.hasNext()) {
MachineFunction cl = functions.next ();
nameToExpressionMap.put (cl.getName(), cl.getExpressionForm());
}
// Determine the strongly connected components and put the information into the code labels.
List<Set<String>> sets = ExpressionAnalyzer.determineStronglyConnectedComponents(m.getName(), nameToExpressionMap);
for (int i = 0; i < sets.size(); ++i) {
Set<String> set = sets.get(i);
Iterator<String> items = set.iterator();
while (items.hasNext()) {
String name = items.next();
MachineFunctionImpl mf = (MachineFunctionImpl)m.getFunction(name);
if (mf != null) {
mf.setStronglyConnectedComponents(set);
}
}
}
// Now that we've determined the closely connected components we can use
// an ExpressionAnalyzer to do optimizing transformations to the expression.
functions = functionsList.iterator();
while (functions.hasNext()) {
MachineFunction cl = functions.next ();
ExpressionAnalyzer ea = new ExpressionAnalyzer (m.getModuleTypeInfo(), cl);
cl.setExpression(ea.transformExpression(cl.getExpressionForm()));
if (ea.getHadUnsafeCoerce()){
cl.setHadUnsafeCoerce();
}