2222namespace mlir {
2323namespace warpforth {
2424
25- void buildWarpForthPipeline (OpPassManager &pm) {
25+ WarpForthPipelineOptions::WarpForthPipelineOptions ()
26+ : chip(*this , " chip" , llvm::cl::desc(" NVVM target chip" ),
27+ llvm::cl::init (" sm_70" )),
28+ features(*this , " features" , llvm::cl::desc(" NVVM target features" ),
29+ llvm::cl::init(" +ptx60" )),
30+ libdevicePath(*this , " libdevice" ,
31+ llvm::cl::desc (" Path to the CUDA libdevice bitcode" ),
32+ llvm::cl::init(WARPFORTH_LIBDEVICE_PATH )),
33+ optLevel(
34+ *this , " opt-level" ,
35+ llvm::cl::desc (" NVVM target optimization level (0, 1, 2, or 3)" ),
36+ llvm::cl::init(llvm::CodeGenOptLevel::Default),
37+ llvm::cl::values(
38+ clEnumValN (llvm::CodeGenOptLevel::None, " 0" , " No optimization" ),
39+ clEnumValN(llvm::CodeGenOptLevel::Less, " 1" , " Less optimization" ),
40+ clEnumValN(llvm::CodeGenOptLevel::Default, " 2" ,
41+ " Default optimization" ),
42+ clEnumValN(llvm::CodeGenOptLevel::Aggressive, " 3" ,
43+ " Aggressive optimization" ))),
44+ compilationTarget(
45+ *this , " compilation-target" ,
46+ llvm::cl::desc (" GPU output format (llvm, isa, bin, or fatbin)" ),
47+ llvm::cl::init(gpu::CompilationTarget::Assembly),
48+ llvm::cl::values(clEnumValN(gpu::CompilationTarget::Offload, " llvm" ,
49+ " LLVM bitcode" ),
50+ clEnumValN(gpu::CompilationTarget::Assembly, " isa" ,
51+ " Target assembly" ),
52+ clEnumValN(gpu::CompilationTarget::Binary, " bin" ,
53+ " Target binary" ),
54+ clEnumValN(gpu::CompilationTarget::Fatbin, " fatbin" ,
55+ " Fat binary" ))) {}
56+
57+ void buildWarpForthPipeline (OpPassManager &pm,
58+ const WarpForthPipelineOptions &options) {
2659 // Stage 1: Lower Forth to MemRef (CF ops pass through as-is)
2760 pm.addPass (createConvertForthToMemRefPass ());
2861
@@ -32,10 +65,13 @@ void buildWarpForthPipeline(OpPassManager &pm) {
3265 // Stage 3: Normalize MemRefs for GPU
3366 pm.addPass (createCanonicalizerPass ());
3467
35- // Stage 4: Attach NVVM target to GPU modules (sm_70 = Volta architecture)
68+ // Stage 4: Attach the configured NVVM target to GPU modules
3669 GpuNVVMAttachTargetOptions nvvmOptions;
37- nvvmOptions.chip = " sm_70" ;
38- nvvmOptions.linkLibs .push_back (WARPFORTH_LIBDEVICE_PATH );
70+ nvvmOptions.chip = options.chip .getValue ();
71+ nvvmOptions.features = options.features .getValue ();
72+ nvvmOptions.optLevel = static_cast <unsigned >(options.optLevel .getValue ());
73+ if (!options.libdevicePath .getValue ().empty ())
74+ nvvmOptions.linkLibs .push_back (options.libdevicePath .getValue ());
3975 pm.addPass (createGpuNVVMAttachTarget (nvvmOptions));
4076
4177 // Stage 5: Lower GPU to NVVM with bare pointers
@@ -55,10 +91,15 @@ void buildWarpForthPipeline(OpPassManager &pm) {
5591
5692 // Stage 9: Compile GPU module to PTX binary
5793 GpuModuleToBinaryPassOptions binaryOptions;
58- binaryOptions.compilationTarget = " isa" ; // Output PTX assembly
94+ binaryOptions.compilationTarget =
95+ gpu::stringifyCompilationTarget (options.compilationTarget .getValue ());
5996 pm.addPass (createGpuModuleToBinaryPass (binaryOptions));
6097}
6198
99+ void buildWarpForthPipeline (OpPassManager &pm) {
100+ buildWarpForthPipeline (pm, WarpForthPipelineOptions ());
101+ }
102+
62103void registerConversionPasses () {
63104 registerPass ([]() -> std::unique_ptr<Pass> {
64105 return createConvertForthToMemRefPass ();
@@ -67,9 +108,11 @@ void registerConversionPasses() {
67108 []() -> std::unique_ptr<Pass> { return createConvertForthToGPUPass (); });
68109
69110 // Register WarpForth pipeline
70- PassPipelineRegistration<>(" warpforth-pipeline" ,
71- " WarpForth compilation pipeline (Forth to PTX)" ,
72- buildWarpForthPipeline);
111+ PassPipelineRegistration<WarpForthPipelineOptions>(
112+ " warpforth-pipeline" , " WarpForth compilation pipeline (Forth to PTX)" ,
113+ [](OpPassManager &pm, const WarpForthPipelineOptions &options) {
114+ buildWarpForthPipeline (pm, options);
115+ });
73116}
74117
75118} // namespace warpforth
0 commit comments