public static enum ExplodeLoop.LoopExplosionKind extends Enum<ExplodeLoop.LoopExplosionKind>
ExplodeLoop
annotation.
continue
or a statement at the end of the loop body. The
term loop exit refers to control flow exiting the loop, such as return
or
break
. Example:
int loopEndExits() { int state = -1; for (int i = 0; i < 4; i++) { if (condition(i)) { continue; // loop end } else if (condition1(i)) { // loop exit (break) state = 2; break; } else if (condition2(i)) { // loop exit (return) state = 3; return state; } else { state = i; // loop end } } // loop exit (after last iteration) return state; }There are 4 loop explosion kinds (plus
MERGE_EXPLODE
, which is meant for bytecode
interpreters), configurable by 2 parameters: UNROLL vs EXPLODE and UNTIL_RETURN vs not.
@ExplodeLoop
void unrollVsExplodeLoop() {
int state = 1;
for (int i = 0; i < 2; i++) {
if (c(i, state)) {
state = 2;
} else {
state = 3;
}
}
}
gets unrolled with FULL_UNROLL
to:
void unrollVsExplodeLoopUnrolled() { int state = 1; if (c(0, 1)) { state = 2; } else { state = 3; } if (c(1, state)) { state = 2; } else { state = 3; } }and exploded with
FULL_EXPLODE
to:
void unrollVsExplodeLoopExploded() { int state = 1; if (c(0, 1)) { if (c(1, 2)) { state = 2; } else { state = 3; } } else { if (c(1, 3)) { state = 2; } else { state = 3; } } }
@ExplodeLoop
int untilReturnLoop() {
for (int i = 0; i < 2; i++) {
if (condition(i)) {
// exit1
return f(i);
}
}
// exit2
return fallback();
}
is expanded with FULL_UNROLL_UNTIL_RETURN
to:
int untilReturn() { if (condition(0)) { return f(0); } if (condition(1)) { return f(1); } return fallback(); }while
FULL_UNROLL
merges loop exits:
int notUntilReturn() { int i; for (;;) { if (condition(0)) { i = 0; break; } if (condition(1)) { i = 1; break; } return fallback(); } return f(i); }
break
statements inside the loop will duplicate code after the loop since
they add new loop exits:
@ExplodeLoop
int breaksLoop() {
int state = -1;
for (int i = 0; i < 2; i++) {
if (condition1(i)) {
return f(i);
} else if (condition2(i)) {
state = i;
break;
}
}
return fallback(state);
}
is expanded with FULL_UNROLL_UNTIL_RETURN
to:
int breaksLoopUnrollUntilReturn() { if (condition1(0)) { return f(0); } else if (condition2(0)) { return fallback(0); } if (condition1(1)) { return f(1); } else if (condition2(1)) { return fallback(1); } return fallback(-1); }
Enum.EnumDesc<E extends Enum<E>>
Enum Constant and Description |
---|
FULL_EXPLODE
Fully explode all loops.
|
FULL_EXPLODE_UNTIL_RETURN
Like
ExplodeLoop.LoopExplosionKind.FULL_EXPLODE , but in addition explosion does not stop at loop exits. |
FULL_UNROLL
Fully unroll all loops.
|
FULL_UNROLL_UNTIL_RETURN
Like
ExplodeLoop.LoopExplosionKind.FULL_UNROLL , but in addition loop unrolling duplicates loop exits in every
iteration instead of merging them. |
MERGE_EXPLODE
like
ExplodeLoop.LoopExplosionKind.FULL_EXPLODE , but copies of the loop body that have the exact same state
(all local variables have the same value) are merged. |
Modifier and Type | Method and Description |
---|---|
static ExplodeLoop.LoopExplosionKind |
valueOf(String name)
Returns the enum constant of this type with the specified name.
|
static ExplodeLoop.LoopExplosionKind[] |
values()
Returns an array containing the constants of this enum type, in
the order they are declared.
|
public static final ExplodeLoop.LoopExplosionKind FULL_UNROLL
public static final ExplodeLoop.LoopExplosionKind FULL_UNROLL_UNTIL_RETURN
ExplodeLoop.LoopExplosionKind.FULL_UNROLL
, but in addition loop unrolling duplicates loop exits in every
iteration instead of merging them. Code after a loop exit is duplicated for every loop
exit and every loop iteration. For example, a loop with 4 iterations and 2 loop exits
(exit1 and exit2, where exit1 is an early return inside a loop, such as
untilReturnLoop()
) leads to 4 copies of the loop body and 4
copies of exit1 and 1 copy of exit2. After each exit all code until a return is
duplicated per iteration. Beware of break statements inside loops since they cause
additional loop exits leading to code duplication along exit2.public static final ExplodeLoop.LoopExplosionKind FULL_EXPLODE
public static final ExplodeLoop.LoopExplosionKind FULL_EXPLODE_UNTIL_RETURN
ExplodeLoop.LoopExplosionKind.FULL_EXPLODE
, but in addition explosion does not stop at loop exits. Code
after the loop is duplicated for every loop exit of every loop iteration. For example, a
loop with 4 iterations and 2 loop exits leads to 4 * 2 = 8 copies of the code after the
loop.public static final ExplodeLoop.LoopExplosionKind MERGE_EXPLODE
ExplodeLoop.LoopExplosionKind.FULL_EXPLODE
, but copies of the loop body that have the exact same state
(all local variables have the same value) are merged. This reduces the number of copies
necessary, but can introduce loops again. This kind is useful for bytecode interpreter
loops.public static ExplodeLoop.LoopExplosionKind[] values()
public static ExplodeLoop.LoopExplosionKind valueOf(String name)
name
- the name of the enum constant to be returned.IllegalArgumentException
- if this enum type has no constant with the specified nameNullPointerException
- if the argument is null