Unreachability
Paul Sandoz
paul.sandoz at oracle.com
Wed Oct 16 20:18:40 UTC 2024
Hi,
Gary encountered an issue when transforming say:
@CodeReflection
public static float f(float input) {
if (input >= 0f) {
return 1f;
} else {
return 0f;
}
// Unreachable
}
Compiler produced model:
func @"f" @loc="10:5:..." (%0 : float)float -> {
%1 : Var<float> = var %0 @"input" @loc="10:5";
java.if @loc="13:9"
()boolean -> {
%2 : float = var.load %1 @loc="13:13";
%3 : float = constant @"0.0" @loc="13:22";
%4 : boolean = ge %2 %3 @loc="13:13";
yield %4 @loc="13:9";
}
()void -> {
%5 : float = constant @"1.0" @loc="14:20";
return %5 @loc="14:13";
}
()void -> {
%6 : float = constant @"0.0" @loc="16:20";
return %6 @loc="16:13";
};
return @loc="10:5";
};
Lowered model:
func @"f" @loc="10:5:..." (%0 : float)float -> {
%1 : Var<float> = var %0 @"input" @loc="10:5";
%2 : float = var.load %1 @loc="13:13";
%3 : float = constant @"0.0" @loc="13:22";
%4 : boolean = ge %2 %3 @loc="13:13";
cbranch %4 ^block_1 ^block_2;
^block_1:
%5 : float = constant @"1.0" @loc="14:20";
return %5 @loc="14:13";
^block_2:
%6 : float = constant @"0.0" @loc="16:20";
return %6 @loc="16:13";
^block_3:
return @loc="10:5";
};
The compiler produced model is incorrect placing a return operation when it should be an unreachable operation.
There are some reminders in ReflectMethods:
CoreOp.FuncOp scanMethod() {
scan(body);
// @@@ Check if unreachable
appendTerminating(CoreOp::_return);
CoreOp.FuncOp func = CoreOp.func(name.toString(), stack.body);
func.setLocation(generateLocation(currentNode, true));
return func;
}
We need to determine if the last statement yields control or not. (It’s easy to see if we lower, as ^block_3 is never referenced.)
In this case we can know because there is no return value in scope, but generally we cannot rely upon that.
The compiler already checks this, I believe in Flow.AliveAnalyzer. However, it does not add additional information to the attributed tree - it does not need to.
Can we reuse the method Flow.aliveAfter? Although I don’t know how to get access to an instance of Env<AttrContext>. Do we get it from TypeEnvs?
Paul.
More information about the babylon-dev
mailing list