diff --git a/lib/Translation/ForthToMLIR/ForthToMLIR.cpp b/lib/Translation/ForthToMLIR/ForthToMLIR.cpp index 664dd13..aa9f726 100644 --- a/lib/Translation/ForthToMLIR/ForthToMLIR.cpp +++ b/lib/Translation/ForthToMLIR/ForthToMLIR.cpp @@ -905,7 +905,7 @@ Value ForthParser::emitOperation(StringRef word, Value inputStack, .getOutputStack(); } - // Unknown word + (void)emitError("unknown word: " + word); return nullptr; } @@ -1281,7 +1281,7 @@ LogicalResult ForthParser::parseBody(Value &stack) { } else { Value newStack = emitOperation(currentToken.text, stack, loc); if (!newStack) - return emitError("unknown word: " + currentToken.text); + return failure(); stack = newStack; consume(); } diff --git a/lib/Translation/ForthToMLIR/ForthToMLIR.h b/lib/Translation/ForthToMLIR/ForthToMLIR.h index 42502fc..04317f6 100644 --- a/lib/Translation/ForthToMLIR/ForthToMLIR.h +++ b/lib/Translation/ForthToMLIR/ForthToMLIR.h @@ -144,7 +144,7 @@ class ForthParser { Location getLoc(); /// Emit a Forth operation based on the current token. - /// Returns the updated stack value or nullptr on error. + /// Returns the updated stack value, or nullptr after emitting a diagnostic. Value emitOperation(StringRef word, Value inputStack, Location loc); /// Create a new block with a single !forth.stack argument, appended to diff --git a/lib/Translation/MLIRToPTX/MLIRToPTX.cpp b/lib/Translation/MLIRToPTX/MLIRToPTX.cpp index 0b1a148..8c6c680 100644 --- a/lib/Translation/MLIRToPTX/MLIRToPTX.cpp +++ b/lib/Translation/MLIRToPTX/MLIRToPTX.cpp @@ -31,11 +31,8 @@ LogicalResult mlir::warpforth::extractPTXFromModule(ModuleOp module, } }); - if (!foundBinary) { - llvm::errs() << "error: no gpu.binary operations found in module\n"; - llvm::errs() << "hint: run 'warpforth-opt --warpforth-pipeline' first\n"; - return failure(); - } + if (!foundBinary) + return module.emitError("no gpu.binary operations found in module"); return success(); } @@ -43,15 +40,7 @@ LogicalResult mlir::warpforth::extractPTXFromModule(ModuleOp module, void mlir::warpforth::registerMLIRToPTXTranslation() { TranslateFromMLIRRegistration registration( "mlir-to-ptx", "Extract PTX assembly from gpu.binary operations", - [](Operation *op, llvm::raw_ostream &output) { - auto module = dyn_cast(op); - if (!module) { - llvm::errs() << "error: expected ModuleOp at top level\n"; - return failure(); - } - return warpforth::extractPTXFromModule(module, output); - }, - [](DialectRegistry ®istry) { + warpforth::extractPTXFromModule, [](DialectRegistry ®istry) { registry.insert(); }); } diff --git a/test/Translation/Forth/loop-index-depth-error.forth b/test/Translation/Forth/loop-index-depth-error.forth index fcb1cf9..93dfc58 100644 --- a/test/Translation/Forth/loop-index-depth-error.forth +++ b/test/Translation/Forth/loop-index-depth-error.forth @@ -1,4 +1,5 @@ \ RUN: %not %warpforth-translate --forth-to-mlir %s 2>&1 | %FileCheck %s \ CHECK: 'J' requires 2 nested DO/LOOP(s) +\ CHECK-NOT: unknown word \! kernel main 10 0 DO J LOOP diff --git a/test/Translation/Forth/param-ref-in-word-error.forth b/test/Translation/Forth/param-ref-in-word-error.forth index 283e234..a83cae5 100644 --- a/test/Translation/Forth/param-ref-in-word-error.forth +++ b/test/Translation/Forth/param-ref-in-word-error.forth @@ -1,5 +1,6 @@ \ RUN: %not %warpforth-translate --forth-to-mlir %s 2>&1 | %FileCheck %s \ CHECK: parameter 'DATA' cannot be referenced inside a word definition +\ CHECK-NOT: unknown word \! kernel main \! param DATA i64[256] : BAD-WORD DATA @ ; diff --git a/test/Translation/Forth/shared-ref-in-word-error.forth b/test/Translation/Forth/shared-ref-in-word-error.forth index 5f7b3f0..db3ab34 100644 --- a/test/Translation/Forth/shared-ref-in-word-error.forth +++ b/test/Translation/Forth/shared-ref-in-word-error.forth @@ -1,5 +1,6 @@ \ RUN: %not %warpforth-translate --forth-to-mlir %s 2>&1 | %FileCheck %s \ CHECK: shared memory 'SCRATCH' cannot be referenced inside a word definition +\ CHECK-NOT: unknown word \! kernel main \! shared SCRATCH i64[256] : BAD-WORD SCRATCH @ ; diff --git a/test/Translation/MLIRToPTX/no-binary-error.mlir b/test/Translation/MLIRToPTX/no-binary-error.mlir new file mode 100644 index 0000000..ba70bd6 --- /dev/null +++ b/test/Translation/MLIRToPTX/no-binary-error.mlir @@ -0,0 +1,6 @@ +// RUN: %not %warpforth-translate --mlir-to-ptx %s 2>&1 | %FileCheck %s + +// CHECK: no-binary-error.mlir:[[@LINE+2]]:1: error: no gpu.binary operations found in module +// CHECK-NOT: hint +module { +} diff --git a/tools/warpforthc/warpforthc.cpp b/tools/warpforthc/warpforthc.cpp index bd13536..413934d 100644 --- a/tools/warpforthc/warpforthc.cpp +++ b/tools/warpforthc/warpforthc.cpp @@ -8,26 +8,22 @@ #include "mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h" #include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h" #include "mlir/Conversion/MemRefToLLVM/MemRefToLLVM.h" -#include "mlir/Dialect/ControlFlow/IR/ControlFlow.h" // IWYU pragma: keep #include "mlir/Dialect/Func/Extensions/InlinerExtension.h" -#include "mlir/Dialect/Func/IR/FuncOps.h" // IWYU pragma: keep -#include "mlir/Dialect/MemRef/IR/MemRef.h" // IWYU pragma: keep #include "mlir/IR/AsmState.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/Diagnostics.h" #include "mlir/IR/MLIRContext.h" #include "mlir/Pass/PassManager.h" +#include "mlir/Support/FileUtilities.h" #include "mlir/Target/LLVM/NVVM/Target.h" #include "mlir/Target/LLVMIR/Dialect/Builtin/BuiltinToLLVMIRTranslation.h" #include "mlir/Target/LLVMIR/Dialect/GPU/GPUToLLVMIRTranslation.h" #include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h" #include "mlir/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.h" #include "warpforth/Conversion/Passes.h" -#include "warpforth/Dialect/Forth/ForthDialect.h" // IWYU pragma: keep #include "warpforth/Translation/ForthToMLIR/ForthToMLIR.h" #include "warpforth/Translation/MLIRToPTX/MLIRToPTX.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/FileSystem.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/ToolOutputFile.h" @@ -55,23 +51,17 @@ int main(int argc, char **argv) { llvm::cl::ParseCommandLineOptions(argc, argv, "WarpForth compiler: Forth to PTX\n"); - // Set up source manager with input file - auto inputFile = llvm::MemoryBuffer::getFileOrSTDIN(inputFilename); - if (auto ec = inputFile.getError()) { - llvm::errs() << "error: could not open input file '" << inputFilename - << "': " << ec.message() << "\n"; + std::string errorMessage; + auto inputFile = openInputFile(inputFilename, &errorMessage); + if (!inputFile) { + llvm::errs() << "error: " << errorMessage << "\n"; return 1; } llvm::SourceMgr sourceMgr; - sourceMgr.AddNewSourceBuffer(std::move(*inputFile), llvm::SMLoc()); + sourceMgr.AddNewSourceBuffer(std::move(inputFile), llvm::SMLoc()); - // Parse Forth source to MLIR DialectRegistry registry; - registry - .insert(); - arith::registerConvertArithToLLVMInterface(registry); cf::registerConvertControlFlowToLLVMInterface(registry); registerConvertFuncToLLVMInterface(registry); @@ -88,36 +78,27 @@ int main(int argc, char **argv) { SourceMgrDiagnosticHandler diagHandler(sourceMgr, &context); auto module = forth::parseForthSource(sourceMgr, &context); - if (!module) { - llvm::errs() << "error: failed to parse Forth source\n"; + if (!module) return 1; - } - // Run the compilation pipeline PassManager pm(&context); if (failed(applyPassManagerCLOptions(pm))) return 1; warpforth::WarpForthPipelineOptions pipelineOptions; pipelineOptions.chip = targetArchitecture.getValue(); warpforth::buildWarpForthPipeline(pm, pipelineOptions); - if (failed(pm.run(*module))) { - llvm::errs() << "error: compilation pipeline failed\n"; + if (failed(pm.run(*module))) return 1; - } - // Extract PTX and write to output - std::error_code ec; - llvm::ToolOutputFile outputFile(outputFilename, ec, llvm::sys::fs::OF_Text); - if (ec) { - llvm::errs() << "error: could not open output file '" << outputFilename - << "': " << ec.message() << "\n"; + auto outputFile = openOutputFile(outputFilename, &errorMessage); + if (!outputFile) { + llvm::errs() << "error: " << errorMessage << "\n"; return 1; } - if (failed(warpforth::extractPTXFromModule(*module, outputFile.os()))) { + if (failed(warpforth::extractPTXFromModule(*module, outputFile->os()))) return 1; - } - outputFile.keep(); + outputFile->keep(); return 0; }