Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2025-10

Constant propagation: params yes, locals no -- Is it an oversight, or more complex?

1 message · 1 person ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Martin Frb
If you inline code, and call it with constants for its parameters, then
those constants are propagated through the entire inlined method.

In the example below (most opts may not be needed, but haven't yet tested...)

"foo1(11,22)" gets inlined. All 6 invocations of "random" are done with the pre-computed (compile time) constant. The 2 variable a and b do no longer exist.

In "foo2" the exact same code, but instead of 2 params, there are 2 locals. Those are unconditionally assigned with constant values. Yet the code compiles the with 2 variables, A+b and a*b are and 3.3.1

Is there something less obvious that the compiler does not know when its 2 locals? Or is that just an oversight?

I admit, at first sight, code like this is not to be expected, because the locals could be declared as const.

Except in generics. If the locals are initialized from a GEN_PARAM.

   generic foo<GP> = class

       x: GP;
       procedure some;

   end

   ...

    LocalVar := x.bar;

The param may be

    record bar: integer; end;
    record public const bar = 11; end;

----------------------------

Another curiosity (but not to bother): if the param is modified, by either of the 2 commented statements, then

- the modified value becomes a local var (ok, that probably takes more work to optimize)

- The statement ONE BEFORE the modification, no longer uses the constant, but uses the value from a local var (at least if opt REGVAR)

  That seems to be (my guess), because the register for "var a" is already loaded, and will keep its value for the modification statement.

-----------------------------

program project1;

  {$INLINE on}
  {$Optimization AUTOINLINE}
  {$Optimization REMOVEEMPTYPROCS}
  {$Optimization DFA}
  {$Optimization DEADSTORE}
  {$Optimization DEADVALUES}
  {$Optimization CONSTPROP}
  {$Optimization CSE}

procedure foo1(a,b: integer); inline;
begin
   writeln(random(a));
   writeln(random(b));
   writeln(random(a+b));
   //a:=a+1;
   //inc(a);
   writeln(random(a*2));
   writeln(random(b*2));
   writeln(random(a*b));
end;
procedure foo2();
var a,b: integer;
begin
   a:=11;
   b:=22;
   writeln(random(a));
   writeln(random(b));
   writeln(random(a+b));
   writeln(random(a*2));
   writeln(random(b*2));
   writeln(random(a*b));
end;
begin
   foo1(11,22);
   foo2();
end.

Reply by email