use of com.oracle.truffle.dsl.processor.parser.SpecializationGroup.TypeGuard in project graal by oracle.
the class FlatNodeGenFactory method initializeCasts.
private List<IfTriple> initializeCasts(FrameState frameState, SpecializationGroup group, DSLExpression expression, NodeExecutionMode specializationExecution) {
Set<VariableElement> boundElements = expression.findBoundVariableElements();
if (boundElements.isEmpty()) {
return Collections.emptyList();
}
List<IfTriple> triples = new ArrayList<>();
for (VariableElement variable : boundElements) {
Parameter p = group.getSpecialization().findByVariable(variable);
if (p != null) {
NodeExecutionData execution = p.getSpecification().getExecution();
if (execution != null) {
LocalVariable var = frameState.getValue(execution);
if (var == null) {
throw new AssertionError();
}
IfTriple triple = createTypeCheckOrCast(frameState, group, new TypeGuard(p.getType(), execution.getIndex()), specializationExecution, true, false);
if (triple != null) {
triples.add(triple);
}
}
}
}
return triples;
}
use of com.oracle.truffle.dsl.processor.parser.SpecializationGroup.TypeGuard in project graal by oracle.
the class FlatNodeGenFactory method createFastPathExecuteChild.
private CodeTree createFastPathExecuteChild(final CodeTreeBuilder parent, FrameState originalFrameState, FrameState frameState, final ExecutableTypeData currentType, SpecializationGroup group, NodeExecutionData execution) {
CodeTreeBuilder builder = parent.create();
LocalVariable var = frameState.getValue(execution);
if (var == null) {
TypeMirror targetType;
TypeGuard eliminatedGuard = null;
if (boxingEliminationEnabled) {
for (TypeGuard checkedGuard : group.getTypeGuards()) {
if (!ElementUtils.isPrimitive(checkedGuard.getType())) {
// no elimination for non primitive types
continue;
} else if (node.getChildExecutions().get(checkedGuard.getSignatureIndex()).getChild().findExecutableType(checkedGuard.getType()) == null) {
// type cannot be executed so it cannot be eliminated
continue;
}
if (checkedGuard.getSignatureIndex() == execution.getIndex()) {
eliminatedGuard = checkedGuard;
break;
}
}
}
if (eliminatedGuard != null) {
// we can optimize the type guard away by executing it
group.getTypeGuards().remove(eliminatedGuard);
targetType = eliminatedGuard.getType();
} else {
targetType = execution.getChild().findAnyGenericExecutableType(context).getReturnType();
}
var = frameState.createValue(execution, targetType).nextName();
LocalVariable fallbackVar;
List<TypeMirror> originalSourceTypes = typeSystem.lookupSourceTypes(targetType);
List<TypeMirror> sourceTypes = resolveOptimizedImplicitSourceTypes(execution, targetType);
if (sourceTypes.size() > 1) {
TypeGuard typeGuard = new TypeGuard(targetType, execution.getIndex());
TypeMirror generic = node.getPolymorphicSpecialization().findParameterOrDie(execution).getType();
fallbackVar = originalFrameState.createValue(execution, generic);
// we want to create the check tree in reverse order
Collections.reverse(sourceTypes);
CodeTree access = var.createReference();
boolean first = true;
for (TypeMirror sType : sourceTypes) {
if (ElementUtils.typeEquals(sType, targetType)) {
continue;
}
String localName = createSourceTypeLocalName(var, sType);
builder.declaration(sType, localName, CodeTreeBuilder.createBuilder().defaultValue(sType).build());
CodeTreeBuilder accessBuilder = builder.create();
accessBuilder.startParantheses();
accessBuilder.tree(state.createContainsOnly(frameState, originalSourceTypes.indexOf(sType), 1, new Object[] { typeGuard }, new Object[] { typeGuard }));
accessBuilder.string(" && ");
accessBuilder.tree(state.createIsNotAny(frameState, reachableSpecializationsArray));
accessBuilder.string(" ? ");
if (ElementUtils.isPrimitive(sType)) {
accessBuilder.string("(").type(generic).string(") ");
}
accessBuilder.string(localName);
accessBuilder.string(" : ");
if (first && ElementUtils.isPrimitive(targetType)) {
accessBuilder.string("(").type(generic).string(") ");
}
accessBuilder.tree(access);
accessBuilder.end();
access = accessBuilder.build();
first = false;
}
fallbackVar = fallbackVar.accessWith(access);
} else {
fallbackVar = var;
}
builder.tree(createAssignExecuteChild(originalFrameState, frameState, builder, execution, currentType, var));
frameState.setValue(execution, var);
originalFrameState.setValue(execution, fallbackVar);
}
return builder.build();
}
Aggregations