From 6af3cb7793625cc40dd9261a9189e24c75fce5f9 Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Sun, 23 Mar 2025 12:41:13 -0700 Subject: [PATCH 1/2] Don't fail altjit compiles when RunAltJitCode=0 With RunAltJitCode=0, the JIT returns CORJIT_SKIPPED. We don't want superpmi to fail these compiles. --- .../superpmi-shared/methodcontext.cpp | 6 +-- .../superpmi/superpmi-shared/methodcontext.h | 4 +- .../tools/superpmi/superpmi/icorjitinfo.cpp | 11 +---- .../tools/superpmi/superpmi/jitinstance.cpp | 41 +++++++++++++++---- .../tools/superpmi/superpmi/jitinstance.h | 2 + 5 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 0621f2bcd1eb23..22213afb82b30a 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -7499,7 +7499,7 @@ MethodContext::Environment MethodContext::cloneEnvironment() } if (GetStringConfigValue != nullptr) { - env.getStingConfigValue = new LightWeightMap(*GetStringConfigValue); + env.getStringConfigValue = new LightWeightMap(*GetStringConfigValue); } return env; } @@ -7525,7 +7525,7 @@ bool MethodContext::IsEnvironmentHeaderEqual(const Environment& prevEnv) { return false; } - if (!AreLWMHeadersEqual(prevEnv.getStingConfigValue, GetStringConfigValue)) + if (!AreLWMHeadersEqual(prevEnv.getStringConfigValue, GetStringConfigValue)) { return false; } @@ -7539,7 +7539,7 @@ bool MethodContext::IsEnvironmentContentEqual(const Environment& prevEnv) { return false; } - if (!IsStringContentEqual(prevEnv.getStingConfigValue, GetStringConfigValue)) + if (!IsStringContentEqual(prevEnv.getStringConfigValue, GetStringConfigValue)) { return false; } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index 8763439565410e..dd9f4abc0f0d4f 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -915,12 +915,12 @@ class MethodContext struct Environment { - Environment() : getIntConfigValue(nullptr), getStingConfigValue(nullptr) + Environment() : getIntConfigValue(nullptr), getStringConfigValue(nullptr) { } LightWeightMap* getIntConfigValue; - LightWeightMap* getStingConfigValue; + LightWeightMap* getStringConfigValue; }; Environment cloneEnvironment(); diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 544b8f5d169bd8..d3792172ddd97f 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -1544,16 +1544,7 @@ void MyICJI::updateEntryPointForTailCall(CORINFO_CONST_LOOKUP* entryPoint) uint32_t MyICJI::getJitFlags(CORJIT_FLAGS* jitFlags, uint32_t sizeInBytes) { jitInstance->mc->cr->AddCall("getJitFlags"); - uint32_t ret = jitInstance->mc->repGetJitFlags(jitFlags, sizeInBytes); - if (jitInstance->forceClearAltJitFlag) - { - jitFlags->Clear(CORJIT_FLAGS::CORJIT_FLAG_ALT_JIT); - } - else if (jitInstance->forceSetAltJitFlag) - { - jitFlags->Set(CORJIT_FLAGS::CORJIT_FLAG_ALT_JIT); - } - return ret; + return jitInstance->getJitFlags(jitFlags, sizeInBytes); } // Runs the given function with the given parameter under an error trap diff --git a/src/coreclr/tools/superpmi/superpmi/jitinstance.cpp b/src/coreclr/tools/superpmi/superpmi/jitinstance.cpp index 0b02e4b8afe9e5..b24201fb831c24 100644 --- a/src/coreclr/tools/superpmi/superpmi/jitinstance.cpp +++ b/src/coreclr/tools/superpmi/superpmi/jitinstance.cpp @@ -56,8 +56,8 @@ JitInstance* JitInstance::InitJit(char* nameOfJit, } } - jit->environment.getIntConfigValue = nullptr; - jit->environment.getStingConfigValue = nullptr; + jit->environment.getIntConfigValue = nullptr; + jit->environment.getStringConfigValue = nullptr; if (st1 != nullptr) st1->Start(); @@ -244,7 +244,7 @@ ReplayResults JitInstance::CompileMethod(MethodContext* MethodToCompile, int mcI pParam->pThis->mc->repCompileMethod(&pParam->info, &pParam->flags, &os); CORJIT_FLAGS jitFlags; - pParam->pThis->mc->repGetJitFlags(&jitFlags, sizeof(jitFlags)); + pParam->pThis->getJitFlags(&jitFlags, sizeof(jitFlags)); pParam->results.IsMinOpts = jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE) || @@ -309,6 +309,17 @@ ReplayResults JitInstance::CompileMethod(MethodContext* MethodToCompile, int mcI { jitResult = CORJIT_OK; } + else + { + // If the target matches, but the JIT is an altjit and the user specified RunAltJitCode=0, + // then the JIT will also return CORJIT_SKIPPED, to prevent the generated code from being used. + // However, we don't want to treat that as a replay failure. + if (jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_ALT_JIT) && + (pParam->pThis->jitHost->getIntConfigValue("RunAltJitCode", 1) == 0)) + { + jitResult = CORJIT_OK; + } + } } if ((jitResult == CORJIT_OK) || (jitResult == CORJIT_BADCODE)) @@ -445,6 +456,22 @@ const char* JitInstance::getOption(const char* key, LightWeightMap return (const char*)options->GetBuffer(options->Get(keyIndex)); } +// Returns extended flags for a particular compilation instance, adjusted for altjit. +// This is a helper call; it does not record the call in the CompileResult. +uint32_t JitInstance::getJitFlags(CORJIT_FLAGS* jitFlags, uint32_t sizeInBytes) +{ + uint32_t ret = mc->repGetJitFlags(jitFlags, sizeInBytes); + if (forceClearAltJitFlag) + { + jitFlags->Clear(CORJIT_FLAGS::CORJIT_FLAG_ALT_JIT); + } + else if (forceSetAltJitFlag) + { + jitFlags->Set(CORJIT_FLAGS::CORJIT_FLAG_ALT_JIT); + } + return ret; +} + // Used to allocate memory that needs to handed to the EE. // For eg, use this to allocated memory for reporting debug info, // which will be handed to the EE by setVars() and setBoundaries() @@ -507,7 +534,7 @@ bool JitInstance::callJitStartup(ICorJitHost* jithost) } PAL_ENDTRY - Assert(environment.getIntConfigValue == nullptr && environment.getStingConfigValue == nullptr); + Assert(environment.getIntConfigValue == nullptr && environment.getStringConfigValue == nullptr); environment = mc->cloneEnvironment(); return param.result; @@ -527,10 +554,10 @@ bool JitInstance::resetConfig(MethodContext* firstContext) environment.getIntConfigValue = nullptr; } - if (environment.getStingConfigValue != nullptr) + if (environment.getStringConfigValue != nullptr) { - delete environment.getStingConfigValue; - environment.getStingConfigValue = nullptr; + delete environment.getStringConfigValue; + environment.getStringConfigValue = nullptr; } mc = firstContext; diff --git a/src/coreclr/tools/superpmi/superpmi/jitinstance.h b/src/coreclr/tools/superpmi/superpmi/jitinstance.h index 164147a100c0d6..b264894d368499 100644 --- a/src/coreclr/tools/superpmi/superpmi/jitinstance.h +++ b/src/coreclr/tools/superpmi/superpmi/jitinstance.h @@ -72,6 +72,8 @@ class JitInstance const char* getOption(const char* key); const char* getOption(const char* key, LightWeightMap* options); + uint32_t getJitFlags(CORJIT_FLAGS* jitFlags, uint32_t sizeInBytes); + const MethodContext::Environment& getEnvironment(); void* allocateArray(size_t size); From 3825faaa9a6f4fd2c4c661ca105bbb2f840bc9f9 Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Sun, 23 Mar 2025 16:17:40 -0700 Subject: [PATCH 2/2] Enable SuperPMI replay for APX ISA testing Create a new `runtime-coreclr superpmi-replay-apx` pipeline that does SuperPMI replay an AltJit with various APX enabling configuration options set. This enables some amount of APX testing even without hardware available to run the generated code. Notes: 1. Create a new jit-replay-pipeline.yml template to share the superpmi-replay pipeline implementation with the existing pipeline. 2. The existing pipeline is designated the "standard" replay type and the new pipeline the "apx" replay type. 3. The APX pipeline does replays for Windows x64 and Linux x64. 4. The configurations tested are: ``` a. "RunAltJitCode=0", "EnableAPX=1", "EnableApxNDD=1" b. "RunAltJitCode=0", "EnableAPX=1", "JitStressRex2Encoding=1" c. "RunAltJitCode=0", "EnableAPX=1", "JitStressPromotedEvexEncoding=1" d. "RunAltJitCode=0", "EnableAPX=1", "JitStressRegs=4000" e. "RunAltJitCode=0", "EnableAPX=1", "EnableApxNDD=1", "JitStressRex2Encoding=1", "JitStressPromotedEvexEncoding=1", "JitStressRegs=4000" ``` --- .../templates/runtimes/send-to-helix-step.yml | 2 + eng/pipelines/coreclr/superpmi-replay-apx.yml | 19 +++++ eng/pipelines/coreclr/superpmi-replay.yml | 56 ++----------- .../coreclr/templates/jit-replay-pipeline.yml | 58 +++++++++++++ .../templates/run-superpmi-replay-job.yml | 9 +- .../coreclr/templates/superpmi-replay-job.yml | 15 ++-- src/coreclr/scripts/superpmi-replay.proj | 29 ++++++- src/coreclr/scripts/superpmi_replay.py | 82 +++++++++++++------ src/coreclr/scripts/superpmi_replay_setup.py | 10 ++- 9 files changed, 192 insertions(+), 88 deletions(-) create mode 100644 eng/pipelines/coreclr/superpmi-replay-apx.yml create mode 100644 eng/pipelines/coreclr/templates/jit-replay-pipeline.yml diff --git a/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml b/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml index 989ccdc9319a92..918ba5b814aaa3 100644 --- a/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml +++ b/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml @@ -30,6 +30,7 @@ parameters: runtimeVariant: '' shouldContinueOnError: false SuperPmiCollect: '' + SuperPmiReplayType: '' SuperPmiDiffType: '' SuperPmiBaseJitOptions: '' SuperPmiDiffJitOptions: '' @@ -65,6 +66,7 @@ steps: RuntimeFlavor: ${{ parameters.runtimeFlavor }} _RuntimeVariant: ${{ parameters.runtimeVariant }} _SuperPmiCollect: ${{ parameters.SuperPmiCollect }} + _SuperPmiReplayType: ${{ parameters.SuperPmiReplayType }} _SuperPmiDiffType: ${{ parameters.SuperPmiDiffType }} _SuperPmiBaseJitOptions: ${{ parameters.SuperPmiBaseJitOptions }} _SuperPmiDiffJitOptions: ${{ parameters.SuperPmiDiffJitOptions }} diff --git a/eng/pipelines/coreclr/superpmi-replay-apx.yml b/eng/pipelines/coreclr/superpmi-replay-apx.yml new file mode 100644 index 00000000000000..f5e3f0d1adba4e --- /dev/null +++ b/eng/pipelines/coreclr/superpmi-replay-apx.yml @@ -0,0 +1,19 @@ +trigger: none + +schedules: +- cron: "0 7 * * *" + displayName: Daily at 11:00 PM (UTC-8:00) + branches: + include: + - main + always: true + +variables: + - template: /eng/pipelines/common/variables.yml + +extends: + template: /eng/pipelines/coreclr/templates/jit-replay-pipeline.yml + parameters: + platforms: + - windows_x64 + replayType: apx \ No newline at end of file diff --git a/eng/pipelines/coreclr/superpmi-replay.yml b/eng/pipelines/coreclr/superpmi-replay.yml index 322b3207dbd965..b3eebfe27034b1 100644 --- a/eng/pipelines/coreclr/superpmi-replay.yml +++ b/eng/pipelines/coreclr/superpmi-replay.yml @@ -12,55 +12,9 @@ variables: - template: /eng/pipelines/common/variables.yml extends: - template: /eng/pipelines/common/templates/pipeline-with-resources.yml + template: /eng/pipelines/coreclr/templates/jit-replay-pipeline.yml parameters: - stages: - # Don't run if the JIT-EE GUID has changed, - # since there won't be any SuperPMI collections with the new GUID until the collection - # pipeline completes after this PR is merged. - - ${{ if eq(variables['Build.Reason'], 'PullRequest') }}: - - stage: EvaluatePaths - displayName: Evaluate Paths - jobs: - - template: /eng/pipelines/common/evaluate-paths-job.yml - parameters: - paths: - - subset: jiteeversionguid - include: - - src/coreclr/inc/jiteeversionguid.h - - - stage: Build - jobs: - - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/global-build-job.yml - buildConfig: checked - platforms: - - windows_x64 - - windows_x86 - jobParameters: - buildArgs: -s clr.alljits+clr.spmi -c $(_BuildConfig) - postBuildSteps: - - template: /eng/pipelines/common/upload-artifact-step.yml - parameters: - rootFolder: $(Build.SourcesDirectory)/artifacts/bin/coreclr - includeRootFolder: false - archiveType: $(archiveType) - tarCompression: $(tarCompression) - archiveExtension: $(archiveExtension) - artifactName: CheckedJIT_$(osGroup)$(osSubgroup)_$(archType) - displayName: JIT and SuperPMI Assets - condition: not(eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_jiteeversionguid.containsChange'], true)) - - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/coreclr/templates/superpmi-replay-job.yml - buildConfig: checked - platforms: - - windows_x64 - - windows_x86 - helixQueueGroup: ci - helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml - jobParameters: - condition: not(eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_jiteeversionguid.containsChange'], true)) + platforms: + - windows_x64 + - windows_x86 + replayType: standard diff --git a/eng/pipelines/coreclr/templates/jit-replay-pipeline.yml b/eng/pipelines/coreclr/templates/jit-replay-pipeline.yml new file mode 100644 index 00000000000000..74f2caf2ff3852 --- /dev/null +++ b/eng/pipelines/coreclr/templates/jit-replay-pipeline.yml @@ -0,0 +1,58 @@ +parameters: + - name: platforms + type: object + - name: replayType + type: string + default: standard + +extends: + template: /eng/pipelines/common/templates/pipeline-with-resources.yml + parameters: + stages: + # Don't run if the JIT-EE GUID has changed, + # since there won't be any SuperPMI collections with the new GUID until the collection + # pipeline completes after this PR is merged. + - ${{ if eq(variables['Build.Reason'], 'PullRequest') }}: + - stage: EvaluatePaths + displayName: Evaluate Paths + jobs: + - template: /eng/pipelines/common/evaluate-paths-job.yml + parameters: + paths: + - subset: jiteeversionguid + include: + - src/coreclr/inc/jiteeversionguid.h + + - stage: Build + jobs: + + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: checked + platforms: ${{ parameters.platforms }} + jobParameters: + buildArgs: -s clr.alljits+clr.spmi -c $(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/common/upload-artifact-step.yml + parameters: + rootFolder: $(Build.SourcesDirectory)/artifacts/bin/coreclr + includeRootFolder: false + archiveType: $(archiveType) + tarCompression: $(tarCompression) + archiveExtension: $(archiveExtension) + artifactName: BuildArtifacts_$(osGroup)$(osSubgroup)_$(archType)_$(_BuildConfig) + displayName: Build Assets + condition: not(eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_jiteeversionguid.containsChange'], true)) + + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/coreclr/templates/superpmi-replay-job.yml + buildConfig: checked + platforms: ${{ parameters.platforms }} + helixQueueGroup: ci + helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml + jobParameters: + condition: not(eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_jiteeversionguid.containsChange'], true)) + replayType: ${{ parameters.replayType }} + unifiedArtifactsName: BuildArtifacts_$(osGroup)$(osSubgroup)_$(archType)_$(_BuildConfig) diff --git a/eng/pipelines/coreclr/templates/run-superpmi-replay-job.yml b/eng/pipelines/coreclr/templates/run-superpmi-replay-job.yml index 4047a8cb2f7cf6..27cc61c653de47 100644 --- a/eng/pipelines/coreclr/templates/run-superpmi-replay-job.yml +++ b/eng/pipelines/coreclr/templates/run-superpmi-replay-job.yml @@ -16,6 +16,7 @@ parameters: enableTelemetry: false # optional -- enable for telemetry liveLibrariesBuildConfig: '' # optional -- live-live libraries configuration to use for the run helixQueues: '' # required -- Helix queues + replayType: 'standard' # required -- 'standard', 'apx' jobs: - template: /eng/pipelines/common/templates/runtimes/xplat-job.yml @@ -47,6 +48,9 @@ jobs: - ${{ each variable in parameters.variables }}: - ${{insert}}: ${{ variable }} + - name: replayType + value: ${{ parameters.replayType }} + - template: /eng/pipelines/coreclr/templates/jit-python-variables.yml parameters: osGroup: ${{ parameters.osGroup }} @@ -74,8 +78,8 @@ jobs: mkdir $(SpmiLogsLocation) displayName: Create directories - - script: $(PythonScript) $(Build.SourcesDirectory)/src/coreclr/scripts/superpmi_replay_setup.py -source_directory $(Build.SourcesDirectory) -product_directory $(buildProductRootFolderPath) -arch $(archType) - displayName: ${{ format('SuperPMI replay setup ({0})', parameters.archType) }} + - script: $(PythonScript) $(Build.SourcesDirectory)/src/coreclr/scripts/superpmi_replay_setup.py -source_directory $(Build.SourcesDirectory) -product_directory $(buildProductRootFolderPath) -type $(replayType) -arch $(archType) + displayName: ${{ format('SuperPMI replay setup ({0} {1})', parameters.replayType, parameters.archType) }} # Run superpmi replay in helix - template: /eng/pipelines/common/templates/runtimes/send-to-helix-step.yml @@ -93,6 +97,7 @@ jobs: BuildConfig: ${{ parameters.buildConfig }} osGroup: ${{ parameters.osGroup }} archType: ${{ parameters.archType }} + SuperPmiReplayType: ${{ parameters.replayType }} # Always upload the available logs for diagnostics - task: CopyFiles@2 diff --git a/eng/pipelines/coreclr/templates/superpmi-replay-job.yml b/eng/pipelines/coreclr/templates/superpmi-replay-job.yml index ea7854339a2147..ec364c8d506321 100644 --- a/eng/pipelines/coreclr/templates/superpmi-replay-job.yml +++ b/eng/pipelines/coreclr/templates/superpmi-replay-job.yml @@ -9,12 +9,14 @@ parameters: variables: {} helixQueues: '' runJobTemplate: '/eng/pipelines/coreclr/templates/run-superpmi-replay-job.yml' + replayType: 'standard' + unifiedArtifactsName: '' jobs: - template: ${{ parameters.runJobTemplate }} parameters: - jobName: ${{ format('superpmi_replay_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - displayName: ${{ format('SuperPMI replay {0}{1} {2} {3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + jobName: ${{ format('superpmi_replay_{0}_{1}{2}_{3}_{4}', parameters.replayType, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + displayName: ${{ format('SuperPMI replay {0} {1}{2} {3} {4}', parameters.replayType, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} pool: ${{ parameters.pool }} buildConfig: ${{ parameters.buildConfig }} archType: ${{ parameters.archType }} @@ -23,6 +25,7 @@ jobs: condition: ${{ parameters.condition }} timeoutInMinutes: ${{ parameters.timeoutInMinutes }} helixQueues: ${{ parameters.helixQueues }} + replayType: ${{ parameters.replayType }} dependsOn: - 'build_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }}_' @@ -30,11 +33,11 @@ jobs: steps: - # Download jit builds + # Download builds - template: /eng/pipelines/common/download-artifact-step.yml parameters: unpackFolder: $(Build.SourcesDirectory)/artifacts/bin/coreclr - artifactFileName: 'CheckedJIT_$(osGroup)$(osSubgroup)_$(archType)$(archiveExtension)' - artifactName: 'CheckedJIT_$(osGroup)$(osSubgroup)_$(archType)' - displayName: 'JIT checked build' + artifactFileName: '${{ parameters.unifiedArtifactsName }}$(archiveExtension)' + artifactName: '${{ parameters.unifiedArtifactsName }}' + displayName: 'unified artifacts' cleanUnpackFolder: false diff --git a/src/coreclr/scripts/superpmi-replay.proj b/src/coreclr/scripts/superpmi-replay.proj index 398dec78ecc221..c19831f43fb2f7 100644 --- a/src/coreclr/scripts/superpmi-replay.proj +++ b/src/coreclr/scripts/superpmi-replay.proj @@ -24,11 +24,17 @@ timeout: %(HelixWorkItem.Timeout) '"/> --> + + + standard + $(_SuperPmiReplayType) + + %HELIX_PYTHONPATH% %HELIX_CORRELATION_PAYLOAD% %HELIX_WORKITEM_UPLOAD_ROOT% - $(Python) $(ProductDirectory)\superpmi_replay.py -jit_directory $(ProductDirectory) + $(Python) $(ProductDirectory)\superpmi_replay.py -type $(SuperPmiReplayType) -jit_directory $(ProductDirectory) 3:15 @@ -49,7 +55,7 @@ - + @@ -97,7 +103,7 @@ - + @@ -118,11 +124,26 @@ + + + + + + + + + + + + + + + $(WorkItemCommand) -arch %(HelixWorkItem.Architecture) -platform %(HelixWorkItem.Platform) -partition %(HelixWorkItem.Partition) -partition_count %(HelixWorkItem.PartitionCount) -log_directory $(SuperpmiLogsLocation) $(WorkItemTimeout) - superpmi_%(HelixWorkItem.Platform)_%(HelixWorkItem.Architecture)_%(HelixWorkItem.Partition).log + superpmi_final_%(HelixWorkItem.Platform)_%(HelixWorkItem.Architecture)_%(HelixWorkItem.Partition).log diff --git a/src/coreclr/scripts/superpmi_replay.py b/src/coreclr/scripts/superpmi_replay.py index d2cf1eec37fb7b..6af44151cb599a 100644 --- a/src/coreclr/scripts/superpmi_replay.py +++ b/src/coreclr/scripts/superpmi_replay.py @@ -19,25 +19,36 @@ parser = argparse.ArgumentParser(description="description") +parser.add_argument("-type", required=True, help="Type of replay (standard, apx)") parser.add_argument("-arch", help="Architecture") parser.add_argument("-platform", help="OS platform") parser.add_argument("-jit_directory", help="path to the directory containing clrjit binaries") parser.add_argument("-log_directory", help="path to the directory containing superpmi log files") parser.add_argument("-partition", help="Partition number specifying which set of flags to use: between 1 and the `-partition_count` value") -parser.add_argument("-partition_count", help="Count of the total number of partitions we are using: should be <= 9 (number of jit_flags_all elements)") - -jit_flags_all = [ - "JitStressRegs=0", - "JitStressRegs=1", - "JitStressRegs=2", - "JitStressRegs=3", - "JitStressRegs=4", - "JitStressRegs=8", - "JitStressRegs=0x10", - "JitStressRegs=0x80", - "JitStressRegs=0x1000", +parser.add_argument("-partition_count", help="Count of the total number of partitions we are using: should be <= the total number of flags combinations for the type") + +configuration_standard = [ + [ "JitStressRegs=0" ], + [ "JitStressRegs=1" ], + [ "JitStressRegs=2" ], + [ "JitStressRegs=3" ], + [ "JitStressRegs=4" ], + [ "JitStressRegs=8" ], + [ "JitStressRegs=0x10" ], + [ "JitStressRegs=0x80" ], + [ "JitStressRegs=0x1000" ] ] +configuration_apx = [ + [ "RunAltJitCode=0", "EnableAPX=1" ], + [ "RunAltJitCode=0", "EnableAPX=1", "EnableApxNDD=1" ], + [ "RunAltJitCode=0", "EnableAPX=1", "JitStressRex2Encoding=1" ], + [ "RunAltJitCode=0", "EnableAPX=1", "JitStressPromotedEvexEncoding=1" ], + [ "RunAltJitCode=0", "EnableAPX=1", "JitStressRegs=4000" ], + [ "RunAltJitCode=0", "EnableAPX=1", "EnableApxNDD=1", "JitStressRex2Encoding=1", "JitStressPromotedEvexEncoding=1", "JitStressRegs=4000" ] +] + + def split(a, n): """ Splits array `a` in `n` partitions. Slightly modified from https://stackoverflow.com/a/2135920. @@ -66,6 +77,11 @@ def setup_args(args): coreclr_args = CoreclrArguments(args, require_built_core_root=False, require_built_product_dir=False, require_built_test_dir=False, default_build_type="Checked") + coreclr_args.verify(args, + "type", + lambda type: type in ["standard", "apx"], + "Invalid type \"{}\"".format) + coreclr_args.verify(args, "arch", lambda unused: True, @@ -137,8 +153,14 @@ def main(main_args): os_name = "universal" if arch_name.startswith("arm") else os_name jit_path = os.path.join(coreclr_args.jit_directory, 'clrjit_{}_{}_{}.dll'.format(os_name, arch_name, host_arch_name)) - jit_flags_partitioned = split(jit_flags_all, coreclr_args.partition_count) - jit_flags = jit_flags_partitioned[coreclr_args.partition - 1] # partition number is 1-based + type_configuration_settings = None + if coreclr_args.type == 'standard': + type_configuration_settings = configuration_standard + elif coreclr_args.type == 'apx': + type_configuration_settings = configuration_apx + + configuration_settings_partitioned = split(type_configuration_settings, coreclr_args.partition_count) + partition_configuration_settings = configuration_settings_partitioned[coreclr_args.partition - 1] # partition number is 1-based print("Running superpmi.py download") run_command([python_path, @@ -152,33 +174,47 @@ def main(main_args): "-log_level", "debug"], _exit_on_fail=True) failed_runs = [] - for jit_flag in jit_flags: - log_file = os.path.join(log_directory, 'superpmi_{}.log'.format(jit_flag.replace("=", "_"))) - print("Running superpmi.py replay for {}".format(jit_flag)) + for configuration_settings in partition_configuration_settings: + # Construct the command-line options and log file based on the configuration settings + log_file_tag = "_".join(configuration_settings).replace("=", "_") + log_file = os.path.join(log_directory, 'superpmi_config_{}.log'.format(log_file_tag)) + + config_arguments = [] + config_display = "" + for flag in configuration_settings: + config_arguments += "-jitoption", flag + config_display += " " + flag + + # Special case: setting altjit requires passing `--altjit` to superpmi.py. + if coreclr_args.type == 'apx': + config_arguments += [ "--altjit" ] + config_display += " --altjit" + + print("Running superpmi.py replay for{}".format(config_display)) - _, _, return_code = run_command([ + command_line = [ python_path, os.path.join(cwd, "superpmi.py"), "replay", "-core_root", cwd, - "-jitoption", jit_flag, "-target_os", platform_name, "-target_arch", arch_name, "-arch", host_arch_name, "-jit_path", jit_path, "-spmi_location", spmi_location, "-log_level", "debug", - "-log_file", log_file]) + "-log_file", log_file] + config_arguments + _, _, return_code = run_command(command_line) if return_code != 0: failed_runs.append("Failure in {}".format(log_file)) # Consolidate all superpmi_*.logs in superpmi_platform_architecture.log - final_log_name = os.path.join(log_directory, "superpmi_{}_{}_{}.log".format(platform_name, arch_name, coreclr_args.partition)) + final_log_name = os.path.join(log_directory, "superpmi_final_{}_{}_{}.log".format(platform_name, arch_name, coreclr_args.partition)) print("Consolidating final {}".format(final_log_name)) with open(final_log_name, "a") as final_superpmi_log: for superpmi_log in os.listdir(log_directory): - if not superpmi_log.startswith("superpmi_Jit") or not superpmi_log.endswith(".log"): + if not superpmi_log.startswith("superpmi_config_") or not superpmi_log.endswith(".log"): continue print("Appending {}".format(superpmi_log)) @@ -193,7 +229,7 @@ def main(main_args): if len(failed_runs) > 0: final_superpmi_log.write(os.linesep) final_superpmi_log.write(os.linesep) - final_superpmi_log.write("========Failed runs summary========".format(os.linesep)) + final_superpmi_log.write("========Failed runs summary========{}".format(os.linesep)) final_superpmi_log.write(os.linesep.join(failed_runs)) return 0 if len(failed_runs) == 0 else 1 diff --git a/src/coreclr/scripts/superpmi_replay_setup.py b/src/coreclr/scripts/superpmi_replay_setup.py index b7717da8efaf24..d3c62f561cab1c 100644 --- a/src/coreclr/scripts/superpmi_replay_setup.py +++ b/src/coreclr/scripts/superpmi_replay_setup.py @@ -22,8 +22,9 @@ parser = argparse.ArgumentParser(description="description") parser.add_argument("-arch", help="Architecture") -parser.add_argument("-source_directory", help="path to the directory containing binaries") -parser.add_argument("-product_directory", help="path to the directory containing binaries") +parser.add_argument("-type", required=True, help="Type of diff (standard, apx)") +parser.add_argument("-source_directory", required=True, help="Path to the root directory of the dotnet/runtime source tree") +parser.add_argument("-product_directory", required=True, help="path to the directory containing binaries") def setup_args(args): @@ -54,6 +55,11 @@ def setup_args(args): lambda product_directory: os.path.isdir(product_directory), "product_directory doesn't exist") + coreclr_args.verify(args, + "type", + lambda type: type in ["standard", "apx"], + "Invalid type \"{}\"".format) + return coreclr_args