How to Manage FB Reusable Procedures by Including Source Modules (vs. compiled modules)

Forum for discussion about the documentation project.
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: How to Manage FB Reusable Procedures by Including Source Modules (vs. compiled modules)

Post by Josep Roca »

What I'm telling you is that we don't like to write libraries. We (the PowerBasic users) are Windows programmers and almost all that we need is provided by Windows, contrarily to cross-platform compilers that have to provide tons of libraries. For the additional wrappers that we may need, working with source code is easier and much less work.

Anyway, this article simply documents an alternate way to reuse code. It is not advocating that you use it instead of libraries. Use wathever you like. Because there is not any mention in the current documentation of this use of PRIVATE to have dead code removal, I spent many time without trying FreeBasic. I don't like bloated code.
marcov
Posts: 3454
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: How to Manage FB Reusable Procedures by Including Source Modules (vs. compiled modules)

Post by marcov »

Josep Roca wrote:What I'm telling you is that we don't like to write libraries.
No, that is not what you said before. You said that you couldn't because it increased binary size. Which points to a faulty toolchain, since dead code optimization at linker level should eliminate them.

I get the feeling you are used to a system that is not very modular, and implements some compiler level deadcode elimination within a compilation unit, but not across compilation units (which is usually at the linker level).

This is simply bad tooling (read: defective compiler), and has nothing to do with liking libraries or not. Missing such crucial functionality is not necessary in this day and age.
Josep Roca wrote: We (the PowerBasic users) are Windows programmers and almost all that we need is provided by Windows, contrarily to cross-platform compilers that have to provide tons of libraries. For the additional wrappers that we may need, working with source code is easier and much less work.
I don't see what windows programming has to do with dead code elimination. Specially if you are obsessing in the single kb range, which is mostly irrelevant anyway in this multi-TB HDD age.
Anyway, this article simply documents an alternate way to reuse code. It is not advocating that you use it instead of libraries. Use wathever you like. Because there is not any mention in the current documentation of this use of PRIVATE to have dead code removal, I spent many time without trying FreeBasic. I don't like bloated code.
So in short you have found a workaround in your defective compiler. What I wonder about is why this applies both to FB and PB. Because FB uses an assembler-linker that CAN do it, also at the library level, as demonstrated by the fact that gen-gcc can do it with the same assembler/linker
Last edited by marcov on Jun 01, 2018 8:11, edited 5 times in total.
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: How to Manage FB Reusable Procedures by Including Source Modules (vs. compiled modules)

Post by fxm »

Josep Roca wrote:... there is not any mention in the current documentation of this use of PRIVATE to have dead code removal ...
Documentation updated:
KeyPgPrivate → fxm [Added that compiler removes the Private procedures that are not called]
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: How to Manage FB Reusable Procedures by Including Source Modules (vs. compiled modules)

Post by Josep Roca »

Thanks very much for the update.
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: How to Manage FB Reusable Procedures by Including Source Modules (vs. compiled modules)

Post by Josep Roca »

So in short you have found a workaround in your defective compiler. What I wonder about is why this applies both to FB and PB. Because FB uses an assembler-linker that CAN do it, also at the library level, as demonstrated by the fact that gen-gcc can do it with the same assembler/linker
Yes, and it is working very well. If a future version of the compiler offers a better way to do it, I will try it.

It applies to both FB and PB, although PB does it by default unless you disable the feature. Also being a three pass compiler, PB also removes procedures that are only called by other procedures that are not called themselves.

I use classes (types) a lot. Can that smartlinker remove uncalled procedures of a class?
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: How to Manage FB Reusable Procedures by Including Source Modules (vs. compiled modules)

Post by dodicat »

I was going to try powerbasic (free).
But your (Josep Roca) download free powerbasic 9 link is dead on this page.
http://www.jose.it-berater.org/smfforum ... pic=5164.0
marcov
Posts: 3454
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: How to Manage FB Reusable Procedures by Including Source Modules (vs. compiled modules)

Post by marcov »

Josep Roca wrote:
I use classes (types) a lot. Can that smartlinker remove uncalled procedures of a class?
The smartlinker works on section level. You put every symbol in a section, and then only put the section in the final exe if the symbol is referenced. ( see for a short description https://stackoverflow.com/questions/982 ... 85#9830185). In the gcc world it is called gc-sections, since it removes/garbage collects dead (unreferenced) sections.

Dead code elimination is an umbrella term for all optimizations that remove unused code, so also cases like

Code: Select all

a=5;
if  a=10 then
  // never get here
else   
 do this 
In the case that symbols are listed in tables (like initializers (CTOR/DTOR), VMTs etc), usually the table must have special(sub)section metadata statements in the assembler to specially structure the table, indicating that entries must be 1) always linked 2) only linked when referenced, omitting the table entry. 3) only linked when referenced, nilling the entry when not used.

This is the rock basic level, and works incremental. Doing this for virtual methods that are never called is harder. Assume TA inherits from baseclass TB and contains virtual method D. TA.D does not call TB.D.

GCC (and associated tools, like the AS/LD binutils that also the gas backend uses) supports it for ages, but the support was slow in coming to windows. There were still gotchas for C++ in 2016.

If the program calls method D on something of type TB, it is hard to determine if TB.D is necessary, unless the class construction is in the same method and always clear. Since when a TB passed from somewhere else could be both TB and TA. And if it is TA then TA.D is called and if TB then TB.D.

You can imagine it gets even more complicated if that TB class could potentially be created by reading a stream of objects from e.g. a file.

The next, much rarer, step analyses virtual methods to remove the virtual attribute when possible, so that more traditional ways can reduce code further. Optimizations like that are called LTO with gcc (link time optimizations), but are much harder to handle. But even that cannot predict the streaming case. One should also not expect wonders from these kind of optimizations.

FreePascal does support a basic devirtualization, but it is still fairly alpha and not used much.
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: How to Manage FB Reusable Procedures by Including Source Modules (vs. compiled modules)

Post by Josep Roca »

dodicat wrote:I was going to try powerbasic (free).
But your (Josep Roca) download free powerbasic 9 link is dead on this page.
http://www.jose.it-berater.org/smfforum ... pic=5164.0
There is a new owner and a free version is no longer available.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: How to Manage FB Reusable Procedures by Including Source Modules (vs. compiled modules)

Post by dodicat »

Thanks Josep Roca.
Looks like a real band of cowboys you've got running the outfit.
I like it.
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: How to Manage FB Reusable Procedures by Including Source Modules (vs. compiled modules)

Post by Munair »

fxm wrote:When old OSs (like DOS) were used, compiling by separate modules was mandatory as soon as the program was not very short, because of the small memory size available for the compiler (about 200 KB with Quick Basic 4.5).
A typical BAT file to compile (selected) QuickBASIC 7.1 modules:

BC FORMS /AH /O /FPI /OT /LR /FS;
BC QBE /AH /O /X /FPI /OT /LR /FS;
BC MENUS /AH /O /FPI /OT /LR /FS;
BC QBEPROCS /AH /O /X /FPI /OT /LR /FS;
@ECHO.
@ECHO OFF


Followed by a OBJECTS definition file for the linker. Modules in parenthesis () are overlays. Note the 16KB stack size for this particular project:

/ST:16384 /NOE /NOD:BRT71EFR.LIB QBE+
QBEPROCS+
(MENUS)+
(FORMS)+
C:\BC7\LIB\NOCOM+
C:\BC7\LIB\NOEMS+
C:\BC7\LIB\NOEVENT+
C:\BC7\LIB\NOGRAPH+
C:\BC7\LIB\NOISAM+
C:\BC7\LIB\SMALLERR+
C:\BC7\DMC\LIB\COLORS+
C:\BC7\DMC\LIB\CONTROLS+
C:\BC7\DMC\LIB\DISK+
C:\BC7\DMC\LIB\INTRFACE+
C:\BC7\DMC\LIB\INTRPT+
C:\BC7\DMC\LIB\KEYBOARD+
C:\BC7\DMC\LIB\MOUSE+
C:\BC7\DMC\LIB\LICENSE+
C:\BC7\DMC\LIB\MATH+
C:\BC7\DMC\LIB\STRING+
C:\BC7\DMC\LIB\FORMAT+
(C:\BC7\DMC\LIB\CALENDAR)+
(C:\BC7\DMC\LIB\SYSINFO)+
(C:\BC7\DMC\LIB\DIALOG)
QBE.EXE

C:\BC7\LIB\BCL71EFR.LIB+
C:\BC7\DMC\LIB\DMC.LIB;


Finally the BAT file that does the actual linking:

LINK @OBJECTS
@ECHO OFF
C:\BC7\DMC\TOOLS\LOGBUILD QBE.EXE C:\BC7\DMC\QBE\BUILD.LOG
@ECHO.


This was the only way to compile and link larger projects (up to 16MB) in DOS with 640KB conventional memory (usually between 580 and 620 netto). QBE.EXE was about 223KB large. Run from a dosbox in Linux:
Image
Image
Last edited by fxm on Nov 30, 2018 15:56, edited 1 time in total.
Reason: Addition of the first sentence of the leading article as an introduction
Post Reply