blob: 85d7cc74805d3923c1d992b2bb1441809af5330c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2019 Willink Transformations and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* E.D.Willink - Initial API and implementation
*******************************************************************************/
package org.eclipse.qvtd.compiler.internal.qvts2qvts.partitioner;
import java.util.List;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.qvtd.pivot.qvtschedule.Node;
/**
* DefaultPartitioningStrategy the creation of a QVTr-style suite of Partitions with activators.
*/
public class DefaultPartitioningStrategy extends AbstractPartitioningStrategy
{
protected final @NonNull List<@NonNull Node> realizedWhenNodes;
protected final List<@NonNull Node> predicatedWhenNodes;
public DefaultPartitioningStrategy(@NonNull PartitionedTransformationAnalysis partitionedTransformationAnalysis, @NonNull MappingPartitioner mappingPartitioner) {
super(partitionedTransformationAnalysis, mappingPartitioner);
assert scheduleManager.useActivators();
this.realizedWhenNodes = mappingPartitioner.getRealizedWhenNodes();
this.predicatedWhenNodes = mappingPartitioner.getPredicatedWhenNodes();
}
@Override
public @NonNull Iterable<@NonNull PartitionAnalysis> partition() {
//
// Create the partitioned regions
//
createActivatorPartition();
createWhenPartitions();
//
boolean isCyclic = transformationAnalysis.isCyclic(regionAnalysis);
boolean hasPredication = (predicatedWhenNodes.size() > 0) || (realizedWhenNodes.size() > 0);
boolean needsSpeculation = isCyclic && hasPredication; //(dispatchedTraceNodes2.isEmpty() ? !predicatedMiddleNodes.isEmpty() : !predicatedMiddleNodes.containsAll(dispatchedTraceNodes2));
if (!needsSpeculation) {
//
// If speculation is not needed just add the functionality as a single region.
//
if (newPartitionAnalyses.isEmpty()) { // i.e. a QVTr non top relation - re-use as is
createNonPartition();
}
else { // i.e. a QVTr top relation - create a residue to finish off the activator
createResidualPartition();
}
}
else { // cycles may need speculation and partitioning into isolated actions
createSpeculationPartitions();
createAssignmentPartitions();
}
check();
return newPartitionAnalyses;
}
protected void createNonPartition() {
newPartitionAnalyses.add(new NonPartitionFactory(mappingPartitioner).createPartitionAnalysis(partitionedTransformationAnalysis));
}
protected void createActivatorPartition() {
List<@NonNull Node> realizedExecutionNodes = mappingPartitioner.getRealizedExecutionNodes();
//
// Create the partitioned regions
//
if (realizedExecutionNodes.size() > 0) { // A 'single' realized "trace" node is a boring no-override top activation.
//
// Create an activator to make a QVTr top relation behave as a non-top relation.
//
newPartitionAnalyses.add(new ActivatorPartitionFactory(mappingPartitioner).createPartitionAnalysis(partitionedTransformationAnalysis));
}
}
protected void createResidualPartition() {
newPartitionAnalyses.add(new ResidualPartitionFactory(mappingPartitioner).createPartitionAnalysis(partitionedTransformationAnalysis));
}
protected void createWhenPartitions() {
if (realizedWhenNodes.size() > 0) {
newPartitionAnalyses.add(new WhenPartitionFactory(mappingPartitioner, useActivators()).createPartitionAnalysis(partitionedTransformationAnalysis));
}
}
@Override
protected boolean useActivators() {
return true;
}
}