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.

_______________________________________________
fpc-devel maillist  -  [email protected]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to