use of com.oracle.truffle.dsl.processor.expression.DSLExpression in project graal by oracle.
the class NodeParser method initializeCaches.
private void initializeCaches(SpecializationData specialization, DSLExpressionResolver resolver) {
TypeMirror cacheMirror = context.getType(Cached.class);
List<CacheExpression> expressions = new ArrayList<>();
for (Parameter parameter : specialization.getParameters()) {
AnnotationMirror annotationMirror = ElementUtils.findAnnotationMirror(parameter.getVariableElement().getAnnotationMirrors(), cacheMirror);
if (annotationMirror != null) {
String initializer = ElementUtils.getAnnotationValue(String.class, annotationMirror, "value");
TypeMirror parameterType = parameter.getType();
DSLExpressionResolver localResolver = resolver;
if (parameterType.getKind() == TypeKind.DECLARED) {
localResolver = localResolver.copy(importPublicStaticMembers(ElementUtils.fromTypeMirror(parameterType), true));
}
CacheExpression cacheExpression;
DSLExpression expression = null;
try {
expression = DSLExpression.parse(initializer);
expression.accept(localResolver);
cacheExpression = new CacheExpression(parameter, annotationMirror, expression);
if (!ElementUtils.typeEquals(expression.getResolvedType(), parameter.getType())) {
cacheExpression.addError("Incompatible return type %s. The expression type must be equal to the parameter type %s.", ElementUtils.getSimpleName(expression.getResolvedType()), ElementUtils.getSimpleName(parameter.getType()));
}
} catch (InvalidExpressionException e) {
cacheExpression = new CacheExpression(parameter, annotationMirror, null);
cacheExpression.addError("Error parsing expression '%s': %s", initializer, e.getMessage());
}
if (!cacheExpression.hasErrors()) {
Cached cached = cacheExpression.getParameter().getVariableElement().getAnnotation(Cached.class);
cacheExpression.setDimensions(cached.dimensions());
if (parameterType.getKind() == TypeKind.ARRAY && !ElementUtils.isSubtype(((ArrayType) parameterType).getComponentType(), context.getType(NodeInterface.class))) {
if (cacheExpression.getDimensions() == -1) {
cacheExpression.addWarning("The cached dimensions attribute must be specified for array types.");
}
} else {
if (cacheExpression.getDimensions() != -1) {
cacheExpression.addError("The dimensions attribute has no affect for the type %s.", ElementUtils.getSimpleName(parameterType));
}
}
}
expressions.add(cacheExpression);
}
}
specialization.setCaches(expressions);
if (specialization.hasErrors()) {
return;
}
// verify that cache expressions are bound in the correct order.
for (int i = 0; i < expressions.size(); i++) {
CacheExpression currentExpression = expressions.get(i);
Set<VariableElement> boundVariables = currentExpression.getExpression().findBoundVariableElements();
for (int j = i + 1; j < expressions.size(); j++) {
CacheExpression boundExpression = expressions.get(j);
if (boundVariables.contains(boundExpression.getParameter().getVariableElement())) {
currentExpression.addError("The initializer expression of parameter '%s' binds unitialized parameter '%s. Reorder the parameters to resolve the problem.", currentExpression.getParameter().getLocalName(), boundExpression.getParameter().getLocalName());
break;
}
}
}
}
use of com.oracle.truffle.dsl.processor.expression.DSLExpression in project graal by oracle.
the class NodeParser method initializeGuards.
private void initializeGuards(SpecializationData specialization, DSLExpressionResolver resolver) {
final TypeMirror booleanType = context.getType(boolean.class);
List<String> guardDefinitions = ElementUtils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "guards");
List<GuardExpression> guardExpressions = new ArrayList<>();
for (String guard : guardDefinitions) {
GuardExpression guardExpression;
DSLExpression expression = null;
try {
expression = DSLExpression.parse(guard);
expression.accept(resolver);
guardExpression = new GuardExpression(specialization, expression);
if (!ElementUtils.typeEquals(expression.getResolvedType(), booleanType)) {
guardExpression.addError("Incompatible return type %s. Guards must return %s.", ElementUtils.getSimpleName(expression.getResolvedType()), ElementUtils.getSimpleName(booleanType));
}
} catch (InvalidExpressionException e) {
guardExpression = new GuardExpression(specialization, null);
guardExpression.addError("Error parsing expression '%s': %s", guard, e.getMessage());
}
guardExpressions.add(guardExpression);
}
specialization.setGuards(guardExpressions);
}
use of com.oracle.truffle.dsl.processor.expression.DSLExpression in project graal by oracle.
the class NodeParser method initializeLimit.
private void initializeLimit(SpecializationData specialization, DSLExpressionResolver resolver) {
AnnotationValue annotationValue = ElementUtils.getAnnotationValue(specialization.getMessageAnnotation(), "limit");
String limitValue;
if (annotationValue == null) {
limitValue = "";
} else {
limitValue = (String) annotationValue.getValue();
}
if (limitValue.isEmpty()) {
limitValue = "3";
} else if (!specialization.hasMultipleInstances()) {
specialization.addWarning(annotationValue, "The limit expression has no effect. Multiple specialization instantiations are impossible for this specialization.");
return;
}
TypeMirror expectedType = context.getType(int.class);
try {
DSLExpression expression = DSLExpression.parse(limitValue);
expression.accept(resolver);
if (!ElementUtils.typeEquals(expression.getResolvedType(), expectedType)) {
specialization.addError(annotationValue, "Incompatible return type %s. Limit expressions must return %s.", ElementUtils.getSimpleName(expression.getResolvedType()), ElementUtils.getSimpleName(expectedType));
}
if (specialization.isDynamicParameterBound(expression)) {
specialization.addError(annotationValue, "Limit expressions must not bind dynamic parameter values.");
}
specialization.setLimitExpression(expression);
} catch (InvalidExpressionException e) {
specialization.addError(annotationValue, "Error parsing expression '%s': %s", limitValue, e.getMessage());
}
}
use of com.oracle.truffle.dsl.processor.expression.DSLExpression in project graal by oracle.
the class FlatNodeGenFactory method createMethodGuardCheck.
private IfTriple createMethodGuardCheck(FrameState frameState, SpecializationData specialization, GuardExpression guard, NodeExecutionMode mode) {
DSLExpression expression = guard.getExpression();
Map<Variable, CodeTree> resolvedBindings = castBoundTypes(bindExpressionValues(frameState, expression, specialization));
CodeTree init = null;
CodeTree expressionCode = DSLExpressionGenerator.write(expression, null, resolvedBindings);
if (mode.isGuardFallback()) {
GuardExpression guardWithBit = getGuardThatNeedsStateBit(specialization, guard);
if (guardWithBit != null) {
CodeTreeBuilder builder = new CodeTreeBuilder(null);
builder.string("(");
builder.tree(state.createNotContains(frameState, new Object[] { guardWithBit }));
builder.string(" || ");
builder.tree(expressionCode);
builder.string(")");
expressionCode = builder.build();
fallbackNeedsState = true;
}
}
// overrule with assertion
CodeTree assertion = null;
if (mode.isFastPath() || mode.isGuardFallback()) {
if (!specialization.isDynamicParameterBound(expression)) {
assertion = CodeTreeBuilder.createBuilder().startAssert().tree(expressionCode).end().build();
expressionCode = null;
}
} else {
if (guard.isConstantTrueInSlowPath(context)) {
assertion = CodeTreeBuilder.createBuilder().startStatement().string("// assert ").tree(expressionCode).end().build();
expressionCode = null;
}
}
return new IfTriple(init, expressionCode, assertion);
}
use of com.oracle.truffle.dsl.processor.expression.DSLExpression in project graal by oracle.
the class SpecializationData method isGuardBindsCache.
public boolean isGuardBindsCache() {
if (!getCaches().isEmpty() && !getGuards().isEmpty()) {
for (GuardExpression guard : getGuards()) {
DSLExpression guardExpression = guard.getExpression();
Set<VariableElement> boundVariables = guardExpression.findBoundVariableElements();
if (isDynamicParameterBound(guardExpression)) {
for (CacheExpression cache : getCaches()) {
if (boundVariables.contains(cache.getParameter().getVariableElement())) {
return true;
}
}
}
}
}
return false;
}
Aggregations