diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 90b633b856b5..ae27bf70d80f 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -239,6 +239,9 @@ struct Configuration { llvm::StringRef opencilkABIBitcodeFile; llvm::TapirTargetID tapirTarget = llvm::TapirTargetID::None; + // Used for Cilk tool. + llvm::StringRef cilktool; + // Used for /thinlto-index-only: llvm::StringRef thinLTOIndexOnlyArg; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 09f5f6c5be8f..59a43ac40ae7 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -817,6 +817,7 @@ static std::string createResponseFile(const opt::InputArgList &args, case OPT_winsysroot: break; case OPT_call_graph_ordering_file: + case OPT_cilktool: case OPT_deffile: case OPT_manifestinput: case OPT_natvis: @@ -2067,6 +2068,7 @@ void LinkerDriver::linkerMain(ArrayRef argsArr) { args.getLastArgValue(OPT_opencilk_abi_bitcode); config->tapirTarget = args::parseTapirTarget(args.getLastArgValue(OPT_tapir_target)); + config->cilktool = args.getLastArgValue(OPT_cilktool); if (config->incremental && args.hasArg(OPT_profile)) { warn("ignoring '/incremental' due to '/profile' specification"); diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp index abaadc9be479..2268f195a40a 100644 --- a/lld/COFF/LTO.cpp +++ b/lld/COFF/LTO.cpp @@ -86,6 +86,7 @@ lto::Config BitcodeCompiler::createConfig() { if (args::validTapirTarget(ctx.config.tapirTarget)) c.TapirTarget = ctx.config.tapirTarget; c.OpenCilkABIBitcodeFile = std::string(ctx.config.opencilkABIBitcodeFile); + c.Cilktool = std::string(ctx.config.cilktool); c.CSIRProfile = std::string(ctx.config.ltoCSProfileFile); c.RunCSIRInstr = ctx.config.ltoCSProfileGenerate; c.PGOWarnMismatch = ctx.config.ltoPGOWarnMismatch; diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td index 962508c7ab72..44b6ec777871 100644 --- a/lld/COFF/Options.td +++ b/lld/COFF/Options.td @@ -225,6 +225,7 @@ def help_q : Flag<["/??", "-??", "/?", "-?"], "">, Alias; // LLD extensions defm auto_import : B_priv<"auto-import">; defm runtime_pseudo_reloc : B_priv<"runtime-pseudo-reloc">; +def cilktool : P<"cilktool", "Name of Cilk tool">; def end_lib : F<"end-lib">, HelpText<"End group of objects treated as if they were in a library">; def exclude_all_symbols : F<"exclude-all-symbols">; diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 91fa8a8febb4..cf63aed31af6 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -157,6 +157,7 @@ struct Config { llvm::StringMap sectionStartMap; llvm::StringRef bfdname; llvm::StringRef chroot; + llvm::StringRef cilktool; llvm::StringRef dependencyFile; llvm::StringRef dwoDir; llvm::StringRef dynamicLinker; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index e7857432d96a..154e729f1834 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1224,6 +1224,7 @@ static void readConfigs(opt::InputArgList &args) { config->checkSections = args.hasFlag(OPT_check_sections, OPT_no_check_sections, true); config->chroot = args.getLastArgValue(OPT_chroot); + config->cilktool = args.getLastArgValue(OPT_cilktool); config->compressDebugSections = getCompressionType( args.getLastArgValue(OPT_compress_debug_sections, "none"), "--compress-debug-sections"); diff --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp index 1d5c8104399c..65709ac61de5 100644 --- a/lld/ELF/DriverUtils.cpp +++ b/lld/ELF/DriverUtils.cpp @@ -186,6 +186,7 @@ std::string elf::createResponseFile(const opt::InputArgList &args) { os << arg->getSpelling() << quote(rewritePath(arg->getValue())) << "\n"; break; case OPT_call_graph_ordering_file: + case OPT_cilktool: case OPT_dynamic_list: case OPT_export_dynamic_symbol_list: case OPT_just_symbols: diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp index 1accdd588036..add2fb499193 100644 --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -131,6 +131,7 @@ static lto::Config createConfig() { if (args::validTapirTarget(config->tapirTarget)) c.TapirTarget = config->tapirTarget; c.OpenCilkABIBitcodeFile = std::string(config->opencilkABIBitcodeFile); + c.Cilktool = std::string(config->cilktool); c.HasWholeProgramVisibility = config->ltoWholeProgramVisibility; c.ValidateAllVtablesHaveTypeInfos = diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td index 4223304d85b6..4274a868ccc8 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -618,6 +618,7 @@ defm lto_validate_all_vtables_have_type_infos: BB<"lto-validate-all-vtables-have defm lto_whole_program_visibility: BB<"lto-whole-program-visibility", "Asserts that the LTO link has whole program visibility", "Asserts that the LTO link does not have whole program visibility">; +defm cilktool: Eq<"cilktool", "Name of Cilk tool">; def disable_verify: F<"disable-verify">; defm mllvm: Eq<"mllvm", "Additional arguments to forward to LLVM's option processing">; defm opencilk_abi_bitcode: EEq<"opencilk-abi-bitcode", "Path to OpenCilk ABI bitcode file">; @@ -683,6 +684,9 @@ def: J<"plugin-opt=cs-profile-path=">, def: J<"plugin-opt=obj-path=">, Alias, HelpText<"Alias for --lto-obj-path=">; +def: J<"plugin-opt=cilktool=">, + Alias, + HelpText<"Alias for --cilktool">; def: J<"plugin-opt=opencilk-abi-bitcode=">, Alias, HelpText<"Alias for --opencilk-abi-bitcode">; diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h index 792a502df7c5..ab7fcf8e1023 100644 --- a/lld/MachO/Config.h +++ b/lld/MachO/Config.h @@ -237,6 +237,7 @@ struct Configuration { llvm::TapirTargetID tapirTarget = llvm::TapirTargetID::None; llvm::StringRef opencilkABIBitcodeFile; + llvm::StringRef cilktool; llvm::MachO::Architecture arch() const { return platformInfo.target.Arch; } diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index 8b9b96a05009..2b85718d7287 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -1682,6 +1682,7 @@ bool link(ArrayRef argsArr, llvm::raw_ostream &stdoutOS, args::parseTapirTarget(args.getLastArgValue(OPT_tapir_target)); config->opencilkABIBitcodeFile = args.getLastArgValue(OPT_opencilk_abi_bitcode); + config->cilktool = args.getLastArgValue(OPT_cilktool); for (const Arg *arg : args.filtered(OPT_alias)) { config->aliasedSymbols.push_back( diff --git a/lld/MachO/LTO.cpp b/lld/MachO/LTO.cpp index f5b56a9eb5ce..7738932fe93b 100644 --- a/lld/MachO/LTO.cpp +++ b/lld/MachO/LTO.cpp @@ -65,6 +65,7 @@ static lto::Config createConfig() { if (args::validTapirTarget(config->tapirTarget)) c.TapirTarget = config->tapirTarget; c.OpenCilkABIBitcodeFile = std::string(config->opencilkABIBitcodeFile); + c.Cilktool = std::string(config->cilktool); if (config->saveTemps) checkError(c.addSaveTemps(config->outputFile.str() + ".", /*UseInputModulePath=*/true)); diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td index c1b4795cc392..69a3e74b5fdb 100644 --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -144,6 +144,9 @@ def tapir_target: Joined<["--"], "tapir-target=">, def opencilk_abi_bitcode: Joined<["--"], "opencilk-abi-bitcode=">, HelpText<"Path to the OpenCilk ABI bitcode file">, Group; +def cilktool: Joined<["--"], "cilktool=">, + HelpText<"Name of Cilk tool">, + Group; // This is a complete Options.td compiled from Apple's ld(1) manpage // dated 2018-03-07 and cross checked with ld64 source code in repo diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h index b45a023f08f3..c57d183a77f9 100644 --- a/llvm/include/llvm/LTO/Config.h +++ b/llvm/include/llvm/LTO/Config.h @@ -104,6 +104,9 @@ struct Config { // Path to OpenCilk runtime bitcode file. std::string OpenCilkABIBitcodeFile; + // Name of Cilk tool. + std::string Cilktool; + /// If this field is set, the set of passes run in the middle-end optimizer /// will be the one specified by the string. Only works with the new pass /// manager as the old one doesn't have this ability. diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp index 7d47dd6eafa1..4ff57e0dc267 100644 --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -42,6 +42,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/TargetParser/SubtargetFeature.h" #include "llvm/Transforms/IPO/WholeProgramDevirt.h" +#include "llvm/Transforms/Instrumentation/ComprehensiveStaticInstrumentation.h" #include "llvm/Transforms/Scalar/LoopPassManager.h" #include "llvm/Transforms/Utils/FunctionImportUtils.h" #include "llvm/Transforms/Utils/SplitModule.h" @@ -239,6 +240,29 @@ static bool hasTapirTarget(const Config &Conf) { (Conf.TapirTarget != TapirTargetID::None); } +enum class CilktoolID { Cilkscale, CilkscaleInstructions, Unknown }; + +static CilktoolID parseCilktool(StringRef ToolName) { + return llvm::StringSwitch(ToolName) + .Case("cilkscale", CilktoolID::Cilkscale) + .Case("cilkscale-instructions", CilktoolID::CilkscaleInstructions) + .Default(CilktoolID::Unknown); +} + +static CSIOptions getCSIOptionsForCilkscale(bool InstrumentBasicBlocks) { + CSIOptions Options; + // Disable CSI hooks that Cilkscale doesn't need. + Options.InstrumentBasicBlocks = InstrumentBasicBlocks; + Options.InstrumentLoops = false; + Options.InstrumentMemoryAccesses = false; + Options.InstrumentCalls = false; + Options.InstrumentAtomics = false; + Options.InstrumentMemIntrinsics = false; + Options.InstrumentAllocas = false; + Options.InstrumentAllocFns = false; + return Options; +} + static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM, unsigned OptLevel, bool IsThinLTO, ModuleSummaryIndex *ExportSummary, @@ -329,6 +353,32 @@ static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM, break; } + // Handle tools with late CSI instrumentation passes. + switch (parseCilktool(Conf.Cilktool)) { + case CilktoolID::Cilkscale: { + PB.registerTapirLoopEndEPCallback( + [&PB](ModulePassManager &MPM, OptimizationLevel Level) { + MPM.addPass(CSISetupPass(getCSIOptionsForCilkscale(false))); + MPM.addPass(ComprehensiveStaticInstrumentationPass( + getCSIOptionsForCilkscale(false))); + MPM.addPass(PB.buildPostCilkInstrumentationPipeline(Level)); + }); + break; + } + case CilktoolID::CilkscaleInstructions: { + PB.registerTapirLoopEndEPCallback( + [&PB](ModulePassManager &MPM, OptimizationLevel Level) { + MPM.addPass(CSISetupPass(getCSIOptionsForCilkscale(true))); + MPM.addPass(ComprehensiveStaticInstrumentationPass( + getCSIOptionsForCilkscale(true))); + MPM.addPass(PB.buildPostCilkInstrumentationPipeline(Level)); + }); + break; + } + case CilktoolID::Unknown: + break; + } + // Parse a custom pipeline if asked to. if (!Conf.OptPipeline.empty()) { if (auto Err = PB.parsePassPipeline(MPM, Conf.OptPipeline)) { diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp index 5c6b811d1c15..96e3a85f380f 100644 --- a/llvm/tools/gold/gold-plugin.cpp +++ b/llvm/tools/gold/gold-plugin.cpp @@ -224,6 +224,7 @@ namespace options { // Tapir lowering options. static TapirTargetID tapir_target = TapirTargetID::Last_TapirTargetID; static std::string opencilk_abi_bitcode_file; + static std::string cilktool; static TapirTargetID parseTapirTarget(StringRef tapirTarget) { return llvm::StringSwitch(tapirTarget) @@ -330,6 +331,8 @@ namespace options { tapir_target = parseTapirTarget(std::string(opt)); } else if (opt.consume_front("opencilk-abi-bitcode=")) { opencilk_abi_bitcode_file = std::string(opt); + } else if (opt.consume_front("cilktool=")) { + cilktool = std::string(opt); } else { // Save this option to pass to the code generator. // ParseCommandLineOptions() expects argv[0] to be program name. Lazily @@ -979,6 +982,8 @@ static std::unique_ptr createLTO(IndexWriteCallback OnIndexWrite, Conf.OpenCilkABIBitcodeFile = options::opencilk_abi_bitcode_file; } + Conf.Cilktool = options::cilktool; + return std::make_unique(std::move(Conf), Backend, options::ParallelCodeGenParallelismLevel); }