Skip to content

Commit 63c7bf4

Browse files
committed
[Driver][FPGA][SYCL] Add specific timing diagnostic for FPGA AOT
There are cases in which the generation of FPGA device code from 'aoc' is known to have timing issues. Add a specific diagnostic from the driver when this case is encountered. A special return code (42) is used to inform the driver of this situation. Additionally in this situation, we also want to allow for the compilation to continue so the user can use the generated binary knowing the timing issue as stated.
1 parent 5eaa14f commit 63c7bf4

File tree

5 files changed

+56
-13
lines changed

5 files changed

+56
-13
lines changed

clang/include/clang/Driver/Job.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ struct ResponseFileSupport {
105105
/// execute.
106106
class Command {
107107
public:
108-
using ErrorCodeDiagMapTy = llvm::DenseMap<int, std::string>;
108+
using ErrorCodeDiagMapTy = llvm::DenseMap<int, std::pair<std::string, bool>>;
109109

110110
private:
111111
/// Source - The action which caused the creation of this job.
@@ -122,6 +122,8 @@ class Command {
122122

123123
/// The container for custom driver-set diagnostic messages that are
124124
/// produced upon particular error codes returned by the command.
125+
/// Given a custom diagnostic, also allow for logic to determine if the
126+
/// compilation should continue, even with a non-zero return code.
125127
/// In order to add such a diagnostic for an external tool, consider the
126128
/// following criteria:
127129
/// 1) Does the command's executable return different codes upon different
@@ -194,15 +196,20 @@ class Command {
194196
virtual int Execute(ArrayRef<Optional<StringRef>> Redirects,
195197
std::string *ErrMsg, bool *ExecutionFailed) const;
196198

197-
/// Store a custom driver diagnostic message upon a particular error code
198-
/// returned by the command
199-
void addDiagForErrorCode(int ErrorCode, StringRef CustomDiag);
199+
/// Store a custom driver diagnostic message and if the compilation should
200+
/// exit upon a particular error code returned by the command
201+
void addDiagForErrorCode(int ErrorCode, StringRef CustomDiag,
202+
bool NoExit = false);
200203

201204
/// Get the custom driver diagnostic message for a particular error code
202205
/// if such was stored. Returns an empty string if no diagnostic message
203206
/// was found for the given error code.
204207
StringRef getDiagForErrorCode(int ErrorCode) const;
205208

209+
/// Will the tool exit when a particular error code is encountered. Returns
210+
/// false if not set (always exit)
211+
bool getWillNotExitForErrorCode(int ErrorCode) const;
212+
206213
/// getSource - Return the Action which caused the creation of this job.
207214
const Action &getSource() const { return Source; }
208215

clang/lib/Driver/Compilation.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,10 @@ static bool ActionFailed(const Action *A,
249249
if (FailingCommands.empty())
250250
return false;
251251

252+
for (const auto &CI : FailingCommands)
253+
if (CI.second->getWillNotExitForErrorCode(CI.first))
254+
return false;
255+
252256
// CUDA/HIP/SYCL can have the same input source code compiled multiple times
253257
// so do not compile again if there are already failures. It is OK to abort
254258
// the CUDA pipeline on errors.
@@ -285,7 +289,10 @@ void Compilation::ExecuteJobs(const JobList &Jobs,
285289
if (int Res = ExecuteCommand(Job, FailingCommand)) {
286290
FailingCommands.push_back(std::make_pair(Res, FailingCommand));
287291
// Bail as soon as one command fails in cl driver mode.
288-
if (TheDriver.IsCLMode())
292+
// Do not bail when the tool is setup to allow for continuation upon
293+
// failure.
294+
if (TheDriver.IsCLMode() &&
295+
!FailingCommand->getWillNotExitForErrorCode(Res))
289296
return;
290297
}
291298
}

clang/lib/Driver/Job.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,17 +158,26 @@ void Command::buildArgvForResponseFile(
158158
}
159159
}
160160

161-
void Command::addDiagForErrorCode(int ErrorCode, StringRef CustomDiag) {
162-
ErrorCodeDiagMap[ErrorCode] = CustomDiag.str();
161+
void Command::addDiagForErrorCode(int ErrorCode, StringRef CustomDiag,
162+
bool NoExit) {
163+
ErrorCodeDiagMap[ErrorCode].first = CustomDiag.str();
164+
ErrorCodeDiagMap[ErrorCode].second = NoExit;
163165
}
164166

165167
StringRef Command::getDiagForErrorCode(int ErrorCode) const {
166168
auto ErrorCodeDiagIt = ErrorCodeDiagMap.find(ErrorCode);
167169
if (ErrorCodeDiagIt != ErrorCodeDiagMap.end())
168-
return ErrorCodeDiagIt->second;
170+
return ErrorCodeDiagIt->second.first;
169171
return StringRef();
170172
}
171173

174+
bool Command::getWillNotExitForErrorCode(int ErrorCode) const {
175+
auto ErrorCodeDiagIt = ErrorCodeDiagMap.find(ErrorCode);
176+
if (ErrorCodeDiagIt != ErrorCodeDiagMap.end())
177+
return ErrorCodeDiagIt->second.second;
178+
return false;
179+
}
180+
172181
/// Rewrite relative include-like flag paths to absolute ones.
173182
static void
174183
rewriteIncludes(const llvm::ArrayRef<const char *> &Args, size_t Idx,

clang/lib/Driver/ToolChains/SYCL.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,16 @@ const char *SYCL::Linker::constructLLVMSpirvCommand(
8282
return OutputFileName;
8383
}
8484

85+
static void addFPGATimingDiagnostic(std::unique_ptr<Command> &Cmd,
86+
Compilation &C) {
87+
const char *Msg = C.getArgs().MakeArgString(
88+
"The FPGA image generated during this compile contains timing violations "
89+
"and may produce functional errors if used. Refer to the Intel oneAPI "
90+
"DPC++ FPGA Optimization Guide section on Timing Failures for more "
91+
"information.");
92+
Cmd->addDiagForErrorCode(/*ErrorCode*/ 42, Msg, true);
93+
}
94+
8595
void SYCL::constructLLVMForeachCommand(Compilation &C, const JobAction &JA,
8696
std::unique_ptr<Command> InputCommand,
8797
const InputInfoList &InputFiles,
@@ -119,8 +129,14 @@ void SYCL::constructLLVMForeachCommand(Compilation &C, const JobAction &JA,
119129
SmallString<128> ForeachPath(C.getDriver().Dir);
120130
llvm::sys::path::append(ForeachPath, "llvm-foreach");
121131
const char *Foreach = C.getArgs().MakeArgString(ForeachPath);
122-
C.addCommand(std::make_unique<Command>(JA, *T, ResponseFileSupport::None(),
123-
Foreach, ForeachArgs, None));
132+
133+
auto Cmd = std::make_unique<Command>(JA, *T, ResponseFileSupport::None(),
134+
Foreach, ForeachArgs, None);
135+
// FIXME: Add the FPGA specific timing diagnostic to the foreach call.
136+
// The foreach call obscures the return codes from the tool it is calling
137+
// to the compiler itself.
138+
addFPGATimingDiagnostic(Cmd, C);
139+
C.addCommand(std::move(Cmd));
124140
}
125141

126142
// The list should match pre-built SYCL device library files located in
@@ -525,6 +541,7 @@ void SYCL::fpga::BackendCompiler::ConstructJob(
525541
const char *Exec = C.getArgs().MakeArgString(ExecPath);
526542
auto Cmd = std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
527543
Exec, CmdArgs, None);
544+
addFPGATimingDiagnostic(Cmd, C);
528545
if (!ForeachInputs.empty())
529546
constructLLVMForeachCommand(C, JA, std::move(Cmd), ForeachInputs, Output,
530547
this, ReportOptArg, ForeachExt);

llvm/tools/llvm-foreach/llvm-foreach.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ int main(int argc, char **argv) {
165165
if (!OutputFileList.empty())
166166
error(EC, "error opening the file '" + OutputFileList + "'");
167167

168+
int Res = 0;
168169
std::string ResOutArg;
169170
std::string IncOutArg;
170171
std::vector<std::string> ResInArgs(InReplaceArgs.size());
@@ -225,13 +226,15 @@ int main(int argc, char **argv) {
225226
int Result =
226227
sys::ExecuteAndWait(Prog, Args, /*Env=*/None, /*Redirects=*/None,
227228
/*SecondsToWait=*/0, /*MemoryLimit=*/0, &ErrMsg);
228-
if (Result != 0)
229-
error(ErrMsg);
229+
if (Result != 0) {
230+
errs() << "llvm-foreach: " << ErrMsg << '\n';
231+
Res = Result;
232+
}
230233
}
231234

232235
if (!OutputFileList.empty()) {
233236
OS.close();
234237
}
235238

236-
return 0;
239+
return Res;
237240
}

0 commit comments

Comments
 (0)