31 MatchResult matchInlinable(Value value)
override {
32 if (isa<BlockArgument>(value) &&
33 value.getParentRegion()->getParentOfType<SCModuleOp>())
34 return Precedence::VAR;
38 void emitInlined(Value value, EmissionPrinter &p)
override {
39 auto module = value.getParentRegion()->getParentOfType<SCModuleOp>();
40 for (
size_t i = 0, e = module.getNumArguments(); i < e; ++i) {
41 if (module.getArgument(i) == value) {
42 p << cast<StringAttr>(module.getPortNames()[i]).getValue();
48 void emitStatement(SCModuleOp module, EmissionPrinter &p)
override {
51 p <<
"\nSC_MODULE(" << module.getModuleName() <<
") ";
52 auto scope = p.
getOstream().scope(
"{\n",
"};\n");
53 for (
size_t i = 0, e = module.getNumArguments(); i < e; ++i) {
54 p.
emitType(module.getArgument(i).getType());
56 auto portName = cast<StringAttr>(module.getPortNames()[i]).getValue();
57 p <<
" " << portName <<
";\n";
69 void emitStatement(SignalWriteOp op, EmissionPrinter &p)
override {
82 MatchResult matchInlinable(Value value)
override {
83 if (value.getDefiningOp<SignalReadOp>())
84 return Precedence::FUNCTION_CALL;
88 void emitInlined(Value value, EmissionPrinter &p)
override {
98 MatchResult matchInlinable(Value value)
override {
99 if (value.getDefiningOp<NewOp>())
100 return Precedence::NEW;
104 void emitInlined(Value value, EmissionPrinter &p)
override {
106 p.
emitType(cast<mlir::emitc::PointerType>(value.getType()).getPointee());
108 auto newOp = value.getDefiningOp<NewOp>();
109 if (newOp.getArgs().empty())
113 llvm::interleaveComma(newOp.getArgs(), p, [&](Value arg) {
114 p.getInlinable(arg).emitWithParensOnLowerPrecedence(Precedence::COMMA);
124 void emitStatement(CtorOp op, EmissionPrinter &p)
override {
127 p <<
"\nSC_CTOR(" << op->getParentOfType<SCModuleOp>().getModuleName()
137 void emitStatement(DestructorOp op, EmissionPrinter &p)
override {
144 p <<
"\n~" << op->getParentOfType<SCModuleOp>().getModuleName()
154 MatchResult matchInlinable(Value value)
override {
155 if (value.getDefiningOp<SCFuncOp>())
156 return Precedence::VAR;
160 void emitInlined(Value value, EmissionPrinter &p)
override {
161 p << value.getDefiningOp<SCFuncOp>().
getName();
164 void emitStatement(SCFuncOp op, EmissionPrinter &p)
override {
167 p <<
"\nvoid " << op.getName() <<
"() ";
176 void emitStatement(MethodOp op, EmissionPrinter &p)
override {
187 void emitStatement(SensitiveOp op, EmissionPrinter &p)
override {
188 if (op.getSensitivities().empty())
191 p <<
"sensitive << ";
193 op.getSensitivities(), p,
194 [&](Value sensitive) {
195 p.getInlinable(sensitive).emitWithParensOnLowerPrecedence(
207 void emitStatement(ThreadOp op, EmissionPrinter &p)
override {
218 void emitStatement(DeleteOp op, EmissionPrinter &p)
override {
230 MatchResult matchInlinable(Value value)
override {
231 if (llvm::isa_and_nonnull<SignalOp>(value.getDefiningOp()))
232 return Precedence::VAR;
236 void emitInlined(Value value, EmissionPrinter &p)
override {
237 p << value.getDefiningOp<SignalOp>().
getName();
240 void emitStatement(SignalOp op, EmissionPrinter &p)
override {
241 p.
emitType(op.getSignal().getType());
247 p <<
"SC_NAMED(" << op.getName() <<
");\n";
251 p << op.getName() <<
";\n";
259 MatchResult matchInlinable(Value value)
override {
260 if (value.getDefiningOp<InstanceDeclOp>())
261 return Precedence::VAR;
265 void emitInlined(Value value, EmissionPrinter &p)
override {
266 p << value.getDefiningOp<InstanceDeclOp>().
getName();
269 void emitStatement(InstanceDeclOp op, EmissionPrinter &p)
override {
271 p <<
" " << op.getName() <<
";\n";
285 p <<
"." << op.getPortName() <<
"(";
296 if (value.getDefiningOp<MemberAccessOp>())
302 auto op = value.getDefiningOp<MemberAccessOp>();
306 if (op.getAccessKind() == MemberAccessKind::Arrow)
308 else if (op.getAccessKind() == MemberAccessKind::Dot)
311 p.
emitError(op,
"member access kind not implemented");
313 p << op.getMemberName();
336 if (value.getDefiningOp<VariableOp>())
342 p << value.getDefiningOp<VariableOp>().getName();
346 p.
emitType(op.getVariable().getType());
347 p <<
" " << op.getName();
373 if (isa<BlockArgument>(value) &&
374 value.getParentRegion()->getParentOfType<FuncOp>())
381 auto func = value.getParentRegion()->getParentOfType<FuncOp>();
382 for (
auto [arg, name] :
383 llvm::zip(func.getArguments(), func.getArgNames())) {
385 p << cast<StringAttr>(name).getValue();
396 if (func.getExternC())
397 p <<
"extern \"C\" ";
400 if (func.getFunctionType().getNumResults() == 0)
403 p.
emitType(func.getFunctionType().getResult(0));
405 p <<
" " << func.getSymName() <<
"(";
409 if (func.isDeclaration() && func.getArgNames().empty())
410 llvm::interleaveComma(func.getFunctionType().getInputs(), p,
411 [&](Type ty) { p.emitType(ty); });
413 llvm::interleaveComma(
414 llvm::zip(func.getFunctionType().getInputs(), func.getArgNames()), p,
415 [&](std::tuple<Type, Attribute> arg) {
416 p.emitType(std::get<0>(arg));
417 p <<
" " << cast<StringAttr>(std::get<1>(arg)).getValue();
423 if (func.isDeclaration()) {
441 if (value.getDefiningOp<CallOp>())
447 printCall(value.getDefiningOp<CallOp>(), p);
453 if (op.getNumResults() > 0)
462 p << op.getCallee() <<
"(";
463 llvm::interleaveComma(op.getOperands(), p, [&](
auto arg) {
464 p.getInlinable(arg).emitWithParensOnLowerPrecedence(Precedence::COMMA);
479 if (value.getDefiningOp<CallIndirectOp>())
486 printCall(value.getDefiningOp<CallIndirectOp>(), p);
492 if (op.getNumResults() > 0)
504 llvm::interleaveComma(op.getCalleeOperands(), p, [&](
auto arg) {
505 p.getInlinable(arg).emitWithParensOnLowerPrecedence(Precedence::COMMA);
516 return isa<ReturnOp>(op) && cast<ReturnOp>(op)->getNumOperands() <= 1;
521 if (!op.getReturnValues().empty()) {
536template <
typename Ty, const
char Mn[]>
538 void emitType(Ty type, EmissionPrinter &p)
override {
548 void emitType(ModuleType type, EmissionPrinter &p)
override {
549 p << type.getModuleName().getValue();
555template <
typename Ty>
557 void emitType(Ty type, EmissionPrinter &p)
override {
558 p <<
"sc_" << Ty::getMnemonic() <<
"<" << type.getWidth() <<
">";
564template <
typename Ty>
566 void emitType(Ty type, EmissionPrinter &p)
override {
567 p <<
"sc_" << Ty::getMnemonic();
579 SCModuleEmitter, CtorEmitter, SCFuncEmitter, MethodEmitter, ThreadEmitter,
581 SignalWriteEmitter, SignalReadEmitter, SignalEmitter, SensitiveEmitter,
593 static constexpr const char in[] =
"sc_in";
594 static constexpr const char inout[] =
"sc_inout";
595 static constexpr const char out[] =
"sc_out";
596 static constexpr const char signal[] =
"sc_signal";
600 SignalTypeEmitter<InputType, in>, SignalTypeEmitter<InOutType, inout>,
601 SignalTypeEmitter<OutputType, out>, SignalTypeEmitter<SignalType, signal>,
603 IntegerTypeEmitter<IntType>, IntegerTypeEmitter<UIntType>,
604 IntegerTypeEmitter<BigIntType>, IntegerTypeEmitter<BigUIntType>,
606 DynIntegerTypeEmitter<IntBaseType>, DynIntegerTypeEmitter<UIntBaseType>,
607 DynIntegerTypeEmitter<SignedType>, DynIntegerTypeEmitter<UnsignedType>,
609 IntegerTypeEmitter<BitVectorType>, IntegerTypeEmitter<LogicVectorType>,
611 DynIntegerTypeEmitter<BitVectorBaseType>,
612 DynIntegerTypeEmitter<LogicVectorBaseType>,
614 DynIntegerTypeEmitter<LogicType>, ModuleTypeEmitter>();
static std::unique_ptr< Context > context
Emit a systemc.cpp.call operation.
OpEmissionPattern(MLIRContext *context)
void printCall(CallOp op, EmissionPrinter &p)
MatchResult matchInlinable(Value value) override
Checks if this pattern is applicable to the given value to emit an inlinable expression.
void emitInlined(Value value, EmissionPrinter &p) override
void emitStatement(CallOp op, EmissionPrinter &p) override
Emit a systemc.cpp.call_indirect operation.
OpEmissionPattern(MLIRContext *context)
MatchResult matchInlinable(Value value) override
Checks if this pattern is applicable to the given value to emit an inlinable expression.
void printCall(CallIndirectOp op, EmissionPrinter &p)
void emitInlined(Value value, EmissionPrinter &p) override
void emitStatement(CallIndirectOp op, EmissionPrinter &p) override
This is intended to be the driving class for all pattern-based IR emission.
void emitRegion(Region ®ion)
Emit the given region to the ostream associated with this printer.
mlir::raw_indented_ostream & getOstream() const
InlineEmitter getInlinable(Value value)
Emit the expression represented by the given value to the ostream associated with this printer accord...
void emitType(Type type)
Emit the given type to the ostream associated with this printer according to the emission patterns re...
InFlightDiagnostic emitError(Operation *op, const Twine &message)
Emit an error on the operation and fail emission.
void emitWithParensOnLowerPrecedence(Precedence prec, StringRef lParen="(", StringRef rParen=")") const
This class allows a pattern's match function for inlining to pass its result's precedence to the patt...
void populateSystemCOpEmitters(OpEmissionPatternSet &patterns, MLIRContext *context)
Register SystemC operation emission patterns.
void populateSystemCTypeEmitters(TypeEmissionPatternSet &patterns)
Register SystemC type emission patterns.
EmissionPatternSet< TypeEmissionPatternBase > TypeEmissionPatternSet
EmissionPatternSet< OpEmissionPatternBase > OpEmissionPatternSet
StringAttr getName(ArrayAttr names, size_t idx)
Return the name at the specified index of the ArrayAttr or null if it cannot be determined.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Emit a systemc.cpp.assign operation.
OpEmissionPattern(MLIRContext *context)
void emitStatement(AssignOp op, EmissionPrinter &p) override
Emit a systemc.instance.bind_port operation using the operator() rather than .bind() variant.
OpEmissionPattern(MLIRContext *context)
void emitStatement(BindPortOp op, EmissionPrinter &p) override
Emit a systemc.cpp.func function.
OpEmissionPattern(MLIRContext *context)
void emitInlined(Value value, EmissionPrinter &p) override
void emitStatement(FuncOp func, EmissionPrinter &p) override
MatchResult matchInlinable(Value value) override
Checks if this pattern is applicable to the given value to emit an inlinable expression.
Emit a systemc.cpp.member_access operation.
OpEmissionPattern(MLIRContext *context)
void emitInlined(Value value, EmissionPrinter &p) override
MatchResult matchInlinable(Value value) override
Checks if this pattern is applicable to the given value to emit an inlinable expression.
Emit a systemc.cpp.return operation.
OpEmissionPattern(MLIRContext *context)
void emitStatement(ReturnOp op, EmissionPrinter &p) override
bool matchStatement(Operation *op) override
Emit a systemc.cpp.variable operation.
OpEmissionPattern(MLIRContext *context)
void emitStatement(VariableOp op, EmissionPrinter &p) override
void emitInlined(Value value, EmissionPrinter &p) override
MatchResult matchInlinable(Value value) override
Checks if this pattern is applicable to the given value to emit an inlinable expression.
This is a convenience class providing default implementations for operation emission patterns.
OpEmissionPattern(MLIRContext *context)
This is a convenience class providing default implementations for type emission patterns.