use of com.oracle.truffle.dsl.processor.model.NodeChildData in project graal by oracle.
the class CreateCastParser method createSpecification.
@Override
public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
List<String> childNames = ElementUtils.getAnnotationValueList(String.class, mirror, "value");
NodeChildData foundChild = null;
for (String childName : childNames) {
foundChild = getNode().findChild(childName);
if (foundChild != null) {
break;
}
}
TypeMirror baseType = getContext().getTruffleTypes().getNode();
if (foundChild != null) {
baseType = foundChild.getOriginalType();
}
MethodSpec spec = new MethodSpec(new ParameterSpec("child", baseType));
addDefaultFieldMethodSpec(spec);
ParameterSpec childSpec = new ParameterSpec("castedChild", baseType);
childSpec.setSignature(true);
spec.addRequired(childSpec);
return spec;
}
use of com.oracle.truffle.dsl.processor.model.NodeChildData in project graal by oracle.
the class NodeParser method initializeChildren.
@SuppressWarnings("unchecked")
private void initializeChildren(NodeData node) {
for (NodeChildData child : node.getChildren()) {
AnnotationValue executeWithValue1 = child.getExecuteWithValue();
List<AnnotationValue> executeWithValues = ElementUtils.resolveAnnotationValue(List.class, executeWithValue1);
List<NodeExecutionData> executeWith = new ArrayList<>();
for (AnnotationValue executeWithValue : executeWithValues) {
String executeWithString = ElementUtils.resolveAnnotationValue(String.class, executeWithValue);
if (child.getName().equals(executeWithString)) {
child.addError(executeWithValue1, "The child node '%s' cannot be executed with itself.", executeWithString);
continue;
}
NodeExecutionData found = null;
boolean before = true;
for (NodeExecutionData resolveChild : node.getChildExecutions()) {
if (resolveChild.getChild() == child) {
before = false;
continue;
}
if (resolveChild.getIndexedName().equals(executeWithString)) {
found = resolveChild;
break;
}
}
if (found == null) {
child.addError(executeWithValue1, "The child node '%s' cannot be executed with '%s'. The child node was not found.", child.getName(), executeWithString);
continue;
} else if (!before) {
child.addError(executeWithValue1, "The child node '%s' cannot be executed with '%s'. The node %s is executed after the current node.", child.getName(), executeWithString, executeWithString);
continue;
}
executeWith.add(found);
}
child.setExecuteWith(executeWith);
}
for (NodeChildData child : node.getChildren()) {
TypeMirror nodeType = child.getNodeType();
NodeData fieldNodeData = parseChildNodeData(node, child, ElementUtils.fromTypeMirror(nodeType));
child.setNode(fieldNodeData);
if (fieldNodeData == null || fieldNodeData.hasErrors()) {
child.addError("Node type '%s' is invalid or not a subclass of Node.", ElementUtils.getQualifiedName(nodeType));
} else {
List<ExecutableTypeData> types = child.findGenericExecutableTypes(context);
if (types.isEmpty()) {
AnnotationValue executeWithValue = child.getExecuteWithValue();
child.addError(executeWithValue, "No generic execute method found with %s evaluated arguments for node type %s and frame types %s.", child.getExecuteWith().size(), ElementUtils.getSimpleName(nodeType), ElementUtils.getUniqueIdentifiers(createAllowedChildFrameTypes(node)));
}
}
}
}
use of com.oracle.truffle.dsl.processor.model.NodeChildData in project graal by oracle.
the class NodeParser method initializeExecutableTypes.
private void initializeExecutableTypes(NodeData node) {
List<ExecutableTypeData> allExecutes = node.getExecutableTypes();
Set<String> inconsistentFrameTypes = new HashSet<>();
TypeMirror frameType = null;
for (ExecutableTypeData execute : allExecutes) {
TypeMirror frame = execute.getFrameParameter();
TypeMirror resolvedFrameType;
if (frame != null) {
resolvedFrameType = frame;
if (frameType == null) {
frameType = resolvedFrameType;
} else if (!ElementUtils.typeEquals(frameType, resolvedFrameType)) {
// found inconsistent frame types
inconsistentFrameTypes.add(ElementUtils.getSimpleName(frameType));
inconsistentFrameTypes.add(ElementUtils.getSimpleName(resolvedFrameType));
}
}
}
if (!inconsistentFrameTypes.isEmpty()) {
// ensure they are sorted somehow
List<String> inconsistentFrameTypesList = new ArrayList<>(inconsistentFrameTypes);
Collections.sort(inconsistentFrameTypesList);
node.addError("Invalid inconsistent frame types %s found for the declared execute methods. The frame type must be identical for all execute methods.", inconsistentFrameTypesList);
}
if (frameType == null) {
frameType = context.getType(void.class);
}
node.setFrameType(frameType);
boolean genericFound = false;
for (ExecutableTypeData type : node.getExecutableTypes()) {
if (!type.hasUnexpectedValue(context)) {
genericFound = true;
break;
}
}
// no generic executes
if (!genericFound) {
node.addError("No accessible and overridable generic execute method found. Generic execute methods usually have the " + "signature 'public abstract {Type} execute(VirtualFrame)' and must not throw any checked exceptions.");
}
int nodeChildDeclarations = 0;
int nodeChildDeclarationsRequired = 0;
List<NodeExecutionData> executions = node.getChildExecutions();
for (NodeExecutionData execution : executions) {
if (execution.getChild() == null) {
nodeChildDeclarationsRequired = execution.getIndex() + 1;
} else {
nodeChildDeclarations++;
}
}
List<String> requireNodeChildDeclarations = new ArrayList<>();
for (ExecutableTypeData type : allExecutes) {
if (type.getEvaluatedCount() < nodeChildDeclarationsRequired) {
requireNodeChildDeclarations.add(ElementUtils.createReferenceName(type.getMethod()));
}
}
if (!requireNodeChildDeclarations.isEmpty()) {
node.addError("Not enough child node declarations found. Please annotate the node class with addtional @NodeChild annotations or remove all execute methods that do not provide all evaluated values. " + "The following execute methods do not provide all evaluated values for the expected signature size %s: %s.", executions.size(), requireNodeChildDeclarations);
}
if (nodeChildDeclarations > 0 && executions.size() == node.getMinimalEvaluatedParameters()) {
for (NodeChildData child : node.getChildren()) {
child.addError("Unnecessary @NodeChild declaration. All evaluated child values are provided as parameters in execute methods.");
}
}
}
use of com.oracle.truffle.dsl.processor.model.NodeChildData in project graal by oracle.
the class FlatNodeGenFactory method parameterBoxingElimination.
/*
* It duplicates a group into small subgroups of specializations that don't need boxing when
* executing the children.
*/
private List<BoxingSplit> parameterBoxingElimination(SpecializationGroup group, int evaluatedcount) {
if (!boxingEliminationEnabled) {
return Collections.emptyList();
}
List<SpecializationData> allSpecializations = group.collectSpecializations();
List<Set<TypeGuard>> signatures = new ArrayList<>();
List<List<SpecializationData>> signatureSpecializations = new ArrayList<>();
for (SpecializationData specialization : allSpecializations) {
int index = -1;
List<TypeGuard> guards = new ArrayList<>();
for (Parameter p : specialization.getSignatureParameters()) {
index++;
if (!ElementUtils.isPrimitive(p.getType())) {
continue;
} else if (index < evaluatedcount) {
continue;
} else {
NodeChildData child = p.getSpecification().getExecution().getChild();
if (child != null && child.findExecutableType(p.getType()) == null) {
// type cannot be executed so it cannot be eliminated
continue;
}
}
guards.add(new TypeGuard(p.getType(), index));
}
if (!guards.isEmpty()) {
boolean directFound = false;
for (int i = 0; i < signatures.size(); i++) {
if (guards.containsAll(signatures.get(i))) {
if (signatures.get(i).containsAll(guards)) {
directFound = true;
}
signatureSpecializations.get(i).add(specialization);
}
}
if (!directFound) {
signatures.add(new LinkedHashSet<>(guards));
List<SpecializationData> specializations = new ArrayList<>();
specializations.add(specialization);
signatureSpecializations.add(specializations);
}
}
}
List<BoxingSplit> groups = new ArrayList<>();
for (int i = 0; i < signatureSpecializations.size(); i++) {
List<SpecializationData> groupedSpecialization = signatureSpecializations.get(i);
if (allSpecializations.size() == groupedSpecialization.size()) {
// contains all specializations does not make sense to group
continue;
}
Set<TypeGuard> signature = signatures.get(i);
TypeMirror[] signatureMirrors = new TypeMirror[signature.size()];
int index = 0;
for (TypeGuard typeGuard : signature) {
signatureMirrors[index] = typeGuard.getType();
index++;
}
groups.add(new BoxingSplit(SpecializationGroup.create(groupedSpecialization), signatureMirrors));
}
Collections.sort(groups, new Comparator<BoxingSplit>() {
public int compare(BoxingSplit o1, BoxingSplit o2) {
return Integer.compare(o2.primitiveSignature.length, o1.primitiveSignature.length);
}
});
return groups;
}
use of com.oracle.truffle.dsl.processor.model.NodeChildData in project graal by oracle.
the class FlatNodeGenFactory method resolveTargetExecutable.
private ExecutableTypeData resolveTargetExecutable(NodeExecutionData execution, TypeMirror target) {
NodeChildData child = execution.getChild();
if (child == null) {
return null;
}
ExecutableTypeData targetExecutable = child.findExecutableType(target);
if (targetExecutable == null) {
targetExecutable = child.findAnyGenericExecutableType(context);
}
return targetExecutable;
}
Aggregations