17 #include "mlir/IR/Threading.h"
18 #include "mlir/Support/FileUtilities.h"
19 #include "mlir/Support/IndentedOstream.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/Support/FileSystem.h"
22 #include "llvm/Support/JSON.h"
23 #include "llvm/Support/Path.h"
24 #include "llvm/Support/ToolOutputFile.h"
26 #define DEBUG_TYPE "di"
29 using namespace circt;
30 using namespace debug;
32 using llvm::MapVector;
33 using llvm::SmallMapVector;
59 SmallVectorImpl<FileLineColLoc> &locs) {
60 if (
auto nameLoc = dyn_cast<NameLoc>(loc)) {
61 if (nameLoc.getName() ==
"emitted")
65 }
else if (
auto fusedLoc = dyn_cast<FusedLoc>(loc)) {
66 auto strAttr = dyn_cast_or_null<StringAttr>(fusedLoc.getMetadata());
67 if (strAttr && strAttr.getValue() ==
"verilogLocations")
70 for (
auto innerLoc : fusedLoc.getLocations())
72 }
else if (
auto fileLoc = dyn_cast<FileLineColLoc>(loc)) {
74 locs.push_back(fileLoc);
83 SmallVector<FileLineColLoc> locs;
87 for (
unsigned head = 0, end = locs.size(); head != end; ++head)
88 if (llvm::sys::fs::exists(locs[head].getFilename().getValue()))
89 locs[tail++] = locs[head];
93 if (!loc.getFilename().getValue().ends_with(
".fir"))
96 if (loc.getFilename().getValue().ends_with(
".fir"))
110 SmallString<128> buffer;
111 llvm::raw_svector_ostream(buffer) << x;
124 SmallVectorImpl<char> &relativePath) {
125 using namespace llvm::sys;
126 auto sourceIt = path::begin(path);
127 auto outputIt = path::begin(relativeTo);
128 auto sourceEnd = path::end(path);
129 auto outputEnd = path::end(relativeTo);
136 while (outputIt != outputEnd && sourceIt != sourceEnd &&
137 *outputIt == *sourceIt) {
151 for (; outputIt != outputEnd && *outputIt !=
".."; ++outputIt)
153 for (; sourceIt != sourceEnd; ++sourceIt)
160 return outputIt == outputEnd;
173 llvm::StringMap<size_t> &nextGeneratedNameIDs) {
190 const EmitHGLDDOptions &options;
194 hw::HWSymbolCache symbolCache;
199 llvm::StringMap<size_t> objectNamespace;
201 GlobalState(Operation *op,
const EmitHGLDDOptions &options)
202 : op(op), options(options), di(op) {
203 symbolCache.addDefinitions(op);
204 symbolCache.freeze();
211 SmallVector<int64_t, 1> packedDims;
212 SmallVector<int64_t, 1> unpackedDims;
214 EmittedType() =
default;
215 EmittedType(StringRef name) : name(name) {}
216 EmittedType(Type type) {
218 if (
auto inoutType = dyn_cast<hw::InOutType>(type))
226 void addPackedDim(int64_t dim) { packedDims.push_back(dim); }
227 void addUnpackedDim(int64_t dim) { unpackedDims.push_back(dim); }
229 operator bool()
const {
return !name.empty(); }
231 static JArray emitDims(ArrayRef<int64_t> dims,
bool skipFirstLen1Dim) {
233 if (skipFirstLen1Dim && !dims.empty() && dims[0] == 1)
234 dims = dims.drop_front();
235 for (
auto dim : llvm::reverse(dims)) {
236 json.push_back(dim - 1);
241 JArray emitPackedDims()
const {
return emitDims(packedDims,
true); }
242 JArray emitUnpackedDims()
const {
return emitDims(unpackedDims,
false); }
249 operator bool()
const {
return expr !=
nullptr && type; }
252 [[maybe_unused]]
static llvm::raw_ostream &
operator<<(llvm::raw_ostream &os,
253 const EmittedType &type) {
255 return os <<
"<null>";
257 for (
auto dim : type.packedDims)
258 os <<
'[' << dim <<
']';
259 if (!type.unpackedDims.empty()) {
261 for (
auto dim : type.unpackedDims)
262 os <<
'[' << dim <<
']';
267 [[maybe_unused]]
static llvm::raw_ostream &
operator<<(llvm::raw_ostream &os,
268 const EmittedExpr &expr) {
270 return os <<
"<null>";
271 return os << expr.expr <<
" : " << expr.type;
278 FileEmitter(GlobalState &state, StringAttr hdlFile)
279 : state(state), hdlFile(hdlFile) {}
282 SmallVector<DIModule *> modules;
284 SmallString<64> outputFileName;
286 llvm::StringMap<size_t> moduleNamespace;
287 SmallMapVector<StringAttr, std::pair<StringAttr, unsigned>, 8> sourceFiles;
288 SmallMapVector<JValue, StringRef, 8> structDefs;
289 SmallString<128> structNameHint;
291 void emit(llvm::raw_ostream &os);
293 JValue emitLoc(FileLineColLoc loc, FileLineColLoc endLoc,
bool emitted);
298 EmittedExpr emitExpression(Value value);
300 unsigned getSourceFile(StringAttr sourceFile,
bool emitted);
308 void findAndEmitLoc(
JOStream &
json, StringRef fieldName, Location loc,
311 json.attribute(fieldName, emitLoc(fileLoc, {}, emitted));
317 void findAndEmitLocOrGuess(
JOStream &
json, StringRef fieldName, Operation *op,
320 json.attribute(fieldName, emitLoc(fileLoc, {}, emitted));
326 SmallMapVector<StringAttr, std::pair<SmallVector<FileLineColLoc>,
unsigned>,
329 op->walk([&](Operation *subop) {
332 locsByFile[fileLoc.getFilename()].first.push_back(fileLoc);
335 for (
auto ®ion : subop->getRegions())
336 for (
auto &block : region)
337 for (
auto arg : block.getArguments())
339 locsByFile[fileLoc.getFilename()].first.push_back(fileLoc);
343 for (
auto ®ion : op->getRegions())
344 for (
auto &block : region)
345 for (
auto arg : block.getArguments())
347 locsByFile[fileLoc.getFilename()].second += 10;
349 if (locsByFile.empty())
353 llvm::sort(locsByFile, [](
auto &a,
auto &b) {
354 return (a.second.first.size() + a.second.second) >
355 (b.second.first.size() + a.second.second);
358 auto &locs = locsByFile.front().second.first;
359 llvm::sort(locs, [](
auto &a,
auto &b) {
360 if (a.getLine() < b.getLine())
362 if (a.getLine() > b.getLine())
364 if (a.getColumn() < b.getColumn())
369 json.attribute(fieldName, emitLoc(locs.front(), locs.back(), emitted));
374 void findAndSetLocs(
JObject &into, Location loc) {
376 into[
"hgl_loc"] = emitLoc(fileLoc, {},
false);
378 into[
"hdl_loc"] = emitLoc(fileLoc, {},
true);
383 StringRef getModuleName(
DIModule *module) {
384 auto name = state.moduleNames.lookup(module);
386 "moduleNames should contain a name for every module");
390 StringRef legalizeInModuleNamespace(StringRef name) {
399 unsigned FileEmitter::getSourceFile(StringAttr sourceFile,
bool emitted) {
400 using namespace llvm::sys;
405 auto &slot = sourceFiles[sourceFile];
408 slot.second = sourceFiles.size();
411 if (path::is_absolute(sourceFile.getValue())) {
412 slot.first = sourceFile;
419 StringRef filePrefix =
420 emitted ? state.options.outputFilePrefix : state.options.sourceFilePrefix;
421 if (!filePrefix.empty()) {
422 SmallString<64> buffer = filePrefix;
433 SmallString<64> sourcePath = sourceFile.getValue();
434 path::remove_dots(sourcePath,
true);
438 StringRef relativeToDir = path::parent_path(outputFileName);
439 if (!path::is_absolute(outputFileName)) {
440 SmallString<64> buffer;
453 SmallString<64> outputPath = relativeToDir;
454 fs::make_absolute(sourcePath);
455 fs::make_absolute(outputPath);
456 if (path::is_absolute(sourcePath) && path::is_absolute(outputPath)) {
457 auto firstSourceComponent = *path::begin(path::relative_path(sourcePath));
458 auto firstOutputComponent = *path::begin(path::relative_path(outputPath));
459 if (firstSourceComponent == firstOutputComponent) {
460 SmallString<64> buffer;
483 SmallVector<std::string, 16> rawObjects;
484 for (
auto *module : modules) {
485 llvm::raw_string_ostream objectOS(rawObjects.emplace_back());
487 objectJson.arrayBegin();
488 objectJson.arrayBegin();
489 emitModule(objectJson, module);
490 objectJson.arrayEnd();
491 objectJson.arrayEnd();
494 std::optional<unsigned> hdlFileIndex;
496 hdlFileIndex = getSourceFile(hdlFile,
true);
499 json.attributeObject(
"HGLDD", [&] {
500 json.attribute(
"version",
"1.0");
501 json.attributeArray(
"file_info", [&] {
502 for (
auto [key, fileAndId] : sourceFiles)
503 json.value(fileAndId.first.getValue());
506 json.attribute(
"hdl_file_index", *hdlFileIndex);
508 json.attributeArray(
"objects", [&] {
509 for (
auto &[structDef, name] : structDefs)
510 json.value(structDef);
511 for (
auto &rawObject : rawObjects) {
522 json.rawValue(StringRef(rawObject)
534 JValue FileEmitter::emitLoc(FileLineColLoc loc, FileLineColLoc endLoc,
537 obj[
"file"] = getSourceFile(loc.getFilename(), emitted);
539 obj[
"begin_line"] = loc.getLine();
540 obj[
"end_line"] = loc.getLine();
542 if (loc.getColumn()) {
543 obj[
"begin_column"] = loc.getColumn();
544 obj[
"end_column"] = loc.getColumn();
547 if (endLoc.getLine())
548 obj[
"end_line"] = endLoc.getLine();
549 if (endLoc.getColumn())
550 obj[
"end_column"] = endLoc.getColumn();
556 if (
auto *op = module.
op)
557 if (
auto attr = op->getAttrOfType<StringAttr>(
"verilogName"))
563 if (
auto *op = inst.
op)
564 if (
auto attr = op->getAttrOfType<StringAttr>(
"hw.verilogName"))
571 moduleNamespace = state.objectNamespace;
572 structNameHint = module->
name.getValue();
574 json.attribute(
"kind",
"module");
575 json.attribute(
"obj_name", getModuleName(module));
576 json.attribute(
"module_name",
579 json.attribute(
"isExtModule", 1);
580 if (
auto *op = module->
op) {
581 findAndEmitLocOrGuess(
json,
"hgl_loc", op,
false);
582 findAndEmitLoc(
json,
"hdl_loc", op->getLoc(),
true);
584 emitModuleBody(
json, module);
590 json.attributeArray(
"port_vars", [&] {
592 emitVariable(
json, var);
594 json.attributeArray(
"children", [&] {
596 emitInstance(
json, instance);
605 auto instanceName = legalizeInModuleNamespace(instance->
name.getValue());
606 json.attribute(
"name", instanceName);
609 if (verilogName != instanceName)
610 json.attribute(
"hdl_obj_name", verilogName.getValue());
612 json.attribute(
"obj_name",
613 getModuleName(instance->
module));
614 json.attribute(
"module_name",
618 if (
auto *op = instance->
op) {
619 findAndEmitLoc(
json,
"hgl_loc", op->getLoc(),
false);
620 findAndEmitLoc(
json,
"hdl_loc", op->getLoc(),
true);
625 auto structNameHintLen = structNameHint.size();
627 structNameHint +=
'_';
628 structNameHint += instance->
module->
name.getValue();
629 }
else if (!instance->
name.empty()) {
630 structNameHint +=
'_';
631 structNameHint += instanceName;
634 structNameHint.resize(structNameHintLen);
643 auto variableName = legalizeInModuleNamespace(variable->
name.getValue());
644 json.attribute(
"var_name", variableName);
645 findAndEmitLoc(
json,
"hgl_loc", variable->
loc,
false);
646 findAndEmitLoc(
json,
"hdl_loc", variable->
loc,
true);
649 if (
auto value = variable->
value) {
650 auto structNameHintLen = structNameHint.size();
651 structNameHint +=
'_';
652 structNameHint += variableName;
653 emitted = emitExpression(value);
654 structNameHint.resize(structNameHintLen);
657 LLVM_DEBUG(llvm::dbgs() <<
"- " << variable->
name <<
": " << emitted <<
"\n");
659 json.attributeBegin(
"value");
660 json.rawValue([&](
auto &os) { os << emitted.expr; });
662 json.attribute(
"type_name", emitted.type.name);
663 if (
auto dims = emitted.type.emitPackedDims(); !dims.empty())
664 json.attribute(
"packed_range", std::move(dims));
665 if (
auto dims = emitted.type.emitUnpackedDims(); !dims.empty())
666 json.attribute(
"unpacked_range", std::move(dims));
673 EmittedExpr FileEmitter::emitExpression(Value value) {
676 auto hglddSigName = [](StringRef sigName) ->
JObject {
677 return JObject{{
"sig_name", sigName}};
679 auto hglddOperator = [](StringRef opcode,
JValue args) ->
JObject {
682 {
"operands", std::move(args)},
685 auto hglddInt32 = [](uint32_t value) ->
JObject {
686 return JObject({{
"integer_num", value}});
689 if (
auto blockArg = dyn_cast<BlockArgument>(value)) {
690 auto module = dyn_cast<hw::HWModuleOp>(blockArg.getOwner()->getParentOp());
693 auto name = module.getInputNameAttr(blockArg.getArgNumber());
696 return {hglddSigName(name), value.getType()};
699 auto result = cast<OpResult>(value);
700 auto *op = result.getOwner();
703 if (isa<hw::WireOp, sv::WireOp, sv::RegOp, sv::LogicOp>(op)) {
704 auto name = op->getAttrOfType<StringAttr>(
"hw.verilogName");
705 if (!name || name.empty())
706 name = op->getAttrOfType<StringAttr>(
"name");
707 if (name && !name.empty())
708 return {hglddSigName(name), result.getType()};
712 if (
auto constOp = dyn_cast<hw::ConstantOp>(op)) {
714 auto type = constOp.getType();
721 return {
JObject({{
"bit_vector",
"0"}}),
725 SmallString<64> buffer;
726 buffer.reserve(width);
727 constOp.getValue().toStringUnsigned(buffer, 2);
732 std::reverse(buffer.begin(), buffer.end());
733 while (buffer.size() < (
size_t)width)
735 std::reverse(buffer.begin(), buffer.end());
736 assert(buffer.size() == (
size_t)width);
738 return {
JObject({{
"bit_vector", buffer}}), type};
743 if (
auto structOp = dyn_cast<debug::StructOp>(op)) {
745 auto structNameHintLen = structNameHint.size();
746 std::vector<JValue> values;
747 SmallVector<std::tuple<EmittedType, StringAttr, Location>> types;
748 for (
auto [nameAttr, field] :
749 llvm::zip(structOp.getNamesAttr(), structOp.getFields())) {
750 auto name = cast<StringAttr>(nameAttr);
751 structNameHint +=
'_';
752 structNameHint += name.getValue();
753 if (
auto value = emitExpression(field)) {
754 values.push_back(value.expr);
755 types.push_back({value.type, name, field.getLoc()});
757 structNameHint.resize(structNameHintLen);
762 return {hglddInt32(0), EmittedType(
"bit")};
766 llvm::StringMap<size_t> structNamespace;
767 for (
auto [type, name, loc] : types) {
769 fieldDef[
"var_name"] =
770 std::string(
legalizeName(name.getValue(), structNamespace));
771 fieldDef[
"type_name"] = type.name;
772 if (
auto dims = type.emitPackedDims(); !dims.empty())
773 fieldDef[
"packed_range"] = std::move(dims);
774 if (
auto dims = type.emitUnpackedDims(); !dims.empty())
775 fieldDef[
"unpacked_range"] = std::move(dims);
776 findAndSetLocs(fieldDef, loc);
777 fieldDefs.push_back(std::move(fieldDef));
779 auto structName =
legalizeName(structNameHint, state.objectNamespace);
781 structDef[
"kind"] =
"struct";
782 structDef[
"obj_name"] = structName;
783 structDef[
"port_vars"] = std::move(fieldDefs);
784 findAndSetLocs(structDef, structOp.getLoc());
786 StringRef structNameFinal =
787 structDefs.insert({std::move(structDef), structName}).first->second;
789 return {hglddOperator(
"'{", values), EmittedType(structNameFinal)};
793 if (
auto arrayOp = dyn_cast<debug::ArrayOp>(op)) {
794 std::vector<JValue> values;
796 for (
auto element : arrayOp.getElements()) {
797 if (
auto value = emitExpression(element)) {
798 values.push_back(value.expr);
799 if (type && type != value.type)
807 return {hglddInt32(0), EmittedType(
"bit")};
809 type.addUnpackedDim(values.size());
810 return {hglddOperator(
"'{", values), type};
814 if (
auto readOp = dyn_cast<sv::ReadInOutOp>(op))
815 return emitExpression(readOp.getInput());
819 StringRef unaryOpcode = TypeSwitch<Operation *, StringRef>(op)
821 .Default([](
auto) {
return ""; });
822 if (!unaryOpcode.empty() && op->getNumOperands() == 1) {
823 auto arg = emitExpression(op->getOperand(0));
826 return {hglddOperator(unaryOpcode,
JArray{arg.expr}), result.getType()};
829 StringRef binaryOpcode =
830 TypeSwitch<Operation *, StringRef>(op)
832 .Case<comb::OrOp>([](
auto) {
return "|"; })
833 .Case<comb::XorOp>([](
auto) {
return "^"; })
834 .Case<comb::AddOp>([](
auto) {
return "+"; })
835 .Case<comb::SubOp>([](
auto) {
return "-"; })
836 .Case<comb::MulOp>([](
auto) {
return "*"; })
837 .Case<comb::DivUOp, comb::DivSOp>([](
auto) {
return "/"; })
838 .Case<comb::ModUOp, comb::ModSOp>([](
auto) {
return "%"; })
839 .Case<comb::ShlOp>([](
auto) {
return "<<"; })
840 .Case<comb::ShrUOp>([](
auto) {
return ">>"; })
841 .Case<comb::ShrSOp>([](
auto) {
return ">>>"; })
842 .Case<comb::ICmpOp>([](
auto cmpOp) -> StringRef {
843 switch (cmpOp.getPredicate()) {
844 case comb::ICmpPredicate::eq:
846 case comb::ICmpPredicate::ne:
848 case comb::ICmpPredicate::ceq:
850 case comb::ICmpPredicate::cne:
852 case comb::ICmpPredicate::weq:
854 case comb::ICmpPredicate::wne:
856 case comb::ICmpPredicate::ult:
857 case comb::ICmpPredicate::slt:
859 case comb::ICmpPredicate::ugt:
860 case comb::ICmpPredicate::sgt:
862 case comb::ICmpPredicate::ule:
863 case comb::ICmpPredicate::sle:
865 case comb::ICmpPredicate::uge:
866 case comb::ICmpPredicate::sge:
871 .Default([](
auto) {
return ""; });
872 if (!binaryOpcode.empty()) {
873 if (op->getNumOperands() != 2) {
874 op->emitOpError(
"must have two operands for HGLDD emission");
877 auto lhs = emitExpression(op->getOperand(0));
878 auto rhs = emitExpression(op->getOperand(1));
881 return {hglddOperator(binaryOpcode, {lhs.expr, rhs.expr}),
886 if (
auto concatOp = dyn_cast<comb::ConcatOp>(op)) {
887 std::vector<JValue> args;
888 for (
auto operand : concatOp.getOperands()) {
889 auto value = emitExpression(operand);
892 args.push_back(value.expr);
894 return {hglddOperator(
"{}", args), concatOp.getType()};
898 if (
auto replicateOp = dyn_cast<comb::ReplicateOp>(op)) {
899 auto arg = emitExpression(replicateOp.getInput());
902 return {hglddOperator(
"R{}",
904 hglddInt32(replicateOp.getMultiple()),
907 replicateOp.getType()};
911 if (
auto extractOp = dyn_cast<comb::ExtractOp>(op)) {
912 auto arg = emitExpression(extractOp.getInput());
915 auto lowBit = extractOp.getLowBit();
916 auto highBit = lowBit + extractOp.getType().getIntOrFloatBitWidth() - 1;
917 return {hglddOperator(
"[]",
923 extractOp.getType()};
927 if (
auto muxOp = dyn_cast<comb::MuxOp>(op)) {
928 auto cond = emitExpression(muxOp.getCond());
929 auto lhs = emitExpression(muxOp.getTrueValue());
930 auto rhs = emitExpression(muxOp.getFalseValue());
931 if (!cond || !lhs || !rhs)
933 return {hglddOperator(
"?:", {cond.expr, lhs.expr, rhs.expr}),
942 for (
auto &use : result.getUses()) {
943 auto *user = use.getOwner();
945 if (
auto wireOp = dyn_cast<hw::WireOp>(user))
946 if (wireOp.getInput() == result)
947 return emitExpression(wireOp);
949 if (
auto assignOp = dyn_cast<sv::AssignOp>(user))
950 if (assignOp.getSrc() == result)
951 return emitExpression(assignOp.getDest());
953 if (isa<hw::OutputOp>(user)) {
954 auto mod = cast<hw::HWModuleLike>(user->getParentOp());
955 auto portName = mod.getPort(mod.getHWModuleType().getPortIdForOutputId(
956 use.getOperandNumber()))
958 return {hglddSigName(portName), result.getType()};
976 SmallVector<FileEmitter, 0> files;
977 Emitter(Operation *module,
const EmitHGLDDOptions &options);
982 Emitter::Emitter(Operation *module,
const EmitHGLDDOptions &options)
983 : state(module, options) {
988 MapVector<StringAttr, FileEmitter> groups;
989 for (
auto [moduleName, module] : state.di.moduleNodes) {
993 hdlFile = fileLoc.getFilename();
995 groups.try_emplace(hdlFile, state, hdlFile).first->second;
996 fileEmitter.modules.push_back(module);
997 state.moduleNames[module] =
998 legalizeName(module->name.getValue(), state.objectNamespace);
1003 files.reserve(groups.size());
1004 for (
auto &[hdlFile, emitter] : groups) {
1005 emitter.outputFileName = options.outputDirectory;
1006 StringRef fileName = hdlFile ? hdlFile.getValue() :
"global";
1007 if (llvm::sys::path::is_absolute(fileName))
1008 emitter.outputFileName = fileName;
1011 llvm::sys::path::replace_extension(emitter.outputFileName,
"dd");
1012 llvm::sys::path::remove_dots(emitter.outputFileName,
true);
1013 files.push_back(std::move(emitter));
1018 llvm::dbgs() <<
"HGLDD files:\n";
1019 for (
auto &emitter : files) {
1020 llvm::dbgs() <<
"- " << emitter.outputFileName <<
" (from "
1021 << emitter.hdlFile <<
")\n";
1022 for (
auto *module : emitter.modules)
1023 llvm::dbgs() <<
" - " << module->name <<
"\n";
1034 Emitter emitter(module, options);
1035 for (
auto &fileEmitter : emitter.files) {
1036 os <<
"\n// ----- 8< ----- FILE \"" + fileEmitter.outputFileName +
1037 "\" ----- 8< -----\n\n";
1038 fileEmitter.emit(os);
1045 Emitter emitter(module, options);
1047 auto emit = [&](
auto &fileEmitter) {
1049 std::string errorMessage;
1051 mlir::openOutputFile(fileEmitter.outputFileName, &errorMessage);
1053 module->emitError(errorMessage);
1058 fileEmitter.emit(output->os());
1063 return mlir::failableParallelForEach(module->getContext(), emitter.files,
assert(baseType &&"element must be base type")
static void emitDims(ArrayRef< Attribute > dims, raw_ostream &os, Location loc, ModuleEmitter &emitter)
Emit a list of packed dimensions.
StringAttr getVerilogInstanceName(DIInstance &inst)
llvm::json::OStream JOStream
static void findLocations(Location loc, unsigned level, SmallVectorImpl< FileLineColLoc > &locs)
Walk the given loc and collect file-line-column locations that we want to report as source ("HGL") lo...
StringAttr getVerilogModuleName(DIModule &module)
static bool makePathRelative(StringRef path, StringRef relativeTo, SmallVectorImpl< char > &relativePath)
Make the given path relative to the relativeTo path and store the result in relativePath.
static FileLineColLoc findBestLocation(Location loc, bool emitted, bool fileMustExist)
Find the best location to report as source location ("HGL", emitted = false) or as emitted location (...
static StringRef legalizeName(StringRef name, llvm::StringMap< size_t > &nextGeneratedNameIDs)
Legalize the given name such that it only consists of valid identifier characters in Verilog and does...
llvm::json::Object JObject
static LogicalResult emit(SolverOp solver, const SMTEmissionOptions &options, mlir::raw_indented_ostream &stream)
Emit the SMT operations in the given 'solver' to the 'stream'.
static StringAttr append(StringAttr base, const Twine &suffix)
Return a attribute with the specified suffix appended.
FileEmitter(VerilogEmitterState &state)
void emit(emit::FileOp op)
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
LogicalResult emitHGLDD(Operation *module, llvm::raw_ostream &os, const EmitHGLDDOptions &options={})
Serialize the debug information in the given module into the HGLDD format and writes it to output.
LogicalResult emitSplitHGLDD(Operation *module, const EmitHGLDDOptions &options={})
Serialize the debug information in the given module into the HGLDD format and emit one companion HGLD...
llvm::raw_ostream & operator<<(llvm::raw_ostream &os, const InstanceInfo::LatticeValue &value)
std::optional< int64_t > getBitWidth(FIRRTLBaseType type, bool ignoreFlip=false)
bool isHWIntegerType(mlir::Type type)
Return true if the specified type is a value HW Integer type.
mlir::Type getCanonicalType(mlir::Type type)
evaluator::ObjectValue Object
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
llvm::hash_code hash_value(const T &e)
Operation * op
The operation that generated this instance.
StringAttr name
The name of this instance.
DIModule * module
The instantiated module.
bool isInline
If this is an inline scope created by a dbg.scope operation.
Operation * op
The operation that generated this level of hierarchy.
SmallVector< DIInstance *, 0 > instances
Levels of hierarchy nested under this module.
SmallVector< DIVariable *, 0 > variables
Variables declared within this module.
bool isExtern
If this is an extern declaration.
StringAttr name
The name of this level of hierarchy.
Value value
The SSA value representing the value of this variable.
StringAttr name
The name of this variable.
LocationAttr loc
The location of the variable's declaration.
Debug information attached to an operation and the operations nested within.
Options for HGLDD emission.
static unsigned getHashValue(const JValue &x)
static bool isEqual(const JValue &a, const JValue &b)
static JValue getEmptyKey()
static JValue getTombstoneKey()