compiler: ctask scheduler loads ppu files, fixed cycle check, fixed -Ur

This commit is contained in:
mattias 2026-02-17 18:05:54 +01:00
parent 8af23fd95b
commit 060425cab6
5 changed files with 127 additions and 236 deletions

View File

@ -72,14 +72,12 @@ type
// Find the task for module m
function findtask(m : tmodule) : ttask_list;
// Can we continue processing this module ? If not, firstwaiting contains first module that m is waiting for.
function cancontinue(m : tmodule; checksub : boolean; out firstwaiting: tmodule): boolean;
function cancontinue(m : tmodule; out firstwaiting: tmodule): boolean;
// Overload of cancontinue, based on task.
function cancontinue(t: ttask_list; out firstwaiting: tmodule): boolean; inline;
// Check modules waiting for t, find highest state and count them
function countwaiting(m : tmodule; out highest_state: tmodulestate; out firsthighestwaiting: tmodule): integer; // EnableCTaskPPU: remove
// Continue processing this module. Return true if the module is done and can be removed.
function continue_task(t : ttask_list): Boolean;
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
// Check for a circular dependency and fix it
function check_cycle: boolean;
{$ENDIF}
@ -173,14 +171,14 @@ constructor ttask_handler.create;
begin
list:=ttasklinkedlist.Create;
hash:=TFPHashList.Create;
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
tmodule.queue_module:=@addmodule;
{$ENDIF}
end;
destructor ttask_handler.destroy;
begin
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
tmodule.queue_module:=nil;
{$ENDIF}
hash.free;
@ -203,35 +201,9 @@ begin
{$IFDEF DEBUG_CTASK_VERBOSE}Writeln('No task found for '+m.ToString);{$ENDIF}
end;
function ttask_handler.cancontinue(m: tmodule; checksub : boolean; out firstwaiting: tmodule): boolean;
procedure CheckUsed(out acandidate : tmodule);
var
itm : TLinkedListItem;
iscandidate : boolean;
m2 : tmodule;
begin
acandidate:=nil;
itm:=m.used_units.First;
while assigned(itm) do
begin
iscandidate:=Not (tused_unit(itm).u.state in [ms_processed,ms_compiled]);
if iscandidate then
begin
acandidate:=tused_unit(itm).u;
if cancontinue(acandidate,false,m2) then
break;
end;
itm:=itm.Next;
end;
acandidate:=nil;
end;
function ttask_handler.cancontinue(m: tmodule; out firstwaiting: tmodule): boolean;
var
m2 : tmodule;
begin
firstwaiting:=nil;
@ -239,7 +211,7 @@ begin
if (m.is_initial and not m.is_unit) and (list.count>1) then
exit(False);
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
if m.do_reload then
cancontinue:=tppumodule(m).canreload(firstwaiting)
else
@ -248,7 +220,7 @@ begin
case m.state of
ms_unknown : cancontinue:=true;
ms_registered : cancontinue:=true;
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
ms_load: cancontinue:=tppumodule(m).ppuloadcancontinue(firstwaiting);
{$ENDIF}
ms_compile : cancontinue:=true;
@ -260,18 +232,13 @@ begin
ms_compiled : cancontinue:=true;
ms_processed : cancontinue:=true;
ms_moduleerror : cancontinue:=true;
{$IFDEF DisableCTaskPPU}
else
InternalError(2024011802);
{$ENDIF}
end;
end;
// EnableCTaskPPU: remove checksub
if (not cancontinue) and checksub then
begin
checkused(m2);
if m2<>nil then
firstwaiting:=m2;
end;
{$IFDEF DEBUG_CTASK_VERBOSE}
Write('CTASK: ',m.ToString,' state: ',m.state,', can continue: ',Result);
if result then
@ -290,71 +257,7 @@ end;
function ttask_handler.cancontinue(t : ttask_list; out firstwaiting : tmodule): boolean;
begin
Result:=cancontinue(t.module,true,firstwaiting);
end;
function ttask_handler.countwaiting(m: tmodule; out highest_state: tmodulestate; out
firsthighestwaiting: tmodule): integer;
var
i: Integer;
dep_unit: tdependent_unit;
state: tmodulestate;
waitfor_unit: tmodule;
begin
Result:=0;
highest_state:=ms_registered;
firsthighestwaiting:=nil;
if m.is_initial and not m.is_unit then
// program/library
exit;
if m.waitingunits<>nil then
begin
for i:=0 to m.waitingunits.Count-1 do
begin
waitfor_unit:=tmodule(m.waitingunits[i]);
state:=waitfor_unit.state;
if state in [ms_compiled, ms_processed] then
// not waiting
else if state<highest_state then
// worse
else if state=highest_state then
// same
inc(Result)
else
begin
// better
Result:=1;
highest_state:=state;
firsthighestwaiting:=waitfor_unit;
end;
end;
end;
if m.dependent_units<>nil then
begin
dep_unit:=tdependent_unit(m.dependent_units.First);
while dep_unit<>nil do
begin
state:=dep_unit.u.state;
if state in [ms_compiled, ms_processed] then
// not waiting
else if state<highest_state then
// worse
else if state=highest_state then
// same
inc(Result)
else
begin
// better
Result:=1;
highest_state:=state;
firsthighestwaiting:=dep_unit.u;
end;
dep_unit:=tdependent_unit(dep_unit.Next);
end;
end;
Result:=cancontinue(t.module,firstwaiting);
end;
function ttask_handler.continue_task(t : ttask_list) : Boolean;
@ -369,18 +272,16 @@ begin
{$IFDEF DEBUG_CTASK}Writeln('CTASK: ',m.ToString,' Continues. State: ',m.state,' do_reload=',m.do_reload);{$ENDIF}
if Assigned(t.state) then
t.RestoreState;
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
if m.do_reload then
begin
writeln('ttask_handler.continue ',m.modulename^,' ',m.state,' reloading...');
tppumodule(m).reload;
exit;
end;
writeln('ttask_handler.continue ',m.modulename^,' ',m.state,' continue...');
{$ENDIF}
case m.state of
ms_registered : parser.compile_module(m);
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
ms_load: (m as tppumodule).continueloadppu;
{$ENDIF}
ms_compile :
@ -403,9 +304,6 @@ begin
else
InternalError(2024011801);
end;
{$IFDEF EnableCTaskPPU}
writeln('ttask_handler.continue AFTER ',m.modulename^,' ',m.state,' reload=',m.do_reload);
{$ENDIF}
if (m.is_initial and not m.is_unit) and (list.Count>1) then
// program must wait for all units to finish
@ -434,7 +332,7 @@ begin
rebuild_hash;
end;
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
function ttask_handler.check_cycle: boolean;
var
last: ttask_list;
@ -449,7 +347,7 @@ var
// mark module as searched
m.cycle_search_stamp:=m.cycle_stamp;
uu:=tused_unit(m.used_units);
uu:=tused_unit(m.used_units.First);
while uu<>nil do
begin
pm:=tppumodule(uu.u);
@ -471,7 +369,7 @@ var
if m.state=ms_load then
begin
{$IFDEF DEBUG_CTASK}
writeln('PPUALGO check_cycle last=',last.module.modulename^,' ',last.module.state,', RECOMPILE ',m.modulename^,' ',m.state);
writeln('PPUALGO check_cycle last=',last.module.modulename^,' ',last.module.statestr,', RECOMPILE ',m.modulename^,' ',m.statestr);
{$ENDIF}
m.recompile_cycle;
check_cycle:=true;
@ -490,15 +388,17 @@ begin
last:=nil;
while t<>nil do
begin
{$IFDEF DEBUG_CTASK}
writeln('PPUALGO check_cycle queued: ',t.module.modulename^,' ',t.module.statestr);
{$ENDIF}
if (last=nil) or (last.module.unit_index<t.module.unit_index) then
last:=t;
t:=t.nexttask;
end;
if tppumodule.cycle_stamp=high(dword) then
tppumodule.cycle_stamp:=0
else
inc(tppumodule.cycle_stamp);
Internalerror(2026021623);
inc(tppumodule.cycle_stamp);
Search(tppumodule(last.module));
end;
{$ENDIF}
@ -541,7 +441,7 @@ begin
m:=t.module;
if (besttask<>nil) and (besttask.module.unit_index>m.unit_index) then
// skip
else if cancontinue(m,false,firstwaiting) then
else if cancontinue(m,firstwaiting) then
begin
{$IFDEF DEBUG_CTASK}
Writeln('CTASK: ',m.ToString,' state=',m.state,' unit_index=',m.unit_index);
@ -554,7 +454,7 @@ begin
t:=t.nexttask;
end;
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
if besttask=nil then
if check_cycle then continue;
{$ENDIF}

View File

@ -55,7 +55,7 @@ interface
type
trecompile_reason = (rr_unknown,
rr_noppu,rr_sourcenewer,rr_build,rr_crcchanged
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
,rr_buildcycle
{$ENDIF}
);
@ -108,7 +108,7 @@ interface
end;
tderefmaparray = array of tderefmaprec;
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
tqueue_module_event = procedure(m: tmodule) of object;
{$ENDIF}
@ -122,7 +122,7 @@ interface
in_interface : boolean;
u : tmodule;
unitsym : tunitsym;
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
dependent_added : boolean;
{$ENDIF}
constructor create(_u : tmodule;intface,inuses:boolean;usym:tunitsym);
@ -143,7 +143,7 @@ interface
public
is_reset, { has reset been called ? }
do_reload, { force reloading of the unit }
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
fromppu: boolean;
{$ENDIF}
sources_avail, { if all sources are reachable }
@ -236,7 +236,9 @@ interface
moduleoptions: tmoduleoptions;
deprecatedmsg: pshortstring;
loadcount : integer; // EnableCTaskPPU: remove
{$IFDEF DisableCTaskPPU}
loadcount : integer;
{$ENDIF}
compilecount : integer;
consume_semicolon_after_uses : Boolean;
initfinalchecked : boolean;
@ -294,7 +296,7 @@ interface
procedure removedependency(callermodule:tmodule);
function hasdependency(callermodule:tmodule): boolean;
procedure flagdependent(callermodule:tmodule);
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
procedure disconnect_depending_modules; virtual;
function is_reload_needed(du: tdependent_unit): boolean; virtual; // true if reload needed after self changed
class var queue_module: tqueue_module_event;
@ -538,15 +540,17 @@ implementation
in_interface:=intface;
in_uses:=inuses;
unitsym:=usym;
if _u.state in [ms_compiled_waitcrc,ms_compiled,ms_processed] then
if _u.state in [ms_load,ms_compiled_waitcrc,ms_compiled,ms_processed] then
checksum:=u.crc
else
checksum:=0;
if _u.interface_compiled then
begin
checksum:=u.crc;
interface_checksum:=u.interface_crc;
indirect_checksum:=u.indirect_crc;
end
else
begin
checksum:=0;
interface_checksum:=0;
indirect_checksum:=0;
end;
@ -874,10 +878,11 @@ implementation
m : tmodule;
begin
is_reset:=true;
{$IFDEF EnableCTaskPPU}
{$IFDEF DisableCTaskPPU}
LoadCount:=0;
{$ELSE}
fromppu:=false;
{$ENDIF}
LoadCount:=0;
if assigned(scanner) then
begin
{ also update current_scanner if it was pointing
@ -1144,7 +1149,7 @@ implementation
{$IFDEF DEBUG_PPU_CYCLES}
writeln('PPUALGO tmodule.flagdependent ',modulename^,' state=',statestr,', is used by ',BoolToStr(dm.in_interface,'interface','implementation'),' of ',m.modulename^,' ',m.statestr);
{$ENDIF}
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
if not m.do_reload and is_reload_needed(dm) then
begin
m.do_reload:=true;
@ -1183,7 +1188,7 @@ implementation
Result:='do_reload,'+Result;
end;
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
procedure tmodule.disconnect_depending_modules;
var
uu: tused_unit;
@ -1203,7 +1208,7 @@ implementation
or (du.in_interface and du.u.interface_compiled);
// Note: see also the override in fppu.tppumodule
end;
{$ENDIF EnableCTaskPPU}
{$ENDIF}
procedure tmodule.addimportedsym(sym:TSymEntry);
begin
@ -1221,7 +1226,7 @@ implementation
end;
function tmodule.usedunitsloaded(interface_units : boolean; out firstwaiting : tmodule): boolean;
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
var
uu: tused_unit;
ok: Boolean;
@ -1232,9 +1237,9 @@ implementation
while assigned(uu) do
begin
ok:=uu.u.interface_compiled and not uu.u.do_reload;
{ $IFDEF DEBUG_CTASK_VERBOSE}
{$IFDEF DEBUG_CTASK_VERBOSE}
writeln(' ',ToString,' checking state of ', uu.u.ToString,' : ',uu.u.statestr,' : ',ok);
{ $ENDIF}
{$ENDIF}
if not ok then
begin
Result:=false;

View File

@ -52,13 +52,13 @@ interface
sourcefn : TPathStr; { Source specified with "uses .. in '..'" }
comments : TCmdStrList;
nsprefix : TCmdStr; { Namespace prefix the unit was found with }
{$ifdef EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
loadedfrommodule: tmodule;
ppu_waitingfor_crc: boolean;
class var cycle_stamp: dword;
var
cycle_search_stamp: dword;
{$endif}
{$endif}
{$ifdef Test_Double_checksum}
interface_read_crc_index,
interface_write_crc_index,
@ -80,19 +80,23 @@ interface
procedure getppucrc;
procedure writeppu;
function loadppu(from_module : tmodule) : boolean;
{$ifdef EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
function continueloadppu : boolean;
function canreload(out firstwaiting: tmodule): boolean;
procedure reload;
function ppuloadcancontinue(out firstwaiting: tmodule): boolean;
function is_reload_needed(pu: tdependent_unit): boolean; override;
procedure recompile_cycle;
{$endif}
{$endif}
procedure post_load_or_compile(from_module : tmodule; second_time: boolean);
procedure discardppu;
function needrecompile:boolean; // EnableCTaskPPU: remove
{$IFDEF DisableCTaskPPU}
function needrecompile:boolean;
{$ENDIF}
procedure setdefgeneration;
procedure reload_flagged_units; // EnableCTaskPPU: remove
{$IFDEF DisableCTaskPPU}
procedure reload_flagged_units;
{$ENDIF}
procedure end_of_parsing;override;
private
unitimportsymsderefs : tfplist;
@ -106,7 +110,9 @@ interface
function check_loadfrompackage: boolean;
procedure check_reload(from_module: tmodule; var do_load: boolean);
function openppu(ppufiletime:longint):boolean;
procedure prepare_second_load(from_module: tmodule); // EnableCTaskPPU: remove
{$IFDEF DisableCTaskPPU}
procedure prepare_second_load(from_module: tmodule);
{$ENDIF}
procedure recompile_from_sources(from_module: tmodule);
function search_unit_files(loaded_from : tmodule; onlysource:boolean):TAvailableUnitFiles;
function search_unit(loaded_from : tmodule; onlysource,shortname:boolean):TAvailableUnitFiles;
@ -114,16 +120,18 @@ interface
procedure load_interface;
procedure load_implementation;
function load_usedunits: boolean;
{$ifdef EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
function load_usedunits_section: boolean;
function ppu_check_used_crcs: boolean;
{$endif}
{$endif}
procedure printcomments;
procedure queuecomment(const s:TMsgStr;v,w:longint);
procedure buildderefunitimportsyms;
procedure derefunitimportsyms;
procedure freederefunitimportsyms;
procedure try_load_ppufile(from_module: tmodule); // EnableCTaskPPU: remove
{$IFDEF DisableCTaskPPU}
procedure try_load_ppufile(from_module: tmodule);
{$ENDIF}
procedure writesourcefiles;
procedure writeusedunit(intf:boolean);
procedure writelinkcontainer(var p:tlinkcontainer;id:byte;strippath:boolean);
@ -204,7 +212,7 @@ var
function tppumodule.statestr: string;
begin
Result:=inherited statestr;
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
if state<>ms_load then exit;
if ppu_waitingfor_crc then
Result:=Result+',waitcrc'
@ -217,7 +225,7 @@ var
procedure tppumodule.reset(for_recompile : boolean);
begin
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
loadedfrommodule:=nil;
ppu_waitingfor_crc:=false;
{$ENDIF}
@ -252,7 +260,7 @@ var
tunitwpoinfo(wpoinfo).derefimpl;
end;
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
{ all dependent units were already flagged recursively for reload }
defsgeneration:=currentdefgeneration;
{$ELSE}
@ -828,7 +836,7 @@ var
{ now load the unit and all used units }
load_interface;
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
if not load_usedunits then
internalerror(2026020415);
{$ELSE}
@ -1417,9 +1425,11 @@ var
hp:=registerunit(self,hs,'',isnew);
if isnew then
usedunits.Concat(tused_unit.create(hp,in_interface,true,nil));
{$IFDEF DisableCTaskPPU}
if LoadCount=1 then
pu:=addusedunit(hp,false,nil)
else
{$ENDIF}
begin
pu:=findusedunit(hp);
{ Safety, normally this should not happen:
@ -1890,9 +1900,22 @@ var
{ flush to be sure }
ppufile.flush;
{ save crc in current module also }
if not crc_final then
begin
crc_final:=true;
crc:=ppufile.crc;
end;
{$IFDEF Debug_WaitCRC}
writeln('tppumodule.writeppu ',realmodulename^,' crc=',hexstr(crc,8));
{$ENDIF}
{ create and write header }
{ Note: the interface_crc and indirect_crc were computed in getppucrc
after the interface was compiled. The implementation must *not* effect them. }
ppufile.header.common.size:=ppufile.size;
ppufile.header.checksum:=ppufile.crc;
ppufile.header.checksum:=crc;
ppufile.header.interface_checksum:=interface_crc;
ppufile.header.indirect_checksum:=indirect_crc;
ppufile.header.common.compiler:=wordversion;
@ -1903,16 +1926,6 @@ var
ppufile.header.symlistsize:=current_module.symlist.count;
ppufile.writeheader;
{ save crc in current module also }
crc_final:=true;
crc:=ppufile.crc;
// make sure, the interface_crc is not affected by the implementation
// interface_crc:=ppufile.interface_crc;
// indirect_crc:=ppufile.indirect_crc;
{$IFDEF Debug_WaitCRC}
writeln('tppumodule.writeppu ',realmodulename^,' crc=',hexstr(crc,8));
{$ENDIF}
{$ifdef Test_Double_checksum_write}
Writeln(ppufile.CRCFile,'End of implementation CRC in writeppu method of ',ppufilename,
' implementation_crc=$',hexstr(ppufile.crc,8),
@ -1999,7 +2012,7 @@ var
crc:=ppufile.crc;
if in_interface then
begin
// Note: the interface_crc is not affected by the implementation
// Note: the interface_crc and indirect_crc are not affected by the implementation
interface_crc:=ppufile.interface_crc;
indirect_crc:=ppufile.indirect_crc;
end;
@ -2060,7 +2073,7 @@ var
begin
{ load the used units from interface }
in_interface:=true;
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
if not load_usedunits_section then
exit(false); // e.g. fail or some used unit interface is not ready
{$ELSE}
@ -2130,7 +2143,7 @@ var
end;
{ now only read the implementation uses }
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
if not ppu_waitingfor_crc then
begin
if not load_usedunits_section then
@ -2171,7 +2184,7 @@ var
end;
{$ENDIF}
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
if not ppu_waitingfor_crc then
{$ENDIF}
begin
@ -2198,7 +2211,7 @@ var
tunitwpoinfo(wpoinfo).derefimpl;
end;
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
// check CRCs
ppu_waitingfor_crc:=true;
if not ppu_check_used_crcs then exit;
@ -2207,7 +2220,7 @@ var
{$ENDIF}
end;
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
function tppumodule.load_usedunits_section: boolean;
var
pu: tused_unit;
@ -2245,8 +2258,8 @@ var
If an unit of a cycle is recompiled, the whole cycle is recompiled.
If this ppu was compiled with -Ur only check interface_crc, not crc }
CRCValid:=(not pu.u.do_reload) and (pu.u.state in [ms_load,ms_compiled_waitcrc,ms_compiled,ms_processed]);
IntfCRCValid:=CRCValid {or (pu.u.state in [ms_compiling_waitimpl,ms_compiling_waitfinish,ms_compiled_waitcrc])};
CRCValid:=(not pu.u.do_reload) and pu.u.crc_final;
IntfCRCValid:=(not pu.u.do_reload) and pu.u.interface_compiled;
if (IntfCRCValid and
((pu.u.interface_crc<>pu.interface_checksum) or
@ -2273,10 +2286,14 @@ var
exit(false);
end;
if (not CRCValid) or (not pu.u.interface_compiled) then
if pu.u.do_reload
or (not pu.u.interface_compiled)
or ((state=ms_load)
and not (mf_release in moduleflags)
and not pu.u.crc_final) then
begin
// an used unit is delayed
// Important: load the rest of the uses section
// Important: do not break, load the remaining uses section
{$IFDEF DEBUG_PPU_CYCLES}
if not Result then writeln('PPUALGO tppumodule.load_usedunits_section ',modulename^,' ',BoolToStr(in_interface,'interface','implementation'),' uses "',pu.u.modulename^,'", state=',pu.u.statestr,', waiting for crc...');
{$ENDIF}
@ -2350,6 +2367,8 @@ var
if check then
begin
if not (pu.u.state in [ms_load,ms_compiled_waitcrc,ms_compiled,ms_processed])
or not pu.u.interface_compiled
or pu.u.do_reload
@ -2384,8 +2403,9 @@ var
set_current_module(from_module);
end;
{$ENDIF EnableCTaskPPU}
{$ENDIF}
{$IFDEF DisableCTaskPPU}
function tppumodule.needrecompile:boolean;
var
pu : tused_unit;
@ -2419,7 +2439,7 @@ var
pu:=tused_unit(pu.next);
end;
end;
{$ENDIF}
procedure tppumodule.setdefgeneration;
begin
@ -2427,7 +2447,7 @@ var
inc(currentdefgeneration);
end;
{$IFDEF DisableCTaskPPU}
procedure tppumodule.reload_flagged_units;
var
hp : tppumodule;
@ -2447,6 +2467,7 @@ var
hp:=tppumodule(hp.next);
end;
end;
{$ENDIF}
procedure tppumodule.end_of_parsing;
begin
@ -2470,8 +2491,7 @@ var
{ When the unit is already loaded or being loaded
we can maybe skip a complete reload/recompile }
if assigned(globalsymtable)
{$IFDEF EnableCTaskPPU}
{$ELSE}
{$IFDEF DisableCTaskPPU}
and (not needrecompile)
{$ENDIF}
then
@ -2510,7 +2530,8 @@ var
end;
end;
procedure tppumodule.prepare_second_load(from_module: tmodule);
{$IFDEF DisableCTaskPPU}
procedure tppumodule.prepare_second_load(from_module: tmodule);
const
CompileStates = [ms_compile, ms_compiling_wait,
@ -2536,7 +2557,9 @@ var
else
state:=ms_load;
end;
{$ENDIF}
{$IFDEF DisableCTaskPPU}
procedure tppumodule.try_load_ppufile(from_module : tmodule);
begin
@ -2568,6 +2591,7 @@ var
if assigned(ppufile) then
discardppu;
end;
{$ENDIF}
procedure tppumodule.recompile_from_sources(from_module : tmodule);
@ -2611,7 +2635,7 @@ var
{$ENDIF}
{ Flag modules to reload }
flagdependent(from_module);
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
was_interfaced_compiled:=interface_compiled;
{ disconnect dependending modules }
disconnect_depending_modules;
@ -2620,7 +2644,7 @@ var
reset(true);
{ mark this module for recompilation }
state:=ms_compile;
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
if was_interfaced_compiled then
setdefgeneration;
queue_module(Self); // queue after reset, so task state is cleared!
@ -2638,8 +2662,7 @@ var
if in_interface then
internalerror(200212283);
{$IFDEF EnableCTaskPPU}
{$ELSE}
{$IFDEF DisableCTaskPPU}
{ for a second_time recompile reload all dependent units,
for a first time compile register the unit _once_ }
if second_time or do_reload then
@ -2658,11 +2681,13 @@ var
function tppumodule.loadppu(from_module : tmodule) : boolean;
const
ImplIntf : array[boolean] of string[15]=('implementation','interface');
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
begin
Result:=false;
{$IFDEF DEBUG_PPU_CYCLES}
writeln('PPUALGO tppumodule.loadppu START ',modulename^,' (',statestr,') used by "',from_module.modulename^,'" (',from_module.statestr,')');
{$ENDIF}
Message3(unit_u_load_unit,from_module.modulename^,
ImplIntf[from_module.in_interface],
@ -2814,7 +2839,7 @@ var
end;
{$ENDIF}
{$ifdef EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
function tppumodule.continueloadppu: boolean;
var
old_module: tmodule;

View File

@ -219,7 +219,7 @@ implementation
begin
{ add to used units }
uu:=curr.addusedunit(hp,false,unitsym);
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
uu.dependent_added:=true;
{$ENDIF}
end;
@ -736,7 +736,7 @@ implementation
if pu.in_uses and
(pu.in_interface=frominterface) then
begin
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
// always call loadppu for the cycle test
tppumodule(lu).loadppu(curr);
if not (curr.state in [ms_compile,ms_compiling_wait,ms_compiling_waitintf,ms_compiling_waitimpl]) then
@ -1327,14 +1327,18 @@ type
{$IFDEF Debug_WaitCRC}
writeln('parse_unit_interface_declarations ',curr.realmodulename^);
{$ENDIF}
{$IFDEF DisableCTaskPPU}
if not(cs_compilesystem in current_settings.moduleswitches) and
(Errorcount=0) then
tppumodule(curr).getppucrc;
{$ELSE}
if Errorcount=0 then
tppumodule(curr).getppucrc;
{$ENDIF}
curr.in_interface:=false;
curr.interface_compiled:=true;
{$IFDEF EnableCTaskPPU}
{$ELSE}
{$IFDEF DisableCTaskPPU}
{ First reload all units depending on our interface, we need to do this
in the implementation part to prevent erroneous circular references }
tppumodule(curr).setdefgeneration;
@ -1799,9 +1803,8 @@ type
if not module.usedunitsfinalcrc(waitingmodule) then
begin
{ Some used units are still compiling, so their CRCs can change.
Compute the final CRC of this module, for the case of a
circular dependency, and wait.
}
Compute the final CRC of this module and wait.
Needed for compiling circular dependent units. }
{$IF defined(Debug_WaitCRC) or defined(Debug_FreeParseMem)}
writeln('finish_compile_unit ',module.realmodulename^,' waiting for used unit CRCs...');
{$ENDIF}
@ -3047,7 +3050,7 @@ type
else
curr.consume_semicolon_after_uses:=false;
{$IFDEF EnableCTaskPPU}
{$IFNDEF DisableCTaskPPU}
if curr.is_initial then
load_ok:=false; // delay program, so ctask can finish all units
if not load_ok then

View File

@ -297,13 +297,8 @@ begin
Step:='Second compile';
UnitPath:=Dir+';'+Dir+PathDelim+'src2';
Compile;
{$IFDEF EnableCTaskPPU}
// the main src is always compiled, bird changed, ant is only reloaded, not recompiled
CheckCompiled(['changeleaf1_prg.pas','changeleaf1_bird.pas']);
{$ELSE}
// the main src is always compiled, bird changed, so ant must be recompiled as well
CheckCompiled(['changeleaf1_prg.pas','changeleaf1_ant.pas','changeleaf1_bird.pas']);
{$ENDIF}
end;
procedure TTestRecompile.TestChangeInner1;
@ -401,15 +396,10 @@ begin
Step:='Second compile';
UnitPath:=Dir+';'+Dir+PathDelim+'src2';
Compile;
{$IFDEF EnableCTaskPPU}
// the main src is always compiled, cat changed but not crc,
// because a ppu needs the crc, bird waits in intf, so ant waits in intf, creating a waiting loop
// triggering a recompile of all the ppus of the whole cycle
CheckCompiled(['cycle3_changec_prg.pas','cycle3_changec_ant.pas','cycle3_changec_bird.pas','cycle3_changec_cat.pas']);
{$ELSE}
// the main src is always compiled, cat changed, so bird must be recompiled as well
CheckCompiled(['cycle3_changec_prg.pas','cycle3_changec_ant.pas','cycle3_changec_bird.pas','cycle3_changec_cat.pas']);
{$ENDIF}
end;
procedure TTestRecompile.TestCycleImpl3_ChangeC;
@ -433,13 +423,8 @@ begin
Step:='Second compile';
UnitPath:=Dir+';'+Dir+PathDelim+'src2';
Compile;
{$IFDEF EnableCTaskPPU}
// the main src is always compiled, cat changed but not crc
CheckCompiled(['cycleimpl3_changec_prg.pas','cycleimpl3_changec_cat.pas']);
{$ELSE}
// the main src is always compiled, cat changed, so bird must be recompiled as well
CheckCompiled(['cycleimpl3_changec_prg.pas','cycleimpl3_changec_ant.pas','cycleimpl3_changec_bird.pas','cycleimpl3_changec_cat.pas']);
{$ENDIF}
end;
procedure TTestRecompile.TestChangeInlineBodyBug;
@ -517,12 +502,7 @@ begin
Step:='Second compile';
Compile;
{$IFDEF EnableCTaskPPU}
CheckCompiled(['bug41457_ant.pas']);
{$ELSE}
// the main src is always compiled
CheckCompiled(['bug41457_ant.pas','bug41457_bird.pas','bug41457_seagull.pas']);
{$ENDIF}
end;
procedure TTestRecompile.TestImplInline1;
@ -540,13 +520,8 @@ begin
Step:='Second compile';
Compile;
{$IFDEF EnableCTaskPPU}
// the main src is always compiled
CheckCompiled(['implinline1_ant.pas']);
{$ELSE}
// the main src is always compiled, and since bird ppu depends on ant, it is always compiled as well
CheckCompiled(['implinline1_ant.pas','implinline1_bird.pas']);
{$ENDIF}
end;
procedure TTestRecompile.TestImplInline2;
@ -636,18 +611,9 @@ begin
Step:='Second compile';
UnitPath:=Dir+';'+Dir+PathDelim+'src2';
Compile;
{$IFDEF EnableCTaskPPU}
// the main src is always compiled, cat intf class TCat changed, so bird and ant are recompiled
CheckCompiled(['ancestorchange1_ant.pas','ancestorchange1_bird.pas','ancestorchange1_cat.pas',
'ancestorchange1_eagle.pas']);
{$ELSE}
// the main src is always compiled,
// cat changed, so bird must be recompiled as well. bird should get the same CRCs.
// finally even though ant does ant directly use cat, ant specializes the changed generic
// function from cat, so ant must be recompiled as well.
CheckCompiled(['ancestorchange1_ant.pas','ancestorchange1_bird.pas','ancestorchange1_cat.pas',
'ancestorchange1_eagle.pas']);
{$ENDIF}
end;
procedure TTestRecompile.TestGeneric_IndirectUses;
@ -672,16 +638,8 @@ begin
Step:='Second compile';
UnitPath:=Dir+';'+Dir+PathDelim+'src2';
Compile;
{$IFDEF EnableCTaskPPU}
// the main src is always compiled, cat impl of the generic changed, so specialization in ant changed
CheckCompiled(['generic_indirectuses_prg.pas','generic_indirectuses_ant.pas','generic_indirectuses_cat.pas']);
{$ELSE}
// the main src is always compiled,
// cat changed, so bird must be recompiled as well. bird should get the same CRCs.
// finally even though ant does ant directly use cat, ant specializes the changed generic
// function from cat, so ant must be recompiled as well.
CheckCompiled(['generic_indirectuses_prg.pas','generic_indirectuses_ant.pas','generic_indirectuses_bird.pas','generic_indirectuses_cat.pas']);
{$ENDIF}
end;
initialization