300 auto checkAndConvertJlmOptOptimizations =
301 [](const ::llvm::cl::list<std::string> & optimizations,
339 std::vector<JlmOptCommandLineOptions::OptimizationId> optimizationIds;
340 for (
auto & optimization : optimizations)
353 optimizationIds.emplace_back(optimizationId);
356 return optimizationIds;
359 CommandLineOptions_.Reset();
361 using namespace ::
llvm;
370 cl::TopLevelSubCommand->reset();
372 cl::opt<bool> onlyPrintCommands(
375 cl::desc(
"Print (but do not run) the commands for this compilation."));
377 cl::list<std::string> inputFiles(cl::Positional, cl::desc(
"<inputs>"));
379 cl::list<std::string> includePaths(
382 cl::desc(
"Add directory <dir> to include search paths."),
383 cl::value_desc(
"dir"));
385 cl::list<std::string> libraryPaths(
388 cl::desc(
"Add directory <dir> to library search paths."),
389 cl::value_desc(
"dir"));
391 cl::list<std::string> libraries(
394 cl::desc(
"Search the library <lib> when linking."),
395 cl::value_desc(
"lib"));
397 cl::opt<std::string> outputFile(
"o", cl::desc(
"Write output to <file>."), cl::value_desc(
"file"));
399 cl::opt<bool> generateDebugInformation(
402 cl::desc(
"Generate source-level debug information."));
404 cl::opt<bool> noLinking(
407 cl::desc(
"Only run preprocess, compile, and assemble steps."));
409 cl::opt<std::string> optimizationLevel(
413 cl::desc(
"Optimization level. [O0, O1, O2, O3]"),
414 cl::value_desc(
"#"));
416 cl::list<std::string> macroDefinitions(
419 cl::desc(
"Add <macro> to preprocessor macros."),
420 cl::value_desc(
"macro"));
422 cl::list<std::string> warnings(
425 cl::desc(
"Enable specified warning."),
426 cl::value_desc(
"warning"));
428 cl::opt<std::string> languageStandard(
430 cl::desc(
"Language standard."),
431 cl::value_desc(
"standard"));
433 cl::list<std::string> flags(
"f", cl::Prefix, cl::desc(
"Specify flags."), cl::value_desc(
"flag"));
435 cl::list<std::string> jlmOptimizations(
438 cl::desc(
"jlm-opt optimization. Run 'jlm-opt -help' for viable options."),
439 cl::value_desc(
"jlmopt"));
441 cl::opt<bool> verbose(
444 cl::desc(
"Show commands to run and use verbose output. (Affects only clang for now)"));
446 cl::opt<bool> rDynamic(
449 cl::desc(
"rDynamic option passed to clang"));
451 cl::opt<bool> suppress(
"w", cl::ValueDisallowed, cl::desc(
"Suppress all warnings"));
453 cl::opt<bool> usePthreads(
456 cl::desc(
"Support POSIX threads in generated code"));
461 cl::desc(
"Write a depfile containing user and system headers"));
463 cl::opt<std::string> mF(
465 cl::desc(
"Write depfile output from -mD to <file>."),
466 cl::value_desc(
"file"));
468 cl::opt<std::string> mT(
470 cl::desc(
"Specify name of main file output in depfile."),
471 cl::value_desc(
"value"));
473 cl::list<util::Statistics::Id> jlmOptPassStatistics(
474 "JlmOptPassStatistics",
478 "Collect control flow graph aggregation pass statistics."),
481 "Collect agnostic mod/ref summarizer pass statistics."),
484 "Collect Andersen alias analysis pass statistics."),
487 "Collect aggregation tree annotation pass statistics."),
490 "Collect memory state encoding pass statistics."),
493 "Collect common node elimination pass statistics."),
496 "Collect control flow recovery pass statistics."),
499 "Collect data node to delta node conversion pass statistics."),
502 "Collect dead node elimination pass statistics."),
505 "Collect function inlining pass statistics."),
508 "Collect invariant value redirection pass statistics."),
511 "Collect Jlm to RVSDG conversion pass statistics."),
514 "Collect loop strength reduction pass statistics."),
517 "Collect loop unrolling pass statistics."),
520 "Collect loop unswitching pass statistics."),
523 "Collect node pull pass statistics."),
526 "Collect node push pass statistics."),
529 "Collect node reduction pass statistics."),
532 "Collect region-aware mod/ref summarizer pass statistics."),
535 "Collect RVSDG construction pass statistics."),
538 "Collect RVSDG destruction pass statistics."),
541 "Collect RVSDG optimization pass statistics."),
544 "Collect RVSDG tree printer pass statistics."),
547 "Collect scalar evolution analysis pass statistics.")),
548 cl::desc(
"Collect jlm-opt pass statistics"));
550 cl::ParseCommandLineOptions(argc, argv);
554 static std::unordered_map<std::string, JlcCommandLineOptions::OptimizationLevel>
560 static std::unordered_map<std::string, JlcCommandLineOptions::LanguageStandard>
572 if (!optimizationLevel.empty())
574 auto iterator = optimizationLevelMap.find(optimizationLevel);
575 if (iterator == optimizationLevelMap.end())
577 std::cerr <<
"Unknown optimization level.\n";
580 CommandLineOptions_.OptimizationLevel_ = iterator->second;
583 if (!languageStandard.empty())
585 auto iterator = languageStandardMap.find(languageStandard);
586 if (iterator == languageStandardMap.end())
588 std::cerr <<
"Unknown language standard.\n";
591 CommandLineOptions_.LanguageStandard_ = iterator->second;
594 if (inputFiles.empty())
596 std::cerr <<
"jlc: no input files.\n";
600 if (inputFiles.size() > 1 && noLinking && !outputFile.empty())
602 std::cerr <<
"jlc: cannot specify -o when generating multiple output files.\n";
606 auto jlmOptOptimizations =
607 checkAndConvertJlmOptOptimizations(jlmOptimizations, CommandLineOptions_.OptimizationLevel_);
609 CommandLineOptions_.Libraries_ = libraries;
610 CommandLineOptions_.MacroDefinitions_ = macroDefinitions;
611 CommandLineOptions_.LibraryPaths_ = libraryPaths;
612 CommandLineOptions_.Warnings_ = warnings;
613 CommandLineOptions_.IncludePaths_ = includePaths;
614 CommandLineOptions_.OnlyPrintCommands_ = onlyPrintCommands;
615 CommandLineOptions_.GenerateDebugInformation_ = generateDebugInformation;
616 CommandLineOptions_.Flags_ = flags;
617 CommandLineOptions_.JlmOptOptimizations_ = jlmOptOptimizations;
619 { jlmOptPassStatistics.begin(), jlmOptPassStatistics.end() });
620 CommandLineOptions_.Verbose_ = verbose;
621 CommandLineOptions_.Rdynamic_ = rDynamic;
622 CommandLineOptions_.Suppress_ = suppress;
623 CommandLineOptions_.UsePthreads_ = usePthreads;
624 CommandLineOptions_.Md_ = mD;
626 for (
auto & inputFile : inputFiles)
629 if (IsObjectFile(inputFilePath))
632 CommandLineOptions_.Compilations_.push_back(
633 { inputFilePath,
util::FilePath(
""), inputFilePath,
"",
false,
false,
false,
true });
638 CommandLineOptions_.Compilations_.push_back(
640 mF.empty() ? ToDependencyFile(inputFilePath) :
util::FilePath(mF),
641 ToObjectFile(inputFilePath),
642 mT.empty() ? ToObjectFile(inputFilePath).
name() : mT,
649 if (!outputFile.empty())
654 JLM_ASSERT(CommandLineOptions_.Compilations_.size() == 1);
655 CommandLineOptions_.Compilations_[0].SetOutputFile(outputFilePath);
659 CommandLineOptions_.OutputFile_ = outputFilePath;
663 return CommandLineOptions_;
671 using namespace ::
llvm;
680 cl::TopLevelSubCommand->reset();
682 cl::opt<std::string> inputFile(cl::Positional, cl::desc(
"<input>"));
684 cl::opt<std::string> outputFile(
687 cl::desc(
"Write output to <file>"),
688 cl::value_desc(
"file"));
691 const auto statisticDirectoryDescription =
692 "Write statistics and debug output to files in <dir>. Default is "
693 + statisticsDirectoryDefault.
to_str() +
".";
694 cl::opt<std::string> statisticDirectory(
696 cl::init(statisticsDirectoryDefault.to_str()),
697 cl::desc(statisticDirectoryDescription),
698 cl::value_desc(
"dir"));
700 cl::opt<bool> dumpRvsdgGraphs(
703 cl::desc(
"Dump RVSDG as json graphs after each transformation in debug folder."));
705 cl::list<util::Statistics::Id> printStatistics(
709 "Write aggregate alloca splitting statistics to file."),
712 "Write aggregation statistics to file."),
715 "Collect agnostic mod/ref summarization pass statistics."),
718 "Evaluate alias analysis precision and store to file"),
721 "Collect Andersen alias analysis pass statistics."),
724 "Write annotation statistics to file."),
727 "Write encoding statistics of basic encoder to file."),
730 "Write common node elimination statistics to file."),
733 "Write control flow recovery statistics to file."),
736 "Write data node to delta node conversion statistics to file."),
739 "Write dead node elimination statistics to file."),
742 "Write function inlining statistics to file."),
745 "Collect if-conversion transformation statistics"),
748 "Write invariant value redirection statistics to file."),
751 "Write Jlm to RVSDG conversion statistics to file."),
754 "Write loop strength reduction statistics to file."),
757 "Write loop unrolling statistics to file."),
760 "Collect loop unswitching pass statistics."),
763 "Write node pull statistics to file."),
766 "Write node push statistics to file."),
769 "Write node reduction statistics to file."),
772 "Collect region-aware mod/ref summarization statistics."),
775 "Write RVSDG construction statistics to file."),
778 "Write RVSDG destruction statistics to file."),
781 "Write RVSDG optimization statistics to file."),
784 "Write RVSDG tree printer pass statistics."),
787 "Write scalar evolution statistics to file."),
790 "Write store value forwarding statistics to file.")),
791 cl::desc(
"Write statistics"));
797 cl::opt<JlmOptCommandLineOptions::InputFormat> inputFormat(
799 cl::desc(
"Select input format:"),
804 "Input LLVM IR [default]"),
809 cl::init(llvmInputFormat));
814 cl::opt<JlmOptCommandLineOptions::OutputFormat> outputFormat(
816 cl::desc(
"Select output format:"),
825 "Output Rvsdg tree as JSON"),
828 "Output LLVM IR [default]"),
834 "Output Rvsdg Tree")),
839 auto aggregateAllocaSplitting =
845 auto invariantValueRedirection =
861 cl::list<JlmOptCommandLineOptions::OptimizationId> optimizationIds(
866 "Andersen alias analysis with agnostic memory state encoding"),
868 aAAndersenRegionAware,
870 "Andersen alias analysis with region-aware memory state encoding"),
872 aggregateAllocaSplitting,
874 "Split aggregate type alloca nodes"),
876 commonNodeElimination,
878 "Common Node Elimination"),
882 "Dead Node Elimination"),
886 "Function Inlining"),
890 "Convert pass-through values of gamma nodes to select operations"),
892 invariantValueRedirection,
894 "Invariant Value Redirection"),
896 ioBarrierElimination,
898 "Eliminate IOBarrier nodes"),
902 "Separate chains of load operations"),
904 loopStrengthReduction,
906 "Loop strength reduction"),
914 "Move conditionals outside loops"),
918 "Hoist nodes out of conditionals and loops."),
922 "DEPRECATED - Use node hoisting instead."),
932 predicateCorrelation,
934 "Correlate predicates between theta and gamma nodes"),
938 "Rvsdg Tree Printer"),
944 storeValueForwarding,
946 "Store Value Forwarding"),
949 "ThetaGammaInversion",
950 "[DEPRECATED] Use --LoopUnswitching instead.")),
951 cl::desc(
"Perform optimization"));
953 cl::list<llvm::RvsdgTreePrinter::Configuration::Annotation> rvsdgTreePrinterAnnotations(
955 cl::values(::clEnumValN(
958 "Annotate region and node IDs")),
959 cl::values(::clEnumValN(
961 "NumAggregateAllocaNodes",
962 "Annotate number of AllocaOperation nodes with aggregate types.")),
963 cl::values(::clEnumValN(
966 "Annotate number of AllocaOperation nodes")),
967 cl::values(::clEnumValN(
970 "Annotate number of LoadOperation nodes")),
971 cl::values(::clEnumValN(
973 "NumMemoryStateInputsOutputs",
974 "Annotate number of inputs/outputs with memory state type")),
975 cl::values(::clEnumValN(
978 "Annotate number of RVSDG nodes")),
979 cl::values(::clEnumValN(
982 "Annotate number of StoreOperation nodes")),
984 cl::desc(
"Comma separated list of RVSDG tree printer annotations"));
986 cl::ParseCommandLineOptions(argc, argv);
992 { printStatistics.begin(), printStatistics.end() });
995 std::move(demandedStatistics),
996 statisticsDirectoryFilePath,
997 inputFilePath.
base());
1000 { rvsdgTreePrinterAnnotations.begin(), rvsdgTreePrinterAnnotations.end() });
1005 std::move(inputFilePath),
1009 std::move(statisticsCollectorSettings),
1010 std::move(treePrinterConfiguration),
1011 std::move(optimizationIds),
1014 return *CommandLineOptions_;
1029 CommandLineOptions_.
Reset();
1031 using namespace ::
llvm;
1040 cl::TopLevelSubCommand->reset();
1042 cl::opt<std::string> inputFile(cl::Positional, cl::desc(
"<input>"));
1044 cl::opt<std::string> outputFolder(
1046 cl::desc(
"Write output to <folder>"),
1047 cl::value_desc(
"folder"));
1049 cl::opt<std::string> hlsFunction(
1052 cl::desc(
"Function that should be accelerated"),
1053 cl::value_desc(
"hls-function"));
1055 cl::opt<int> latency(
1058 cl::init(CommandLineOptions_.MemoryLatency_),
1059 cl::desc(
"Memory latency"),
1060 cl::value_desc(
"latency"));
1062 cl::opt<bool> extractHlsFunction(
1065 cl::desc(
"Extracts function specified by hls-function"));
1067 cl::opt<bool> dumpRvsdgGraphs(
1070 cl::desc(
"Dump RVSDG as json graphs after each transformation in debug folder."));
1072 cl::opt<JlmHlsCommandLineOptions::OutputFormat> format(
1077 "Output FIRRTL [default]"),
1079 cl::desc(
"Select output format"));
1081 cl::ParseCommandLineOptions(argc, argv);
1083 if (outputFolder.empty())
1084 throw util::Error(
"jlm-hls no output directory provided, i.e, -o.\n");
1086 if (extractHlsFunction && hlsFunction.empty())
1088 "jlm-hls: --hls-function is not specified.\n which is required for --extract\n");
1091 CommandLineOptions_.HlsFunction_ = std::move(hlsFunction);
1093 CommandLineOptions_.ExtractHlsFunction_ = extractHlsFunction;
1094 CommandLineOptions_.OutputFormat_ = format;
1095 CommandLineOptions_.dumpRvsdgGraphs_ = dumpRvsdgGraphs;
1099 throw util::Error(
"The --latency must be set to a number larger than zero.");
1101 CommandLineOptions_.MemoryLatency_ = latency;
1103 return CommandLineOptions_;
1118 CommandLineOptions_.
Reset();
1120 using namespace ::
llvm;
1129 cl::TopLevelSubCommand->reset();
1131 cl::opt<bool> onlyPrintCommands(
1133 cl::ValueDisallowed,
1134 cl::desc(
"Print (but do not run) the commands for this compilation."));
1136 cl::list<std::string> inputFiles(cl::Positional, cl::desc(
"<inputs>"));
1138 cl::list<std::string> includePaths(
1141 cl::desc(
"Add directory <dir> to include search paths."),
1142 cl::value_desc(
"dir"));
1144 cl::list<std::string> libraryPaths(
1147 cl::desc(
"Add directory <dir> to library search paths."),
1148 cl::value_desc(
"dir"));
1150 cl::list<std::string> libraries(
1153 cl::desc(
"Search the library <lib> when linking."),
1154 cl::value_desc(
"lib"));
1156 cl::opt<std::string> outputFile(
"o", cl::desc(
"Write output to <file>."), cl::value_desc(
"file"));
1158 cl::opt<bool> generateDebugInformation(
1160 cl::ValueDisallowed,
1161 cl::desc(
"Generate source-level debug information."));
1163 cl::opt<bool> noLinking(
1165 cl::ValueDisallowed,
1166 cl::desc(
"Only run preprocess, compile, and assemble steps."));
1168 cl::opt<std::string> optimizationLevel(
1172 cl::desc(
"Optimization level. [O0, O1, O2, O3]"),
1173 cl::value_desc(
"#"));
1175 cl::list<std::string> macroDefinitions(
1178 cl::desc(
"Add <macro> to preprocessor macros."),
1179 cl::value_desc(
"macro"));
1181 cl::list<std::string> warnings(
1184 cl::desc(
"Enable specified warning."),
1185 cl::value_desc(
"warning"));
1187 cl::opt<std::string> languageStandard(
1189 cl::desc(
"Language standard."),
1190 cl::value_desc(
"standard"));
1192 cl::list<std::string> flags(
"f", cl::Prefix, cl::desc(
"Specify flags."), cl::value_desc(
"flag"));
1194 cl::list<std::string> jlmHlsOptimizations(
1197 cl::desc(
"jlm-hls optimization. Run 'jlm-hls -help' for viable options."),
1198 cl::value_desc(
"jlmhls"));
1200 cl::opt<bool> verbose(
1202 cl::ValueDisallowed,
1203 cl::desc(
"Show commands to run and use verbose output. (Affects only clang for now)"));
1205 cl::opt<bool> rdynamic(
1207 cl::ValueDisallowed,
1208 cl::desc(
"rdynamic option passed to clang"));
1210 cl::opt<bool> suppress(
"w", cl::ValueDisallowed, cl::desc(
"Suppress all warnings"));
1212 cl::opt<bool> usePthreads(
1214 cl::ValueDisallowed,
1215 cl::desc(
"Support POSIX threads in generated code"));
1219 cl::ValueDisallowed,
1220 cl::desc(
"Write a depfile containing user and system headers"));
1222 cl::opt<std::string> mF(
1224 cl::desc(
"Write depfile output from -MD to <file>."),
1225 cl::value_desc(
"file"));
1227 cl::opt<std::string> mT(
1229 cl::desc(
"Specify name of main file output in depfile."),
1230 cl::value_desc(
"value"));
1232 cl::list<std::string> hlsFunction(
1235 cl::desc(
"function that should be accelerated"),
1236 cl::value_desc(
"regex"));
1238 cl::opt<bool> generateFirrtl(
"firrtl", cl::ValueDisallowed, cl::desc(
"Generate firrtl"));
1240 cl::opt<bool> useCirct(
1243 cl::desc(
"DEPRACATED - CIRCT is always used to generate FIRRTL"));
1245 cl::ParseCommandLineOptions(argc, argv);
1249 static std::unordered_map<std::string, JhlsCommandLineOptions::OptimizationLevel> Olvlmap(
1255 static std::unordered_map<std::string, JhlsCommandLineOptions::LanguageStandard> stdmap(
1266 if (!optimizationLevel.empty())
1268 auto it = Olvlmap.find(optimizationLevel);
1269 if (it == Olvlmap.end())
1271 std::cerr <<
"Unknown optimization level.\n";
1274 CommandLineOptions_.OptimizationLevel_ = it->second;
1277 if (!languageStandard.empty())
1279 auto it = stdmap.find(languageStandard);
1280 if (it == stdmap.end())
1282 std::cerr <<
"Unknown language standard.\n";
1285 CommandLineOptions_.LanguageStandard_ = it->second;
1288 if (inputFiles.empty())
1290 std::cerr <<
"jlc: no input files.\n";
1294 if (inputFiles.size() > 1 && noLinking && !outputFile.empty())
1296 std::cerr <<
"jlc: cannot specify -o when generating multiple output files.\n";
1300 if (!hlsFunction.empty())
1302 CommandLineOptions_.Hls_ =
true;
1303 CommandLineOptions_.HlsFunctionRegex_ = hlsFunction.front();
1306 if (hlsFunction.size() > 1)
1308 std::cerr <<
"jlc-hls: more than one function regex specified\n";
1312 CommandLineOptions_.Libraries_ = libraries;
1313 CommandLineOptions_.MacroDefinitions_ = macroDefinitions;
1314 CommandLineOptions_.LibraryPaths_ = libraryPaths;
1315 CommandLineOptions_.Warnings_ = warnings;
1316 CommandLineOptions_.IncludePaths_ = includePaths;
1317 CommandLineOptions_.OnlyPrintCommands_ = onlyPrintCommands;
1318 CommandLineOptions_.GenerateDebugInformation_ = generateDebugInformation;
1319 CommandLineOptions_.Flags_ = flags;
1320 CommandLineOptions_.JlmHls_ = jlmHlsOptimizations;
1321 CommandLineOptions_.Verbose_ = verbose;
1322 CommandLineOptions_.Rdynamic_ = rdynamic;
1323 CommandLineOptions_.Suppress_ = suppress;
1324 CommandLineOptions_.UsePthreads_ = usePthreads;
1325 CommandLineOptions_.Md_ = mD;
1326 CommandLineOptions_.GenerateFirrtl_ = generateFirrtl;
1328 for (
auto & inputFile : inputFiles)
1331 if (IsObjectFile(inputFilePath))
1334 CommandLineOptions_.Compilations_.push_back(
1335 { inputFilePath,
util::FilePath(
""), inputFilePath,
"",
false,
false,
false,
true });
1340 CommandLineOptions_.Compilations_.push_back(
1342 mF.empty() ? CreateDependencyFileFromFile(inputFilePath) :
util::FilePath(mF),
1343 CreateObjectFileFromFile(inputFilePath),
1344 mT.empty() ? CreateObjectFileFromFile(inputFilePath).
name() : mT,
1351 if (!outputFile.empty())
1356 JLM_ASSERT(CommandLineOptions_.Compilations_.size() == 1);
1357 CommandLineOptions_.Compilations_[0].SetOutputFile(outputFilePath);
1361 CommandLineOptions_.OutputFile_ = outputFilePath;
1365 return CommandLineOptions_;