18#include "mlir/Support/FileUtilities.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/ADT/TypeSwitch.h"
21#include "llvm/Support/ToolOutputFile.h"
22#include "llvm/Support/raw_ostream.h"
27#define GEN_PASS_DEF_EMITRTGISAASSEMBLYPASS
28#include "circt/Dialect/RTG/Transforms/RTGPasses.h.inc"
35#define DEBUG_TYPE "emit-rtg-isa-assembly"
41 Emitter(llvm::raw_ostream &os,
const DenseSet<StringAttr> &unsupportedInstr)
42 : os(os), unsupportedInstr(unsupportedInstr) {}
44 LogicalResult
emitFile(emit::FileOp fileOp) {
45 for (
auto &op : *fileOp.getBody()) {
46 if (op.hasTrait<OpTrait::ConstantLike>()) {
47 SmallVector<OpFoldResult> results;
48 if (failed(op.fold(results)))
51 for (
auto [val, res] : llvm::zip(op.getResults(), results)) {
52 auto attr = res.dyn_cast<Attribute>();
63 TypeSwitch<Operation *, LogicalResult>(&op)
64 .Case<InstructionOpInterface, LabelDeclOp, LabelOp, CommentOp>(
65 [&](
auto op) {
return emit(op); })
66 .Default([](
auto op) {
67 return op->emitError(
"emitter unknown RTG operation");
79 LogicalResult
emit(InstructionOpInterface instr) {
80 os << llvm::indent(4);
82 unsupportedInstr.contains(instr->getName().getIdentifier());
89 SmallVector<Attribute> operands;
90 for (
auto operand : instr->getOperands()) {
91 if (isa<LabelType>(operand.getType()) && useBinary)
92 return instr->emitError(
"labels cannot be emitted as binary");
94 auto attr = state.lookup(operand);
98 operands.push_back(attr);
101 instr.printInstructionAssembly(os, operands);
107 os << llvm::indent(4);
110 instr.printInstructionBinary(os, operands);
116 LogicalResult
emit(LabelDeclOp op) {
117 if (!op.getArgs().empty())
118 return op->emitError(
119 "label arguments must be elaborated before emission");
121 state[op.getLabel()] = op.getFormatStringAttr();
125 LogicalResult
emit(LabelOp op) {
126 auto labelStr = cast<StringAttr>(state[op.getLabel()]).getValue();
127 if (op.getVisibility() == LabelVisibility::external) {
128 os <<
".extern " << labelStr <<
"\n";
132 if (op.getVisibility() == LabelVisibility::global)
133 os <<
".global " << labelStr <<
"\n";
135 os << labelStr <<
":\n";
139 LogicalResult
emit(CommentOp op) {
140 os << llvm::indent(4) <<
"# " << op.getComment() <<
"\n";
146 llvm::raw_ostream &os;
149 const DenseSet<StringAttr> &unsupportedInstr;
152 DenseMap<Value, Attribute> state;
159 const std::string &unsupportedInstructionsFile,
160 DenseSet<StringAttr> &unsupportedInstrs) {
161 if (!unsupportedInstructionsFile.empty()) {
162 std::ifstream input(unsupportedInstructionsFile, std::ios::in);
164 while (std::getline(input, token,
',')) {
165 auto trimmed = StringRef(token).trim();
166 if (!trimmed.empty())
167 unsupportedInstrs.insert(StringAttr::get(ctxt, trimmed));
177struct EmitRTGISAAssemblyPass
178 :
public rtg::impl::EmitRTGISAAssemblyPassBase<EmitRTGISAAssemblyPass> {
180 void runOnOperation()
override;
184void EmitRTGISAAssemblyPass::runOnOperation() {
186 DenseSet<StringAttr> unsupportedInstr;
187 for (
const auto &instr : unsupportedInstructions)
188 unsupportedInstr.insert(StringAttr::
get(&getContext(), instr));
190 &getContext(), unsupportedInstructionsFile.getValue(), unsupportedInstr);
193 auto filename = getOperation().getFileName();
194 std::unique_ptr<llvm::ToolOutputFile> file;
195 bool emitToFile = !filename.empty() && filename !=
"-";
198 [&]() {
return getOperation().emitError(); });
200 return signalPassFailure();
205 Emitter emitter(emitToFile ? file->os()
208 if (failed(emitter.emitFile(getOperation())))
209 return signalPassFailure();
static void parseUnsupportedInstructionsFile(MLIRContext *ctxt, const std::string &unsupportedInstructionsFile, DenseSet< StringAttr > &unsupportedInstrs)
static LogicalResult emitFile(ArrayRef< Operation * > operations, StringRef filePath, raw_ostream &os)
Emits the given operation to a file represented by the passed ostream and file-path.
static InstancePath empty
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
std::unique_ptr< llvm::ToolOutputFile > createOutputFile(StringRef filename, StringRef dirname, function_ref< InFlightDiagnostic()> emitError)
Creates an output file with the given filename in the specified directory.