Skip to content

Conversation

chiragramani
Copy link
Contributor

@chiragramani chiragramani commented Sep 17, 2025

This PR introduces three new instrumentation flags and plumbs them through to IRGen:

  1. -ir-profile-generate - enable IR-level instrumentation.
  2. -cs-profile-generate - enable context-sensitive IR-level instrumentation.
  3. -ir-profile-use - IR-level PGO input profdata file to enable profile-guided optimization (both IRPGO and CSIRPGO)

Context: https://forums.swift.org/t/ir-level-pgo-instrumentation-in-swift/82123

Swift-driver PR: swiftlang/swift-driver#1992

Tests and validation:
This PR includes ir level verification tests, also checks few edge-cases when -ir-profile-use supplied profile is either missing or is an invalid IR profile.

However, for argument validation, linking, and generating IR profiles that can later be consumed by -cs-profile-generate, I’ll need corresponding swift-driver changes. Those changes are being tracked in swiftlang/swift-driver#1992

The plan is:

  1. Land this PR first.
  2. Then update swift-driver with the required changes.
  3. Then add the remaining set of test cases in this repo.

Open Questions (Reviewer Input Requested)

1. Naming:
Is -ir-profile-generate a good flag name?
-cs-profile-generate pairs nicely with Clang’s -fcs-profile-generate. However, -ir-profile-generate feels closer to Clang's -fprofile-generate but -profile-generate already exists in Swift as a frontend level and not IR level. Should it stay as is, or is there a clearer alternative?

2. Missing LLVM runtime + Blocked on tests

At the moment, I haven’t added tests because they currently fail locally due to missing LLVM runtime symbols. This is expected, since the required runtime linking through libclang APIs will be handled in swift-driver(swiftlang/swift-driver#1992). However, swift-driver itself depends on these new options being available in Swift.

Does that mean the correct order of the PRs should be the following?

1. Create a PR in Swift that introduces just the new options, and land that PR first.
2. Land the corresponding swift-driver PR to handle runtime linking,
3. Then follow up with a Swift PR adding the full functionality and tests?

~~

@aschwaighofer
Copy link
Contributor

I don't have a strong opinion on naming. My feeling is that context sensitive and non context sensitive LLVM IR level instrumentation should follow a similar pattern to make clear they are related. We have already deviated from clang's naming scheme -- that is, clang's fprofile-generate(llvm ir level instrumentation) is not equal swift's -profile-generate ("AST" based insertion of instrumentation). -ir-profile-generate and -cs-ir-profile-generate would make it clearer that they are related.

@aschwaighofer
Copy link
Contributor

Does that mean the correct order of the PRs should be the following?
Create a PR in Swift that introduces just the new options, and land that PR first.
Land the corresponding swift-driver PR to handle runtime linking,
Then follow up with a Swift PR adding the full functionality and tests?

You could add LLVM IR level tests that test the functionality of this PR (look at most tests in test/IRGen) and merge this PR first. Then you could land the corresponding swift-driver PR. Then you could at a swiftlang/swift repo commit to add execution tests.

// RUN: %target-swift-frontend -ir-profile-generate -emit-ir %s | %FileCheck %s

// CHECK: define @mangleNameOfA
// CHECK: the llvm ir you expect to see (calls to profile runtime function/intrinsics)
public func a(_ cond: Bool) {
  if cond {
     b()
  } else {
    c()
  }
}

Preferably, you would as .sil tests rather than .swift tests as that would make them more "stable".

That would look something like the following (I ran swiftc -emit-sil test.swift and edited the output a little bit):

// RUN: %target-swift-frontend -ir-profile-generate -emit-ir %s | %FileCheck %s

sil_stage canonical

import Builtin
import Swift
import SwiftShims

sil @b : $@convention(thin) () -> ()

sil @c : $@convention(thin) () -> ()

// CHECK: define {{.*}} void @a
// CHECK: the llvm ir you expect to see (calls to profile runtime function/intrinsics)

sil @a : $@convention(thin) (Bool) -> () {
bb0(%0 : $Bool):
  %2 = struct_extract %0, #Bool._value
  cond_br %2, bb1, bb2

bb1:
  // function_ref b()
  %4 = function_ref @b : $@convention(thin) () -> ()
  %5 = apply %4() : $@convention(thin) () -> ()
  br bb3 

bb2:
  // function_ref c()
  %7 = function_ref @c: $@convention(thin) () -> ()
  %8 = apply %7() : $@convention(thin) () -> ()
  br bb3 

bb3:
  %10 = tuple ()
  return %10
}

@chiragramani
Copy link
Contributor Author

Preferably, you would as .sil tests rather than .swift tests as that would make them more "stable".

You could add LLVM IR level tests that test the functionality of this PR (look at most tests in test/IRGen) and merge this PR first. Then you could land the corresponding swift-driver PR. Then you could at a swiftlang/swift repo commit to add execution tests.

Thanks for the guidance here, it definitely helped me understand things better!

Added tests
@chiragramani
Copy link
Contributor Author

Hi @aschwaighofer, I've added the tests based on your suggestions. When you have a moment, could you please review the changes and share your feedback? Thanks

@chiragramani
Copy link
Contributor Author

@kavon would love to hear your perspective on this PR as well, when you have a moment.

@chiragramani
Copy link
Contributor Author

@swift-ci test

@chiragramani
Copy link
Contributor Author

Hey @aschwaighofer, would it be possible for you to tag or add the respective POCs who could help review this PR please? I’d really appreciate it.

@drodriguez
Copy link
Contributor

@swift-ci please test

@chiragramani
Copy link
Contributor Author

@swift-ci please test

@drodriguez
Copy link
Contributor

@swift-ci please test

@drodriguez
Copy link
Contributor

please test

@chiragramani sadly you need a special role for starting the tests. The details are in https://www.swift.org/contributing/#member (still some hoops to jump through, but easier than before)

@aschwaighofer
Copy link
Contributor

@swift-ci test

Copy link
Contributor

@aschwaighofer aschwaighofer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@drodriguez
Copy link
Contributor

@swift-ci please test

@chiragramani
Copy link
Contributor Author

chiragramani commented Oct 1, 2025

@chiragramani sadly you need a special role for starting the tests. The details are in https://www.swift.org/contributing/#member (still some hoops to jump through, but easier than before)

Really appreciate you helping trigger the tests and sharing the process. I’ll send in a request soon.

@aschwaighofer
Copy link
Contributor

@swift-ci please test

@chiragramani
Copy link
Contributor Author

Swift Test Linux Platform — Failed

I noticed that the above job has failed, but I’m unable to open the link for the Linux job details. Could someone with access kindly share the logs or error message? Thanks

@drodriguez
Copy link
Contributor

ci.swift.org seems to give me time-outs. It might be having a bad day.

@chiragramani
Copy link
Contributor Author

ci.swift.org seems to give me time-outs. It might be having a bad day.

Thanks for checking. It looks like the link works now, but the error seems related to a CI infra issue (agent removal). Would it be possible to retry the job?

@drodriguez
Copy link
Contributor

@swift-ci please test Linux platform

@chiragramani
Copy link
Contributor Author

@swift-ci please test Linux platform

Thanks! The smoke test ran post this but the Swift Test Linux Platform didn’t get picked up. Can we give it another run/retry please 🙏?

@drodriguez
Copy link
Contributor

The "(smoke test)" gets fulfilled by the non smoke test. It seems, however, that your comment quote did trigger the Linux Platform build in https://ci.swift.org/job/swift-PR-Linux/24357/ so I cannot check the previous results, but hopefully those will turn green.

(I have a couple of PRs and I am also in testing hell, but in my case with macOS failing randomly all the time… patience)

@chiragramani
Copy link
Contributor Author

******************** TEST 'Swift(linux-x86_64) :: Interop/Cxx/class/access/swiftify-private-fileid.swift' FAILED ********************
15:30:00  couldn't parse text: '://162106643'
15:30:00  in expression: 'rdar://162106643'
15:30:00  in REQUIRES: directive on test line 1
15:30:00  ********************

It failed 😅
I saw that the failure is in swiftify-private-fileid.swift, but it looks unrelated to this PR changes. Any suggestions how to go about it?

@drodriguez
Copy link
Contributor

#84775 should take care of those. It has been one of those weeks.

@drodriguez
Copy link
Contributor

@swift-ci please test Linux platform

@chiragramani
Copy link
Contributor Author

Thank you for all your help @drodriguez , its all green now 🙌

@drodriguez drodriguez merged commit 5179bc9 into swiftlang:main Oct 10, 2025
5 checks passed
dendiz pushed a commit to dendiz/swift that referenced this pull request Oct 21, 2025
This PR introduces three new instrumentation flags and plumbs them
through to IRGen:

1. `-ir-profile-generate` - enable IR-level instrumentation.
2. `-cs-profile-generate` - enable context-sensitive IR-level
instrumentation.
3. `-ir-profile-use` - IR-level PGO input profdata file to enable
profile-guided optimization (both IRPGO and CSIRPGO)

**Context:**
https://forums.swift.org/t/ir-level-pgo-instrumentation-in-swift/82123

**Swift-driver PR:** swiftlang/swift-driver#1992

**Tests and validation:**
This PR includes ir level verification tests, also checks few edge-cases
when `-ir-profile-use` supplied profile is either missing or is an
invalid IR profile.

However, for argument validation, linking, and generating IR profiles
that can later be consumed by -cs-profile-generate, I’ll need
corresponding swift-driver changes. Those changes are being tracked in
swiftlang/swift-driver#1992
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants