Add linux-x64 hosted tpdiff to superpmi-diffs pipeline (#86021)
authorBruce Forstall <brucefo@microsoft.com>
Wed, 10 May 2023 21:42:26 +0000 (14:42 -0700)
committerGitHub <noreply@github.com>
Wed, 10 May 2023 21:42:26 +0000 (14:42 -0700)
* Add linux-x64 hosted tpdiff to superpmi-diffs pipeline

With this, we get instruction count diffs based on clang compiled
native JITs.

* Fix some variables

Also, fix some Python 'lint' issues.

* Fix more path issues, Windows targeting global var

* Feedback

1. Make `determine_jit_name` a utility library function.
All 3 versions were different, so required some adjustments.
jitrollingbuild.py had not previously used `jitutil` so added use
and removed additional duplicated code.
2. Renamed partitions to not use `unix` name. This is purely an internal
name, not exposed.
3. Simplified some FileSeparatorChar usage.
4. Fixed more pylint complaints

12 files changed:
eng/pipelines/coreclr/superpmi-diffs.yml
eng/pipelines/coreclr/templates/run-superpmi-diffs-job.yml
eng/pipelines/coreclr/templates/superpmi-diffs-job.yml
src/coreclr/scripts/jitrollingbuild.py
src/coreclr/scripts/jitutil.py
src/coreclr/scripts/superpmi-asmdiffs-checked-release.proj
src/coreclr/scripts/superpmi-diffs.proj
src/coreclr/scripts/superpmi-replay.proj
src/coreclr/scripts/superpmi.py
src/coreclr/scripts/superpmi_diffs.py
src/coreclr/scripts/superpmi_diffs_setup.py
src/coreclr/scripts/superpmi_diffs_summarize.py

index dc97bac..8dab51f 100644 (file)
@@ -61,6 +61,7 @@ extends:
           platforms:
           - windows_x64
           - windows_x86
+          - linux_x64
           jobParameters:
             uploadAs: 'pipelineArtifacts'
             condition: not(eq(dependencies.evaluate_paths.outputs['SetPathVars_jiteeversionguid.containsChange'], true))
@@ -87,6 +88,7 @@ extends:
           platforms:
           - windows_x64
           - windows_x86
+          - linux_x64
           helixQueueGroup: ci
           helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
           jobParameters:
index 1aeb887..b987c25 100644 (file)
@@ -47,18 +47,32 @@ jobs:
     - name: diffType
       value: ${{ parameters.diffType }}
 
-    - name: PythonScript
-      value: 'py -3'
-    - name: PipScript
-      value: 'py -3 -m pip'
-    - name: SpmiCollectionLocation
-      value: '$(Build.SourcesDirectory)\artifacts\spmi\'
-    - name: SpmiLogsLocation
-      value: '$(Build.SourcesDirectory)\artifacts\spmi_logs\'
-    - name: SpmiDiffsLocation
-      value: '$(Build.SourcesDirectory)\artifacts\spmi_diffs\'
-    - name: HelixResultLocation
-      value: '$(Build.SourcesDirectory)\artifacts\helixresults\'
+    - ${{ if eq(parameters.osGroup, 'windows') }}:
+      - name: PythonScript
+        value: 'py -3'
+      - name: PipScript
+        value: 'py -3 -m pip'
+      - name: SpmiCollectionLocation
+        value: '$(Build.SourcesDirectory)\artifacts\spmi\'
+      - name: SpmiLogsLocation
+        value: '$(Build.SourcesDirectory)\artifacts\spmi_logs\'
+      - name: SpmiDiffsLocation
+        value: '$(Build.SourcesDirectory)\artifacts\spmi_diffs\'
+      - name: HelixResultLocation
+        value: '$(Build.SourcesDirectory)\artifacts\helixresults\'
+    - ${{ if ne(parameters.osGroup, 'windows') }}:
+      - name: PythonScript
+        value: 'python3'
+      - name: PipScript
+        value: 'pip3'
+      - name: SpmiCollectionLocation
+        value: '$(Build.SourcesDirectory)/artifacts/spmi/'
+      - name: SpmiLogsLocation
+        value: '$(Build.SourcesDirectory)/artifacts/spmi_logs/'
+      - name: SpmiDiffsLocation
+        value: '$(Build.SourcesDirectory)/artifacts/spmi_diffs/'
+      - name: HelixResultLocation
+        value: '$(Build.SourcesDirectory)/artifacts/helixresults/'
 
     - name: SetupScriptDirs
       value: ''
@@ -80,14 +94,21 @@ jobs:
     steps:
     - ${{ parameters.steps }}
 
-    - script: |
-        mkdir $(SpmiCollectionLocation)
-        mkdir $(SpmiLogsLocation)
-        mkdir $(SpmiDiffsLocation)
-      displayName: Create directories
-
-    - script: $(PythonScript) $(Build.SourcesDirectory)/src/coreclr/scripts/superpmi_diffs_setup.py -source_directory $(Build.SourcesDirectory) $(SetupScriptDirs) -type $(diffType) -arch $(archType)
-      displayName: ${{ format('SuperPMI diffs setup ({0} {1})', parameters.diffType, parameters.archType) }}
+    - ${{ if ne(parameters.osGroup, 'windows') }}:
+      - script: |
+          mkdir -p $(SpmiCollectionLocation)
+          mkdir -p $(SpmiLogsLocation)
+          mkdir -p $(SpmiDiffsLocation)
+        displayName: Create directories
+    - ${{ if eq(parameters.osGroup, 'windows') }}:
+      - script: |
+          mkdir $(SpmiCollectionLocation)
+          mkdir $(SpmiLogsLocation)
+          mkdir $(SpmiDiffsLocation)
+        displayName: Create directories
+
+    - script: $(PythonScript) $(Build.SourcesDirectory)/src/coreclr/scripts/superpmi_diffs_setup.py -source_directory $(Build.SourcesDirectory) $(SetupScriptDirs) -type $(diffType) -platform $(osGroup) -arch $(archType)
+      displayName: ${{ format('SuperPMI diffs setup ({0} {1}{2} {3})', parameters.diffType, parameters.osGroup, parameters.osSubgroup, parameters.archType) }}
 
       # Run superpmi-diffs.py script in helix
     - template: /eng/pipelines/common/templates/runtimes/send-to-helix-step.yml
@@ -104,6 +125,7 @@ jobs:
         helixProjectArguments: '$(Build.SourcesDirectory)/src/coreclr/scripts/superpmi-diffs.proj'
         BuildConfig: ${{ parameters.buildConfig }}
         osGroup: ${{ parameters.osGroup }}
+        osSubgroup: ${{ parameters.osSubgroup }}
         archType: ${{ parameters.archType }}
         SuperPmiDiffType: ${{ parameters.diffType }}
         SuperPmiBaseJitOptions: ${{ parameters.baseJitOptions }}
@@ -135,15 +157,15 @@ jobs:
           targetFolder: '$(SpmiDiffsLocation)'
         condition: always()
 
-    - script: $(PythonScript) $(Build.SourcesDirectory)/src/coreclr/scripts/superpmi_diffs_summarize.py -diff_summary_dir $(SpmiDiffsLocation) -type $(diffType) -arch $(archType)
-      displayName: ${{ format('Summarize ({0} {1})', parameters.diffType, parameters.archType) }}
+    - script: $(PythonScript) $(Build.SourcesDirectory)/src/coreclr/scripts/superpmi_diffs_summarize.py -diff_summary_dir $(SpmiDiffsLocation) -type $(diffType) -platform $(osGroup) -arch $(archType)
+      displayName: ${{ format('Summarize ({0} {1}{2} {3})', parameters.diffType, parameters.osGroup, parameters.osSubgroup, parameters.archType) }}
       condition: always()
 
     - task: PublishPipelineArtifact@1
       displayName: Publish SuperPMI logs
       inputs:
         targetPath: $(SpmiLogsLocation)
-        artifactName: 'SuperPMI_Logs_$(diffType)_$(archType)_$(buildConfig)_Attempt$(System.JobAttempt)'
+        artifactName: 'SuperPMI_Logs_$(diffType)_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)_Attempt$(System.JobAttempt)'
       condition: always()
       continueOnError: true
 
@@ -151,7 +173,7 @@ jobs:
       displayName: Publish SuperPMI diffs files
       inputs:
         targetPath: $(SpmiDiffsLocation)
-        artifactName: 'SuperPMI_Diffs_$(diffType)_$(archType)_$(buildConfig)_Attempt$(System.JobAttempt)'
+        artifactName: 'SuperPMI_Diffs_$(diffType)_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)_Attempt$(System.JobAttempt)'
       condition: always()
       continueOnError: true
 
@@ -159,6 +181,6 @@ jobs:
       displayName: Publish SuperPMI build logs
       inputs:
         targetPath: $(Build.SourcesDirectory)/artifacts/log
-        artifactName: 'SuperPMI_BuildLogs_$(diffType)_$(archType)_$(buildConfig)_Attempt$(System.JobAttempt)'
+        artifactName: 'SuperPMI_BuildLogs_$(diffType)_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)_Attempt$(System.JobAttempt)'
       condition: always()
       continueOnError: true
index 15299de..aace201 100644 (file)
@@ -42,8 +42,12 @@ jobs:
       - ${{insert}}: ${{ variable }}
 
     - ${{ if in(parameters.diffType, 'tpdiff', 'all') }}:
-      - name: releaseProductRootFolderPath
-        value: '$(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).Release'
+      - ${{ if eq(parameters.osGroup, 'windows') }}:
+        - name: releaseProductRootFolderPath
+          value: '$(Build.SourcesDirectory)\artifacts\bin\coreclr\$(osGroup).$(archType).Release'
+      - ${{ if ne(parameters.osGroup, 'windows') }}:
+        - name: releaseProductRootFolderPath
+          value: '$(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).Release'
       - name: releaseProductArtifactName
         value: 'CoreCLRProduct_${{ parameters.pgoType }}_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_release'
 
index 5097c45..07d48c1 100644 (file)
@@ -26,6 +26,7 @@ import zipfile
 import re
 
 from coreclr_arguments import *
+from jitutil import TempDir, ChangeDir, determine_jit_name
 
 locale.setlocale(locale.LC_ALL, '')  # Use '' for auto, or force e.g. to 'en_US.UTF-8'
 
@@ -125,72 +126,6 @@ list_parser.add_argument("--all", action="store_true", help="Show all JITs, not
 list_parser.add_argument("--global_all", action="store_true", help="Show all JITs in Azure Storage")
 
 ################################################################################
-# Helper classes
-################################################################################
-
-
-class TempDir:
-    """ Class to create a temporary working directory, or use one that is passed as an argument.
-
-        Use with: "with TempDir() as temp_dir" to change to that directory and then automatically
-        change back to the original working directory afterwards and remove the temporary
-        directory and its contents (if args.skip_cleanup is False).
-    """
-
-    def __init__(self, path=None):
-        self.mydir = tempfile.mkdtemp() if path is None else path
-        self.cwd = None
-
-    def __enter__(self):
-        self.cwd = os.getcwd()
-        os.chdir(self.mydir)
-        return self.mydir
-
-    def __exit__(self, exc_type, exc_val, exc_tb):
-        os.chdir(self.cwd)
-        # Note: we are using the global `args`, not coreclr_args. This works because
-        # the `skip_cleanup` argument is not processed by CoreclrArguments, but is
-        # just copied there.
-        if not args.skip_cleanup:
-            shutil.rmtree(self.mydir)
-
-
-class ChangeDir:
-    """ Class to temporarily change to a given directory. Use with "with".
-    """
-
-    def __init__(self, mydir):
-        self.mydir = mydir
-        self.cwd = None
-
-    def __enter__(self):
-        self.cwd = os.getcwd()
-        os.chdir(self.mydir)
-
-    def __exit__(self, exc_type, exc_val, exc_tb):
-        os.chdir(self.cwd)
-
-
-def determine_jit_name(coreclr_args):
-    """ Determine the jit based on the OS. If "-altjit" is specified, then use the specified altjit,
-        or an appropriate altjit based on target.
-
-    Args:
-        coreclr_args (CoreclrArguments): parsed args
-
-    Return:
-        jit_name(str) : name of the jit for this os
-    """
-
-    jit_base_name = "clrjit"
-    if coreclr_args.host_os == "osx":
-        return "lib" + jit_base_name + ".dylib"
-    elif coreclr_args.host_os == "linux":
-        return "lib" + jit_base_name + ".so"
-    elif coreclr_args.host_os == "windows":
-        return jit_base_name + ".dll"
-    else:
-        raise RuntimeError("Unknown OS.")
 
 
 def process_git_hash_arg(coreclr_args, return_first_hash=False):
@@ -447,7 +382,7 @@ def upload_command(coreclr_args):
     files = []
 
     # First, find the primary JIT that we expect to find.
-    jit_name = determine_jit_name(coreclr_args)
+    jit_name = determine_jit_name(coreclr_args.host_os)
     jit_path = os.path.join(coreclr_args.product_location, jit_name)
     if not os.path.isfile(jit_path):
         logging.error("Error: Couldn't find JIT at {}".format(jit_path))
index be0bdaa..5a6b4dd 100644 (file)
@@ -30,6 +30,7 @@ import zipfile
 ##
 ################################################################################
 
+
 class TempDir:
     """ Class to create a temporary working directory, or use one that is passed as an argument.
 
@@ -69,6 +70,7 @@ class TempDir:
                 except Exception:
                     pass
 
+
 class ChangeDir:
     """ Class to temporarily change to a given directory. Use with "with".
     """
@@ -103,7 +105,6 @@ def set_pipeline_variable(name, value):
     print(define_variable_format.format(name, value))  # set variable
 
 
-
 ################################################################################
 ##
 ## Helper functions
@@ -127,6 +128,7 @@ def decode_and_print(str_to_decode):
     finally:
         return output
 
+
 def run_command(command_to_run, _cwd=None, _exit_on_fail=False, _output_file=None, _env=None):
     """ Runs the command.
 
@@ -134,7 +136,7 @@ def run_command(command_to_run, _cwd=None, _exit_on_fail=False, _output_file=Non
         command_to_run ([string]): Command to run along with arguments.
         _cwd (string): Current working directory.
         _exit_on_fail (bool): If it should exit on failure.
-        _output_file (): 
+        _output_file ():
         _env: environment for sub-process, passed to subprocess.Popen()
     Returns:
         (string, string, int): Returns a tuple of stdout, stderr, and command return code if _output_file= None
@@ -450,6 +452,48 @@ def is_url(path):
     # If it doesn't look like an URL, treat it like a file, possibly a UNC file.
     return path.lower().startswith("http:") or path.lower().startswith("https:")
 
+
+def determine_jit_name(host_os, target_os=None, host_arch=None, target_arch=None, use_cross_compile_jit=False):
+    """ Determine the jit file name to use.
+
+    Args:
+        host_os               (str)  : name of the OS the JIT will run on
+        target_os             (str)  : name of the OS the JIT will generate code for. Only needed for cross-compiler case.
+        host_arch             (str)  : name of the architecture the JIT will run on. Only needed for cross-compiler case.
+        target_arch           (str)  : name of the architecture the JIT will generate code for. Only needed for cross-compiler case.
+        use_cross_compile_jit (bool) : If True, will always generate a fully named "cross-compile" JIT,
+                                       not the default "clrjit.dll".
+
+        If you pass one of target_os, host_arch, or target_arch, you must pass them all.
+
+    Return:
+        (str) : name of the jit for this OS
+    """
+
+    jit_base_name = 'clrjit'
+
+    if use_cross_compile_jit or (host_arch != target_arch) or ((target_os is not None) and (host_os != target_os)):
+        if target_arch.startswith("arm"):
+            jit_os_name = "universal"
+        elif target_os == "windows":
+            jit_os_name = "win"
+        elif target_os == "osx" or target_os == "linux":
+            jit_os_name = "unix"
+        else:
+            raise RuntimeError("Unknown target OS.")
+
+        jit_base_name = 'clrjit_{}_{}_{}'.format(jit_os_name, target_arch, host_arch)
+
+    if host_os == "osx":
+        return "lib" + jit_base_name + ".dylib"
+    elif host_os == "linux":
+        return "lib" + jit_base_name + ".so"
+    elif host_os == "windows":
+        return jit_base_name + ".dll"
+    else:
+        raise RuntimeError("Unknown host OS.")
+
+
 ################################################################################
 ##
 ## Azure Storage functions
index 2f5c43d..412ceee 100644 (file)
   </ItemGroup>
 
   <ItemGroup Condition="'$(Architecture)' == 'x64'">
-    <SPMI_Partition Include="win-x64" Platform="windows" Architecture="x64" />
-    <SPMI_Partition Include="win-arm64" Platform="windows" Architecture="arm64" />
-    <SPMI_Partition Include="unix-x64" Platform="linux" Architecture="x64" />
-    <SPMI_Partition Include="unix-arm64" Platform="linux" Architecture="arm64" />
+    <SPMI_Partition Include="windows-x64" Platform="windows" Architecture="x64" />
+    <SPMI_Partition Include="windows-arm64" Platform="windows" Architecture="arm64" />
+    <SPMI_Partition Include="linux-x64" Platform="linux" Architecture="x64" />
+    <SPMI_Partition Include="linux-arm64" Platform="linux" Architecture="arm64" />
   </ItemGroup>
 
   <ItemGroup Condition="'$(Architecture)' == 'x86'">
-    <SPMI_Partition Include="win-x86" Platform="windows" Architecture="x86" />
-    <SPMI_Partition Include="unix-arm" Platform="linux" Architecture="arm" />
+    <SPMI_Partition Include="windows-x86" Platform="windows" Architecture="x86" />
+    <SPMI_Partition Include="linux-arm" Platform="linux" Architecture="arm" />
   </ItemGroup>
 
   <ItemGroup>
index 7faf1f1..015de22 100644 (file)
      timeout: %(HelixWorkItem.Timeout)  '"/>
   </Target> -->
 
-  <PropertyGroup>
+  <PropertyGroup Condition="'$(AGENT_OS)' == 'Windows_NT' ">
     <Python>%HELIX_PYTHONPATH%</Python>
     <ProductDirectory>%HELIX_CORRELATION_PAYLOAD%</ProductDirectory>
     <SuperpmiLogsLocation>%HELIX_WORKITEM_UPLOAD_ROOT%</SuperpmiLogsLocation>
     <!-- Workaround until https://github.com/dotnet/arcade/pull/6179 is not available -->
     <HelixResultsDestinationDir>$(BUILD_SOURCESDIRECTORY)\artifacts\helixresults</HelixResultsDestinationDir>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(AGENT_OS)' != 'Windows_NT'">
+    <Python>$HELIX_PYTHONPATH</Python>
+    <ProductDirectory>$HELIX_CORRELATION_PAYLOAD</ProductDirectory>
+    <SuperpmiLogsLocation>$HELIX_WORKITEM_UPLOAD_ROOT</SuperpmiLogsLocation>
+    <!-- Workaround until https://github.com/dotnet/arcade/pull/6179 is not available -->
+    <HelixResultsDestinationDir>$(BUILD_SOURCESDIRECTORY)/artifacts/helixresults</HelixResultsDestinationDir>
+  </PropertyGroup>
 
   <PropertyGroup>
     <EnableAzurePipelinesReporter>false</EnableAzurePipelinesReporter>
@@ -53,7 +60,7 @@
   </PropertyGroup>
 
   <PropertyGroup>
-    <WorkItemCommand>$(Python) $(ProductDirectory)\superpmi_diffs.py -type $(SuperPmiDiffType) -base_jit_directory $(ProductDirectory)\base -diff_jit_directory $(ProductDirectory)\diff $(SuperPmiBaseJitOptionsArg) $(SuperPmiDiffJitOptionsArg) -log_directory $(SuperpmiLogsLocation)</WorkItemCommand>
+    <WorkItemCommand>$(Python) $(ProductDirectory)/superpmi_diffs.py -type $(SuperPmiDiffType) -base_jit_directory $(ProductDirectory)/base -diff_jit_directory $(ProductDirectory)/diff $(SuperPmiBaseJitOptionsArg) $(SuperPmiDiffJitOptionsArg) -log_directory $(SuperpmiLogsLocation)</WorkItemCommand>
     <WorkItemTimeout>2:00</WorkItemTimeout>
   </PropertyGroup>
 
     </HelixCorrelationPayload>
   </ItemGroup>
 
-  <ItemGroup Condition="'$(Architecture)' == 'x64'">
-    <SPMI_Partition Include="win-x64" Platform="windows" Architecture="x64" />
-    <SPMI_Partition Include="win-arm64" Platform="windows" Architecture="arm64" />
-    <SPMI_Partition Include="unix-x64" Platform="linux" Architecture="x64" />
-    <SPMI_Partition Include="linux-arm64" Platform="linux" Architecture="arm64" />
-    <SPMI_Partition Include="osx-arm64" Platform="osx" Architecture="arm64" />
+  <ItemGroup Condition="'$(AGENT_OS)' == 'Windows_NT' and '$(Architecture)' == 'x64'">
+    <SPMI_Partition Include="windows-x64" HostOS="windows" TargetOS="windows" Architecture="x64" />
+    <SPMI_Partition Include="windows-arm64" HostOS="windows" TargetOS="windows" Architecture="arm64" />
+    <SPMI_Partition Include="linux-x64" HostOS="windows" TargetOS="linux" Architecture="x64" />
+    <SPMI_Partition Include="linux-arm64" HostOS="windows" TargetOS="linux" Architecture="arm64" />
+    <SPMI_Partition Include="osx-arm64" HostOS="windows" TargetOS="osx" Architecture="arm64" />
+  </ItemGroup>
+
+  <!-- Currently assume that AGENT_OS != Windows means Linux -->
+  <ItemGroup Condition="'$(AGENT_OS)' != 'Windows_NT' and '$(Architecture)' == 'x64'">
+    <SPMI_Partition Include="linux-x64" HostOS="linux" TargetOS="linux" Architecture="x64" />
+    <SPMI_Partition Include="linux-arm64" HostOS="linux" TargetOS="linux" Architecture="arm64" />
   </ItemGroup>
 
   <ItemGroup Condition="'$(Architecture)' == 'x86'">
-    <SPMI_Partition Include="win-x86" Platform="windows" Architecture="x86" />
-    <SPMI_Partition Include="unix-arm" Platform="linux" Architecture="arm" />
+    <SPMI_Partition Include="windows-x86" HostOS="windows" TargetOS="windows" Architecture="x86" />
+    <SPMI_Partition Include="linux-arm" HostOS="windows" TargetOS="linux" Architecture="arm" />
   </ItemGroup>
 
   <ItemGroup>
     <HelixWorkItem Include="@(SPMI_Partition)">
-      <Command>$(WorkItemCommand) -arch %(HelixWorkItem.Architecture) -platform %(HelixWorkItem.Platform)</Command>
+      <Command>$(WorkItemCommand) -arch %(HelixWorkItem.Architecture) -host_os %(HelixWorkItem.HostOS) -target_os %(HelixWorkItem.TargetOS)</Command>
       <Timeout>$(WorkItemTimeout)</Timeout>
-      <DownloadFilesFromResults Condition=" '$(SuperPmiDiffType)'=='asmdiffs' ">superpmi_download_%(HelixWorkItem.Platform)_%(HelixWorkItem.Architecture).log;superpmi_asmdiffs_%(HelixWorkItem.Platform)_%(HelixWorkItem.Architecture).log;superpmi_asmdiffs_summary_%(HelixWorkItem.Platform)_%(HelixWorkItem.Architecture).md;Asmdiffs_%(HelixWorkItem.Platform)_%(HelixWorkItem.Architecture).zip</DownloadFilesFromResults>
-      <DownloadFilesFromResults Condition=" '$(SuperPmiDiffType)'=='tpdiff' "  >superpmi_download_%(HelixWorkItem.Platform)_%(HelixWorkItem.Architecture).log;superpmi_tpdiff_%(HelixWorkItem.Platform)_%(HelixWorkItem.Architecture).log;superpmi_tpdiff_summary_%(HelixWorkItem.Platform)_%(HelixWorkItem.Architecture).md</DownloadFilesFromResults>
-      <DownloadFilesFromResults Condition=" '$(SuperPmiDiffType)'=='all' "     >superpmi_download_%(HelixWorkItem.Platform)_%(HelixWorkItem.Architecture).log;superpmi_asmdiffs_%(HelixWorkItem.Platform)_%(HelixWorkItem.Architecture).log;superpmi_asmdiffs_summary_%(HelixWorkItem.Platform)_%(HelixWorkItem.Architecture).md;Asmdiffs_%(HelixWorkItem.Platform)_%(HelixWorkItem.Architecture).zip;superpmi_tpdiff_%(HelixWorkItem.Platform)_%(HelixWorkItem.Architecture).log;superpmi_tpdiff_summary_%(HelixWorkItem.Platform)_%(HelixWorkItem.Architecture).md</DownloadFilesFromResults>
+      <DownloadFilesFromResults Condition=" '$(SuperPmiDiffType)'=='asmdiffs' ">superpmi_download_%(HelixWorkItem.TargetOS)_%(HelixWorkItem.Architecture).log;superpmi_asmdiffs_%(HelixWorkItem.TargetOS)_%(HelixWorkItem.Architecture).log;superpmi_asmdiffs_summary_%(HelixWorkItem.TargetOS)_%(HelixWorkItem.Architecture).md;Asmdiffs_%(HelixWorkItem.TargetOS)_%(HelixWorkItem.Architecture).zip</DownloadFilesFromResults>
+      <DownloadFilesFromResults Condition=" '$(SuperPmiDiffType)'=='tpdiff' "  >superpmi_download_%(HelixWorkItem.TargetOS)_%(HelixWorkItem.Architecture).log;superpmi_tpdiff_%(HelixWorkItem.TargetOS)_%(HelixWorkItem.Architecture).log;superpmi_tpdiff_summary_%(HelixWorkItem.TargetOS)_%(HelixWorkItem.Architecture).md</DownloadFilesFromResults>
+      <DownloadFilesFromResults Condition=" '$(SuperPmiDiffType)'=='all' "     >superpmi_download_%(HelixWorkItem.TargetOS)_%(HelixWorkItem.Architecture).log;superpmi_asmdiffs_%(HelixWorkItem.TargetOS)_%(HelixWorkItem.Architecture).log;superpmi_asmdiffs_summary_%(HelixWorkItem.TargetOS)_%(HelixWorkItem.Architecture).md;Asmdiffs_%(HelixWorkItem.TargetOS)_%(HelixWorkItem.Architecture).zip;superpmi_tpdiff_%(HelixWorkItem.TargetOS)_%(HelixWorkItem.Architecture).log;superpmi_tpdiff_summary_%(HelixWorkItem.TargetOS)_%(HelixWorkItem.Architecture).md</DownloadFilesFromResults>
     </HelixWorkItem>
   </ItemGroup>
   </Project>
index 555db1d..0b1a735 100644 (file)
   </ItemGroup>
 
   <ItemGroup Condition="'$(Architecture)' == 'x64'">
-    <SPMI_Partition Include="win-x64-1" Platform="windows" Architecture="x64" Partition="1" PartitionCount="3"/>
-    <SPMI_Partition Include="win-x64-2" Platform="windows" Architecture="x64" Partition="2" PartitionCount="3"/>
-    <SPMI_Partition Include="win-x64-3" Platform="windows" Architecture="x64" Partition="3" PartitionCount="3"/>
-    <SPMI_Partition Include="win-arm64-1" Platform="windows" Architecture="arm64" Partition="1" PartitionCount="3"/>
-    <SPMI_Partition Include="win-arm64-2" Platform="windows" Architecture="arm64" Partition="2" PartitionCount="3"/>
-    <SPMI_Partition Include="win-arm64-3" Platform="windows" Architecture="arm64" Partition="3" PartitionCount="3"/>
-    <SPMI_Partition Include="unix-x64-1" Platform="linux" Architecture="x64" Partition="1" PartitionCount="3"/>
-    <SPMI_Partition Include="unix-x64-2" Platform="linux" Architecture="x64" Partition="2" PartitionCount="3"/>
-    <SPMI_Partition Include="unix-x64-3" Platform="linux" Architecture="x64" Partition="3" PartitionCount="3"/>
+    <SPMI_Partition Include="windows-x64-1" Platform="windows" Architecture="x64" Partition="1" PartitionCount="3"/>
+    <SPMI_Partition Include="windows-x64-2" Platform="windows" Architecture="x64" Partition="2" PartitionCount="3"/>
+    <SPMI_Partition Include="windows-x64-3" Platform="windows" Architecture="x64" Partition="3" PartitionCount="3"/>
+    <SPMI_Partition Include="windows-arm64-1" Platform="windows" Architecture="arm64" Partition="1" PartitionCount="3"/>
+    <SPMI_Partition Include="windows-arm64-2" Platform="windows" Architecture="arm64" Partition="2" PartitionCount="3"/>
+    <SPMI_Partition Include="windows-arm64-3" Platform="windows" Architecture="arm64" Partition="3" PartitionCount="3"/>
+    <SPMI_Partition Include="linux-x64-1" Platform="linux" Architecture="x64" Partition="1" PartitionCount="3"/>
+    <SPMI_Partition Include="linux-x64-2" Platform="linux" Architecture="x64" Partition="2" PartitionCount="3"/>
+    <SPMI_Partition Include="linux-x64-3" Platform="linux" Architecture="x64" Partition="3" PartitionCount="3"/>
     <SPMI_Partition Include="linux-arm64-1" Platform="linux" Architecture="arm64" Partition="1" PartitionCount="3"/>
     <SPMI_Partition Include="linux-arm64-2" Platform="linux" Architecture="arm64" Partition="2" PartitionCount="3"/>
     <SPMI_Partition Include="linux-arm64-3" Platform="linux" Architecture="arm64" Partition="3" PartitionCount="3"/>
   </ItemGroup>
 
   <ItemGroup Condition="'$(Architecture)' == 'x86'">
-    <SPMI_Partition Include="win-x86-1" Platform="windows" Architecture="x86" Partition="1" PartitionCount="3"/>
-    <SPMI_Partition Include="win-x86-2" Platform="windows" Architecture="x86" Partition="2" PartitionCount="3"/>
-    <SPMI_Partition Include="win-x86-3" Platform="windows" Architecture="x86" Partition="3" PartitionCount="3"/>
-    <SPMI_Partition Include="unix-arm-1" Platform="linux" Architecture="arm" Partition="1" PartitionCount="3"/>
-    <SPMI_Partition Include="unix-arm-2" Platform="linux" Architecture="arm" Partition="2" PartitionCount="3"/>
-    <SPMI_Partition Include="unix-arm-3" Platform="linux" Architecture="arm" Partition="3" PartitionCount="3"/>
+    <SPMI_Partition Include="windows-x86-1" Platform="windows" Architecture="x86" Partition="1" PartitionCount="3"/>
+    <SPMI_Partition Include="windows-x86-2" Platform="windows" Architecture="x86" Partition="2" PartitionCount="3"/>
+    <SPMI_Partition Include="windows-x86-3" Platform="windows" Architecture="x86" Partition="3" PartitionCount="3"/>
+    <SPMI_Partition Include="linux-arm-1" Platform="linux" Architecture="arm" Partition="1" PartitionCount="3"/>
+    <SPMI_Partition Include="linux-arm-2" Platform="linux" Architecture="arm" Partition="2" PartitionCount="3"/>
+    <SPMI_Partition Include="linux-arm-3" Platform="linux" Architecture="arm" Partition="3" PartitionCount="3"/>
   </ItemGroup>
 
   <ItemGroup>
index 710bfb3..673f960 100644 (file)
@@ -40,7 +40,7 @@ from coreclr_arguments import *
 from jitutil import TempDir, ChangeDir, remove_prefix, is_zero_length_file, is_nonzero_length_file, \
     make_safe_filename, find_file, download_one_url, download_files, report_azure_error, \
     require_azure_storage_libraries, authenticate_using_azure, \
-    create_unique_directory_name, create_unique_file_name, get_files_from_path
+    create_unique_directory_name, create_unique_file_name, get_files_from_path, determine_jit_name
 
 locale.setlocale(locale.LC_ALL, '')  # Use '' for auto, or force e.g. to 'en_US.UTF-8'
 
@@ -642,7 +642,7 @@ class SuperPMICollect:
 
         self.collection_shim_path = os.path.join(self.core_root, self.collection_shim_name)
 
-        self.jit_path = os.path.join(coreclr_args.core_root, determine_jit_name(coreclr_args))
+        self.jit_path = os.path.join(coreclr_args.core_root, get_jit_name(coreclr_args))
         self.superpmi_path = determine_superpmi_tool_path(coreclr_args)
         self.mcs_path = determine_mcs_tool_path(coreclr_args)
 
@@ -1734,7 +1734,6 @@ class SuperPMIReplayAsmDiffs:
                 with ChangeDir(self.coreclr_args.core_root):
                     command = [self.superpmi_path] + flags + [self.base_jit_path, self.diff_jit_path, mch_file]
                     return_code = run_and_log(command)
-                    logging.debug("return_code: %s", return_code)
 
                 base_metrics = read_csv_metrics(base_metrics_summary_file)
                 diff_metrics = read_csv_metrics(diff_metrics_summary_file)
@@ -2462,7 +2461,10 @@ class SuperPMIReplayThroughputDiff:
                 with ChangeDir(self.coreclr_args.core_root):
                     command = [self.pin_path] + pin_options + ["--"] + [self.superpmi_path] + flags + [self.base_jit_path, self.diff_jit_path, mch_file]
                     return_code = run_and_log(command)
-                    logging.debug("return_code: %s", return_code)
+
+                if return_code != 0:
+                    command_string = " ".join(command)
+                    logging.debug("'%s': Error return code: %s", command_string, return_code)
 
                 base_metrics = read_csv_metrics(base_metrics_summary_file)
                 diff_metrics = read_csv_metrics(diff_metrics_summary_file)
@@ -2688,8 +2690,8 @@ def determine_pmi_location(coreclr_args):
     return pmi_location
 
 
-def determine_jit_name(coreclr_args):
-    """ Determine the jit based on the OS. If "-jit_name" is specified, then use the specified jit.
+def get_jit_name(coreclr_args):
+    """ Determine the JIT file name to use based on the platform. If "-jit_name" is specified, then use the specified jit.
         This function is called for cases where the "-jit_name" flag is not used, so be careful not
         to depend on the "jit_name" attribute existing.
 
@@ -2704,30 +2706,7 @@ def determine_jit_name(coreclr_args):
     if hasattr(coreclr_args, "jit_name") and coreclr_args.jit_name is not None:
         return coreclr_args.jit_name
 
-    jit_base_name = "clrjit"
-
-    if coreclr_args.arch != coreclr_args.target_arch or coreclr_args.host_os != coreclr_args.target_os:
-        # If `-target_arch` or `-target_os` was specified, then figure out the name of the cross-compiler JIT to use.
-
-        if coreclr_args.target_arch.startswith("arm"):
-            os_name = "universal"
-        elif coreclr_args.target_os == "osx" or coreclr_args.target_os == "linux":
-            os_name = "unix"
-        elif coreclr_args.target_os == "windows":
-            os_name = "win"
-        else:
-            raise RuntimeError("Unknown OS.")
-
-        jit_base_name = 'clrjit_{}_{}_{}'.format(os_name, coreclr_args.target_arch, coreclr_args.arch)
-
-    if coreclr_args.host_os == "osx":
-        return "lib" + jit_base_name + ".dylib"
-    elif coreclr_args.host_os == "linux":
-        return "lib" + jit_base_name + ".so"
-    elif coreclr_args.host_os == "windows":
-        return jit_base_name + ".dll"
-    else:
-        raise RuntimeError("Unknown OS.")
+    return determine_jit_name(coreclr_args.host_os, coreclr_args.target_os, coreclr_args.arch, coreclr_args.target_arch)
 
 
 def find_tool(coreclr_args, tool_name, search_core_root=True, search_product_location=True, search_path=True, throw_on_not_found=True):
@@ -3648,7 +3627,7 @@ def process_base_jit_path_arg(coreclr_args):
         for git_hash in change_list_hashes:
             logging.debug("%s: %s", hashnum, git_hash)
 
-            jit_name = determine_jit_name(coreclr_args)
+            jit_name = get_jit_name(coreclr_args)
             basejit_dir = os.path.join(default_basejit_root_dir, "{}.{}.{}.{}".format(git_hash, coreclr_args.host_os, coreclr_args.arch, coreclr_args.build_type))
             basejit_path = os.path.join(basejit_dir, jit_name)
             if os.path.isfile(basejit_path):
@@ -3840,7 +3819,7 @@ def setup_args(args):
     def setup_jit_path_arg(jit_path):
         if jit_path is not None:
             return os.path.abspath(jit_path)
-        return find_tool(coreclr_args, determine_jit_name(coreclr_args), search_path=False)  # It doesn't make sense to search PATH for the JIT dll.
+        return find_tool(coreclr_args, get_jit_name(coreclr_args), search_path=False)  # It doesn't make sense to search PATH for the JIT dll.
 
     def setup_error_limit(error_limit):
         if error_limit is None:
@@ -3929,7 +3908,7 @@ def setup_args(args):
                             "Unable to set jit_name.")
 
         coreclr_args.verify(args,
-                            "altjit",                   # Must be set before `jit_path` (determine_jit_name() depends on it)
+                            "altjit",                   # Must be set before `jit_path` (get_jit_name() depends on it)
                             lambda unused: True,
                             "Unable to set altjit.")
 
index a5abbc3..73e191e 100644 (file)
@@ -16,19 +16,29 @@ import argparse
 from os import walk, path
 import shutil
 from coreclr_arguments import *
-from jitutil import run_command, TempDir
+from jitutil import run_command, TempDir, determine_jit_name
 
 parser = argparse.ArgumentParser(description="description")
 
+host_os_help = "OS (windows, osx, linux). Default: current OS."
+
+target_os_help = "Target OS, for use with cross-compilation JIT (windows, osx, linux). Default: current OS."
+
 parser.add_argument("-arch", help="Architecture")
 parser.add_argument("-type", help="Type of diff (asmdiffs, tpdiff, all)")
-parser.add_argument("-platform", help="OS platform")
+parser.add_argument("-host_os", help=host_os_help)
+parser.add_argument("-target_os", help=target_os_help)
 parser.add_argument("-base_jit_directory", help="path to the directory containing base clrjit binaries")
 parser.add_argument("-diff_jit_directory", help="path to the directory containing diff clrjit binaries")
 parser.add_argument("-base_jit_options", help="Semicolon separated list of base jit options (in format A=B without DOTNET_ prefix)")
 parser.add_argument("-diff_jit_options", help="Semicolon separated list of diff jit options (in format A=B without DOTNET_ prefix)")
 parser.add_argument("-log_directory", help="path to the directory containing superpmi log files")
 
+
+def check_target_os(coreclr_args, target_os):
+    return (target_os is not None) and (target_os in coreclr_args.valid_host_os)
+
+
 def setup_args(args):
     """ Setup the args for SuperPMI to use.
 
@@ -53,9 +63,10 @@ def setup_args(args):
                         "Invalid type \"{}\"".format)
 
     coreclr_args.verify(args,
-                        "platform",
-                        lambda unused: True,
-                        "Unable to set platform")
+                        "target_os",
+                        lambda target_os: check_target_os(coreclr_args, target_os),
+                        lambda target_os: "Unknown target_os {}\nSupported OS: {}".format(target_os, (", ".join(coreclr_args.valid_host_os))),
+                        modify_arg=lambda target_os: target_os if target_os is not None else coreclr_args.host_os)  # Default to `host_os`
 
     coreclr_args.verify(args,
                         "base_jit_directory",
@@ -84,6 +95,7 @@ def setup_args(args):
 
     return coreclr_args
 
+
 class Diff:
     """ Class handling asmdiffs and tpdiff invocations
     """
@@ -105,43 +117,38 @@ class Diff:
         self.spmi_location = os.path.join(self.script_dir, "artifacts", "spmi")
 
         self.log_directory = coreclr_args.log_directory
-        self.platform_name = coreclr_args.platform
+        self.host_os = coreclr_args.host_os
+        self.target_os = coreclr_args.target_os
         self.arch_name = coreclr_args.arch
-
-        self.os_name = "win" if self.platform_name.lower() == "windows" else "unix"
         self.host_arch_name = "x64" if self.arch_name.endswith("64") else "x86"
-        self.os_name = "universal" if self.arch_name.startswith("arm") else self.os_name
 
         # Core_Root is where the superpmi tools (superpmi.exe, mcs.exe) are expected to be found.
         # We pass the full path of the JITs to use as arguments.
         self.core_root_dir = self.script_dir
-        
+
         # Assume everything succeeded. If any step fails, it will change this to True.
         self.failed = False
-        
+
         # List of summary MarkDown files
         self.summary_md_files = []
 
-
     def download_mch(self):
         """ Download MCH files for the diff
         """
         print("Running superpmi.py download to get MCH files")
 
-        log_file = os.path.join(self.log_directory, "superpmi_download_{}_{}.log".format(self.platform_name, self.arch_name))
+        log_file = os.path.join(self.log_directory, "superpmi_download_{}_{}.log".format(self.target_os, self.arch_name))
         run_command([
             self.python_path,
             os.path.join(self.script_dir, "superpmi.py"),
             "download",
             "--no_progress",
             "-core_root", self.core_root_dir,
-            "-target_os", self.platform_name,
+            "-target_os", self.target_os,
             "-target_arch", self.arch_name,
             "-spmi_location", self.spmi_location,
             "-log_level", "debug",
-            "-log_file", log_file
-            ], _exit_on_fail=True)
-
+            "-log_file", log_file], _exit_on_fail=True)
 
     def copy_dasm_files(self, upload_directory, tag_name):
         """ Copies .dasm files to a tempDirectory, zip it, and copy the compressed file to the upload directory.
@@ -200,12 +207,11 @@ class Diff:
             except PermissionError as pe_error:
                 print('Ignoring PermissionError: {0}'.format(pe_error))
 
-
     def do_asmdiffs(self):
         """ Run asmdiffs
         """
 
-        print("Running superpmi.py asmdiffs")
+        print("Running asmdiffs")
 
         # Find the built jit-analyze and put its directory on the PATH
         jit_analyze_dir = os.path.join(self.script_dir, "jit-analyze")
@@ -213,7 +219,7 @@ class Diff:
             print("Error: jit-analyze not found in {} (continuing)".format(jit_analyze_dir))
         else:
             # Put the jit-analyze directory on the PATH so superpmi.py can find it.
-            print("Adding {} to PATH".format(jit_analyze_dir))
+            print("Adding jit-analyze directory {} to PATH".format(jit_analyze_dir))
             os.environ["PATH"] = jit_analyze_dir + os.pathsep + os.environ["PATH"]
 
         # Find the portable `git` installation, and put `git.exe` on the PATH, for use by `jit-analyze`.
@@ -223,21 +229,22 @@ class Diff:
             print("Error: `git` not found at {} (continuing)".format(git_exe_tool))
         else:
             # Put the git/cmd directory on the PATH so jit-analyze can find it.
-            print("Adding {} to PATH".format(git_directory))
+            print("Adding git directory {} to PATH".format(git_directory))
             os.environ["PATH"] = git_directory + os.pathsep + os.environ["PATH"]
 
         # Figure out which JITs to use
-        base_checked_jit_path = os.path.join(self.coreclr_args.base_jit_directory, "checked", 'clrjit_{}_{}_{}.dll'.format(self.os_name, self.arch_name, self.host_arch_name))
-        diff_checked_jit_path = os.path.join(self.coreclr_args.diff_jit_directory, "checked", 'clrjit_{}_{}_{}.dll'.format(self.os_name, self.arch_name, self.host_arch_name))
+        jit_name = determine_jit_name(self.host_os, self.target_os, self.host_arch_name, self.arch_name, use_cross_compile_jit=True)
+        base_checked_jit_path = os.path.join(self.coreclr_args.base_jit_directory, "checked", jit_name)
+        diff_checked_jit_path = os.path.join(self.coreclr_args.diff_jit_directory, "checked", jit_name)
 
-        log_file = os.path.join(self.log_directory, "superpmi_asmdiffs_{}_{}.log".format(self.platform_name, self.arch_name))
+        log_file = os.path.join(self.log_directory, "superpmi_asmdiffs_{}_{}.log".format(self.target_os, self.arch_name))
 
         # This is the summary file name and location written by superpmi.py. If the file exists, remove it to ensure superpmi.py doesn't created a numbered version.
         overall_md_asmdiffs_summary_file = os.path.join(self.spmi_location, "diff_summary.md")
         if os.path.isfile(overall_md_asmdiffs_summary_file):
             os.remove(overall_md_asmdiffs_summary_file)
 
-        overall_md_asmdiffs_summary_file_target = os.path.join(self.log_directory, "superpmi_asmdiffs_summary_{}_{}.md".format(self.platform_name, self.arch_name))
+        overall_md_asmdiffs_summary_file_target = os.path.join(self.log_directory, "superpmi_asmdiffs_summary_{}_{}.md".format(self.target_os, self.arch_name))
         self.summary_md_files.append((overall_md_asmdiffs_summary_file, overall_md_asmdiffs_summary_file_target))
 
         _, _, return_code = run_command([
@@ -246,7 +253,7 @@ class Diff:
             "asmdiffs",
             "--no_progress",
             "-core_root", self.core_root_dir,
-            "-target_os", self.platform_name,
+            "-target_os", self.target_os,
             "-target_arch", self.arch_name,
             "-arch", self.host_arch_name,
             "-base_jit_path", base_checked_jit_path,
@@ -261,27 +268,27 @@ class Diff:
             self.failed = True
 
         # Prepare .dasm files to upload to AzDO
-        self.copy_dasm_files(self.log_directory, "{}_{}".format(self.platform_name, self.arch_name))
-
+        self.copy_dasm_files(self.log_directory, "{}_{}".format(self.target_os, self.arch_name))
 
     def do_tpdiff(self):
         """ Run tpdiff
         """
 
-        print("Running superpmi.py tpdiff")
+        print("Running tpdiff")
 
         # Figure out which JITs to use
-        base_release_jit_path = os.path.join(self.coreclr_args.base_jit_directory, "release", 'clrjit_{}_{}_{}.dll'.format(self.os_name, self.arch_name, self.host_arch_name))
-        diff_release_jit_path = os.path.join(self.coreclr_args.diff_jit_directory, "release", 'clrjit_{}_{}_{}.dll'.format(self.os_name, self.arch_name, self.host_arch_name))
+        jit_name = determine_jit_name(self.host_os, self.target_os, self.host_arch_name, self.arch_name, use_cross_compile_jit=True)
+        base_release_jit_path = os.path.join(self.coreclr_args.base_jit_directory, "release", jit_name)
+        diff_release_jit_path = os.path.join(self.coreclr_args.diff_jit_directory, "release", jit_name)
 
-        log_file = os.path.join(self.log_directory, "superpmi_tpdiff_{}_{}.log".format(self.platform_name, self.arch_name))
+        log_file = os.path.join(self.log_directory, "superpmi_tpdiff_{}_{}.log".format(self.target_os, self.arch_name))
 
         # This is the summary file name and location written by superpmi.py. If the file exists, remove it to ensure superpmi.py doesn't created a numbered version.
         overall_md_tpdiff_summary_file = os.path.join(self.spmi_location, "tpdiff_summary.md")
         if os.path.isfile(overall_md_tpdiff_summary_file):
             os.remove(overall_md_tpdiff_summary_file)
 
-        overall_md_tpdiff_summary_file_target = os.path.join(self.log_directory, "superpmi_tpdiff_summary_{}_{}.md".format(self.platform_name, self.arch_name))
+        overall_md_tpdiff_summary_file_target = os.path.join(self.log_directory, "superpmi_tpdiff_summary_{}_{}.md".format(self.target_os, self.arch_name))
         self.summary_md_files.append((overall_md_tpdiff_summary_file, overall_md_tpdiff_summary_file_target))
 
         _, _, return_code = run_command([
@@ -290,7 +297,7 @@ class Diff:
             "tpdiff",
             "--no_progress",
             "-core_root", self.core_root_dir,
-            "-target_os", self.platform_name,
+            "-target_os", self.target_os,
             "-target_arch", self.arch_name,
             "-arch", self.host_arch_name,
             "-base_jit_path", base_release_jit_path,
index 9fbeb93..db12452 100644 (file)
@@ -27,13 +27,15 @@ from jitutil import copy_directory, set_pipeline_variable, run_command, TempDir,
 
 parser = argparse.ArgumentParser(description="description")
 
-parser.add_argument("-arch", help="Architecture")
-parser.add_argument("-type", help="Type of diff (asmdiffs, tpdiff, all)")
-parser.add_argument("-source_directory", help="Path to the root directory of the dotnet/runtime source tree")
+parser.add_argument("-arch", required=True, help="Architecture")
+parser.add_argument("-platform", required=True, help="OS platform")
+parser.add_argument("-type", required=True, help="Type of diff (asmdiffs, tpdiff, all)")
+parser.add_argument("-source_directory", required=True, help="Path to the root directory of the dotnet/runtime source tree")
 parser.add_argument("-checked_directory", help="Path to the directory containing built checked binaries (e.g., <source_directory>/artifacts/bin/coreclr/windows.x64.Checked)")
 parser.add_argument("-release_directory", help="Path to the directory containing built release binaries (e.g., <source_directory>/artifacts/bin/coreclr/windows.x64.Release)")
 
 is_windows = platform.system() == "Windows"
+target_windows = True
 
 
 def setup_args(args):
@@ -55,6 +57,11 @@ def setup_args(args):
                         "Unable to set arch")
 
     coreclr_args.verify(args,
+                        "platform",
+                        lambda unused: True,
+                        "Unable to set platform")
+
+    coreclr_args.verify(args,
                         "type",
                         lambda type: type in ["asmdiffs", "tpdiff", "all"],
                         "Invalid type \"{}\"".format)
@@ -101,35 +108,51 @@ def setup_args(args):
             print("release_directory doesn't exist")
             sys.exit(1)
 
+    if coreclr_args.platform.lower() != "windows" and do_asmdiffs:
+        print("asmdiffs currently only implemented for windows")
+        sys.exit(1)
+
+    global target_windows
+    target_windows = coreclr_args.platform.lower() == "windows"
+
     return coreclr_args
 
 
 def match_jit_files(full_path):
     """ Match all the JIT files that we want to copy and use.
-        Note that we currently only match Windows files, and not osx cross-compile files.
+        We don't match osx cross-compile files.
         We also don't copy the "default" clrjit.dll, since we always use the fully specified
         JITs, e.g., clrjit_win_x86_x86.dll.
+        On non-Windows, don't bother copying Windows cross-targeting or arm32 cross-bitness compilers
+        (we assume here everything is running on 64-bit).
     """
     file_name = os.path.basename(full_path)
 
-    if file_name.startswith("clrjit_") and file_name.endswith(".dll") and file_name.find("osx") == -1:
-        return True
+    if target_windows:
+        if file_name.startswith("clrjit_") and file_name.endswith(".dll") and file_name.find("osx") == -1:
+            return True
+    else:
+        if file_name.startswith("libclrjit_") and file_name.endswith(".so") and file_name.find("_win_") == -1 and file_name.find("_arm_") == -1:
+            return True
 
     return False
 
 
 def match_superpmi_tool_files(full_path):
     """ Match all the SuperPMI tool files that we want to copy and use.
-        Note that we currently only match Windows files.
     """
     file_name = os.path.basename(full_path)
 
-    if file_name == "superpmi.exe" or file_name == "mcs.exe":
-        return True
+    if target_windows:
+        if file_name == "superpmi.exe" or file_name == "mcs.exe":
+            return True
+    else:
+        if file_name == "superpmi" or file_name == "mcs":
+            return True
 
     return False
 
-    
+
 def build_jit_analyze(coreclr_args, source_directory, jit_analyze_build_directory):
     """ Build and publish jit-analyze for use by asmdiffs
     """
@@ -211,6 +234,7 @@ def main(main_args):
     Note:
     1. asmdiffs uses Checked JITs, tpdiff uses Release JITs. Only the one needed is copied to the payload directory.
     2. Only asmdiffs needs jit-analyze and git
+    3. tpdiff can run on Linux, but asmdiffs is not implemented to run on Linux
 
     Args:
         main_args ([type]): Arguments to the script
@@ -229,6 +253,7 @@ def main(main_args):
     coreclr_args = setup_args(main_args)
 
     arch = coreclr_args.arch
+    platform_name = coreclr_args.platform.lower()
     source_directory = coreclr_args.source_directory
     checked_directory = coreclr_args.checked_directory
     release_directory = coreclr_args.release_directory
@@ -293,9 +318,6 @@ def main(main_args):
 
     ######## Get baseline JITs
 
-    # Note: we only support downloading Windows versions of the JIT currently. To support downloading
-    # non-Windows JITs on a Windows machine, pass `-host_os <os>` to jitrollingbuild.py.
-
     print("Fetching history of `main` branch so we can find the baseline JIT")
     run_command(["git", "fetch", "--depth=500", "origin", "main"], source_directory, _exit_on_fail=True)
 
@@ -310,6 +332,7 @@ def main(main_args):
             jit_rolling_build_script,
             "download",
             "-arch", arch,
+            "-host_os", platform_name,
             "-build_type", "checked",
             "-target_dir", base_jit_checked_directory],
             source_directory)
@@ -328,6 +351,7 @@ def main(main_args):
             jit_rolling_build_script,
             "download",
             "-arch", arch,
+            "-host_os", platform_name,
             "-build_type", "release",
             "-target_dir", base_jit_release_directory],
             source_directory)
index 0d4c80e..d8838fc 100644 (file)
@@ -20,9 +20,13 @@ from coreclr_arguments import *
 
 parser = argparse.ArgumentParser(description="description")
 
-parser.add_argument("-diff_summary_dir", help="Path to diff summary directory")
-parser.add_argument("-arch", help="Architecture")
-parser.add_argument("-type", help="Type of diff (asmdiffs, tpdiff, all)")
+parser.add_argument("-diff_summary_dir", required=True, help="Path to diff summary directory")
+parser.add_argument("-arch", required=True, help="Architecture")
+parser.add_argument("-platform", required=True, help="OS platform")
+parser.add_argument("-type", required=True, help="Type of diff (asmdiffs, tpdiff, all)")
+
+target_windows = True
+
 
 def setup_args(args):
     """ Setup the args.
@@ -48,14 +52,35 @@ def setup_args(args):
                         "Unable to set arch")
 
     coreclr_args.verify(args,
+                        "platform",
+                        lambda unused: True,
+                        "Unable to set platform")
+
+    coreclr_args.verify(args,
                         "type",
                         lambda type: type in ["asmdiffs", "tpdiff", "all"],
                         "Invalid type \"{}\"".format)
 
+    do_asmdiffs = False
+    do_tpdiff = False
+    if coreclr_args.type == 'asmdiffs':
+        do_asmdiffs = True
+    if coreclr_args.type == 'tpdiff':
+        do_tpdiff = True
+    if coreclr_args.type == 'all':
+        do_asmdiffs = True
+        do_tpdiff = True
+
+    if coreclr_args.platform.lower() != "windows" and do_asmdiffs:
+        print("asmdiffs currently only implemented for windows")
+        sys.exit(1)
+
+    target_windows = coreclr_args.platform.lower() == "windows"
+
     return coreclr_args
 
 
-def append_diff_file(f, arch, file_name, full_file_path):
+def append_diff_file(f, file_name, full_file_path):
     """ Append a single summary file to the consolidated diff file.
 
     Args:
@@ -112,6 +137,7 @@ def main(main_args):
 
     diff_summary_dir = coreclr_args.diff_summary_dir
     arch = coreclr_args.arch
+    platform_name = coreclr_args.platform.lower()
 
     do_asmdiffs = False
     do_tpdiff = False
@@ -128,31 +154,31 @@ def main(main_args):
     # (Don't name it "superpmi_xxx.md" or we might consolidate it into itself.)
     # If there are no summary files found, add a "No diffs found" text to be explicit about that.
     #
-    # Note that we currently do this summarizing in an architecture-specific job. That means that diffs run
-    # in a Windows x64 job and those run in a Windows x86 job will be summarized in two separate files.
+    # Note that we currently do this summarizing in an architecture-specific job. That means that diffs that run
+    # in a Windows x64 job and those that run in a Windows x86 job will be summarized in two separate files.
     # We should create a job that depends on all the diff jobs, downloads all the .md file artifacts,
     # and consolidates everything together in one file.
 
-    final_md_path = os.path.join(diff_summary_dir, "overall_{}_summary_windows_{}.md".format(coreclr_args.type, arch))
+    final_md_path = os.path.join(diff_summary_dir, "overall_{}_summary_{}_{}.md".format(coreclr_args.type, platform_name, arch))
     print("Consolidating final {}".format(final_md_path))
     with open(final_md_path, "a") as f:
 
         if do_asmdiffs:
-            f.write("# ASM diffs generated on Windows {}\n\n".format(arch))
+            f.write("# ASM diffs generated on {} {}\n\n".format(platform_name, arch))
 
             any_asmdiffs_found = False
             for dirpath, _, files in os.walk(diff_summary_dir):
                 for file_name in files:
                     if file_name.startswith("superpmi_asmdiffs") and file_name.endswith(".md"):
                         full_file_path = os.path.join(dirpath, file_name)
-                        if append_diff_file(f, arch, file_name, full_file_path):
+                        if append_diff_file(f, file_name, full_file_path):
                             any_asmdiffs_found = True
 
             if not any_asmdiffs_found:
                 f.write("No asmdiffs found\n")
 
         if do_tpdiff:
-            f.write("# Throughput impact on Windows {}\n\n".format(arch))
+            f.write("# Throughput impact on {} {}\n\n".format(platform_name, arch))
             f.write("The following shows the impact on throughput " +
                     "in terms of number of instructions executed inside the JIT. " +
                     "Negative percentages/lower numbers are better.\n\n")
@@ -162,7 +188,7 @@ def main(main_args):
                 for file_name in files:
                     if file_name.startswith("superpmi_tpdiff") and file_name.endswith(".md"):
                         full_file_path = os.path.join(dirpath, file_name)
-                        if append_diff_file(f, arch, file_name, full_file_path):
+                        if append_diff_file(f, file_name, full_file_path):
                             any_tpdiff_found = True
 
             if not any_tpdiff_found:
@@ -200,6 +226,7 @@ def main(main_args):
 
     return 0
 
+
 def html_color_diff(lines):
     new_text = ""
 
@@ -246,6 +273,7 @@ def html_color_diff(lines):
     commit_block()
     return "<pre><code>" + new_text + "</code></pre>"
 
+
 if __name__ == "__main__":
     args = parser.parse_args()
     sys.exit(main(args))