In the code
if true then begin
write(1);
end
else begin
write(2);
end;the "else" block will not generate code (at least O2 and higher).
But
TFoo = class
procedure MyFoo;
end;
X = class(TFoo)
end;
//if @X.MyFoo = @TFoo.MyFoo then begin
if @TFoo.MyFoo = @TFoo.MyFoo then begin
write(1);
end
else begin
write(2);
end;Does not detect this at compile time.
Note, that this is not on an instance, this is on the actual class => so it is known.
Is there any way to get that optimize the "else" block away (or the "then" if the compare goes the other way)?
I can't just compare the classes, as subclasses can have the same method (if it isn't overridden/reintroduced)
Background:
This seems useless in the above example.
But I want to to that in a generic, and I am testing if the method on the generic param is the same method as on a specific known class.
The best part is, that in the specialized generic (probably by the peephole opt) the asm goes
# if @A.MyFoo = @TFoo.MyFoo then begin
leaq P$PROJECT1$_$TFOO_$__$$_MYFOO(%rip),%rax cmpq %rax,%rax
jne .Lj14
And rax is always equal to rax, so the conditional jump always does the same. But it still is a conditional jump (though I guess the branch prediction in the CPU will be overjoyed).
----------------------------------------------
program project1;
{$Mode objfpc}
type
TFoo = class
procedure MyFoo;
end;
TFoo2 = class
procedure MyFoo;
end;
generic TBar<A> = class
procedure MyBar;
end;
procedure TFoo.MyFoo;
begin
write;
end;
procedure TFoo2.MyFoo;
begin
write;
end;
procedure TBar.MyBar;
begin
if @A.MyFoo = @TFoo.MyFoo then begin
write(1);
end
else begin
write(2);
end;
end;
type
X = class(TFoo) end;
TB1 = specialize TBar<TFoo>;
TB2 = specialize TBar<TFoo2>;
procedure xyz;
begin
//if @X.MyFoo = @TFoo.MyFoo then begin
if @TFoo.MyFoo = @TFoo.MyFoo then begin
write(1);
end
else begin
write(2);
end;
end;
procedure xyz2;
begin
if true then begin
write(1);
end
else begin
write(2);
end;
end;
var
b1: TB1;
b2: TB2;
begin
xyz;
xyz2;
b1.MyBar;
b2.MyBar;
end.