use of com.oracle.truffle.dsl.processor.model.SpecializationData in project graal by oracle.
the class FlatNodeGenFactory method accessesCachedState.
private static boolean accessesCachedState(List<SpecializationData> specializations) {
final AtomicBoolean needsState = new AtomicBoolean(false);
for (final SpecializationData specialization : specializations) {
if (!specialization.getAssumptionExpressions().isEmpty()) {
needsState.set(true);
break;
}
for (GuardExpression expression : specialization.getGuards()) {
expression.getExpression().accept(new DSLExpressionVisitor() {
public void visitVariable(Variable binary) {
if (!needsState.get() && isVariableAccessMember(binary)) {
needsState.set(true);
}
}
private boolean isVariableAccessMember(Variable variable) {
if (variable.getName().equals("null") && variable.getReceiver() == null) {
return false;
}
Parameter p = specialization.findByVariable(variable.getResolvedVariable());
if (p == null && !variable.getResolvedVariable().getModifiers().contains(STATIC)) {
DSLExpression receiver = variable.getReceiver();
if (receiver instanceof Variable) {
return isVariableAccessMember((Variable) receiver);
} else if (receiver instanceof Call) {
return isMethodAccessMember((Call) receiver);
}
return true;
} else if (p != null && p.getSpecification().isCached()) {
return true;
}
return false;
}
public void visitBooleanLiteral(BooleanLiteral binary) {
}
public void visitNegate(Negate negate) {
}
public void visitIntLiteral(IntLiteral binary) {
}
private boolean isMethodAccessMember(Call call) {
if (!call.getResolvedMethod().getModifiers().contains(STATIC)) {
DSLExpression receiver = call.getReceiver();
if (receiver instanceof Variable) {
return isVariableAccessMember((Variable) receiver);
} else if (receiver instanceof Call) {
return isMethodAccessMember((Call) receiver);
}
return true;
}
return false;
}
public void visitCall(Call call) {
if (!needsState.get() && isMethodAccessMember(call)) {
needsState.set(true);
}
}
public void visitBinary(Binary binary) {
}
});
}
}
boolean needsStat = needsState.get();
return needsStat;
}
use of com.oracle.truffle.dsl.processor.model.SpecializationData in project graal by oracle.
the class NodeParser method initializeFallbackReachability.
private static void initializeFallbackReachability(NodeData node) {
List<SpecializationData> specializations = node.getSpecializations();
SpecializationData fallback = null;
for (int i = specializations.size() - 1; i >= 0; i--) {
SpecializationData specialization = specializations.get(i);
if (specialization.isFallback() && specialization.getMethod() != null) {
fallback = specialization;
break;
}
}
if (fallback == null) {
// no need to compute reachability
return;
}
for (int index = 0; index < specializations.size(); index++) {
SpecializationData specialization = specializations.get(index);
SpecializationData lastReachable = specialization;
for (int searchIndex = index + 1; searchIndex < specializations.size(); searchIndex++) {
SpecializationData search = specializations.get(searchIndex);
if (search == fallback) {
// reached the end of the specialization
break;
}
assert lastReachable != search;
if (!lastReachable.isReachableAfter(search)) {
lastReachable = search;
} else if (search.getReplaces().contains(specialization)) {
lastReachable = search;
}
}
specialization.setReachesFallback(lastReachable == specialization);
List<SpecializationData> failedSpecializations = null;
if (specialization.isReachesFallback() && !specialization.getCaches().isEmpty() && !specialization.getGuards().isEmpty()) {
boolean guardBoundByCache = false;
for (GuardExpression guard : specialization.getGuards()) {
if (specialization.isGuardBoundWithCache(guard)) {
guardBoundByCache = true;
break;
}
}
if (guardBoundByCache && specialization.getMaximumNumberOfInstances() > 1) {
if (failedSpecializations == null) {
failedSpecializations = new ArrayList<>();
}
failedSpecializations.add(specialization);
}
}
if (failedSpecializations != null) {
List<String> specializationIds = failedSpecializations.stream().map((e) -> e.getId()).collect(Collectors.toList());
fallback.addError("Some guards for the following specializations could not be negated for the @%s specialization: %s. " + "Guards cannot be negated for the @%s when they bind @%s parameters and the specialization may consist of multiple instances. " + "To fix this limit the number of instances to '1' or " + "introduce a more generic specialization declared between this specialization and the fallback. " + "Alternatively the use of @%s can be avoided by declaring a @%s with manually specified negated guards.", Fallback.class.getSimpleName(), specializationIds, Fallback.class.getSimpleName(), Cached.class.getSimpleName(), Fallback.class.getSimpleName(), Specialization.class.getSimpleName());
}
}
}
use of com.oracle.truffle.dsl.processor.model.SpecializationData in project graal by oracle.
the class NodeParser method collectIncludes.
private void collectIncludes(SpecializationData specialization, Set<SpecializationData> found, Set<SpecializationData> visited) {
if (visited.contains(specialization)) {
// circle found
specialization.addError("Circular replaced specialization '%s' found.", specialization.createReferenceName());
return;
}
visited.add(specialization);
for (SpecializationData included : specialization.getReplaces()) {
collectIncludes(included, found, new HashSet<>(visited));
found.add(included);
}
}
use of com.oracle.truffle.dsl.processor.model.SpecializationData in project graal by oracle.
the class NodeParser method initializeReplaces.
private static void initializeReplaces(NodeData node) {
for (SpecializationData specialization : node.getSpecializations()) {
Set<SpecializationData> resolvedSpecializations = specialization.getReplaces();
resolvedSpecializations.clear();
Set<String> includeNames = specialization.getReplacesNames();
for (String includeName : includeNames) {
// TODO reduce complexity of this lookup.
SpecializationData foundSpecialization = lookupSpecialization(node, includeName);
AnnotationValue value = ElementUtils.getAnnotationValue(specialization.getMarkerAnnotation(), "replaces");
if (value == null) {
// TODO remove if deprecated api was removed.
value = ElementUtils.getAnnotationValue(specialization.getMarkerAnnotation(), "contains");
}
if (foundSpecialization == null) {
specialization.addError(value, "The referenced specialization '%s' could not be found.", includeName);
} else {
if (foundSpecialization.compareTo(specialization) > 0) {
if (foundSpecialization.compareTo(specialization) > 0) {
specialization.addError(value, "The replaced specialization '%s' must be declared before the replacing specialization.", includeName);
}
}
resolvedSpecializations.add(foundSpecialization);
}
}
}
}
use of com.oracle.truffle.dsl.processor.model.SpecializationData in project graal by oracle.
the class NodeParser method createGenericSpecialization.
private SpecializationData createGenericSpecialization(final NodeData node) {
FallbackParser parser = new FallbackParser(context, node);
MethodSpec specification = parser.createDefaultMethodSpec(node.getSpecializations().iterator().next().getMethod(), null, true, null);
List<VariableElement> parameterTypes = new ArrayList<>();
int signatureIndex = 1;
for (ParameterSpec spec : specification.getRequired()) {
parameterTypes.add(new CodeVariableElement(createGenericType(node, spec), "arg" + signatureIndex));
if (spec.isSignature()) {
signatureIndex++;
}
}
TypeMirror returnType = createGenericType(node, specification.getReturnType());
SpecializationData generic = parser.create("Generic", TemplateMethod.NO_NATURAL_ORDER, null, null, returnType, parameterTypes);
if (generic == null) {
throw new RuntimeException("Unable to create generic signature for node " + node.getNodeId() + " with " + parameterTypes + ". Specification " + specification + ".");
}
return generic;
}
Aggregations