TransformerFactory.java
package dev.civl.mc.transform.IF;
import java.util.List;
import java.util.Map;
import dev.civl.abc.ast.IF.AST;
import dev.civl.abc.ast.IF.ASTFactory;
import dev.civl.abc.ast.node.IF.ASTNode;
import dev.civl.abc.ast.node.IF.expression.ExpressionNode.ExpressionKind;
import dev.civl.abc.ast.node.IF.expression.FunctionCallNode;
import dev.civl.abc.ast.node.IF.expression.IdentifierExpressionNode;
import dev.civl.abc.front.IF.ASTBuilder;
import dev.civl.abc.program.IF.Program;
import dev.civl.abc.transform.IF.TransformRecord;
import dev.civl.abc.transform.IF.Transformer;
import dev.civl.mc.config.IF.CIVLConfiguration;
/**
* This class manages the set of transformations provided by CIVL.
*
* It provides a static method
* {@link #applyTransformer(Program, String, List, ASTBuilder)} to apply a
* certain transformer to a given program.
*
* @author Manchun Zheng
*
*/
public class TransformerFactory {
private ASTFactory astFactory;
private GeneralTransformer generalTransformer;
// private MacroTransformer macroTransformer;
private IOTransformer ioTransformer;
// private OpenMPSimplifier openMPSimplifier;
private MPI2CIVLTransformer mpi2CivlTransformer;
private OpenMP2CIVLTransformer openMP2CivlTransformer;
private Pthread2CIVLTransformer pthread2CivlTransformer;
private Cuda2CIVLTransformer cuda2CivlTransformer;
// private SvcompTransformer svcompTransformer;
private ContractTransformer contractTransformer;
// private IntOperationTransformer intOpTransformer;
private DirectingTransformer directingTransformer;
/**
* A cache for a created {@link LoopContractTransformer}
*/
private LoopContractTransformer loopContractTransformer = null;
public TransformerFactory(ASTFactory astFactory) {
this.astFactory = astFactory;
}
public TransformRecord getGeneralTransformerRecord() {
return new TransformRecord(GeneralTransformer.CODE,
GeneralTransformer.LONG_NAME,
GeneralTransformer.SHORT_DESCRIPTION) {
@Override
public Transformer create(ASTFactory astFactory) {
if (generalTransformer == null)
generalTransformer = new GeneralTransformer(astFactory);
return generalTransformer;
}
};
}
public TransformRecord getContractTransformerRecord(String targetFunction,
CIVLConfiguration civlConfig) {
return new TransformRecord(ContractTransformer.CODE,
ContractTransformer.LONG_NAME,
ContractTransformer.SHORT_DESCRIPTION) {
@Override
public Transformer create(ASTFactory astFactory) {
if (contractTransformer == null)
contractTransformer = new ContractTransformer(astFactory,
targetFunction, civlConfig);
return contractTransformer;
}
};
}
/**
* @return A {@link TransformRecord} for loop contract transformer
*/
public TransformRecord getLoopContractTransformerRecord() {
return new TransformRecord(LoopContractTransformer.CODE,
LoopContractTransformer.LONG_NAME,
LoopContractTransformer.SHORT_DESCRIPTION) {
@Override
public Transformer create(ASTFactory astFactory) {
if (loopContractTransformer == null)
loopContractTransformer = new LoopContractTransformer(
astFactory);
return loopContractTransformer;
}
};
}
public TransformRecord getMacroTransformerRecord(CIVLConfiguration config) {
return new TransformRecord(MacroTransformer.CODE,
MacroTransformer.LONG_NAME,
MacroTransformer.SHORT_DESCRIPTION) {
@Override
public Transformer create(ASTFactory astFactory) {
return new MacroTransformer(astFactory, config);
}
};
}
public TransformRecord getIOTransformerRecord(CIVLConfiguration config) {
return new TransformRecord(IOTransformer.CODE, IOTransformer.LONG_NAME,
IOTransformer.SHORT_DESCRIPTION) {
@Override
public Transformer create(ASTFactory astFactory) {
if (ioTransformer == null)
ioTransformer = new IOTransformer(astFactory, config);
return ioTransformer;
}
};
}
public TransformRecord getOpenMPSimplifierRecord(CIVLConfiguration config) {
return new TransformRecord(OpenMPSimplifier.CODE,
OpenMPSimplifier.LONG_NAME,
OpenMPSimplifier.SHORT_DESCRIPTION) {
@Override
public Transformer create(ASTFactory astFactory) {
return new OpenMPSimplifier(astFactory, config);
}
};
}
public TransformRecord getMPI2CIVLTransformerRecord() {
return new TransformRecord(MPI2CIVLTransformer.CODE,
MPI2CIVLTransformer.LONG_NAME,
MPI2CIVLTransformer.SHORT_DESCRIPTION) {
@Override
public Transformer create(ASTFactory astFactory) {
if (mpi2CivlTransformer == null)
mpi2CivlTransformer = new MPI2CIVLTransformer(astFactory);
return mpi2CivlTransformer;
}
};
}
public TransformRecord getOpenMP2CIVLTransformerRecord(
CIVLConfiguration config) {
return new TransformRecord(OpenMP2CIVLTransformer.CODE,
OpenMP2CIVLTransformer.LONG_NAME,
OpenMP2CIVLTransformer.SHORT_DESCRIPTION) {
@Override
public Transformer create(ASTFactory astFactory) {
if (openMP2CivlTransformer == null)
openMP2CivlTransformer = new OpenMP2CIVLTransformer(
astFactory, config);
return openMP2CivlTransformer;
}
};
}
public TransformRecord getPthread2CIVLTransformerRecord() {
return new TransformRecord(Pthread2CIVLTransformer.CODE,
Pthread2CIVLTransformer.LONG_NAME,
Pthread2CIVLTransformer.SHORT_DESCRIPTION) {
@Override
public Transformer create(ASTFactory astFactory) {
if (pthread2CivlTransformer == null)
pthread2CivlTransformer = new Pthread2CIVLTransformer(
astFactory);
return pthread2CivlTransformer;
}
};
}
public TransformRecord getCuda2CIVLTransformerRecord() {
return new TransformRecord(Cuda2CIVLTransformer.CODE,
Cuda2CIVLTransformer.LONG_NAME,
Cuda2CIVLTransformer.SHORT_DESCRIPTION) {
@Override
public Transformer create(ASTFactory astFactory) {
if (cuda2CivlTransformer == null)
cuda2CivlTransformer = new Cuda2CIVLTransformer(astFactory);
return cuda2CivlTransformer;
}
};
}
public TransformRecord getSvcompTransformerRecord(
CIVLConfiguration config) {
return new TransformRecord(SvcompTransformer.CODE,
SvcompTransformer.LONG_NAME,
SvcompTransformer.SHORT_DESCRIPTION) {
@Override
public Transformer create(ASTFactory astFactory) {
return new SvcompTransformer(astFactory, config);
}
};
}
/**
* Creates a new instance of a {@link ShortCircuitTransformer}
*
* @param config
* A reference to {@link CIVLConfiguration}
* @return A {@link TransformRecord} of a {@link ShortCircuitTransformer}.
*/
public TransformRecord getShortCircuitTransformerRecord(
CIVLConfiguration config) {
return new TransformRecord(ShortCircuitTransformer.CODE,
ShortCircuitTransformer.LONG_NAME,
ShortCircuitTransformer.SHORT_DESCRIPTION) {
@Override
public Transformer create(ASTFactory astFactory) {
return new ShortCircuitTransformer(astFactory);
}
};
}
public TransformRecord getIntOperationTransformerRecord(
Map<String, String> macros, CIVLConfiguration config) {
return new TransformRecord(IntOperationTransformer.CODE,
IntOperationTransformer.LONG_NAME,
IntOperationTransformer.SHORT_DESCRIPTION) {
@Override
public Transformer create(ASTFactory astFactory) {
return new IntOperationTransformer(astFactory, macros, config);
}
};
}
public TransformRecord getDirectingTransformerRecord(
CIVLConfiguration config) {
return new TransformRecord(DirectingTransformer.CODE,
DirectingTransformer.LONG_NAME,
DirectingTransformer.SHORT_DESCRIPTION) {
@Override
public Transformer create(ASTFactory astFactory) {
if (directingTransformer == null)
directingTransformer = new DirectingTransformer(astFactory,
config);
return directingTransformer;
}
};
}
public static boolean hasFunctionCalls(AST ast, List<String> functions) {
ASTNode root = ast.getRootNode();
return checkFunctionCalls(root, functions);
}
private static boolean checkFunctionCalls(ASTNode node,
List<String> functions) {
int numChildren = node.numChildren();
boolean result = false;
for (int i = 0; i < numChildren; i++) {
ASTNode child = node.child(i);
if (child != null) {
result = checkFunctionCalls(child, functions);
if (result)
return true;
}
}
if (node instanceof FunctionCallNode) {
FunctionCallNode functionCall = (FunctionCallNode) node;
if (functionCall.getFunction()
.expressionKind() == ExpressionKind.IDENTIFIER_EXPRESSION) {
IdentifierExpressionNode functionExpression = (IdentifierExpressionNode) functionCall
.getFunction();
String functionName = functionExpression.getIdentifier().name();
if (functions.contains(functionName))
return true;
}
}
return false;
}
public Transformer getOpenMPSimplifier(CIVLConfiguration config) {
return new OpenMPSimplifier(astFactory, config);
}
public Transformer getOpenMP2CIVLTransformer(CIVLConfiguration config) {
return new OpenMP2CIVLTransformer(astFactory, config);
}
//
// public Transformer getSvcompUnPPTransformer() {
// if (svcompUnPPTransformer == null)
// svcompUnPPTransformer = new SvcompUnPPTransformer(astFactory);
// return svcompUnPPTransformer;
// }
//
// public Transformer getSvcompTransformer() {
// if (svcompTransformer == null)
// svcompTransformer = new SvcompTransformer(astFactory);
// return svcompTransformer;
// }
//
// public Transformer getIntDivTransformer() {
// if (intDivTransformer == null)
// intDivTransformer = new IntDivisionTransformer(astFactory);
// return intDivTransformer;
// }
}