299 auto checkAndConvertJlmOptOptimizations =
300 [](const ::llvm::cl::list<std::string> & optimizations,
336 std::vector<JlmOptCommandLineOptions::OptimizationId> optimizationIds;
337 for (
auto & optimization : optimizations)
350 optimizationIds.emplace_back(optimizationId);
353 return optimizationIds;
356 CommandLineOptions_.Reset();
358 using namespace ::
llvm;
367 cl::TopLevelSubCommand->reset();
369 cl::opt<bool> onlyPrintCommands(
372 cl::desc(
"Print (but do not run) the commands for this compilation."));
374 cl::list<std::string> inputFiles(cl::Positional, cl::desc(
"<inputs>"));
376 cl::list<std::string> includePaths(
379 cl::desc(
"Add directory <dir> to include search paths."),
380 cl::value_desc(
"dir"));
382 cl::list<std::string> libraryPaths(
385 cl::desc(
"Add directory <dir> to library search paths."),
386 cl::value_desc(
"dir"));
388 cl::list<std::string> libraries(
391 cl::desc(
"Search the library <lib> when linking."),
392 cl::value_desc(
"lib"));
394 cl::opt<std::string> outputFile(
"o", cl::desc(
"Write output to <file>."), cl::value_desc(
"file"));
396 cl::opt<bool> generateDebugInformation(
399 cl::desc(
"Generate source-level debug information."));
401 cl::opt<bool> noLinking(
404 cl::desc(
"Only run preprocess, compile, and assemble steps."));
406 cl::opt<std::string> optimizationLevel(
410 cl::desc(
"Optimization level. [O0, O1, O2, O3]"),
411 cl::value_desc(
"#"));
413 cl::list<std::string> macroDefinitions(
416 cl::desc(
"Add <macro> to preprocessor macros."),
417 cl::value_desc(
"macro"));
419 cl::list<std::string> warnings(
422 cl::desc(
"Enable specified warning."),
423 cl::value_desc(
"warning"));
425 cl::opt<std::string> languageStandard(
427 cl::desc(
"Language standard."),
428 cl::value_desc(
"standard"));
430 cl::list<std::string> flags(
"f", cl::Prefix, cl::desc(
"Specify flags."), cl::value_desc(
"flag"));
432 cl::list<std::string> jlmOptimizations(
435 cl::desc(
"jlm-opt optimization. Run 'jlm-opt -help' for viable options."),
436 cl::value_desc(
"jlmopt"));
438 cl::opt<bool> verbose(
441 cl::desc(
"Show commands to run and use verbose output. (Affects only clang for now)"));
443 cl::opt<bool> rDynamic(
446 cl::desc(
"rDynamic option passed to clang"));
448 cl::opt<bool> suppress(
"w", cl::ValueDisallowed, cl::desc(
"Suppress all warnings"));
450 cl::opt<bool> usePthreads(
453 cl::desc(
"Support POSIX threads in generated code"));
458 cl::desc(
"Write a depfile containing user and system headers"));
460 cl::opt<std::string> mF(
462 cl::desc(
"Write depfile output from -mD to <file>."),
463 cl::value_desc(
"file"));
465 cl::opt<std::string> mT(
467 cl::desc(
"Specify name of main file output in depfile."),
468 cl::value_desc(
"value"));
470 cl::list<util::Statistics::Id> jlmOptPassStatistics(
471 "JlmOptPassStatistics",
475 "Collect control flow graph aggregation pass statistics."),
478 "Collect agnostic mod/ref summarizer pass statistics."),
481 "Collect Andersen alias analysis pass statistics."),
484 "Collect aggregation tree annotation pass statistics."),
487 "Collect memory state encoding pass statistics."),
490 "Collect common node elimination pass statistics."),
493 "Collect control flow recovery pass statistics."),
496 "Collect data node to delta node conversion pass statistics."),
499 "Collect dead node elimination pass statistics."),
502 "Collect function inlining pass statistics."),
505 "Collect invariant value redirection pass statistics."),
508 "Collect Jlm to RVSDG conversion pass statistics."),
511 "Collect loop strength reduction pass statistics."),
514 "Collect loop unrolling pass statistics."),
517 "Collect loop unswitching pass statistics."),
520 "Collect node pull pass statistics."),
523 "Collect node push pass statistics."),
526 "Collect node reduction pass statistics."),
529 "Collect region-aware mod/ref summarizer pass statistics."),
532 "Collect RVSDG construction pass statistics."),
535 "Collect RVSDG destruction pass statistics."),
538 "Collect RVSDG optimization pass statistics."),
541 "Collect RVSDG tree printer pass statistics."),
544 "Collect scalar evolution analysis pass statistics.")),
545 cl::desc(
"Collect jlm-opt pass statistics"));
547 cl::ParseCommandLineOptions(argc, argv);
551 static std::unordered_map<std::string, JlcCommandLineOptions::OptimizationLevel>
557 static std::unordered_map<std::string, JlcCommandLineOptions::LanguageStandard>
569 if (!optimizationLevel.empty())
571 auto iterator = optimizationLevelMap.find(optimizationLevel);
572 if (iterator == optimizationLevelMap.end())
574 std::cerr <<
"Unknown optimization level.\n";
577 CommandLineOptions_.OptimizationLevel_ = iterator->second;
580 if (!languageStandard.empty())
582 auto iterator = languageStandardMap.find(languageStandard);
583 if (iterator == languageStandardMap.end())
585 std::cerr <<
"Unknown language standard.\n";
588 CommandLineOptions_.LanguageStandard_ = iterator->second;
591 if (inputFiles.empty())
593 std::cerr <<
"jlc: no input files.\n";
597 if (inputFiles.size() > 1 && noLinking && !outputFile.empty())
599 std::cerr <<
"jlc: cannot specify -o when generating multiple output files.\n";
603 auto jlmOptOptimizations =
604 checkAndConvertJlmOptOptimizations(jlmOptimizations, CommandLineOptions_.OptimizationLevel_);
606 CommandLineOptions_.Libraries_ = libraries;
607 CommandLineOptions_.MacroDefinitions_ = macroDefinitions;
608 CommandLineOptions_.LibraryPaths_ = libraryPaths;
609 CommandLineOptions_.Warnings_ = warnings;
610 CommandLineOptions_.IncludePaths_ = includePaths;
611 CommandLineOptions_.OnlyPrintCommands_ = onlyPrintCommands;
612 CommandLineOptions_.GenerateDebugInformation_ = generateDebugInformation;
613 CommandLineOptions_.Flags_ = flags;
614 CommandLineOptions_.JlmOptOptimizations_ = jlmOptOptimizations;
616 { jlmOptPassStatistics.begin(), jlmOptPassStatistics.end() });
617 CommandLineOptions_.Verbose_ = verbose;
618 CommandLineOptions_.Rdynamic_ = rDynamic;
619 CommandLineOptions_.Suppress_ = suppress;
620 CommandLineOptions_.UsePthreads_ = usePthreads;
621 CommandLineOptions_.Md_ = mD;
623 for (
auto & inputFile : inputFiles)
626 if (IsObjectFile(inputFilePath))
629 CommandLineOptions_.Compilations_.push_back(
630 { inputFilePath,
util::FilePath(
""), inputFilePath,
"",
false,
false,
false,
true });
635 CommandLineOptions_.Compilations_.push_back(
637 mF.empty() ? ToDependencyFile(inputFilePath) :
util::FilePath(mF),
638 ToObjectFile(inputFilePath),
639 mT.empty() ? ToObjectFile(inputFilePath).
name() : mT,
646 if (!outputFile.empty())
651 JLM_ASSERT(CommandLineOptions_.Compilations_.size() == 1);
652 CommandLineOptions_.Compilations_[0].SetOutputFile(outputFilePath);
656 CommandLineOptions_.OutputFile_ = outputFilePath;
660 return CommandLineOptions_;
668 using namespace ::
llvm;
677 cl::TopLevelSubCommand->reset();
679 cl::opt<std::string> inputFile(cl::Positional, cl::desc(
"<input>"));
681 cl::opt<std::string> outputFile(
684 cl::desc(
"Write output to <file>"),
685 cl::value_desc(
"file"));
688 const auto statisticDirectoryDescription =
689 "Write statistics and debug output to files in <dir>. Default is "
690 + statisticsDirectoryDefault.
to_str() +
".";
691 cl::opt<std::string> statisticDirectory(
693 cl::init(statisticsDirectoryDefault.to_str()),
694 cl::desc(statisticDirectoryDescription),
695 cl::value_desc(
"dir"));
697 cl::opt<bool> dumpRvsdgGraphs(
700 cl::desc(
"Dump RVSDG as json graphs after each transformation in debug folder."));
702 cl::list<util::Statistics::Id> printStatistics(
706 "Write aggregate alloca splitting statistics to file."),
709 "Write aggregation statistics to file."),
712 "Collect agnostic mod/ref summarization pass statistics."),
715 "Evaluate alias analysis precision and store to file"),
718 "Collect Andersen alias analysis pass statistics."),
721 "Write annotation statistics to file."),
724 "Write encoding statistics of basic encoder to file."),
727 "Write common node elimination statistics to file."),
730 "Write control flow recovery statistics to file."),
733 "Write data node to delta node conversion statistics to file."),
736 "Write dead node elimination statistics to file."),
739 "Write function inlining statistics to file."),
742 "Collect if-conversion transformation statistics"),
745 "Write invariant value redirection statistics to file."),
748 "Write Jlm to RVSDG conversion statistics to file."),
751 "Write loop strength reduction statistics to file."),
754 "Write loop unrolling statistics to file."),
757 "Collect loop unswitching pass statistics."),
760 "Write node pull statistics to file."),
763 "Write node push statistics to file."),
766 "Write node reduction statistics to file."),
769 "Collect region-aware mod/ref summarization statistics."),
772 "Write RVSDG construction statistics to file."),
775 "Write RVSDG destruction statistics to file."),
778 "Write RVSDG optimization statistics to file."),
781 "Write RVSDG tree printer pass statistics."),
784 "Write scalar evolution statistics to file."),
787 "Write store value forwarding statistics to file.")),
788 cl::desc(
"Write statistics"));
794 cl::opt<JlmOptCommandLineOptions::InputFormat> inputFormat(
796 cl::desc(
"Select input format:"),
801 "Input LLVM IR [default]"),
806 cl::init(llvmInputFormat));
811 cl::opt<JlmOptCommandLineOptions::OutputFormat> outputFormat(
813 cl::desc(
"Select output format:"),
822 "Output Rvsdg tree as JSON"),
825 "Output LLVM IR [default]"),
831 "Output Rvsdg Tree")),
836 auto aggregateAllocaSplitting =
842 auto invariantValueRedirection =
857 cl::list<JlmOptCommandLineOptions::OptimizationId> optimizationIds(
862 "Andersen alias analysis with agnostic memory state encoding"),
864 aAAndersenRegionAware,
866 "Andersen alias analysis with region-aware memory state encoding"),
868 aggregateAllocaSplitting,
870 "Split aggregate type alloca nodes"),
872 commonNodeElimination,
874 "Common Node Elimination"),
878 "Dead Node Elimination"),
882 "Function Inlining"),
886 "Convert pass-through values of gamma nodes to select operations"),
888 invariantValueRedirection,
890 "Invariant Value Redirection"),
892 ioBarrierElimination,
894 "Eliminate IOBarrier nodes"),
898 "Separate chains of load operations"),
900 loopStrengthReduction,
902 "Loop strength reduction"),
910 "Move conditionals outside loops"),
924 predicateCorrelation,
926 "Correlate predicates between theta and gamma nodes"),
930 "Rvsdg Tree Printer"),
936 storeValueForwarding,
938 "Store Value Forwarding"),
941 "ThetaGammaInversion",
942 "[DEPRECATED] Use --LoopUnswitching instead.")),
943 cl::desc(
"Perform optimization"));
945 cl::list<llvm::RvsdgTreePrinter::Configuration::Annotation> rvsdgTreePrinterAnnotations(
947 cl::values(::clEnumValN(
950 "Annotate region and node IDs")),
951 cl::values(::clEnumValN(
953 "NumAggregateAllocaNodes",
954 "Annotate number of AllocaOperation nodes with aggregate types.")),
955 cl::values(::clEnumValN(
958 "Annotate number of AllocaOperation nodes")),
959 cl::values(::clEnumValN(
962 "Annotate number of LoadOperation nodes")),
963 cl::values(::clEnumValN(
965 "NumMemoryStateInputsOutputs",
966 "Annotate number of inputs/outputs with memory state type")),
967 cl::values(::clEnumValN(
970 "Annotate number of RVSDG nodes")),
971 cl::values(::clEnumValN(
974 "Annotate number of StoreOperation nodes")),
976 cl::desc(
"Comma separated list of RVSDG tree printer annotations"));
978 cl::ParseCommandLineOptions(argc, argv);
984 { printStatistics.begin(), printStatistics.end() });
987 std::move(demandedStatistics),
988 statisticsDirectoryFilePath,
989 inputFilePath.
base());
992 { rvsdgTreePrinterAnnotations.begin(), rvsdgTreePrinterAnnotations.end() });
997 std::move(inputFilePath),
1001 std::move(statisticsCollectorSettings),
1002 std::move(treePrinterConfiguration),
1003 std::move(optimizationIds),
1006 return *CommandLineOptions_;
1021 CommandLineOptions_.
Reset();
1023 using namespace ::
llvm;
1032 cl::TopLevelSubCommand->reset();
1034 cl::opt<std::string> inputFile(cl::Positional, cl::desc(
"<input>"));
1036 cl::opt<std::string> outputFolder(
1038 cl::desc(
"Write output to <folder>"),
1039 cl::value_desc(
"folder"));
1041 cl::opt<std::string> hlsFunction(
1044 cl::desc(
"Function that should be accelerated"),
1045 cl::value_desc(
"hls-function"));
1047 cl::opt<int> latency(
1050 cl::init(CommandLineOptions_.MemoryLatency_),
1051 cl::desc(
"Memory latency"),
1052 cl::value_desc(
"latency"));
1054 cl::opt<bool> extractHlsFunction(
1057 cl::desc(
"Extracts function specified by hls-function"));
1059 cl::opt<bool> dumpRvsdgGraphs(
1062 cl::desc(
"Dump RVSDG as json graphs after each transformation in debug folder."));
1064 cl::opt<JlmHlsCommandLineOptions::OutputFormat> format(
1069 "Output FIRRTL [default]"),
1071 cl::desc(
"Select output format"));
1073 cl::ParseCommandLineOptions(argc, argv);
1075 if (outputFolder.empty())
1076 throw util::Error(
"jlm-hls no output directory provided, i.e, -o.\n");
1078 if (extractHlsFunction && hlsFunction.empty())
1080 "jlm-hls: --hls-function is not specified.\n which is required for --extract\n");
1083 CommandLineOptions_.HlsFunction_ = std::move(hlsFunction);
1085 CommandLineOptions_.ExtractHlsFunction_ = extractHlsFunction;
1086 CommandLineOptions_.OutputFormat_ = format;
1087 CommandLineOptions_.dumpRvsdgGraphs_ = dumpRvsdgGraphs;
1091 throw util::Error(
"The --latency must be set to a number larger than zero.");
1093 CommandLineOptions_.MemoryLatency_ = latency;
1095 return CommandLineOptions_;
1110 CommandLineOptions_.
Reset();
1112 using namespace ::
llvm;
1121 cl::TopLevelSubCommand->reset();
1123 cl::opt<bool> onlyPrintCommands(
1125 cl::ValueDisallowed,
1126 cl::desc(
"Print (but do not run) the commands for this compilation."));
1128 cl::list<std::string> inputFiles(cl::Positional, cl::desc(
"<inputs>"));
1130 cl::list<std::string> includePaths(
1133 cl::desc(
"Add directory <dir> to include search paths."),
1134 cl::value_desc(
"dir"));
1136 cl::list<std::string> libraryPaths(
1139 cl::desc(
"Add directory <dir> to library search paths."),
1140 cl::value_desc(
"dir"));
1142 cl::list<std::string> libraries(
1145 cl::desc(
"Search the library <lib> when linking."),
1146 cl::value_desc(
"lib"));
1148 cl::opt<std::string> outputFile(
"o", cl::desc(
"Write output to <file>."), cl::value_desc(
"file"));
1150 cl::opt<bool> generateDebugInformation(
1152 cl::ValueDisallowed,
1153 cl::desc(
"Generate source-level debug information."));
1155 cl::opt<bool> noLinking(
1157 cl::ValueDisallowed,
1158 cl::desc(
"Only run preprocess, compile, and assemble steps."));
1160 cl::opt<std::string> optimizationLevel(
1164 cl::desc(
"Optimization level. [O0, O1, O2, O3]"),
1165 cl::value_desc(
"#"));
1167 cl::list<std::string> macroDefinitions(
1170 cl::desc(
"Add <macro> to preprocessor macros."),
1171 cl::value_desc(
"macro"));
1173 cl::list<std::string> warnings(
1176 cl::desc(
"Enable specified warning."),
1177 cl::value_desc(
"warning"));
1179 cl::opt<std::string> languageStandard(
1181 cl::desc(
"Language standard."),
1182 cl::value_desc(
"standard"));
1184 cl::list<std::string> flags(
"f", cl::Prefix, cl::desc(
"Specify flags."), cl::value_desc(
"flag"));
1186 cl::list<std::string> jlmHlsOptimizations(
1189 cl::desc(
"jlm-hls optimization. Run 'jlm-hls -help' for viable options."),
1190 cl::value_desc(
"jlmhls"));
1192 cl::opt<bool> verbose(
1194 cl::ValueDisallowed,
1195 cl::desc(
"Show commands to run and use verbose output. (Affects only clang for now)"));
1197 cl::opt<bool> rdynamic(
1199 cl::ValueDisallowed,
1200 cl::desc(
"rdynamic option passed to clang"));
1202 cl::opt<bool> suppress(
"w", cl::ValueDisallowed, cl::desc(
"Suppress all warnings"));
1204 cl::opt<bool> usePthreads(
1206 cl::ValueDisallowed,
1207 cl::desc(
"Support POSIX threads in generated code"));
1211 cl::ValueDisallowed,
1212 cl::desc(
"Write a depfile containing user and system headers"));
1214 cl::opt<std::string> mF(
1216 cl::desc(
"Write depfile output from -MD to <file>."),
1217 cl::value_desc(
"file"));
1219 cl::opt<std::string> mT(
1221 cl::desc(
"Specify name of main file output in depfile."),
1222 cl::value_desc(
"value"));
1224 cl::list<std::string> hlsFunction(
1227 cl::desc(
"function that should be accelerated"),
1228 cl::value_desc(
"regex"));
1230 cl::opt<bool> generateFirrtl(
"firrtl", cl::ValueDisallowed, cl::desc(
"Generate firrtl"));
1232 cl::opt<bool> useCirct(
1235 cl::desc(
"DEPRACATED - CIRCT is always used to generate FIRRTL"));
1237 cl::ParseCommandLineOptions(argc, argv);
1241 static std::unordered_map<std::string, JhlsCommandLineOptions::OptimizationLevel> Olvlmap(
1247 static std::unordered_map<std::string, JhlsCommandLineOptions::LanguageStandard> stdmap(
1258 if (!optimizationLevel.empty())
1260 auto it = Olvlmap.find(optimizationLevel);
1261 if (it == Olvlmap.end())
1263 std::cerr <<
"Unknown optimization level.\n";
1266 CommandLineOptions_.OptimizationLevel_ = it->second;
1269 if (!languageStandard.empty())
1271 auto it = stdmap.find(languageStandard);
1272 if (it == stdmap.end())
1274 std::cerr <<
"Unknown language standard.\n";
1277 CommandLineOptions_.LanguageStandard_ = it->second;
1280 if (inputFiles.empty())
1282 std::cerr <<
"jlc: no input files.\n";
1286 if (inputFiles.size() > 1 && noLinking && !outputFile.empty())
1288 std::cerr <<
"jlc: cannot specify -o when generating multiple output files.\n";
1292 if (!hlsFunction.empty())
1294 CommandLineOptions_.Hls_ =
true;
1295 CommandLineOptions_.HlsFunctionRegex_ = hlsFunction.front();
1298 if (hlsFunction.size() > 1)
1300 std::cerr <<
"jlc-hls: more than one function regex specified\n";
1304 CommandLineOptions_.Libraries_ = libraries;
1305 CommandLineOptions_.MacroDefinitions_ = macroDefinitions;
1306 CommandLineOptions_.LibraryPaths_ = libraryPaths;
1307 CommandLineOptions_.Warnings_ = warnings;
1308 CommandLineOptions_.IncludePaths_ = includePaths;
1309 CommandLineOptions_.OnlyPrintCommands_ = onlyPrintCommands;
1310 CommandLineOptions_.GenerateDebugInformation_ = generateDebugInformation;
1311 CommandLineOptions_.Flags_ = flags;
1312 CommandLineOptions_.JlmHls_ = jlmHlsOptimizations;
1313 CommandLineOptions_.Verbose_ = verbose;
1314 CommandLineOptions_.Rdynamic_ = rdynamic;
1315 CommandLineOptions_.Suppress_ = suppress;
1316 CommandLineOptions_.UsePthreads_ = usePthreads;
1317 CommandLineOptions_.Md_ = mD;
1318 CommandLineOptions_.GenerateFirrtl_ = generateFirrtl;
1320 for (
auto & inputFile : inputFiles)
1323 if (IsObjectFile(inputFilePath))
1326 CommandLineOptions_.Compilations_.push_back(
1327 { inputFilePath,
util::FilePath(
""), inputFilePath,
"",
false,
false,
false,
true });
1332 CommandLineOptions_.Compilations_.push_back(
1334 mF.empty() ? CreateDependencyFileFromFile(inputFilePath) :
util::FilePath(mF),
1335 CreateObjectFileFromFile(inputFilePath),
1336 mT.empty() ? CreateObjectFileFromFile(inputFilePath).
name() : mT,
1343 if (!outputFile.empty())
1348 JLM_ASSERT(CommandLineOptions_.Compilations_.size() == 1);
1349 CommandLineOptions_.Compilations_[0].SetOutputFile(outputFilePath);
1353 CommandLineOptions_.OutputFile_ = outputFilePath;
1357 return CommandLineOptions_;