use of com.oracle.truffle.dsl.processor.model.Parameter in project graal by oracle.
the class MethodSpecParser method parseParametersRequired.
private static List<Parameter> parseParametersRequired(MethodSpec spec, List<VariableElement> types, boolean typeVarArgs) {
List<Parameter> parsedParams = new ArrayList<>();
List<ParameterSpec> specifications = spec.getRequired();
boolean specVarArgs = spec.isVariableRequiredParameters();
int typeIndex = 0;
int specificationIndex = 0;
ParameterSpec specification;
while ((specification = nextSpecification(specifications, specificationIndex, specVarArgs)) != null) {
VariableElement actualType = nextActualType(types, typeIndex, typeVarArgs);
if (actualType == null) {
if (spec.isIgnoreAdditionalSpecifications()) {
break;
}
return null;
}
int typeVarArgsIndex = typeVarArgs ? typeIndex - types.size() + 1 : -1;
int specVarArgsIndex = specVarArgs ? specificationIndex - specifications.size() + 1 : -1;
if (typeVarArgsIndex >= 0 && specVarArgsIndex >= 0) {
// we would get into an endless loop if we would continue
break;
}
Parameter resolvedParameter = matchParameter(specification, actualType, specVarArgsIndex, typeVarArgsIndex);
if (resolvedParameter == null) {
return null;
}
parsedParams.add(resolvedParameter);
typeIndex++;
specificationIndex++;
}
// consume randomly ordered annotated parameters
VariableElement variable;
while ((variable = nextActualType(types, typeIndex, typeVarArgs)) != null) {
Parameter matchedParamter = matchAnnotatedParameter(spec, variable);
if (matchedParamter == null) {
break;
}
parsedParams.add(matchedParamter);
typeIndex++;
}
if (typeIndex < types.size()) {
if (spec.isIgnoreAdditionalParameters()) {
return parsedParams;
} else {
return null;
}
}
return parsedParams;
}
use of com.oracle.truffle.dsl.processor.model.Parameter 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.Parameter in project graal by oracle.
the class FlatNodeGenFactory method createExecuteAndSpecializeType.
private ExecutableTypeData createExecuteAndSpecializeType() {
SpecializationData polymorphicSpecialization = node.getPolymorphicSpecialization();
TypeMirror polymorphicType = polymorphicSpecialization.getReturnType().getType();
List<TypeMirror> parameters = new ArrayList<>();
for (Parameter param : polymorphicSpecialization.getSignatureParameters()) {
parameters.add(param.getType());
}
return new ExecutableTypeData(node, polymorphicType, "executeAndSpecialize", node.getFrameType(), parameters);
}
use of com.oracle.truffle.dsl.processor.model.Parameter in project graal by oracle.
the class FlatNodeGenFactory method createTypeCheckOrCast.
private IfTriple createTypeCheckOrCast(FrameState frameState, SpecializationGroup group, TypeGuard typeGuard, NodeExecutionMode specializationExecution, boolean castOnly, boolean forceImplicitCast) {
CodeTreeBuilder prepareBuilder = CodeTreeBuilder.createBuilder();
CodeTreeBuilder checkBuilder = CodeTreeBuilder.createBuilder();
int signatureIndex = typeGuard.getSignatureIndex();
LocalVariable value = frameState.getValue(signatureIndex);
TypeMirror targetType = typeGuard.getType();
if (!ElementUtils.needsCastTo(value.getTypeMirror(), targetType)) {
boolean foundImplicitSubType = false;
if (forceImplicitCast) {
List<ImplicitCastData> casts = typeSystem.lookupByTargetType(targetType);
for (ImplicitCastData cast : casts) {
if (ElementUtils.isSubtype(cast.getSourceType(), targetType)) {
foundImplicitSubType = true;
break;
}
}
}
if (!foundImplicitSubType) {
return null;
}
}
NodeExecutionData execution = node.getChildExecutions().get(signatureIndex);
CodeTreeBuilder castBuilder = prepareBuilder.create();
List<ImplicitCastData> sourceTypes = typeSystem.lookupByTargetType(targetType);
CodeTree valueReference = value.createReference();
if (sourceTypes.isEmpty()) {
checkBuilder.tree(TypeSystemCodeGenerator.check(typeSystem, targetType, valueReference));
castBuilder.tree(TypeSystemCodeGenerator.cast(typeSystem, targetType, valueReference));
} else {
List<SpecializationData> specializations = group.collectSpecializations();
List<Parameter> parameters = new ArrayList<>();
for (SpecializationData otherSpecialization : specializations) {
parameters.add(otherSpecialization.findParameterOrDie(execution));
}
if (specializationExecution.isFastPath() || specializationExecution.isGuardFallback()) {
CodeTree implicitState;
if (specializationExecution.isGuardFallback()) {
implicitState = CodeTreeBuilder.singleString("0b" + allsetMask(sourceTypes.size() + 1));
} else {
implicitState = state.createExtractInteger(frameState, typeGuard);
}
checkBuilder.tree(TypeSystemCodeGenerator.implicitCheckFlat(typeSystem, targetType, valueReference, implicitState));
castBuilder.tree(TypeSystemCodeGenerator.implicitCastFlat(typeSystem, targetType, valueReference, implicitState));
} else {
Parameter parameter = parameters.get(0);
String implicitStateName = createImplicitTypeStateLocalName(parameter);
CodeTree defaultValue = null;
prepareBuilder.declaration(context.getType(int.class), implicitStateName, defaultValue);
CodeTree specializeCall = TypeSystemCodeGenerator.implicitSpecializeFlat(typeSystem, targetType, valueReference);
checkBuilder.startParantheses();
checkBuilder.string(implicitStateName, " = ").tree(specializeCall);
checkBuilder.end();
checkBuilder.string(" != 0");
castBuilder.tree(TypeSystemCodeGenerator.implicitCastFlat(typeSystem, targetType, valueReference, CodeTreeBuilder.singleString(implicitStateName)));
}
}
if (castOnly) {
LocalVariable currentValue = frameState.getValue(execution);
CodeTreeBuilder localsBuilder = CodeTreeBuilder.createBuilder();
LocalVariable castVariable = currentValue.nextName().newType(typeGuard.getType()).accessWith(null);
frameState.setValue(execution, castVariable);
localsBuilder.tree(castVariable.createDeclaration(castBuilder.build()));
return new IfTriple(localsBuilder.build(), null, null);
} else {
return new IfTriple(prepareBuilder.build(), checkBuilder.build(), null);
}
}
use of com.oracle.truffle.dsl.processor.model.Parameter in project graal by oracle.
the class FlatNodeGenFactory method persistCache.
private Collection<IfTriple> persistCache(FrameState frameState, SpecializationData specialization, CacheExpression cache, CodeTree cacheValue) {
String name = createFieldName(specialization, cache.getParameter());
LocalVariable local = frameState.get(name);
CodeTree value;
if (local != null) {
// already initialized and stored don't use init.
value = local.createReference();
} else if (cacheValue == null) {
return Collections.emptyList();
} else {
value = cacheValue;
}
TypeMirror type = cache.getParameter().getType();
String frameStateInitialized = name + "$initialized";
if (frameState.getBoolean(frameStateInitialized, false)) {
return Collections.emptyList();
} else {
frameState.setBoolean(frameStateInitialized, true);
}
List<IfTriple> triples = new ArrayList<>();
CodeTreeBuilder builder = new CodeTreeBuilder(null);
Parameter parameter = cache.getParameter();
boolean useSpecializationClass = useSpecializationClass(specialization);
if (!useSpecializationClass || frameState.getBoolean(createSpecializationClassPersisted(specialization), false)) {
String insertTarget;
if (useSpecializationClass) {
insertTarget = createSpecializationLocalName(specialization);
} else {
insertTarget = "super";
}
TypeMirror nodeType = context.getType(Node.class);
TypeMirror nodeArrayType = context.getType(Node[].class);
boolean isNode = ElementUtils.isAssignable(parameter.getType(), nodeType);
boolean isNodeInterface = isNode || ElementUtils.isAssignable(type, context.getType(NodeInterface.class));
boolean isNodeArray = ElementUtils.isAssignable(type, nodeArrayType);
boolean isNodeInterfaceArray = isNodeArray || isNodeInterfaceArray(type);
if (isNodeInterface || isNodeInterfaceArray) {
builder = new CodeTreeBuilder(null);
String fieldName = createFieldName(specialization, cache.getParameter()) + "__";
String insertName = useSpecializationClass ? useInsertAccessor(specialization, !isNodeInterface) : "insert";
final TypeMirror castType;
if (isNodeInterface) {
if (isNode) {
castType = null;
} else {
castType = nodeType;
}
} else {
assert isNodeInterfaceArray;
if (isNodeArray) {
castType = null;
} else {
castType = nodeArrayType;
}
}
if (castType == null) {
CodeTreeBuilder noCast = new CodeTreeBuilder(null);
noCast.startCall(insertTarget, insertName);
noCast.tree(value);
noCast.end();
value = noCast.build();
} else {
builder.declaration(cache.getExpression().getResolvedType(), fieldName, value);
builder.startIf().string(fieldName).instanceOf(castType).end().startBlock();
builder.startStatement().startCall(insertTarget, insertName);
builder.startGroup().cast(castType).string(fieldName).end();
builder.end().end();
builder.end();
value = CodeTreeBuilder.singleString(fieldName);
}
}
}
builder.startStatement();
builder.tree(createCacheReference(frameState, specialization, cache.getParameter())).string(" = ").tree(value);
builder.end();
triples.add(new IfTriple(builder.build(), null, null));
return triples;
}
Aggregations