CIRCT 20.0.0git
Loading...
Searching...
No Matches
circt_tcl.cpp
Go to the documentation of this file.
1#include <stdlib.h>
2#include <tcl.h>
3
8#include "mlir/CAPI/IR.h"
9#include "mlir/Parser/Parser.h"
10#include "mlir/Support/FileUtilities.h"
11#include "llvm/Support/SourceMgr.h"
12
13static int operationTypeSetFromAnyProc(Tcl_Interp *interp, Tcl_Obj *obj) {
14 return TCL_ERROR;
15}
16
17static void operationTypeUpdateStringProc(Tcl_Obj *obj) {
18 std::string str;
19 auto *op = unwrap(MlirOperation{obj->internalRep.otherValuePtr});
20 llvm::raw_string_ostream stream(str);
21 op->print(stream);
22 obj->length = str.length();
23 obj->bytes = Tcl_Alloc(obj->length);
24 memcpy(obj->bytes, str.c_str(), obj->length);
25 obj->bytes[obj->length] = '\0';
26}
27
28static void operationTypeDupIntRepProc(Tcl_Obj *src, Tcl_Obj *dup) {
29 auto *op = unwrap(MlirOperation{src->internalRep.otherValuePtr})->clone();
30 dup->internalRep.otherValuePtr = wrap(op).ptr;
31}
32
33static void operationTypeFreeIntRepProc(Tcl_Obj *obj) {
34 auto *op = unwrap(MlirOperation{obj->internalRep.otherValuePtr});
35 op->erase();
36}
37
38static int returnErrorStr(Tcl_Interp *interp, const char *error) {
39 Tcl_SetObjResult(interp, Tcl_NewStringObj(error, -1));
40 return TCL_ERROR;
41}
42
43static int loadFirMlirFile(mlir::MLIRContext *context, Tcl_Interp *interp,
44 int objc, Tcl_Obj *const objv[]) {
45 if (objc != 3) {
46 Tcl_WrongNumArgs(interp, objc, objv, "usage: circt load [MLIR|FIR] [file]");
47 return TCL_ERROR;
48 }
49
50 std::string errorMessage;
51 auto input = mlir::openInputFile(llvm::StringRef(Tcl_GetString(objv[2])),
52 &errorMessage);
53
54 if (!input)
55 return returnErrorStr(interp, errorMessage.c_str());
56
57 llvm::SourceMgr sourceMgr;
58 sourceMgr.AddNewSourceBuffer(std::move(input), llvm::SMLoc());
59 mlir::SourceMgrDiagnosticHandler sourceMgrHandler(sourceMgr, context);
60
61 MlirOperation module;
62 if (!strcmp(Tcl_GetString(objv[1]), "MLIR"))
63 module = wrap(mlir::parseSourceFile<mlir::ModuleOp>(sourceMgr, context)
64 .release()
65 .getOperation());
66 else if (!strcmp(Tcl_GetString(objv[1]), "FIR"))
67 // TODO
68 return returnErrorStr(interp, "loading FIR files is unimplemented :(");
69 else
70 return TCL_ERROR;
71
72 if (mlirOperationIsNull(module))
73 return returnErrorStr(interp, "error loading module");
74
75 auto *m = module.ptr;
76
77 auto *obj = Tcl_NewObj();
78 obj->typePtr = Tcl_GetObjType("MlirOperation");
79 obj->internalRep.otherValuePtr = (void *)m;
80 obj->length = 0;
81 obj->bytes = nullptr;
82 Tcl_SetObjResult(interp, obj);
83
84 return TCL_OK;
85}
86
87static int circtTclFunction(ClientData cdata, Tcl_Interp *interp, int objc,
88 Tcl_Obj *const objv[]) {
89 if (objc < 2) {
90 Tcl_WrongNumArgs(interp, objc, objv, "usage: circt load");
91 return TCL_ERROR;
92 }
93
94 auto *context = (mlir::MLIRContext *)cdata;
95
96 if (!strcmp("load", Tcl_GetString(objv[1])))
97 return loadFirMlirFile(context, interp, objc - 1, objv + 1);
98
99 return returnErrorStr(interp, "usage: circt load");
100}
101
102static void deleteContext(ClientData data) { delete (mlir::MLIRContext *)data; }
103
104extern "C" {
105
106int DLLEXPORT Circt_Init(Tcl_Interp *interp) {
107 if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL)
108 return TCL_ERROR;
109
110 // Register types
111 Tcl_ObjType *operationType = new Tcl_ObjType;
112 operationType->name = "MlirOperation";
113 operationType->setFromAnyProc = operationTypeSetFromAnyProc;
114 operationType->updateStringProc = operationTypeUpdateStringProc;
115 operationType->dupIntRepProc = operationTypeDupIntRepProc;
116 operationType->freeIntRepProc = operationTypeFreeIntRepProc;
117 Tcl_RegisterObjType(operationType);
118
119 // Register package
120 if (Tcl_PkgProvide(interp, "Circt", "1.0") == TCL_ERROR)
121 return TCL_ERROR;
122
123 // Register commands
124 auto *context = new mlir::MLIRContext;
125 context->loadDialect<circt::hw::HWDialect, circt::comb::CombDialect,
126 circt::sv::SVDialect>();
127 Tcl_CreateObjCommand(interp, "circt", circtTclFunction, context,
129 return TCL_OK;
130}
131}
return wrap(CMemoryType::get(unwrap(ctx), baseType, numElements))
static EvaluatorValuePtr unwrap(OMEvaluatorValue c)
Definition OM.cpp:113
static int returnErrorStr(Tcl_Interp *interp, const char *error)
Definition circt_tcl.cpp:38
static void operationTypeUpdateStringProc(Tcl_Obj *obj)
Definition circt_tcl.cpp:17
static int circtTclFunction(ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Definition circt_tcl.cpp:87
int DLLEXPORT Circt_Init(Tcl_Interp *interp)
static int loadFirMlirFile(mlir::MLIRContext *context, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Definition circt_tcl.cpp:43
static int operationTypeSetFromAnyProc(Tcl_Interp *interp, Tcl_Obj *obj)
Definition circt_tcl.cpp:13
static void operationTypeFreeIntRepProc(Tcl_Obj *obj)
Definition circt_tcl.cpp:33
static void deleteContext(ClientData data)
static void operationTypeDupIntRepProc(Tcl_Obj *src, Tcl_Obj *dup)
Definition circt_tcl.cpp:28