Skip to content

Commit 4d2cf6d

Browse files
authored
Add AArch64 SIMD for Blake, SHA, CRC, XXH3, Argon2, and Adler32 (#88)
1 parent d54fd7e commit 4d2cf6d

74 files changed

Lines changed: 8008 additions & 787 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci/ppc64-be-build.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ docker run --rm --platform linux/ppc64 \
3838
-e FPC_TARBALL_TARGET \
3939
-e MAKE_BUILD_BACKEND \
4040
-e MAKE_PACKAGE_SCOPE \
41+
-e MAKE_RUN_BENCHMARK \
4142
-e LAZARUS_BRANCH \
4243
-e LAZARUS_REPO \
4344
-e CI_DEBUG \

.github/workflows/make.pas

Lines changed: 153 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -224,23 +224,32 @@ TMakeRunner = class
224224
FTargetOs: string;
225225
FErrorCount: Integer;
226226
FUseColor: Boolean;
227+
// Selected via MAKE_RUN_BENCHMARK (defaults to False when unset). When true,
228+
// builds and runs console benchmark projects under BenchmarkTargetFolder
229+
// after the test suite completes.
230+
FRunBenchmark: Boolean;
227231
FGraph: TPackageGraph;
228232
function ParseBackendEnv: TBuildBackend;
229233
function ParsePackageScopeEnv: TPackageScope;
234+
function ParseBoolEnv(const AName: string; ADefault: Boolean): Boolean;
230235
function ParseDefinesEnv: TStringList;
231236
procedure InitEnvironment;
232237
procedure UpdateSubmodules;
233238
procedure InstallDependencies;
234239
procedure BuildDiscoveredPackagesFpc;
235240
function CollectProjectRequiredNames: TStringList;
241+
procedure CollectRequiredNamesFromDirectory(const ADirectory: string;
242+
AResult: TStringList);
236243
procedure BuildAllProjects;
244+
procedure RunBenchmarkProjects;
237245
procedure BuildGuiProject(const ALpiPath: string);
238246
function BuildProject(const ALpiPath: string): string;
239247
function BuildProjectWithLazbuild(const APath: string): string;
240248
function BuildProjectWithFpc(const APath: string): string;
241249
function ExtractBinaryFromBuildLog(const AOutput, AFallback: string): string;
242250
function IsGUIProject(const ALpiPath: string): Boolean;
243251
function IsTestProject(const ALpiPath: string): Boolean;
252+
function IsBenchmarkProject(const ALpiPath: string): Boolean;
244253
procedure RunTestProject(const APath: string);
245254
procedure RunSampleProject(const APath: string);
246255
procedure InitSslForDownloads;
@@ -267,6 +276,7 @@ TMakeRunner = class
267276
AStreamToStderr: Boolean; out AOutput: string): Boolean; overload;
268277
function RepoRoot: string;
269278
function TargetDirectory: string;
279+
function BenchmarkDirectory: string;
270280
procedure ForEachLpkInDir(const ARoot: string; ACallback: TLpkPathProc);
271281
procedure RunBuiltBinary(const ABinaryPath: string;
272282
const AArgs: array of string; const AFailMessage: string);
@@ -295,7 +305,8 @@ TMakeRunner = class
295305
// ---------------------------------------------------------------------------
296306

297307
const
298-
Target: string = 'HashLib.Tests';
308+
TestTargetFolder: string = 'HashLib.Tests';
309+
BenchmarkTargetFolder: string = 'HashLib.Benchmark';
299310

300311
CSI_Reset = #27'[0m';
301312
CSI_Red = #27'[31m';
@@ -510,7 +521,8 @@ class function TLazXml.CollectFileSourceDirs(const AContent, APkgDir, ATargetCpu
510521

511522
class function TLazXml.ParseCompilerOptions(const AContent: string): TLazCompilerOptions;
512523
var
513-
Block: string;
524+
Block, AfterProjectOptions: string;
525+
P: Integer;
514526
begin
515527
Result.CompilerMode := 'delphi';
516528
Result.OptLevel := '2';
@@ -520,7 +532,18 @@ class function TLazXml.ParseCompilerOptions(const AContent: string): TLazCompile
520532
Result.UnitPaths := '';
521533
Result.UnitOutputDirTemplate := 'lib\$(TargetCPU)-$(TargetOS)';
522534

523-
Block := ExtractBlock(AContent, 'CompilerOptions');
535+
// Lazarus stores the active compiler options in a root-level <CompilerOptions>
536+
// block (after </ProjectOptions>). BuildModes can contain additional
537+
// <CompilerOptions> sections; prefer the root block when present.
538+
Block := '';
539+
P := Pos('</ProjectOptions>', AContent);
540+
if P > 0 then
541+
begin
542+
AfterProjectOptions := Copy(AContent, P, Length(AContent) - P + 1);
543+
Block := ExtractBlock(AfterProjectOptions, 'CompilerOptions');
544+
end;
545+
if Block = '' then
546+
Block := ExtractBlock(AContent, 'CompilerOptions');
524547
if Block = '' then
525548
Exit;
526549

@@ -1330,6 +1353,7 @@ constructor TMakeRunner.Create;
13301353
FBackendResolved := False;
13311354
FPackageScope := TPackageScope.Required;
13321355
FErrorCount := 0;
1356+
FRunBenchmark := False;
13331357
// Honor the NO_COLOR convention (https://no-color.org): any value disables
13341358
// ANSI colors. GitHub Actions renders ANSI in its log viewer, so default on.
13351359
FUseColor := GetEnvironmentVariable('NO_COLOR') = '';
@@ -1417,6 +1441,20 @@ function TMakeRunner.ParsePackageScopeEnv: TPackageScope;
14171441
raise Exception.CreateFmt('unknown MAKE_PACKAGE_SCOPE: "%s"', [Env]);
14181442
end;
14191443

1444+
function TMakeRunner.ParseBoolEnv(const AName: string; ADefault: Boolean): Boolean;
1445+
var
1446+
Env: string;
1447+
begin
1448+
Env := LowerCase(Trim(GetEnvironmentVariable(AName)));
1449+
if Env = '' then
1450+
Exit(ADefault);
1451+
if (Env = '1') or (Env = 'true') or (Env = 'yes') then
1452+
Exit(True);
1453+
if (Env = '0') or (Env = 'false') or (Env = 'no') then
1454+
Exit(False);
1455+
raise Exception.CreateFmt('unknown %s: "%s"', [AName, Env]);
1456+
end;
1457+
14201458
// Parse MAKE_DEFINES into a deduped list of conditional-define names. Accepts a
14211459
// space/comma/semicolon-separated list; each entry must be a valid identifier
14221460
// ([A-Za-z_][A-Za-z0-9_]*) so it is a safe -d argument in either backend.
@@ -1601,7 +1639,7 @@ function TMakeRunner.RepoRoot: string;
16011639
Candidate := Seeds[I];
16021640
while Candidate <> '' do
16031641
begin
1604-
DemoDir := IncludeTrailingPathDelimiter(ConcatPaths([Candidate, Target]));
1642+
DemoDir := IncludeTrailingPathDelimiter(ConcatPaths([Candidate, TestTargetFolder]));
16051643
if DirectoryExists(DemoDir) then
16061644
Exit(ExcludeTrailingPathDelimiter(Candidate));
16071645
Parent := ExpandFileName(IncludeTrailingPathDelimiter(Candidate) + '..');
@@ -1615,7 +1653,12 @@ function TMakeRunner.RepoRoot: string;
16151653

16161654
function TMakeRunner.TargetDirectory: string;
16171655
begin
1618-
Result := IncludeTrailingPathDelimiter(ConcatPaths([RepoRoot, Target]));
1656+
Result := IncludeTrailingPathDelimiter(ConcatPaths([RepoRoot, TestTargetFolder]));
1657+
end;
1658+
1659+
function TMakeRunner.BenchmarkDirectory: string;
1660+
begin
1661+
Result := IncludeTrailingPathDelimiter(ConcatPaths([RepoRoot, BenchmarkTargetFolder]));
16191662
end;
16201663

16211664
procedure TMakeRunner.ForEachLpkInDir(const ARoot: string;
@@ -1690,6 +1733,12 @@ procedure TMakeRunner.InitEnvironment;
16901733
Log(CSI_Yellow, 'defines: ' + FDefines.DelimitedText)
16911734
else
16921735
Log(CSI_Yellow, 'defines: (none)');
1736+
1737+
FRunBenchmark := ParseBoolEnv('MAKE_RUN_BENCHMARK', False);
1738+
if FRunBenchmark then
1739+
Log(CSI_Yellow, 'run benchmark: true')
1740+
else
1741+
Log(CSI_Yellow, 'run benchmark: false');
16931742
end;
16941743

16951744
procedure TMakeRunner.UpdateSubmodules;
@@ -1993,20 +2042,17 @@ procedure TMakeRunner.BuildDiscoveredPackagesFpc;
19932042
end;
19942043
end;
19952044

1996-
// Union of RequiredPackages across the buildable (non-GUI) projects under the
1997-
// target directory. Drives the fpc backend's 'required' scope so it compiles
1998-
// only the dependency closure those projects need.
1999-
function TMakeRunner.CollectProjectRequiredNames: TStringList;
2045+
procedure TMakeRunner.CollectRequiredNamesFromDirectory(const ADirectory: string;
2046+
AResult: TStringList);
20002047
var
20012048
List: TStringList;
20022049
Each: string;
20032050
Proj: TLpiProject;
20042051
I: Integer;
20052052
begin
2006-
Result := TStringList.Create;
2007-
Result.Sorted := True;
2008-
Result.Duplicates := dupIgnore;
2009-
List := TProjectFiles.FindAll(TargetDirectory, '*.lpi');
2053+
if not DirectoryExists(ADirectory) then
2054+
Exit;
2055+
List := TProjectFiles.FindAll(ADirectory, '*.lpi');
20102056
try
20112057
for Each in List do
20122058
begin
@@ -2016,7 +2062,7 @@ function TMakeRunner.CollectProjectRequiredNames: TStringList;
20162062
try
20172063
if Proj.IsValid then
20182064
for I := 0 to Proj.RequiredPackageNames.Count - 1 do
2019-
Result.Add(Proj.RequiredPackageNames[I]);
2065+
AResult.Add(Proj.RequiredPackageNames[I]);
20202066
finally
20212067
Proj.Free;
20222068
end;
@@ -2026,6 +2072,19 @@ function TMakeRunner.CollectProjectRequiredNames: TStringList;
20262072
end;
20272073
end;
20282074

2075+
// Union of RequiredPackages across the buildable (non-GUI) projects under the
2076+
// test and (when enabled) benchmark directories. Drives the fpc backend's
2077+
// 'required' scope so it compiles only the dependency closure those projects need.
2078+
function TMakeRunner.CollectProjectRequiredNames: TStringList;
2079+
begin
2080+
Result := TStringList.Create;
2081+
Result.Sorted := True;
2082+
Result.Duplicates := dupIgnore;
2083+
CollectRequiredNamesFromDirectory(TargetDirectory, Result);
2084+
if FRunBenchmark then
2085+
CollectRequiredNamesFromDirectory(BenchmarkDirectory, Result);
2086+
end;
2087+
20292088
function TMakeRunner.ExtractBinaryFromBuildLog(const AOutput,
20302089
AFallback: string): string;
20312090
var
@@ -2190,6 +2249,26 @@ function TMakeRunner.IsTestProject(const ALpiPath: string): Boolean;
21902249
Result := Pos('consoletestrunner', Content) > 0;
21912250
end;
21922251

2252+
function TMakeRunner.IsBenchmarkProject(const ALpiPath: string): Boolean;
2253+
var
2254+
LprPath, Content, ProjectBaseName: string;
2255+
begin
2256+
Result := False;
2257+
if not SameText(ExtractFileExt(ALpiPath), '.lpi') then
2258+
Exit;
2259+
2260+
ProjectBaseName := ChangeFileExt(ExtractFileName(ALpiPath), '');
2261+
if Pos('BenchmarkConsole', ProjectBaseName) > 0 then
2262+
Exit(True);
2263+
2264+
LprPath := ChangeFileExt(ALpiPath, '.lpr');
2265+
if not FileExists(LprPath) then
2266+
Exit;
2267+
2268+
Content := TLazXml.ReadFile(LprPath);
2269+
Result := Pos('TPerformanceBenchmark.Run', Content) > 0;
2270+
end;
2271+
21932272
procedure TMakeRunner.RunTestProject(const APath: string);
21942273
var
21952274
BinaryPath: string;
@@ -2271,13 +2350,73 @@ procedure TMakeRunner.BuildAllProjects;
22712350
end;
22722351
end;
22732352

2353+
procedure TMakeRunner.RunBenchmarkProjects;
2354+
var
2355+
List: TStringList;
2356+
Each, BinaryPath: string;
2357+
begin
2358+
if not FRunBenchmark then
2359+
begin
2360+
Log(CSI_Yellow, 'benchmarks: skipped (MAKE_RUN_BENCHMARK=false)');
2361+
Exit;
2362+
end;
2363+
2364+
if not DirectoryExists(BenchmarkDirectory) then
2365+
begin
2366+
IncError;
2367+
Log(CSI_Red, 'benchmark directory missing: ' + BenchmarkDirectory);
2368+
Exit;
2369+
end;
2370+
2371+
Log(CSI_Cyan, 'using benchmark directory: ' + BenchmarkDirectory);
2372+
List := TProjectFiles.FindAll(BenchmarkDirectory, '*.lpi');
2373+
try
2374+
for Each in List do
2375+
begin
2376+
if IsGUIProject(Each) then
2377+
begin
2378+
if not LclSupported then
2379+
begin
2380+
Log(CSI_Yellow, 'skip GUI benchmark project ' + Each);
2381+
Continue;
2382+
end;
2383+
BuildGuiProject(Each);
2384+
Continue;
2385+
end;
2386+
2387+
if not IsBenchmarkProject(Each) then
2388+
begin
2389+
Log(CSI_Yellow, 'skip non-benchmark project ' + Each);
2390+
Continue;
2391+
end;
2392+
2393+
BinaryPath := BuildProject(Each);
2394+
if BinaryPath = '' then
2395+
Continue;
2396+
try
2397+
Log(CSI_Yellow, 'run benchmark ' + BinaryPath);
2398+
RunBuiltBinary(BinaryPath, [], 'benchmark failed: ' + BinaryPath);
2399+
except
2400+
on E: Exception do
2401+
begin
2402+
IncError;
2403+
Log(CSI_Red, E.ClassName + ': ' + E.Message);
2404+
end;
2405+
end;
2406+
end;
2407+
finally
2408+
List.Free;
2409+
end;
2410+
end;
2411+
22742412
function TMakeRunner.Execute: Integer;
22752413
begin
22762414
InitEnvironment;
22772415
Log(CSI_Cyan, 'using target directory: ' + TargetDirectory);
22782416
UpdateSubmodules;
22792417
InstallDependencies;
22802418
BuildAllProjects;
2419+
RunBenchmarkProjects;
22812420
ReportSummary;
22822421
Result := FErrorCount;
22832422
end;

.github/workflows/make.yml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ env:
4444
# single: MAKE_DEFINES: WITH_GTK2_IM
4545
# multiple: MAKE_DEFINES: 'WITH_GTK2_IM DEBUG_LOG USE_CTHREADS'
4646
MAKE_DEFINES: ''
47+
# When true, make.pas builds and runs console benchmarks after the test suite.
48+
# Override per job below, like MAKE_BUILD_BACKEND.
49+
MAKE_RUN_BENCHMARK: false
4750
# Set by the workflow_dispatch "debug" toggle; '1' enables `set -x` tracing in
4851
# install-fpc-lazarus.sh, '0' otherwise. Forwarded into the sandboxed jobs below.
4952
CI_DEBUG: ${{ github.event.inputs.debug == 'true' && '1' || '0' }}
@@ -192,6 +195,7 @@ jobs:
192195
LAZARUS_REPO: ${{ env.LAZARUS_REPO }}
193196
MAKE_BUILD_BACKEND: ${{ env.MAKE_BUILD_BACKEND }}
194197
MAKE_PACKAGE_SCOPE: ${{ env.MAKE_PACKAGE_SCOPE }}
198+
MAKE_RUN_BENCHMARK: ${{ env.MAKE_RUN_BENCHMARK }}
195199
CI_DEBUG: ${{ env.CI_DEBUG }}
196200
run: bash .github/workflows/ci/arm32-run.sh
197201

@@ -217,6 +221,7 @@ jobs:
217221
FPC_TARBALL_TARGET: ${{ fromJSON(needs.setup.outputs.target_map)['linux-powerpc64-be'].fpc_tarball_target }}
218222
MAKE_BUILD_BACKEND: ${{ env.MAKE_BUILD_BACKEND }}
219223
MAKE_PACKAGE_SCOPE: ${{ env.MAKE_PACKAGE_SCOPE }}
224+
MAKE_RUN_BENCHMARK: ${{ env.MAKE_RUN_BENCHMARK }}
220225
run: bash .github/workflows/ci/ppc64-be-build.sh
221226

222227
freebsd:
@@ -238,7 +243,7 @@ jobs:
238243
FPC_TARBALL_TARGET: ${{ fromJSON(needs.setup.outputs.target_map)['freebsd'].fpc_tarball_target }}
239244
FREEBSD_INSTALL_MODE: interim
240245
with:
241-
envs: FPC_VERSION FPC_TARGET FPC_TARBALL_TARGET LAZARUS_BRANCH LAZARUS_REPO MAKE_BUILD_BACKEND MAKE_PACKAGE_SCOPE FREEBSD_INSTALL_MODE CI_DEBUG
246+
envs: FPC_VERSION FPC_TARGET FPC_TARBALL_TARGET LAZARUS_BRANCH LAZARUS_REPO MAKE_BUILD_BACKEND MAKE_PACKAGE_SCOPE MAKE_RUN_BENCHMARK FREEBSD_INSTALL_MODE CI_DEBUG
242247
release: "15.0"
243248
usesh: true
244249
prepare: sh .github/workflows/ci/vm-freebsd-prepare.sh
@@ -262,7 +267,7 @@ jobs:
262267
FPC_TARGET: ${{ fromJSON(needs.setup.outputs.target_map)['netbsd'].fpc_target }}
263268
FPC_TARBALL_TARGET: ${{ fromJSON(needs.setup.outputs.target_map)['netbsd'].fpc_tarball_target }}
264269
with:
265-
envs: FPC_VERSION LAZARUS_BRANCH LAZARUS_REPO MAKE_BUILD_BACKEND MAKE_PACKAGE_SCOPE FPC_TARGET FPC_TARBALL_TARGET CI_DEBUG
270+
envs: FPC_VERSION LAZARUS_BRANCH LAZARUS_REPO MAKE_BUILD_BACKEND MAKE_PACKAGE_SCOPE MAKE_RUN_BENCHMARK FPC_TARGET FPC_TARBALL_TARGET CI_DEBUG
266271
prepare: sh .github/workflows/ci/vm-netbsd-prepare.sh
267272
run: bash .github/workflows/ci/vm-run-shared.sh
268273

@@ -285,7 +290,7 @@ jobs:
285290
FPC_TARBALL_TARGET: ${{ fromJSON(needs.setup.outputs.target_map)['dragonflybsd'].fpc_tarball_target }}
286291
LD_LIBRARY_PATH_EXTRA: /usr/local/lib
287292
with:
288-
envs: FPC_VERSION LAZARUS_BRANCH LAZARUS_REPO MAKE_BUILD_BACKEND MAKE_PACKAGE_SCOPE FPC_TARGET FPC_TARBALL_TARGET LD_LIBRARY_PATH_EXTRA CI_DEBUG
293+
envs: FPC_VERSION LAZARUS_BRANCH LAZARUS_REPO MAKE_BUILD_BACKEND MAKE_PACKAGE_SCOPE MAKE_RUN_BENCHMARK FPC_TARGET FPC_TARBALL_TARGET LD_LIBRARY_PATH_EXTRA CI_DEBUG
289294
usesh: true
290295
prepare: sh .github/workflows/ci/vm-dragonfly-prepare.sh
291296
run: bash .github/workflows/ci/vm-run-shared.sh
@@ -308,7 +313,7 @@ jobs:
308313
FPC_TARGET: ${{ fromJSON(needs.setup.outputs.target_map)['solaris'].fpc_target }}
309314
FPC_TARBALL_TARGET: ${{ fromJSON(needs.setup.outputs.target_map)['solaris'].fpc_tarball_target }}
310315
with:
311-
envs: FPC_VERSION LAZARUS_BRANCH LAZARUS_REPO MAKE_BUILD_BACKEND MAKE_PACKAGE_SCOPE FPC_TARGET FPC_TARBALL_TARGET CI_DEBUG
316+
envs: FPC_VERSION LAZARUS_BRANCH LAZARUS_REPO MAKE_BUILD_BACKEND MAKE_PACKAGE_SCOPE MAKE_RUN_BENCHMARK FPC_TARGET FPC_TARBALL_TARGET CI_DEBUG
312317
release: "11.4-gcc"
313318
usesh: true
314319
prepare: sh .github/workflows/ci/vm-solaris-prepare.sh

0 commit comments

Comments
 (0)