Skip to content

Conversation

@aelovikov-intel
Copy link
Contributor

We only run SYCL JIT on a single TU at a time, so using ClangTool is a bit awkward, as it is primarily used to run the same action across a set of files:

/// Utility to run a FrontendAction over a set of files.
///
/// This class is written to be usable for command line utilities.
/// By default the class uses ClangSyntaxOnlyAdjuster to modify
/// command line arguments before the arguments are used to run
/// a frontend action. One could install an additional command line
/// arguments adjuster by calling the appendArgumentsAdjuster() method.
class ClangTool {

Using ToolInvocation better matches our scenario of always doing a single clang invocation:

/// Utility to run a FrontendAction in a single clang invocation.
class ToolInvocation {

Another benefit is that we have more control over the virtual file system which I'm planning to use in a subsequent PR to have the SYCL toolchain headers distributed inside libsycl-jit.so and then put into an llvm::vfs::InMemoryFileSystem once to be re-used across all compilation queries.

I'm also simplifying the inheritance scheme around clang::ToolAction. Instead of having both hashing/compiling doing that, I'm providing a single helper that accepts a reference to the FrontendAction that can be kept on the caller's stack, reducing the amount of boilerplate helpers necessary, i.e.
RTCToolActionBase/GetSourceHashAction/GetLLVMModuleAction before vs. single SYCLToolchain::Action after.

We only run SYCL JIT on a single TU at a time, so using `ClangTool` is a
bit awkward, as it is primarily used to run the same action across a set
of files:

https://github.com/intel/llvm/blob/357f96b7e19d8acb972eb2f1fb276dbc6aa2060b/clang/include/clang/Tooling/Tooling.h#L310-L317

Using `ToolInvocation` better matches our scenario of always doing a
single clang invocation:

https://github.com/intel/llvm/blob/357f96b7e19d8acb972eb2f1fb276dbc6aa2060b/clang/include/clang/Tooling/Tooling.h#L244-L245

Another benefit is that we have more control over the virtual file
system which I'm planning to use in a subsequent PR to have the SYCL
toolchain headers distributed inside `libsycl-jit.so` and then put into
an `llvm::vfs::InMemoryFileSystem` once to be re-used across all
compilation queries.

I'm also simplifying the inheritance scheme around `clang::ToolAction`.
Instead of having both hashing/compiling doing that, I'm providing a
single helper that accepts a reference to the `FrontendAction` that can
be kept on the caller's stack, reducing the amount of boilerplate
helpers necessary, i.e.
`RTCToolActionBase`/`GetSourceHashAction`/`GetLLVMModuleAction` before
vs. single `SYCLToolchain::Action` after.
Comment on lines +410 to 412
} else {
return createStringError(BuildLog);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
} else {
return createStringError(BuildLog);
}
}
return createStringError(BuildLog);

Comment on lines +386 to +388
} else {
return createStringError("Calculating source hash failed");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
} else {
return createStringError("Calculating source hash failed");
}
}
return createStringError("Calculating source hash failed");

const std::string &DPCPPRoot, BinaryFormat Format,
SmallVectorImpl<std::string> &CommandLine) {
static std::vector<std::string>
createCommandLine(const InputArgList &UserArgList, std::string_view DPCPPRoot,
Copy link
Contributor

Choose a reason for hiding this comment

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

what will the command line typically be? clang++ -c <source1..N> ? Might be nice to document it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Still not sure what this pre-existing code does 😆 Currently it would be

/full/path/to/dpcpp/installation/on/the/actual/file/system/bin/clang++ <magic> rtc_N.cpp

I'm trying to drop the requirement to have an actual installation and turn it to this instead:

/fake_path/bin/clang++ <magic> rtc_N.cpp

in #19924

Copy link
Contributor

Choose a reason for hiding this comment

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

@jopperm would know more about this, but the correct path might be relevant for determining the location of libraries and headers that are part of the DPC++ distribution.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, IIRC setting the argv0 of the invocation to the actual clang++ binary made the detection of include paths work automatically. Some logic might still be sensitive to the exe being called clang++, but if you set the include paths explicitly anyways, a fake path should be fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it is. The virtual in-memory filesystem has to have the files in /fake_path/include/sycl too.

Copy link
Contributor

@jopperm jopperm left a comment

Choose a reason for hiding this comment

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

Neat!

@aelovikov-intel aelovikov-intel merged commit e8ce925 into intel:sycl Aug 29, 2025
49 of 51 checks passed
@aelovikov-intel aelovikov-intel deleted the refactor-sycl-rtc branch August 29, 2025 14:13
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.

5 participants