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"
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"))
108 SmallString<128> buffer;
109 llvm::raw_svector_ostream(buffer) << x;
122 SmallVectorImpl<char> &relativePath) {
123 using namespace llvm::sys;
124 auto sourceIt = path::begin(path);
125 auto outputIt = path::begin(relativeTo);
126 auto sourceEnd = path::end(path);
127 auto outputEnd = path::end(relativeTo);
134 while (outputIt != outputEnd && sourceIt != sourceEnd &&
135 *outputIt == *sourceIt) {
149 for (; outputIt != outputEnd && *outputIt !=
".."; ++outputIt)
150 path::append(relativePath,
"..");
151 for (; sourceIt != sourceEnd; ++sourceIt)
152 path::append(relativePath, *sourceIt);
158 return outputIt == outputEnd;
171 llvm::StringMap<size_t> &nextGeneratedNameIDs) {
172 return sv::legalizeName(name, nextGeneratedNameIDs,
true);
188 const EmitHGLDDOptions &options;
197 llvm::StringMap<size_t> objectNamespace;
199 GlobalState(Operation *op,
const EmitHGLDDOptions &options)
200 : op(op), options(options), di(op) {
209 SmallVector<int64_t, 1> packedDims;
210 SmallVector<int64_t, 1> unpackedDims;
212 EmittedType() =
default;
213 EmittedType(StringRef name) : name(name) {}
214 EmittedType(Type type) {
215 type = hw::getCanonicalType(type);
216 if (
auto inoutType = dyn_cast<hw::InOutType>(type))
217 type = hw::getCanonicalType(inoutType.getElementType());
218 if (hw::isHWIntegerType(type)) {
220 addPackedDim(hw::getBitWidth(type));
224 void addPackedDim(int64_t dim) { packedDims.push_back(dim); }
225 void addUnpackedDim(int64_t dim) { unpackedDims.push_back(dim); }
227 operator bool()
const {
return !name.empty(); }
229 static JArray emitDims(ArrayRef<int64_t> dims,
bool skipFirstLen1Dim) {
231 if (skipFirstLen1Dim && !dims.empty() && dims[0] == 1)
232 dims = dims.drop_front();
233 for (
auto dim :
llvm::reverse(dims)) {
234 json.push_back(dim - 1);
239 JArray emitPackedDims()
const {
return emitDims(packedDims,
true); }
240 JArray emitUnpackedDims()
const {
return emitDims(unpackedDims,
false); }
247 operator bool()
const {
return expr !=
nullptr && type; }
250[[maybe_unused]]
static llvm::raw_ostream &
operator<<(llvm::raw_ostream &os,
251 const EmittedType &type) {
253 return os <<
"<null>";
255 for (
auto dim : type.packedDims)
256 os <<
'[' << dim <<
']';
257 if (!type.unpackedDims.empty()) {
259 for (
auto dim : type.unpackedDims)
260 os <<
'[' << dim <<
']';
265[[maybe_unused]]
static llvm::raw_ostream &
operator<<(llvm::raw_ostream &os,
266 const EmittedExpr &expr) {
268 return os <<
"<null>";
269 return os << expr.expr <<
" : " << expr.type;
276 FileEmitter(GlobalState &state, StringAttr hdlFile)
277 : state(state), hdlFile(hdlFile) {}
280 SmallVector<DIModule *> modules;
282 SmallString<64> outputFileName;
284 llvm::StringMap<size_t> moduleNamespace;
287 SmallString<128> structNameHint;
289 void emit(llvm::raw_ostream &os);
291 JValue emitLoc(FileLineColLoc loc, FileLineColLoc endLoc,
bool emitted);
296 EmittedExpr emitExpression(Value value);
298 unsigned getSourceFile(StringAttr sourceFile,
bool emitted);
301 return ::findBestLocation(loc, emitted, state.options.onlyExistingFileLocs);
306 void findAndEmitLoc(
JOStream &
json, StringRef fieldName, Location loc,
309 json.attribute(fieldName, emitLoc(fileLoc, {}, emitted));
315 void findAndEmitLocOrGuess(
JOStream &
json, StringRef fieldName, Operation *op,
318 json.attribute(fieldName, emitLoc(fileLoc, {}, emitted));
327 op->walk([&](Operation *subop) {
330 locsByFile[fileLoc.getFilename()].first.push_back(fileLoc);
333 for (
auto ®ion : subop->getRegions())
334 for (auto &block : region)
335 for (auto arg : block.getArguments())
337 locsByFile[fileLoc.getFilename()].first.push_back(fileLoc);
341 for (
auto ®ion : op->getRegions())
342 for (auto &block : region)
343 for (auto arg : block.getArguments())
345 locsByFile[fileLoc.getFilename()].second += 10;
347 if (locsByFile.empty())
351 llvm::sort(locsByFile, [](
auto &a,
auto &b) {
352 return (a.second.first.size() + a.second.second) >
353 (b.second.first.size() + a.second.second);
356 auto &locs = locsByFile.front().second.first;
357 llvm::sort(locs, [](
auto &a,
auto &b) {
358 if (a.getLine() < b.getLine())
360 if (a.getLine() > b.getLine())
362 if (a.getColumn() < b.getColumn())
367 json.attribute(fieldName, emitLoc(locs.front(), locs.back(), emitted));
372 void findAndSetLocs(
JObject &into, Location loc) {
374 into[
"hgl_loc"] = emitLoc(fileLoc, {},
false);
376 into[
"hdl_loc"] = emitLoc(fileLoc, {},
true);
381 StringRef getModuleName(
DIModule *module) {
382 auto name = state.moduleNames.lookup(module);
384 "moduleNames should contain a name for every module");
388 StringRef legalizeInModuleNamespace(StringRef name) {
397unsigned FileEmitter::getSourceFile(StringAttr sourceFile,
bool emitted) {
398 using namespace llvm::sys;
403 auto &slot = sourceFiles[sourceFile];
406 slot.second = sourceFiles.size();
409 if (path::is_absolute(sourceFile.getValue())) {
410 slot.first = sourceFile;
417 StringRef filePrefix =
418 emitted ? state.options.outputFilePrefix : state.options.sourceFilePrefix;
419 if (!filePrefix.empty()) {
420 SmallString<64> buffer = filePrefix;
421 path::append(buffer, sourceFile.getValue());
422 slot.first = StringAttr::get(sourceFile.getContext(), buffer);
431 SmallString<64> sourcePath = sourceFile.getValue();
432 path::remove_dots(sourcePath,
true);
436 StringRef relativeToDir = path::parent_path(outputFileName);
437 if (!path::is_absolute(outputFileName)) {
438 SmallString<64> buffer;
440 slot.first = StringAttr::get(sourceFile.getContext(), buffer);
451 SmallString<64> outputPath = relativeToDir;
452 fs::make_absolute(sourcePath);
453 fs::make_absolute(outputPath);
454 if (path::is_absolute(sourcePath) && path::is_absolute(outputPath)) {
455 auto firstSourceComponent = *path::begin(path::relative_path(sourcePath));
456 auto firstOutputComponent = *path::begin(path::relative_path(outputPath));
457 if (firstSourceComponent == firstOutputComponent) {
458 SmallString<64> buffer;
460 slot.first = StringAttr::get(sourceFile.getContext(), buffer);
467 slot.first = StringAttr::get(sourceFile.getContext(), sourcePath);
481 SmallVector<std::string, 16> rawObjects;
482 for (
auto *module : modules) {
483 llvm::raw_string_ostream objectOS(rawObjects.emplace_back());
485 objectJson.arrayBegin();
486 objectJson.arrayBegin();
487 emitModule(objectJson, module);
488 objectJson.arrayEnd();
489 objectJson.arrayEnd();
492 std::optional<unsigned> hdlFileIndex;
494 hdlFileIndex = getSourceFile(hdlFile,
true);
497 json.attributeObject(
"HGLDD", [&] {
498 json.attribute(
"version",
"1.0");
499 json.attributeArray(
"file_info", [&] {
500 for (
auto [key, fileAndId] : sourceFiles)
501 json.value(fileAndId.first.getValue());
504 json.attribute(
"hdl_file_index", *hdlFileIndex);
506 json.attributeArray(
"objects", [&] {
507 for (
auto &[structDef, name] : structDefs)
508 json.value(structDef);
509 for (
auto &rawObject : rawObjects) {
520 json.rawValue(StringRef(rawObject)
532JValue FileEmitter::emitLoc(FileLineColLoc loc, FileLineColLoc endLoc,
535 obj[
"file"] = getSourceFile(loc.getFilename(), emitted);
537 obj[
"begin_line"] = loc.getLine();
538 obj[
"end_line"] = loc.getLine();
540 if (loc.getColumn()) {
541 obj[
"begin_column"] = loc.getColumn();
542 obj[
"end_column"] = loc.getColumn();
545 if (endLoc.getLine())
546 obj[
"end_line"] = endLoc.getLine();
547 if (endLoc.getColumn())
548 obj[
"end_column"] = endLoc.getColumn();
554 if (
auto *op = module.
op)
555 if (
auto attr = op->getAttrOfType<StringAttr>(
"verilogName"))
561 if (
auto *op = inst.
op)
562 if (
auto attr = op->getAttrOfType<StringAttr>(
"hw.verilogName"))
569 moduleNamespace = state.objectNamespace;
570 structNameHint =
module->name.getValue();
572 json.attribute(
"kind",
"module");
573 json.attribute(
"obj_name", getModuleName(module));
574 json.attribute(
"module_name",
577 json.attribute(
"isExtModule", 1);
578 if (
auto *op = module->
op) {
579 findAndEmitLocOrGuess(
json,
"hgl_loc", op,
false);
580 findAndEmitLoc(
json,
"hdl_loc", op->getLoc(),
true);
582 emitModuleBody(
json, module);
588 json.attributeArray(
"port_vars", [&] {
589 for (
auto *var : module->variables)
590 emitVariable(
json, var);
592 json.attributeArray(
"children", [&] {
593 for (
auto *instance : module->instances)
594 emitInstance(
json, instance);
603 auto instanceName = legalizeInModuleNamespace(instance->
name.getValue());
604 json.attribute(
"name", instanceName);
605 if (!instance->module->isInline) {
607 if (verilogName != instanceName)
608 json.attribute(
"hdl_obj_name", verilogName.getValue());
610 json.attribute(
"obj_name",
611 getModuleName(instance->module));
612 json.attribute(
"module_name",
616 if (
auto *op = instance->
op) {
617 findAndEmitLoc(
json,
"hgl_loc", op->getLoc(),
false);
618 findAndEmitLoc(
json,
"hdl_loc", op->getLoc(),
true);
622 if (instance->module->isInline) {
623 auto structNameHintLen = structNameHint.size();
624 if (!instance->module->
name.empty()) {
625 structNameHint +=
'_';
626 structNameHint += instance->module->
name.getValue();
627 }
else if (!instance->
name.empty()) {
628 structNameHint +=
'_';
629 structNameHint += instanceName;
631 emitModuleBody(
json, instance->module);
632 structNameHint.resize(structNameHintLen);
641 auto variableName = legalizeInModuleNamespace(variable->
name.getValue());
642 json.attribute(
"var_name", variableName);
643 findAndEmitLoc(
json,
"hgl_loc", variable->
loc,
false);
644 findAndEmitLoc(
json,
"hdl_loc", variable->
loc,
true);
647 if (
auto value = variable->
value) {
648 auto structNameHintLen = structNameHint.size();
649 structNameHint +=
'_';
650 structNameHint += variableName;
651 emitted = emitExpression(value);
652 structNameHint.resize(structNameHintLen);
655 LLVM_DEBUG(llvm::dbgs() <<
"- " << variable->
name <<
": " << emitted <<
"\n");
657 json.attributeBegin(
"value");
658 json.rawValue([&](
auto &os) { os << emitted.expr; });
660 json.attribute(
"type_name", emitted.type.name);
661 if (
auto dims = emitted.type.emitPackedDims(); !dims.empty())
662 json.attribute(
"packed_range", std::move(dims));
663 if (
auto dims = emitted.type.emitUnpackedDims(); !dims.empty())
664 json.attribute(
"unpacked_range", std::move(dims));
671EmittedExpr FileEmitter::emitExpression(Value value) {
674 auto hglddSigName = [](StringRef sigName) ->
JObject {
675 return JObject{{
"sig_name", sigName}};
677 auto hglddOperator = [](StringRef opcode,
JValue args) ->
JObject {
680 {
"operands", std::move(args)},
683 auto hglddInt32 = [](uint32_t value) ->
JObject {
684 return JObject({{
"integer_num", value}});
687 if (
auto blockArg = dyn_cast<BlockArgument>(value)) {
688 auto module = dyn_cast<hw::HWModuleOp>(blockArg.getOwner()->getParentOp());
691 auto name =
module.getInputNameAttr(blockArg.getArgNumber());
694 return {hglddSigName(name), value.getType()};
697 auto result = cast<OpResult>(value);
698 auto *op = result.getOwner();
701 if (isa<hw::WireOp, sv::WireOp, sv::RegOp, sv::LogicOp>(op)) {
702 auto name = op->getAttrOfType<StringAttr>(
"hw.verilogName");
703 if (!name || name.empty())
704 name = op->getAttrOfType<StringAttr>(
"name");
705 if (name && !name.empty())
706 return {hglddSigName(name), result.getType()};
710 if (
auto constOp = dyn_cast<hw::ConstantOp>(op)) {
712 auto type = constOp.getType();
713 auto width = hw::getBitWidth(type);
719 return {
JObject({{
"bit_vector",
"0"}}),
720 IntegerType::get(op->getContext(), 1)};
723 SmallString<64> buffer;
724 buffer.reserve(width);
725 constOp.getValue().toStringUnsigned(buffer, 2);
730 std::reverse(buffer.begin(), buffer.end());
731 while (buffer.size() < (
size_t)width)
733 std::reverse(buffer.begin(), buffer.end());
734 assert(buffer.size() == (
size_t)width);
736 return {
JObject({{
"bit_vector", buffer}}), type};
741 if (
auto structOp = dyn_cast<debug::StructOp>(op)) {
743 auto structNameHintLen = structNameHint.size();
744 std::vector<JValue> values;
745 SmallVector<std::tuple<EmittedType, StringAttr, Location>> types;
746 for (
auto [nameAttr, field] :
747 llvm::zip(structOp.getNamesAttr(), structOp.getFields())) {
748 auto name = cast<StringAttr>(nameAttr);
749 structNameHint +=
'_';
750 structNameHint += name.getValue();
751 if (
auto value = emitExpression(field)) {
752 values.push_back(value.expr);
753 types.push_back({value.type, name, field.getLoc()});
755 structNameHint.resize(structNameHintLen);
760 return {hglddInt32(0), EmittedType(
"bit")};
764 llvm::StringMap<size_t> structNamespace;
765 for (
auto [type, name, loc] : types) {
767 fieldDef[
"var_name"] =
768 std::string(
legalizeName(name.getValue(), structNamespace));
769 fieldDef[
"type_name"] = type.name;
770 if (
auto dims = type.emitPackedDims(); !dims.empty())
771 fieldDef[
"packed_range"] = std::move(dims);
772 if (
auto dims = type.emitUnpackedDims(); !dims.empty())
773 fieldDef[
"unpacked_range"] = std::move(dims);
774 findAndSetLocs(fieldDef, loc);
775 fieldDefs.push_back(std::move(fieldDef));
777 auto structName =
legalizeName(structNameHint, state.objectNamespace);
779 structDef[
"kind"] =
"struct";
780 structDef[
"obj_name"] = structName;
781 structDef[
"port_vars"] = std::move(fieldDefs);
782 findAndSetLocs(structDef, structOp.getLoc());
784 StringRef structNameFinal =
785 structDefs.insert({std::move(structDef), structName}).first->second;
787 return {hglddOperator(
"'{", values), EmittedType(structNameFinal)};
791 if (
auto arrayOp = dyn_cast<debug::ArrayOp>(op)) {
792 std::vector<JValue> values;
794 for (
auto element : arrayOp.getElements()) {
795 if (
auto value = emitExpression(element)) {
796 values.push_back(value.expr);
797 if (type && type != value.type)
805 return {hglddInt32(0), EmittedType(
"bit")};
807 type.addUnpackedDim(values.size());
808 return {hglddOperator(
"'{", values), type};
812 if (
auto readOp = dyn_cast<sv::ReadInOutOp>(op))
813 return emitExpression(readOp.getInput());
817 StringRef unaryOpcode = TypeSwitch<Operation *, StringRef>(op)
819 .Default([](
auto) {
return ""; });
820 if (!unaryOpcode.empty() && op->getNumOperands() == 1) {
821 auto arg = emitExpression(op->getOperand(0));
824 return {hglddOperator(unaryOpcode,
JArray{arg.expr}), result.getType()};
827 StringRef binaryOpcode =
828 TypeSwitch<Operation *, StringRef>(op)
830 .Case<comb::OrOp>([](
auto) {
return "|"; })
831 .Case<comb::XorOp>([](
auto) {
return "^"; })
832 .Case<comb::AddOp>([](
auto) {
return "+"; })
833 .Case<comb::SubOp>([](
auto) {
return "-"; })
834 .Case<comb::MulOp>([](
auto) {
return "*"; })
835 .Case<comb::DivUOp, comb::DivSOp>([](
auto) {
return "/"; })
836 .Case<comb::ModUOp, comb::ModSOp>([](
auto) {
return "%"; })
837 .Case<comb::ShlOp>([](
auto) {
return "<<"; })
838 .Case<comb::ShrUOp>([](
auto) {
return ">>"; })
839 .Case<comb::ShrSOp>([](
auto) {
return ">>>"; })
840 .Case<comb::ICmpOp>([](
auto cmpOp) -> StringRef {
841 switch (cmpOp.getPredicate()) {
842 case comb::ICmpPredicate::eq:
844 case comb::ICmpPredicate::ne:
846 case comb::ICmpPredicate::ceq:
848 case comb::ICmpPredicate::cne:
850 case comb::ICmpPredicate::weq:
852 case comb::ICmpPredicate::wne:
854 case comb::ICmpPredicate::ult:
855 case comb::ICmpPredicate::slt:
857 case comb::ICmpPredicate::ugt:
858 case comb::ICmpPredicate::sgt:
860 case comb::ICmpPredicate::ule:
861 case comb::ICmpPredicate::sle:
863 case comb::ICmpPredicate::uge:
864 case comb::ICmpPredicate::sge:
869 .Default([](
auto) {
return ""; });
870 if (!binaryOpcode.empty()) {
871 if (op->getNumOperands() != 2) {
872 op->emitOpError(
"must have two operands for HGLDD emission");
875 auto lhs = emitExpression(op->getOperand(0));
876 auto rhs = emitExpression(op->getOperand(1));
879 return {hglddOperator(binaryOpcode, {lhs.expr, rhs.expr}),
884 if (
auto concatOp = dyn_cast<comb::ConcatOp>(op)) {
885 std::vector<JValue> args;
886 for (
auto operand : concatOp.getOperands()) {
887 auto value = emitExpression(operand);
890 args.push_back(value.expr);
892 return {hglddOperator(
"{}", args), concatOp.getType()};
896 if (
auto replicateOp = dyn_cast<comb::ReplicateOp>(op)) {
897 auto arg = emitExpression(replicateOp.getInput());
900 return {hglddOperator(
"R{}",
902 hglddInt32(replicateOp.getMultiple()),
905 replicateOp.getType()};
909 if (
auto extractOp = dyn_cast<comb::ExtractOp>(op)) {
910 auto arg = emitExpression(extractOp.getInput());
913 auto lowBit = extractOp.getLowBit();
914 auto highBit = lowBit + extractOp.getType().getIntOrFloatBitWidth() - 1;
915 return {hglddOperator(
"[]",
921 extractOp.getType()};
925 if (
auto muxOp = dyn_cast<comb::MuxOp>(op)) {
926 auto cond = emitExpression(muxOp.getCond());
927 auto lhs = emitExpression(muxOp.getTrueValue());
928 auto rhs = emitExpression(muxOp.getFalseValue());
929 if (!cond || !lhs || !rhs)
931 return {hglddOperator(
"?:", {cond.expr, lhs.expr, rhs.expr}),
940 for (
auto &use : result.getUses()) {
941 auto *user = use.getOwner();
943 if (
auto wireOp = dyn_cast<hw::WireOp>(user))
944 if (wireOp.getInput() == result)
945 return emitExpression(wireOp);
947 if (
auto assignOp = dyn_cast<sv::AssignOp>(user))
948 if (assignOp.getSrc() == result)
949 return emitExpression(assignOp.getDest());
951 if (isa<hw::OutputOp>(user)) {
952 auto mod = cast<hw::HWModuleLike>(user->getParentOp());
953 auto portName = mod.getPort(mod.getHWModuleType().getPortIdForOutputId(
954 use.getOperandNumber()))
956 return {hglddSigName(portName), result.getType()};
974 SmallVector<FileEmitter, 0> files;
975 Emitter(Operation *module,
const EmitHGLDDOptions &options);
980Emitter::Emitter(Operation *module,
const EmitHGLDDOptions &options)
981 : state(module, options) {
987 for (
auto [moduleName, module] : state.di.moduleNodes) {
991 hdlFile = fileLoc.getFilename();
993 groups.try_emplace(hdlFile, state, hdlFile).first->second;
994 fileEmitter.modules.push_back(module);
995 state.moduleNames[module] =
996 legalizeName(module->name.getValue(), state.objectNamespace);
1001 files.reserve(groups.size());
1002 for (
auto &[hdlFile, emitter] : groups) {
1003 emitter.outputFileName = options.outputDirectory;
1004 StringRef fileName = hdlFile ? hdlFile.getValue() :
"global";
1005 if (llvm::sys::path::is_absolute(fileName))
1006 emitter.outputFileName = fileName;
1008 llvm::sys::path::append(emitter.outputFileName, fileName);
1009 llvm::sys::path::replace_extension(emitter.outputFileName,
"dd");
1010 llvm::sys::path::remove_dots(emitter.outputFileName,
true);
1011 files.push_back(std::move(emitter));
1016 llvm::dbgs() <<
"HGLDD files:\n";
1017 for (
auto &emitter : files) {
1018 llvm::dbgs() <<
"- " << emitter.outputFileName <<
" (from "
1019 << emitter.hdlFile <<
")\n";
1020 for (
auto *module : emitter.modules)
1021 llvm::dbgs() <<
" - " << module->name <<
"\n";
1030LogicalResult debug::emitHGLDD(Operation *module, llvm::raw_ostream &os,
1032 Emitter emitter(module, options);
1033 for (
auto &fileEmitter : emitter.files) {
1034 os <<
"\n// ----- 8< ----- FILE \"" + fileEmitter.outputFileName +
1035 "\" ----- 8< -----\n\n";
1036 fileEmitter.emit(os);
1041LogicalResult debug::emitSplitHGLDD(Operation *module,
1043 Emitter emitter(module, options);
1045 auto emit = [&](
auto &fileEmitter) {
1047 std::string errorMessage;
1049 mlir::openOutputFile(fileEmitter.outputFileName, &errorMessage);
1051 module->emitError(errorMessage);
1056 fileEmitter.emit(output->os());
1061 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...
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 Location getLoc(DefSlot slot)
void emit(emit::FileOp op)
void addDefinitions(mlir::Operation *top)
Populate the symbol cache with all symbol-defining operations within the 'top' operation.
This stores lookup tables to make manipulating and working with the IR more efficient.
void freeze()
Mark the cache as frozen, which allows it to be shared across threads.
StringRef getVerilogModuleName(Operation *module)
OS & operator<<(OS &os, const InnerSymTarget &target)
Printing InnerSymTarget's.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
llvm::hash_code hash_value(const DenseSet< T > &set)
Operation * op
The operation that generated this instance.
StringAttr name
The name of this instance.
Operation * op
The operation that generated this level of hierarchy.
bool isExtern
If this is an extern declaration.
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)