would this optimize better?
function Foo:pointer;
begin
Result:=function1;
if Result<>nil then exit;
Result:=function2;
if Result<>nil then exit;
Result:=function3;
if Result<>nil then exit;
Result:=function4;
if Result<>nil then exit;
end;
Within the controllable factors, probably similar to the nested begin/end.
However, it inverts the comparison logic (if the compiler does not internally change it in either version).
This may affects the branch predictor. And if so, then it depends what results are most likely by either function.
I have no idea how fpc handles this. Afaik some compilers create code that a "then" is assumed more likely than an "else" (though not sure, what is in absence of an "else").
So then (if code is indeed generated in such way) the question is at which percentage does each procedure return nil or non-nil. And therefore how often the branch predictor gets it right.
Again, on any modern CPU the difference will be nano second, if at all. You need to run millions (if not billions) of iterations to get a measurable difference. But if you run that code such often, you also spent time in the called functions that often => assuming that they are actually doing work they will consume much more time. So in terms of time gained, you are talking tiny fractions of a percent.
The real optimization potential may lay elsewhere.
For example if each of the called functions would start something like
function func_n: Pointer;
begin
If SomeVal <> CONST_EXP then exit(nil);
//... lots of code to process
Then you may (in many, but not all cases) want that condition to be executed before the function is called.
But you don't necessarily want to copy and paste it to every place where the function is called...
So you do
function func_n: Pointer; INLINE;
begin
If SomeVal <> CONST_EXP then exit(nil);
result := Internally_do_func_n;
end;
function Internally_do_func_n: Pointer;
begin
//... lots of code to process
So then the compiler can inline that one condition for you.
Again, even for this, you need the code to be called many times in a loop, or you wont notice the difference.
And also, it only makes sense, if the condition has some likelihood of returning without calling the Internally_do_func_n.
Otherwise you make the code on the caller site larger => And increasing the size of a loop body can (sometimes) also be slowing things down.