Somehow I can't imagine that constants influence the asm code in any way. Isn't a constant something like a simple macro that is immediately replaced with its value when the code is read?mk-soft wrote:PureBasic is a one-pass compiler, so there may be one PUSH/POP too many when using constants.
[NOT] Optimizing compiler
Re: [NOT] Optimizing compiler
sorry for my bad english
Re: [NOT] Optimizing compiler
This might be more to your liking...
PureBasic is a one-pass compiler, so there may be one PUSH/POP too many when using it.
Re: [NOT] Optimizing compiler
The problem is that PureBasic has always been focused on compilation speed and being a fast one-pass compiler. This means little things like useless PUSH/POPs get ignored, and we have to Declare procedures, and uncalled procedures sometimes get included for absolutely no reason (depending on their code). A fast compilation speed may have been a nice selling point a decade ago, but computers are sufficiently fast enough these days that a two-pass compiler should be the norm, so we get less bloat due to better peephole optimization, and not have to worry about Declaring procedures, or that uncalled procedures will be included. I know hell will freeze over before this happens, but just wanted to give my two cents.
Re: [NOT] Optimizing compiler
@BarryG
100% agree. A 2-pass compiler must be the norm. For PB too. It's advantages are too many.
Also, it is sad the PB choose to use null-terminated pure c-strings instead of a handy length prefix. This makes string processing slow.
banned c functions: strcpy, strcat, strncpy, strncat, sprintf, vsprintf, gmtime, localtime, ctime, ctime_r, asctime, asctime_r
https://news.ycombinator.com/item?id=26347867
"For reasons that were never clearly articulated, the prefix approach was considered odd, backwards, and to have numerous downsides, at least where I learned C. In hindsight, I can only cringe at that attitude. Strings as added in later Pascal, about 40 years ago now, were memory safe in a way that C strings still are not."
"In the case of C, it's a design decision Denis Ritchie made that came down to the particular instruction set of PDP-11, that could efficiently process zero terminated strings.
So a severely memory limited architecture of the 70s led to blending of data with control - which is never a safe idea, see naked SQL."
"Whenever I review C code, I first look at the string function uses. Almost always I'll find a bug. It's usually an off by one error dealing with the terminating 0. It's also always a tangled bit of code, and slow due to repeatedly running strlen.
But strings in BASIC are so simple. They just work. I decided when designing D that it wouldn't be good unless string handling was as easy as in BASIC."
Anyway, the topic is not helpful in anyway without specific details.
100% agree. A 2-pass compiler must be the norm. For PB too. It's advantages are too many.
Also, it is sad the PB choose to use null-terminated pure c-strings instead of a handy length prefix. This makes string processing slow.
banned c functions: strcpy, strcat, strncpy, strncat, sprintf, vsprintf, gmtime, localtime, ctime, ctime_r, asctime, asctime_r
https://news.ycombinator.com/item?id=26347867
"For reasons that were never clearly articulated, the prefix approach was considered odd, backwards, and to have numerous downsides, at least where I learned C. In hindsight, I can only cringe at that attitude. Strings as added in later Pascal, about 40 years ago now, were memory safe in a way that C strings still are not."
"In the case of C, it's a design decision Denis Ritchie made that came down to the particular instruction set of PDP-11, that could efficiently process zero terminated strings.
So a severely memory limited architecture of the 70s led to blending of data with control - which is never a safe idea, see naked SQL."
"Whenever I review C code, I first look at the string function uses. Almost always I'll find a bug. It's usually an off by one error dealing with the terminating 0. It's also always a tangled bit of code, and slow due to repeatedly running strlen.
But strings in BASIC are so simple. They just work. I decided when designing D that it wouldn't be good unless string handling was as easy as in BASIC."
Anyway, the topic is not helpful in anyway without specific details.
Re: [NOT] Optimizing compiler
Sadly, this cannot hold true for any language.Everything wrote:PB is almost perfect and I want to remove the word "almost".
If you are satisfied no matter what, shame on you![]()

Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel 

Re: [NOT] Optimizing compiler
I also looked into this once and never found procedures included for no reason. As soon as you have created a reference to a procedure, it will always be included, because a compiler simply cannot determine whether the procedure will be accessed by the reference at runtime.BarryG wrote:... and uncalled procedures sometimes get included for absolutely no reason (depending on their code).
I would also prefer a two-pass compiler, but you can't make the one-pass compiler responsible for everything that has nothing to do with this.
sorry for my bad english
Re: [NOT] Optimizing compiler
A one-pass compiler can't, but a two-pass compiler can - I coded one in the past for PureBasic as a test, so I know with 100% certainty that it works. A two-pass compiler can easily see that there are no calls to the procedure below, and therefore the compiler simply doesn't include that procedure on the second pass (as if it was commented out, or removed). That's what my two-pass compiler did, and it worked great. I really need to write it again.Josh wrote:a compiler simply cannot determine whether the procedure will be accessed by the reference at runtime
Code: Select all
Procedure Never_Called_But_Included()
MessageRequester("This is in the compiled exe","")
EndProcedure
Re: [NOT] Optimizing compiler
Did you even read what I wrote?
Here is just a simple example where the compiler could theoretically still determine whether the procedure is called or not. But just change the value of the variable 'a'. This value could come from anywhere, then the compiler can't determine for sure if the procedure is called or not.
I think in Pb is only one possibility that a procedure is included without a need. If a procedure is called in a procedure that itself is never called. But I can live with this exceptional case, because this additional procedure has no negative impact on the program.
The compiler can't do miracles. But if your self-written two-pass compiler can do that, why don't you use it?
No, no compiler can do that, no matter if one-pass or two-pass compiler. If the procedure is called by reference, the access is determined only at runtime. How should the compiler know then?BarryG wrote:A one-pass compiler can't, but a two-pass compiler canJosh wrote:a compiler simply cannot determine whether the procedure will be accessed by the reference at runtime
Code: Select all
a = 5
Procedure MyProc()
MessageRequester ("", "Procedure called")
EndProcedure
x = @Myproc()
y = x + 2
y + a
CallFunctionFast (y-7)
I think in Pb is only one possibility that a procedure is included without a need. If a procedure is called in a procedure that itself is never called. But I can live with this exceptional case, because this additional procedure has no negative impact on the program.
The compiler can't do miracles. But if your self-written two-pass compiler can do that, why don't you use it?
sorry for my bad english
Re: [NOT] Optimizing compiler
In your example, my two-pass compiler would've included the procedure due to the "x = @Myproc()" line. If that line wasn't there, then my two-pass compiler would've omitted the "Myproc" procedure entirely. That's what I mean. No different to how a human optimizing the source would decide to omit the procedure if the "x = @Myproc()" line wasn't there. So when I say "called procedure", I don't mean conditionally called as you showed; I simply mean a call to the procedure anywhere in the source code - whether it's ever done at runtime or not.
Re: [NOT] Optimizing compiler
This is exactly what the Pb compiler does and even manages this in one pass. If the procedure is not called anywhere, it is not included in the exe.BarryG wrote:In your example, my two-pass compiler would've included the procedure due to the "x = @Myproc()" line. If that line wasn't there, then my two-pass compiler would've omitted the "Myproc" procedure entirely.
sorry for my bad english
Re: [NOT] Optimizing compiler
Where pb falls short on the "included procedures" front is the simplistic method it uses, which is just a flag indicating if it's "referenced anywhere". Some compilers use a call tree, which allows it to omit called procedures if the call is in an uncalled procedure. This is easy when it's two pass. (But you clearly can't use that method for libraries you compile ahead of time... Nor when only compiling files that have changed, like Ninja [as opposed to Make].)
Re: [NOT] Optimizing compiler
Not true. Obsolete code inside an uncalled procedure can sometimes be included in the exe. My other post (with MessageRequester) clearly and demonstrably shows this.Josh wrote:If the procedure is not called anywhere, it is not included in the exe.
Here's another example: the following code creates a 148 KB executable, because the unused code inside the uncalled procedure with the PNG commands is included.
Remove the procedure, like you would if manually optimizing the code by hand, and the executable becomes a tiny 5 KB instead.
Code: Select all
Procedure Never_Used()
UsePNGImageEncoder()
UsePNGImageDecoder()
; Assume an image load routine is here.
; I haven't coded it for this example.
EndProcedure
MessageRequester("Hi","This exe is huge for no reason!")
Re: [NOT] Optimizing compiler
What I have written in my post yesterday 12:24?BarryG wrote:Not true. Obsolete code inside an uncalled procedure can ...Josh wrote:If the procedure is not called anywhere, it is not included in the exe.
This also applies to my statementBarryG wrote:So when I say "called procedure", I don't mean conditionally called as you showed; I simply mean a call to the procedure anywhere in the source code - whether it's ever done at runtime or not.
sorry for my bad english
Re: [NOT] Optimizing compiler
UsePNGImageEncoder is not a function, but a compiler directive that the encoder is linked. Therefore, this has nothing to do within a procedure, but must only be entered before the first use.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: [NOT] Optimizing compiler
You could try pbOptimizer, although there aren't many ASM optimizations yet (like removing PUSH/POP). Maybe I'll add them later?!Everything wrote:Is it possible to do something else in the field of code optimization?
Et cetera is my worst enemy