Skip to content

Commit

Permalink
[ImportVerilog] Fix single unit preprocessor option (#6682)
Browse files Browse the repository at this point in the history
Make `ImportVerilog` honor the `singleUnit` option by either adding all
source files to a single preprocessor (single unit), or creating a fresh
preprocessor for every single file (multiple units).

Fixes #6680.
  • Loading branch information
fabianschuiki authored Feb 9, 2024
1 parent 6dd88f8 commit 512cc7a
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 7 deletions.
41 changes: 34 additions & 7 deletions lib/Conversion/ImportVerilog/ImportVerilog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,13 +244,10 @@ LogicalResult ImportContext::importVerilog(ModuleOp module) {
/// stream.
LogicalResult ImportContext::preprocessVerilog(llvm::raw_ostream &os) {
auto parseTimer = ts.nest("Verilog preprocessing");
for (auto &buffer : driver.buffers) {
slang::BumpAllocator alloc;
slang::Diagnostics diagnostics;
slang::parsing::Preprocessor preprocessor(
driver.sourceManager, alloc, diagnostics, driver.createOptionBag());
preprocessor.pushSource(buffer);

// Run the preprocessor to completion across all sources previously added with
// `pushSource`, report diagnostics, and print the output.
auto preprocessAndPrint = [&](slang::parsing::Preprocessor &preprocessor) {
slang::syntax::SyntaxPrinter output;
output.setIncludeComments(false);
while (true) {
Expand All @@ -260,14 +257,44 @@ LogicalResult ImportContext::preprocessVerilog(llvm::raw_ostream &os) {
break;
}

for (auto &diag : diagnostics) {
for (auto &diag : preprocessor.getDiagnostics()) {
if (diag.isError()) {
driver.diagEngine.issue(diag);
return failure();
}
}
os << output.str();
return success();
};

// Depending on whether the single-unit option is set, either add all source
// files to a single preprocessor such that they share define macros and
// directives, or create a separate preprocessor for each, such that each
// source file is in its own compilation unit.
auto optionBag = driver.createOptionBag();
if (driver.options.singleUnit == true) {
slang::BumpAllocator alloc;
slang::Diagnostics diagnostics;
slang::parsing::Preprocessor preprocessor(driver.sourceManager, alloc,
diagnostics, optionBag);
// Sources have to be pushed in reverse, as they form a stack in the
// preprocessor. Last pushed source is processed first.
for (auto &buffer : slang::make_reverse_range(driver.buffers))
preprocessor.pushSource(buffer);
if (failed(preprocessAndPrint(preprocessor)))
return failure();
} else {
for (auto &buffer : driver.buffers) {
slang::BumpAllocator alloc;
slang::Diagnostics diagnostics;
slang::parsing::Preprocessor preprocessor(driver.sourceManager, alloc,
diagnostics, optionBag);
preprocessor.pushSource(buffer);
if (failed(preprocessAndPrint(preprocessor)))
return failure();
}
}

return success();
}

Expand Down
19 changes: 19 additions & 0 deletions test/circt-verilog/preprocess-multiple-files.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// RUN: split-file %s %t
// RUN: circt-verilog %t/a.sv %t/b.sv -E | FileCheck %s --check-prefixes=CHECK-MULTI-UNIT
// RUN: circt-verilog %t/a.sv %t/b.sv -E --single-unit | FileCheck %s --check-prefixes=CHECK-SINGLE-UNIT
// REQUIRES: slang

// CHECK-MULTI-UNIT: import hello::undefined;
// CHECK-SINGLE-UNIT: import hello::defined;

//--- a.sv

`define HELLO

//--- b.sv

`ifdef HELLO
import hello::defined;
`else
import hello::undefined;
`endif

0 comments on commit 512cc7a

Please sign in to comment.