Skip to content

Commit c1324e6

Browse files
authored
[SYCL] Add splitting module capabilities when compiling for NVPTX and AMDGCN (#4107)
The patch allows modules splitting for NVPTX and AMDGCN targets. As those path needs to rely on existing tool, the approach taken here is to generate and intercept commands so they can be wrapped by a `llvm-foreach` tool call. To do that, the patch adds `ForEachWrappingAction` which allows to encapsulate a set of actions whose underlying commands will be wrapped under a llvm-foreach commands. During the binding phases, the action will trigger the emission of jobs outside the set, record the Jobs state then triggers the emission of the jobs inside the set. The newly added commands are stolen from the Jobs list and the commands are re-emitted with the llvm-foreach wrapping. To allow standard clang tools to work properly, SYCLPostLinkJobAction and FileTableTformJobAction reports the underlying file type rather than TY_Tempfilelist or TY_tempfiletable for those targets. Otherwise tools get confused as they don't know how to process the input. To not make this patch too large, I maintained the SPIR-V path behaviour as it is, meaning the list of actions are not set up in the same way nor does it uses the `ForEachWrappingAction`. Otherwise there is a long list of test to update. Signed-off-by: Victor Lomuller <[email protected]>
1 parent 0e22fdd commit c1324e6

File tree

8 files changed

+252
-103
lines changed

8 files changed

+252
-103
lines changed

clang/include/clang/Driver/Action.h

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class Action {
5757
InputClass = 0,
5858
BindArchClass,
5959
OffloadClass,
60+
ForEachWrappingClass,
6061
PreprocessJobClass,
6162
PrecompileJobClass,
6263
HeaderModulePrecompileJobClass,
@@ -737,7 +738,15 @@ class SYCLPostLinkJobAction : public JobAction {
737738
void anchor() override;
738739

739740
public:
740-
SYCLPostLinkJobAction(Action *Input, types::ID OutputType);
741+
// The tempfiletable management relies on a shadowing the main file type by
742+
// types::TY_Tempfiletable. The problem of shadowing is it prevents its
743+
// integration with clang tools that relies on the file type to properly set
744+
// args.
745+
// We "trick" the driver by declaring the underlying file type and set a
746+
// "true output type" which will be used by the SYCLPostLinkJobAction
747+
// to properly set the job.
748+
SYCLPostLinkJobAction(Action *Input, types::ID ShadowOutputType,
749+
types::ID TrueOutputType);
741750

742751
static bool classof(const Action *A) {
743752
return A->getKind() == SYCLPostLinkJobClass;
@@ -747,8 +756,11 @@ class SYCLPostLinkJobAction : public JobAction {
747756

748757
bool getRTSetsSpecConstants() const { return RTSetsSpecConsts; }
749758

759+
types::ID getTrueType() const { return TrueOutputType; }
760+
750761
private:
751762
bool RTSetsSpecConsts = true;
763+
types::ID TrueOutputType;
752764
};
753765

754766
class BackendCompileJobAction : public JobAction {
@@ -771,6 +783,9 @@ class FileTableTformJobAction : public JobAction {
771783
void anchor() override;
772784

773785
public:
786+
static constexpr const char *COL_CODE = "Code";
787+
static constexpr const char *COL_ZERO = "0";
788+
774789
struct Tform {
775790
enum Kind {
776791
EXTRACT,
@@ -791,8 +806,10 @@ class FileTableTformJobAction : public JobAction {
791806
SmallVector<std::string, 2> TheArgs;
792807
};
793808

794-
FileTableTformJobAction(Action *Input, types::ID OutputType);
795-
FileTableTformJobAction(ActionList &Inputs, types::ID OutputType);
809+
FileTableTformJobAction(Action *Input, types::ID ShadowOutputType,
810+
types::ID TrueOutputType);
811+
FileTableTformJobAction(ActionList &Inputs, types::ID ShadowOutputType,
812+
types::ID TrueOutputType);
796813

797814
// Deletes all columns except the one with given name.
798815
void addExtractColumnTform(StringRef ColumnName, bool WithColTitle = true);
@@ -820,7 +837,10 @@ class FileTableTformJobAction : public JobAction {
820837

821838
const ArrayRef<Tform> getTforms() const { return Tforms; }
822839

840+
types::ID getTrueType() const { return TrueOutputType; }
841+
823842
private:
843+
types::ID TrueOutputType;
824844
SmallVector<Tform, 2> Tforms; // transformation actions requested
825845

826846
// column to copy single file from if requested
@@ -849,6 +869,30 @@ class StaticLibJobAction : public JobAction {
849869
}
850870
};
851871

872+
/// Wrap all jobs performed between TFormInput (excluded) and Job (included)
873+
/// behind a `llvm-foreach` call.
874+
///
875+
/// Assumptions:
876+
/// - No change of toolchain, boundarch and offloading kind should occur
877+
/// within the sub-region;
878+
/// - No job should produce multiple outputs;
879+
/// - Results of action within the sub-region should not be used outside the
880+
/// wrapped region.
881+
/// Note: this doesn't bind to a tool directly and this need special casing
882+
/// anyhow. Hence why this is an Action and not a JobAction, even if there is a
883+
/// command behind.
884+
class ForEachWrappingAction : public Action {
885+
public:
886+
ForEachWrappingAction(JobAction *TFormInput, JobAction *Job);
887+
888+
JobAction *getTFormInput() const;
889+
JobAction *getJobAction() const;
890+
891+
static bool classof(const Action *A) {
892+
return A->getKind() == ForEachWrappingClass;
893+
}
894+
};
895+
852896
} // namespace driver
853897
} // namespace clang
854898

clang/include/clang/Driver/Job.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,8 @@ class JobList {
319319
/// Clear the job list.
320320
void clear();
321321

322+
/// Return a mutable list of Jobs for llvm-foreach wrapping.
323+
list_type &getJobsForOverride() { return Jobs; }
322324
const list_type &getJobs() const { return Jobs; }
323325

324326
bool empty() const { return Jobs.empty(); }

clang/lib/Driver/Action.cpp

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ const char *Action::getClassName(ActionClass AC) {
5959
return "append-footer";
6060
case StaticLibJobClass:
6161
return "static-lib-linker";
62+
case ForEachWrappingClass:
63+
return "foreach";
6264
}
6365

6466
llvm_unreachable("invalid class");
@@ -474,8 +476,11 @@ SPIRCheckJobAction::SPIRCheckJobAction(Action *Input, types::ID Type)
474476

475477
void SYCLPostLinkJobAction::anchor() {}
476478

477-
SYCLPostLinkJobAction::SYCLPostLinkJobAction(Action *Input, types::ID Type)
478-
: JobAction(SYCLPostLinkJobClass, Input, Type) {}
479+
SYCLPostLinkJobAction::SYCLPostLinkJobAction(Action *Input,
480+
types::ID ShadowOutputType,
481+
types::ID TrueOutputType)
482+
: JobAction(SYCLPostLinkJobClass, Input, ShadowOutputType),
483+
TrueOutputType(TrueOutputType) {}
479484

480485
void BackendCompileJobAction::anchor() {}
481486

@@ -489,12 +494,17 @@ BackendCompileJobAction::BackendCompileJobAction(Action *Input,
489494

490495
void FileTableTformJobAction::anchor() {}
491496

492-
FileTableTformJobAction::FileTableTformJobAction(Action *Input, types::ID Type)
493-
: JobAction(FileTableTformJobClass, Input, Type) {}
497+
FileTableTformJobAction::FileTableTformJobAction(Action *Input,
498+
types::ID ShadowOutputType,
499+
types::ID TrueOutputType)
500+
: JobAction(FileTableTformJobClass, Input, ShadowOutputType),
501+
TrueOutputType(TrueOutputType) {}
494502

495503
FileTableTformJobAction::FileTableTformJobAction(ActionList &Inputs,
496-
types::ID Type)
497-
: JobAction(FileTableTformJobClass, Inputs, Type) {}
504+
types::ID ShadowOutputType,
505+
types::ID TrueOutputType)
506+
: JobAction(FileTableTformJobClass, Inputs, ShadowOutputType),
507+
TrueOutputType(TrueOutputType) {}
498508

499509
void FileTableTformJobAction::addExtractColumnTform(StringRef ColumnName,
500510
bool WithColTitle) {
@@ -533,3 +543,15 @@ void StaticLibJobAction::anchor() {}
533543

534544
StaticLibJobAction::StaticLibJobAction(ActionList &Inputs, types::ID Type)
535545
: JobAction(StaticLibJobClass, Inputs, Type) {}
546+
547+
ForEachWrappingAction::ForEachWrappingAction(JobAction *TFormInput,
548+
JobAction *Job)
549+
: Action(ForEachWrappingClass, {TFormInput, Job}, Job->getType()) {}
550+
551+
JobAction *ForEachWrappingAction::getTFormInput() const {
552+
return llvm::cast<JobAction>(getInputs()[0]);
553+
}
554+
555+
JobAction *ForEachWrappingAction::getJobAction() const {
556+
return llvm::cast<JobAction>(getInputs()[1]);
557+
}

0 commit comments

Comments
 (0)