Skip to content

Commit 05084ac

Browse files
Merge pull request #79199 from aschwaighofer/cond_fail_remarks
IRGen: Annotate LLVM IR of condfail with the condfail's message
2 parents 7da2333 + 767c96f commit 05084ac

File tree

6 files changed

+116
-3
lines changed

6 files changed

+116
-3
lines changed

include/swift/AST/IRGenOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,8 @@ class IRGenOptions {
490490

491491
unsigned ConditionalRuntimeRecords : 1;
492492

493+
unsigned AnnotateCondFailMessage : 1;
494+
493495
unsigned InternalizeAtLink : 1;
494496

495497
/// Internalize symbols (static library) - do not export any public symbols.
@@ -634,6 +636,7 @@ class IRGenOptions {
634636
DisableStandardSubstitutionsInReflectionMangling(false),
635637
EnableGlobalISel(false), VirtualFunctionElimination(false),
636638
WitnessMethodElimination(false), ConditionalRuntimeRecords(false),
639+
AnnotateCondFailMessage(false),
637640
InternalizeAtLink(false), InternalizeSymbols(false),
638641
MergeableSymbols(false), EmitGenericRODatas(true),
639642
NoPreallocatedInstantiationCaches(false),

include/swift/Option/FrontendOptions.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,12 @@ def enable_arm64_corocc : Flag<["-"], "enable-arm64-corocc">,
11751175
def disable_arm64_corocc : Flag<["-"], "disable-arm64-corocc">,
11761176
HelpText<"Don't use swiftcorocc for yield_once_2 routines on arm64 variants.">;
11771177

1178+
def enable_cond_fail_message_annotation : Flag<["-"], "enable-cond-fail-message-annotation">,
1179+
HelpText<"Enable large loadable types register to memory pass">;
1180+
1181+
def disable_cond_fail_message_annotation : Flag<["-"], "dissable-cond-fail-message-annotation">,
1182+
HelpText<"Disable large loadable types register to memory pass">;
1183+
11781184
let Flags = [FrontendOption, NoDriverOption, HelpHidden, ModuleInterfaceOptionIgnorable] in {
11791185
def enable_pack_metadata_stack_promotion :
11801186
Joined<["-"], "enable-pack-metadata-stack-promotion=">,

lib/Frontend/CompilerInvocation.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3770,6 +3770,11 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
37703770
Opts.EnableLayoutStringValueWitnessesInstantiation = Args.hasFlag(OPT_enable_layout_string_value_witnesses_instantiation,
37713771
OPT_disable_layout_string_value_witnesses_instantiation,
37723772
Opts.EnableLayoutStringValueWitnessesInstantiation);
3773+
Opts.AnnotateCondFailMessage =
3774+
Args.hasFlag(OPT_enable_cond_fail_message_annotation,
3775+
OPT_disable_cond_fail_message_annotation,
3776+
Opts.AnnotateCondFailMessage);
3777+
37733778

37743779
if (Opts.EnableLayoutStringValueWitnessesInstantiation &&
37753780
!Opts.EnableLayoutStringValueWitnesses) {

lib/IRGen/IRGen.cpp

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@
9494
#include "llvm/Transforms/Scalar.h"
9595
#include "llvm/Transforms/Scalar/DCE.h"
9696

97+
#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
98+
#include "llvm/IR/DiagnosticInfo.h"
99+
#include "llvm/IR/LLVMRemarkStreamer.h"
100+
#include "llvm/Support/ToolOutputFile.h"
101+
97102
#include <thread>
98103

99104
#if HAVE_UNISTD_H
@@ -598,6 +603,38 @@ static void countStatsPostIRGen(UnifiedStatsReporter &Stats,
598603
}
599604
}
600605

606+
namespace {
607+
class SwiftDiagnosticHandler final : public llvm::DiagnosticHandler {
608+
609+
public:
610+
SwiftDiagnosticHandler(const IRGenOptions &Opts) : IRGenOpts(Opts) {}
611+
612+
bool handleDiagnostics(const llvm::DiagnosticInfo &DI) override {
613+
return true;
614+
}
615+
616+
bool isAnalysisRemarkEnabled(StringRef PassName) const override {
617+
return IRGenOpts.AnnotateCondFailMessage &&
618+
PassName == "annotation-remarks";
619+
}
620+
bool isMissedOptRemarkEnabled(StringRef PassName) const override {
621+
return IRGenOpts.AnnotateCondFailMessage &&
622+
PassName == "annotation-remarks";
623+
}
624+
bool isPassedOptRemarkEnabled(StringRef PassName) const override {
625+
return IRGenOpts.AnnotateCondFailMessage &&
626+
PassName == "annotation-remarks";
627+
}
628+
629+
bool isAnyRemarkEnabled() const override {
630+
return IRGenOpts.AnnotateCondFailMessage;
631+
}
632+
633+
private:
634+
const IRGenOptions &IRGenOpts;
635+
};
636+
}
637+
601638
/// Run the LLVM passes. In multi-threaded compilation this will be done for
602639
/// multiple LLVM modules in parallel.
603640
bool swift::performLLVM(const IRGenOptions &Opts,
@@ -666,6 +703,32 @@ bool swift::performLLVM(const IRGenOptions &Opts,
666703
assert(Opts.OutputKind == IRGenOutputKind::Module && "no output specified");
667704
}
668705

706+
std::string OptRemarksRecordFile;
707+
if (Opts.AnnotateCondFailMessage && !OutputFilename.empty()) {
708+
OptRemarksRecordFile = std::string(OutputFilename);
709+
OptRemarksRecordFile.append(".opt.yaml");
710+
}
711+
712+
auto &Ctxt = Module->getContext();
713+
std::unique_ptr<llvm::DiagnosticHandler> OldDiagnosticHandler =
714+
Ctxt.getDiagnosticHandler();
715+
Ctxt.setDiagnosticHandler(std::make_unique<SwiftDiagnosticHandler>(Opts));
716+
717+
llvm::Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr =
718+
setupLLVMOptimizationRemarks(Ctxt, OptRemarksRecordFile.c_str(), "annotation-remarks", "yaml",
719+
false/*RemarksWithHotness*/,
720+
0/*RemarksHotnessThreshold*/);
721+
722+
if (Error E = OptRecordFileOrErr.takeError()) {
723+
diagnoseSync(Diags, DiagMutex, SourceLoc(), diag::error_opening_output,
724+
StringRef(OptRemarksRecordFile.c_str()),
725+
toString(std::move(E)));
726+
return true;
727+
}
728+
729+
std::unique_ptr<llvm::ToolOutputFile> OptRecordFile =
730+
std::move(*OptRecordFileOrErr);
731+
669732
performLLVMOptimizations(Opts, Diags, DiagMutex, Module, TargetMachine,
670733
OutputFile ? &OutputFile->getOS() : nullptr);
671734

@@ -695,9 +758,15 @@ bool swift::performLLVM(const IRGenOptions &Opts,
695758
}
696759
}
697760

698-
return compileAndWriteLLVM(Module, TargetMachine, Opts, Stats, Diags,
761+
auto res = compileAndWriteLLVM(Module, TargetMachine, Opts, Stats, Diags,
699762
*OutputFile, DiagMutex,
700763
CASIDFile ? CASIDFile.get() : nullptr);
764+
if (OptRecordFile)
765+
OptRecordFile->keep();
766+
767+
Ctxt.setDiagnosticHandler(std::move(OldDiagnosticHandler));
768+
769+
return res;
701770
}
702771

703772
bool swift::compileAndWriteLLVM(

lib/IRGen/IRGenSIL.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8249,8 +8249,11 @@ void IRGenSILFunction::visitCondFailInst(swift::CondFailInst *i) {
82498249

82508250
llvm::BasicBlock *failBB = llvm::BasicBlock::Create(IGM.getLLVMContext());
82518251
llvm::BasicBlock *contBB = llvm::BasicBlock::Create(IGM.getLLVMContext());
8252-
Builder.CreateCondBr(expectedCond, failBB, contBB);
8253-
8252+
auto br = Builder.CreateCondBr(expectedCond, failBB, contBB);
8253+
8254+
if (IGM.getOptions().AnnotateCondFailMessage && !i->getMessage().empty())
8255+
br->addAnnotationMetadata(i->getMessage());
8256+
82548257
Builder.SetInsertPoint(&CurFn->back());
82558258
Builder.emitBlock(failBB);
82568259
if (IGM.DebugInfo)

test/IRGen/annotated_cond_fail.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %target-swift-frontend -module-name A -enable-cond-fail-message-annotation -primary-file %s -O -emit-ir | %FileCheck %s
2+
3+
// REQUIRES: swift_stdlib_no_asserts,optimized_stdlib
4+
// REQUIRES: PTRSIZE=64
5+
6+
public func test(_ a: [Int], _ i: Int) -> Int {
7+
return a[i + 1]
8+
}
9+
10+
// CHECK: define{{.*}} swiftcc i64 @"$s1A4testySiSaySiG_SitF"(ptr{{.*}} %0, i64 %1)
11+
12+
// CHECK: [[ADD:%.*]] = tail call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %1, i64 1)
13+
// CHECK: [[IDX:%.*]] = extractvalue { i64, i1 } [[ADD]], 0
14+
// CHECK: [[OVERFLOW:%.*]] = extractvalue { i64, i1 } [[ADD]], 1
15+
// CHECK: br i1 [[OVERFLOW]], {{.*}}!annotation ![[ARITH_OVERFLOW:[0-9]+]]
16+
17+
// CHECK: [[C0:%.*]] = icmp slt i64 [[IDX]], 0
18+
// CHECK: br i1 [[C0]], {{.*}}!annotation ![[ARRAY_INDEX_OUT_OF_BOUNDS:[0-9]+]]
19+
20+
// CHECK: [[SIZE_ADDR:%.*]] = getelementptr
21+
// CHECK: [[SIZE:%.*]] = load i64, ptr [[SIZE_ADDR]]
22+
// CHECK: [[C1:%.*]] = icmp ult i64 [[IDX]], [[SIZE]]
23+
// CHECK: br i1 [[C1]], {{.*}}!annotation ![[ARRAY_INDEX_OUT_OF_BOUNDS]]
24+
25+
26+
// CHECK-DAG: ![[ARITH_OVERFLOW]] = !{!"arithmetic overflow"}
27+
// CHECK-DAG: ![[ARRAY_INDEX_OUT_OF_BOUNDS]] = !{!"Index out of range"}

0 commit comments

Comments
 (0)