use of com.dat3m.dartagnan.configuration.OptionNames.BOUND in project Dat3M by hernanponcedeleon.
the class LoopUnrolling method unrollLoop.
private void unrollLoop(CondJump loopBackJump, int bound) {
Label loopBegin = loopBackJump.getLabel();
Preconditions.checkArgument(bound >= 1, "Positive unrolling bound expected.");
Preconditions.checkArgument(loopBegin.getOId() < loopBackJump.getOId(), "The jump does not belong to a loop.");
Preconditions.checkArgument(loopBackJump.getUId() < 0, "The loop has already been unrolled");
// (1) Collect continue points of the loop
List<CondJump> continues = new ArrayList<>();
for (Event e = loopBegin; e != null && e != loopBackJump; e = e.getSuccessor()) {
if (e instanceof CondJump && ((CondJump) e).getLabel() == loopBegin) {
continues.add((CondJump) e);
}
}
continues.add(loopBackJump);
// (2) Collect forward jumps from the outside into the loop
List<CondJump> enterJumps = new ArrayList<>();
for (Event e = loopBegin; e != null && e != loopBackJump; e = e.getSuccessor()) {
if (e instanceof Label) {
Label label = (Label) e;
label.getJumpSet().stream().filter(j -> j.getOId() < loopBegin.getOId()).forEach(enterJumps::add);
}
}
int iterCounter = 0;
while (--bound >= 0) {
iterCounter++;
if (bound == 0) {
Label exit = (Label) loopBackJump.getThread().getExit();
loopBegin.setName(loopBegin.getName() + "_" + iterCounter);
for (CondJump cont : continues) {
if (!cont.isGoto()) {
logger.warn("Conditional jump {} was replaced by unconditional bound event", cont);
}
CondJump boundEvent = EventFactory.newGoto(exit);
// Keep tags of original jump.
boundEvent.addFilters(cont.getFilters());
boundEvent.addFilters(Tag.BOUND, Tag.NOOPT);
cont.getPredecessor().setSuccessor(boundEvent);
boundEvent.setSuccessor(cont.getSuccessor());
cont.delete();
}
} else {
Map<Event, Event> copyCtx = new HashMap<>();
List<Event> copies = copyPath(loopBegin, loopBackJump, copyCtx);
((Label) copyCtx.get(loopBegin)).setName(loopBegin.getName() + "_" + iterCounter);
// Insert copies at right place
loopBegin.getPredecessor().setSuccessor(copies.get(0));
copies.get(copies.size() - 1).setSuccessor(loopBegin);
// Update entering jumps to go to the copies.
for (CondJump enterJump : enterJumps) {
enterJump.updateReferences(copyCtx);
}
enterJumps.clear();
// All "continues" that were copied need to get updated to jump forward to the next iteration.
for (CondJump cont : continues) {
if (cont == loopBackJump) {
continue;
}
CondJump copy = (CondJump) copyCtx.get(cont);
copy.updateReferences(Map.of(copy.getLabel(), loopBegin));
enterJumps.add(cont);
}
}
}
}
Aggregations