Jlm
jlm-hls.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2022 Magnus Sjalander <work@sjalander.com>
3  * See COPYING for terms of redistribution.
4  */
5 
14 #include <jlm/hls/HlsDotWriter.hpp>
17 #include <jlm/llvm/DotWriter.hpp>
21 
22 #include <llvm/IR/LLVMContext.h>
23 #include <llvm/IR/Module.h>
24 #include <llvm/IRReader/IRReader.h>
25 #include <llvm/Support/raw_os_ostream.h>
26 #include <llvm/Support/SourceMgr.h>
27 
28 static void
29 stringToFile(const std::string & output, const jlm::util::FilePath & fileName)
30 {
31  std::ofstream outputFile;
32  outputFile.open(fileName.to_str());
33  outputFile << output;
34  outputFile.close();
35 }
36 
37 static void
39 {
40  llvm::LLVMContext ctx;
41  jlm::util::StatisticsCollector statisticsCollector;
42  auto jm = jlm::llvm::RvsdgToIpGraphConverter::CreateAndConvertModule(module, statisticsCollector);
44  std::error_code EC;
45  llvm::raw_fd_ostream os(fileName.to_str(), EC);
46  lm->print(os, nullptr);
47 }
48 
49 int
50 main(int argc, char ** argv)
51 {
52  auto & commandLineOptions = jlm::tooling::JlmHlsCommandLineParser::Parse(argc, argv);
53 
54  llvm::LLVMContext ctx;
55  llvm::SMDiagnostic err;
56  auto llvmModule = llvm::parseIRFile(commandLineOptions.InputFile_.to_str(), err, ctx);
57  llvmModule->setSourceFileName(commandLineOptions.OutputFiles_.Dirname().Join("jlm_hls").to_str());
58  if (!llvmModule)
59  {
60  err.print(argv[0], llvm::errs());
61  exit(1);
62  }
63 
64  // TODO: Get demanded statistics and output folder from command line options
65  auto moduleName = commandLineOptions.InputFile_.base();
67  {},
69  moduleName);
70  jlm::util::StatisticsCollector collector(std::move(settings));
71 
72  /* LLVM to JLM pass */
73  auto jlmModule = jlm::llvm::ConvertLlvmModule(*llvmModule);
74 
75  auto rvsdgModule = jlm::llvm::ConvertInterProceduralGraphModule(*jlmModule, collector);
76 
77  jlm::hls::setMemoryLatency(commandLineOptions.MemoryLatency_);
78 
79  if (commandLineOptions.ExtractHlsFunction_)
80  {
81  auto hlsFunction = jlm::hls::split_hls_function(*rvsdgModule, commandLineOptions.HlsFunction_);
82 
83  llvmToFile(*rvsdgModule, commandLineOptions.OutputFiles_.WithSuffix(".rest.ll"));
84  llvmToFile(*hlsFunction, commandLineOptions.OutputFiles_.WithSuffix(".function.ll"));
85  return 0;
86  }
87 
88  if (commandLineOptions.OutputFormat_
90  {
91  jlm::hls::rvsdg2ref(*rvsdgModule, commandLineOptions.OutputFiles_.WithSuffix(".ref.ll"));
92 
93  jlm::hls::HlsDotWriter dotWriter;
94  auto transformationSequence =
95  jlm::hls::createTransformationSequence(dotWriter, commandLineOptions.dumpRvsdgDotGraphs_);
96  transformationSequence->Run(*rvsdgModule, collector);
97 
98  // Writing the FIRRTL to a file and then reading it back in to convert to Verilog.
99  // Could potentially change to pass the FIRRTL directly to the converter, but the converter
100  // is based on CIRCT's Firtool library, which assumes that the FIRRTL is read from a file.
102  auto output = hls.ToString(*rvsdgModule);
103 
104  const auto firrtlFile = commandLineOptions.OutputFiles_.WithSuffix(".fir");
105  stringToFile(output, firrtlFile);
106 
107  const auto outputVerilogFile = commandLineOptions.OutputFiles_.WithSuffix(".v");
108  if (!jlm::hls::FirrtlToVerilogConverter::Convert(firrtlFile, outputVerilogFile))
109  {
110  std::cerr << "The FIRRTL to Verilog conversion failed.\n" << std::endl;
111  exit(1);
112  }
113 
114  jlm::hls::VerilatorHarnessHLS vhls(outputVerilogFile);
115  stringToFile(
116  vhls.run(*rvsdgModule),
117  commandLineOptions.OutputFiles_.WithSuffix(".harness.cpp"));
118 
119  jlm::hls::VerilatorHarnessAxi ahls(outputVerilogFile);
120  stringToFile(
121  ahls.run(*rvsdgModule),
122  commandLineOptions.OutputFiles_.WithSuffix(".harness_axi.cpp"));
123 
124  // TODO: hide behind flag
125  jlm::hls::JsonHLS jhls;
126  stringToFile(jhls.run(*rvsdgModule), commandLineOptions.OutputFiles_.WithSuffix(".json"));
127  }
128  else if (
129  commandLineOptions.OutputFormat_ == jlm::tooling::JlmHlsCommandLineOptions::OutputFormat::Dot)
130  {
131  jlm::hls::HlsDotWriter dotWriter;
132  auto transformationSequence =
133  jlm::hls::createTransformationSequence(dotWriter, commandLineOptions.dumpRvsdgDotGraphs_);
134  transformationSequence->Run(*rvsdgModule, collector);
135 
136  jlm::hls::DotHLS dhls;
137  stringToFile(
138  dhls.run(*rvsdgModule),
139  commandLineOptions.OutputFiles_.Dirname().Join("jlm_hls.dot"));
140  }
141  else
142  {
143  JLM_UNREACHABLE("Format not supported.\n");
144  }
145 
146  collector.PrintStatistics();
147 
148  return 0;
149 }
std::string run(llvm::LlvmRvsdgModule &rm)
Definition: base-hls.hpp:28
static bool Convert(const util::FilePath inputFirrtlFile, const util::FilePath outputVerilogFile)
std::string ToString(llvm::LlvmRvsdgModule &rvsdgModule)
static std::unique_ptr<::llvm::Module > CreateAndConvertModule(InterProceduralGraphModule &ipGraphModule, ::llvm::LLVMContext &ctx)
static std::unique_ptr< InterProceduralGraphModule > CreateAndConvertModule(LlvmRvsdgModule &rvsdgModule, util::StatisticsCollector &statisticsCollector)
static const JlmHlsCommandLineOptions & Parse(int argc, const char *const *argv)
static FilePath TempDirectoryPath()
Definition: file.hpp:317
const std::string & to_str() const noexcept
Definition: file.hpp:275
#define JLM_UNREACHABLE(msg)
Definition: common.hpp:43
int main(int argc, char **argv)
Definition: jlm-hls.cpp:50
static void llvmToFile(jlm::llvm::LlvmRvsdgModule &module, const jlm::util::FilePath &fileName)
Definition: jlm-hls.cpp:38
static void stringToFile(const std::string &output, const jlm::util::FilePath &fileName)
Definition: jlm-hls.cpp:29
std::unique_ptr< rvsdg::TransformationSequence > createTransformationSequence(rvsdg::DotWriter &dotWriter, const bool dumpRvsdgDotGraphs)
Definition: rvsdg2rhls.cpp:446
void setMemoryLatency(size_t memoryLatency)
std::unique_ptr< jlm::llvm::LlvmRvsdgModule > split_hls_function(llvm::LlvmRvsdgModule &rm, const std::string &function_name)
Definition: rvsdg2rhls.cpp:344
void rvsdg2ref(llvm::LlvmRvsdgModule &rhls, const util::FilePath &path)
Definition: rvsdg2rhls.cpp:440
std::unique_ptr< InterProceduralGraphModule > ConvertLlvmModule(::llvm::Module &llvmModule)
static std::unique_ptr< LlvmRvsdgModule > ConvertInterProceduralGraphModule(InterProceduralGraphModule &interProceduralGraphModule, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)