10 auto LoadModule(mlir::MLIRContext& context,
const std::string& filename) -> std::unique_ptr<mlir::ModuleOp> {
31 auto Store(
const mlir::ArrayAttr& array, std::string from, std::string name, T& container) ->
bool {
48auto main(
int argc,
char **argv) ->
int {
49 mlir::MLIRContext context;
51 mlir::DialectRegistry registry;
54 mlir::arith::ArithDialect,
56 mlir::memref::MemRefDialect,
57 mlir::LLVM::LLVMDialect,
59 mlir::omp::OpenMPDialect>();
60 context.appendDialectRegistry(registry);
63 llvm::errs() <<
"usage: mllif-mlir <output> <file>...\n";
66 const std::string output = argv[1];
71 for (
auto i = 2; i < argc; ++i) {
72 auto module = LoadModule(context, std::string(argv[i]));
74 module->walk([&module, &tree](mlir::Operation* op, const mlir::WalkStage& stage) {
75 auto fn = mlir::dyn_cast<cir::FuncOp>(op);
76 if (!fn || !stage.isAfterAllRegions()) {
80 const auto annotations = fn.getAnnotations();
81 if (!annotations || annotations->empty()) {
85 std::deque<std::string> path;
89 for (
auto attribute : annotations.value()) {
90 auto annotation = mlir::dyn_cast<cir::AnnotationAttr>(attribute);
95 auto key = annotation.getName().getValue();
103 success &= Store(annotation.getArgs(), fn.getSymName().str(),
"path segment", path);
106 const auto args = annotation.getArgs().getValue();
107 if (args.size() < 1) {
108 llvm::errs() <<
"error: insufficient argument number: function type should be specified for function '" << fn.getSymName() <<
"'\n";
113 const auto str = mlir::dyn_cast<mlir::StringAttr>(args[0]);
115 llvm::errs() <<
"error: function type should be string (" << fn.getSymName() <<
")\n";
120 tag = str.getValue();
123 llvm::errs() <<
"error: unrecognized key '" << key <<
"' for function '" << fn.getSymName() <<
"'\n";
129 llvm::errs() <<
"error: function '" << fn.getSymName() <<
"' has invalid annotations; couldn't be exported\n";
134 const auto args = fn.getArguments();
136 std::vector<std::string> argNames;
137 argNames.reserve(args.size());
138 fn.getBody().walk([&argNames](mlir::Operation* op) {
139 if (
auto alloca = llvm::dyn_cast<cir::AllocaOp>(op); alloca && alloca.getInit()) {
140 argNames.push_back(alloca.getName().str());
144 if (args.size() != argNames.size()) {
145 llvm::errs() <<
"error: invalid function signature for '" << fn.getSymName() <<
"' (annotation mismatched)\n";
151 for (
auto iParm = 0; iParm < args.size(); ++iParm) {
153 llvm::raw_string_ostream os(buffer);
154 args[iParm].getType().print(os);
159 .emplace_back(
"param", argNames[iParm])
161 .emplace_back(
"type", buffer);
166 std::error_code error;
167 llvm::raw_fd_ostream os(output, error);
169 llvm::errs() <<
"error: couldn't open file '" << output <<
"': " << error.message() <<
"\n";
173 tree.root().print(os);
auto main(int argc, char **argv) -> int