[Printer] Conditionally print Clang types in emitted SIL.

Hopefully, this helps us debug Clang type mismatches better.
This commit is contained in:
Varun Gandhi
2020-01-15 16:15:44 -08:00
parent 5f45820755
commit a27c5f0a16
15 changed files with 86 additions and 37 deletions

View File

@@ -564,7 +564,7 @@ struct PrintOptions {
static PrintOptions printDocInterface();
/// Retrieve the set of options suitable for printing SIL functions.
static PrintOptions printSIL() {
static PrintOptions printSIL(bool printFullConvention = false) {
PrintOptions result;
result.PrintLongAttrsOnSeparateLines = true;
result.PrintStorageRepresentationAttrs = true;
@@ -575,6 +575,9 @@ struct PrintOptions {
result.PrintIfConfig = false;
result.OpaqueReturnTypePrinting =
OpaqueReturnTypePrintingMode::StableReference;
if (printFullConvention)
result.PrintFunctionRepresentationAttrs =
PrintOptions::FunctionRepresentationMode::Full;
return result;
}

View File

@@ -78,6 +78,9 @@ public:
/// variables by name when we print it out. This eases diffing of SIL files.
bool EmitSortedSIL = false;
/// See \ref FrontendOptions.PrintFullConvention
bool PrintFullConvention = false;
/// Whether to stop the optimization pipeline after serializing SIL.
bool StopOptimizationAfterSerialization = false;

View File

@@ -253,6 +253,9 @@ public:
/// See the \ref SILOptions.EmitSortedSIL flag.
bool EmitSortedSIL = false;
/// Should we emit the cType when printing @convention(c) or no?
bool PrintFullConvention = false;
/// Indicates whether the dependency tracker should track system
/// dependencies as well.
bool TrackSystemDeps = false;

View File

@@ -31,8 +31,8 @@ struct ModuleInterfaceOptions {
/// interface, or should we fully-qualify them?
bool PreserveTypesAsWritten = false;
/// Should we emit the cType when printing @convention(c) or no?
/// FIXME: [clang-function-type-serialization] This check should go away.
/// See \ref FrontendOptions.PrintFullConvention.
/// FIXME: [clang-function-type-serialization] This flag should go away.
bool PrintFullConvention = false;
/// Copy of all the command-line flags passed at .swiftinterface

View File

@@ -608,10 +608,12 @@ def module_interface_preserve_types_as_written :
HelpText<"When emitting a module interface, preserve types as they were "
"written in the source">;
// FIXME: [clang-function-type-serialization] Make this a SIL-only option once we
// start unconditionally emitting non-canonical Clang types in swiftinterfaces.
def experimental_print_full_convention :
Flag<["-"], "experimental-print-full-convention">,
HelpText<"When emitting a module interface, emit additional @convention "
"arguments, regardless of whether they were written in the source">;
HelpText<"When emitting a module interface or SIL, emit additional @convention"
" arguments, regardless of whether they were written in the source">;
def prebuilt_module_cache_path :
Separate<["-"], "prebuilt-module-cache-path">,

View File

@@ -647,10 +647,11 @@ public:
/// \param ShouldSort If set to true sorts functions, vtables, sil global
/// variables, and witness tables by name to ease diffing.
/// \param PrintASTDecls If set to true print AST decls.
void print(raw_ostream &OS, bool Verbose = false,
ModuleDecl *M = nullptr, bool ShouldSort = false,
void print(raw_ostream &OS,
ModuleDecl *M = nullptr,
const SILOptions &Opts = SILOptions(),
bool PrintASTDecls = true) const {
SILPrintContext PrintCtx(OS, Verbose, ShouldSort);
SILPrintContext PrintCtx(OS, Opts);
print(PrintCtx, M, PrintASTDecls);
}

View File

@@ -13,6 +13,7 @@
#ifndef SWIFT_SIL_PRINTCONTEXT_H
#define SWIFT_SIL_PRINTCONTEXT_H
#include "swift/AST/SILOptions.h"
#include "swift/SIL/SILDebugScope.h"
#include "swift/SIL/SILValue.h"
#include "llvm/ADT/DenseMap.h"
@@ -65,6 +66,9 @@ protected:
/// Print debug locations and scopes.
bool DebugInfo;
/// See \ref FrontendOptions.PrintFullConvention.
bool PrintFullConvention;
public:
/// Constructor with default values for options.
///
@@ -72,6 +76,11 @@ public:
SILPrintContext(llvm::raw_ostream &OS, bool Verbose = false,
bool SortedSIL = false);
/// Constructor based on SILOptions.
///
/// DebugInfo will be set according to the -sil-print-debuginfo option.
SILPrintContext(llvm::raw_ostream &OS, const SILOptions &Opts);
SILPrintContext(llvm::raw_ostream &OS, bool Verbose,
bool SortedSIL, bool DebugInfo);
@@ -94,6 +103,9 @@ public:
/// Returns true if debug locations and scopes should be printed.
bool printDebugInfo() const { return DebugInfo; }
/// Returns true if the entire @convention(c, cType: ..) should be printed.
bool printFullConvention() const { return PrintFullConvention; }
SILPrintContext::ID getID(const SILBasicBlock *Block);
SILPrintContext::ID getID(const SILNode *node);

View File

@@ -581,7 +581,8 @@ public:
std::string getAsString() const;
void dump() const;
void print(raw_ostream &OS) const;
void print(raw_ostream &OS,
const PrintOptions &PO = PrintOptions::printSIL()) const;
};
// Statically prevent SILTypes from being directly cast to a type

View File

@@ -68,6 +68,8 @@ bool ArgsToFrontendOptionsConverter::convert(
Opts.EmitVerboseSIL |= Args.hasArg(OPT_emit_verbose_sil);
Opts.EmitSortedSIL |= Args.hasArg(OPT_emit_sorted_sil);
Opts.PrintFullConvention |=
Args.hasArg(OPT_experimental_print_full_convention);
Opts.EnableTesting |= Args.hasArg(OPT_enable_testing);
Opts.EnablePrivateImports |= Args.hasArg(OPT_enable_private_imports);

View File

@@ -942,6 +942,8 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
Opts.DebugSerialization |= Args.hasArg(OPT_sil_debug_serialization);
Opts.EmitVerboseSIL |= Args.hasArg(OPT_emit_verbose_sil);
Opts.EmitSortedSIL |= Args.hasArg(OPT_emit_sorted_sil);
Opts.PrintFullConvention |=
Args.hasArg(OPT_experimental_print_full_convention);
Opts.PrintInstCounts |= Args.hasArg(OPT_print_inst_counts);
if (const Arg *A = Args.getLastArg(OPT_external_pass_pipeline_filename))
Opts.ExternalPassPipelineFilename = A->getValue();

View File

@@ -499,20 +499,19 @@ static bool emitSyntax(SourceFile *SF, StringRef OutputFilename) {
}
/// Writes SIL out to the given file.
static bool writeSIL(SILModule &SM, ModuleDecl *M, bool EmitVerboseSIL,
StringRef OutputFilename, bool SortSIL) {
static bool writeSIL(SILModule &SM, ModuleDecl *M, const SILOptions &Opts,
StringRef OutputFilename) {
auto OS = getFileOutputStream(OutputFilename, M->getASTContext());
if (!OS) return true;
SM.print(*OS, EmitVerboseSIL, M, SortSIL);
SM.print(*OS, M, Opts);
return M->getASTContext().hadError();
}
static bool writeSIL(SILModule &SM, const PrimarySpecificPaths &PSPs,
const CompilerInstance &Instance,
const SILOptions &opts) {
return writeSIL(SM, Instance.getMainModule(), opts.EmitVerboseSIL,
PSPs.OutputFilename, opts.EmitSortedSIL);
const SILOptions &Opts) {
return writeSIL(SM, Instance.getMainModule(), Opts, PSPs.OutputFilename);
}
/// Prints the Objective-C "generated header" interface for \p M to \p

View File

@@ -419,12 +419,11 @@ static void printSILTypeColorAndSigil(raw_ostream &OS, SILType t) {
::print(OS, t.getCategory());
}
void SILType::print(raw_ostream &OS) const {
void SILType::print(raw_ostream &OS, const PrintOptions &PO) const {
printSILTypeColorAndSigil(OS, *this);
// Print other types as their Swift representation.
PrintOptions SubPrinter = PrintOptions::printSIL();
getASTType().print(OS, SubPrinter);
getASTType().print(OS, PO);
}
void SILType::dump() const {
@@ -493,7 +492,8 @@ public:
SILPrintContext &PrintCtx,
llvm::DenseMap<CanType, Identifier> *AlternativeTypeNames = nullptr)
: Ctx(PrintCtx),
PrintState{{PrintCtx.OS()}, PrintOptions::printSIL()},
PrintState{{PrintCtx.OS()},
PrintOptions::printSIL(PrintCtx.printFullConvention())},
LastBufferID(0) {
PrintState.ASTOptions.AlternativeTypeNames = AlternativeTypeNames;
PrintState.ASTOptions.PrintForSIL = true;
@@ -2449,7 +2449,8 @@ void SILFunction::print(SILPrintContext &PrintCtx) const {
}
{
PrintOptions withGenericEnvironment = PrintOptions::printSIL();
PrintOptions withGenericEnvironment =
PrintOptions::printSIL(PrintCtx.printFullConvention());
withGenericEnvironment.GenericEnv = env;
withGenericEnvironment.AlternativeTypeNames =
Aliases.empty() ? nullptr : &Aliases;
@@ -2732,7 +2733,8 @@ void SILModule::print(SILPrintContext &PrintCtx, ModuleDecl *M,
// Print the declarations and types from the associated context (origin module or
// current file).
if (M && PrintASTDecls) {
PrintOptions Options = PrintOptions::printSIL();
PrintOptions Options =
PrintOptions::printSIL(PrintCtx.printFullConvention());
Options.TypeDefinitions = true;
Options.VarInitializers = true;
// FIXME: ExplodePatternBindingDecls is incompatible with VarInitializers!
@@ -3116,6 +3118,11 @@ SILPrintContext::SILPrintContext(llvm::raw_ostream &OS, bool Verbose,
OutStream(OS), Verbose(Verbose), SortedSIL(SortedSIL),
DebugInfo(SILPrintDebugInfo) { }
SILPrintContext::SILPrintContext(llvm::raw_ostream &OS,
const SILOptions &Opts) :
OutStream(OS), Verbose(Opts.EmitVerboseSIL), SortedSIL(Opts.EmitSortedSIL),
DebugInfo(SILPrintDebugInfo), PrintFullConvention(Opts.PrintFullConvention) {}
SILPrintContext::SILPrintContext(llvm::raw_ostream &OS, bool Verbose,
bool SortedSIL, bool DebugInfo) :
OutStream(OS), Verbose(Verbose), SortedSIL(SortedSIL),

View File

@@ -0,0 +1,8 @@
// RUN: %target-swift-frontend %s -emit-sil -swift-version 5 -use-clang-function-types -experimental-print-full-convention -o - | %FileCheck %s
public func f(g: @convention(c) () -> ()) { g() }
// CHECK: sil @$s4main1f1gyyyXC_tF : $@convention(thin) (@convention(c, cType: "void (*)(void)") @noescape () -> ()) -> () {
// CHECK: bb0(%0 : $@convention(c, cType: "void (*)(void)") @noescape () -> ()):
// CHECK: debug_value %0 : $@convention(c, cType: "void (*)(void)") @noescape () -> (), let, name "g", argno 1 // id: %1
// CHECK: %2 = apply %0() : $@convention(c, cType: "void (*)(void)") @noescape () -> ()

View File

@@ -101,10 +101,10 @@ static llvm::cl::opt<std::string> Triple("target",
llvm::cl::desc("target triple"));
static llvm::cl::opt<bool>
EnableSILSortOutput("emit-sorted-sil", llvm::cl::Hidden,
llvm::cl::init(false),
llvm::cl::desc("Sort Functions, VTables, Globals, "
"WitnessTables by name to ease diffing."));
EmitSortedSIL("emit-sorted-sil", llvm::cl::Hidden,
llvm::cl::init(false),
llvm::cl::desc("Sort Functions, VTables, Globals, "
"WitnessTables by name to ease diffing."));
static llvm::cl::opt<bool>
DisableASTDump("sil-disable-ast-dump", llvm::cl::Hidden,
@@ -250,6 +250,10 @@ int main(int argc, char **argv) {
Invocation.getLangOptions().EnableAccessControl = false;
Invocation.getLangOptions().EnableObjCAttrRequiresFoundation = false;
SILOptions &Opts = Invocation.getSILOptions();
Opts.EmitVerboseSIL = EmitVerboseSIL;
Opts.EmitSortedSIL = EmitSortedSIL;
serialization::ExtendedValidationInfo extendedInfo;
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
Invocation.setUpInputForSILTool(InputFilename, ModuleName,
@@ -356,8 +360,8 @@ int main(int argc, char **argv) {
OutputFilename.size() ? StringRef(OutputFilename) : "-";
if (OutputFile == "-") {
CI.getSILModule()->print(llvm::outs(), EmitVerboseSIL, CI.getMainModule(),
EnableSILSortOutput, !DisableASTDump);
CI.getSILModule()->print(llvm::outs(), CI.getMainModule(),
Invocation.getSILOptions(), !DisableASTDump);
} else {
std::error_code EC;
llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::F_None);
@@ -366,8 +370,8 @@ int main(int argc, char **argv) {
<< '\n';
return 1;
}
CI.getSILModule()->print(OS, EmitVerboseSIL, CI.getMainModule(),
EnableSILSortOutput, !DisableASTDump);
CI.getSILModule()->print(OS, CI.getMainModule(),
Invocation.getSILOptions(), !DisableASTDump);
}
}
}

View File

@@ -196,10 +196,10 @@ static llvm::cl::opt<std::string>
ModuleCachePath("module-cache-path", llvm::cl::desc("Clang module cache path"));
static llvm::cl::opt<bool>
EnableSILSortOutput("emit-sorted-sil", llvm::cl::Hidden,
llvm::cl::init(false),
llvm::cl::desc("Sort Functions, VTables, Globals, "
"WitnessTables by name to ease diffing."));
EmitSortedSIL("emit-sorted-sil", llvm::cl::Hidden,
llvm::cl::init(false),
llvm::cl::desc("Sort Functions, VTables, Globals, "
"WitnessTables by name to ease diffing."));
static llvm::cl::opt<bool>
DisableASTDump("sil-disable-ast-dump", llvm::cl::Hidden,
@@ -375,6 +375,8 @@ int main(int argc, char **argv) {
break;
}
}
SILOpts.EmitVerboseSIL |= EmitVerboseSIL;
SILOpts.EmitSortedSIL |= EmitSortedSIL;
serialization::ExtendedValidationInfo extendedInfo;
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
@@ -481,8 +483,8 @@ int main(int argc, char **argv) {
StringRef(OutputFilename) : "-";
if (OutputFile == "-") {
CI.getSILModule()->print(llvm::outs(), EmitVerboseSIL, CI.getMainModule(),
EnableSILSortOutput, !DisableASTDump);
CI.getSILModule()->print(llvm::outs(), CI.getMainModule(),
Invocation.getSILOptions(), !DisableASTDump);
} else {
std::error_code EC;
llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::F_None);
@@ -491,8 +493,8 @@ int main(int argc, char **argv) {
<< EC.message() << '\n';
return 1;
}
CI.getSILModule()->print(OS, EmitVerboseSIL, CI.getMainModule(),
EnableSILSortOutput, !DisableASTDump);
CI.getSILModule()->print(OS, CI.getMainModule(),
Invocation.getSILOptions(), !DisableASTDump);
}
}