MLIR 24.0.0git
GPUToXeVMPipeline.cpp
Go to the documentation of this file.
1//===- GPUToXeVMPipeline.cpp - Lowering pipeline to XeVM/LLVM -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements a pass for testing the lowering to XeVM as a generally
10// usable sink pass. If XeGPU ops are used, it expects the MLIR code to have
11// XeGPU ops already embedded in gpu code.
12//
13//===----------------------------------------------------------------------===//
14
41
42#include <utility>
43
44using namespace mlir;
45
46namespace {
47//===----------------------------------------------------------------------===//
48// Pre-GPU common pipeline for both Host and GPU.
49//===----------------------------------------------------------------------===//
50void buildPreGPUCommonPassPipeline(
52 // builtin.module scope passes.
54 {
55 GpuXeVMAttachTargetOptions xevmTargetOptions;
56 xevmTargetOptions.moduleMatcher = options.xevmModuleMatcher;
57 xevmTargetOptions.triple = options.zebinTriple;
58 xevmTargetOptions.chip = options.zebinChip;
59 xevmTargetOptions.optLevel = options.optLevel;
60 xevmTargetOptions.cmdOptions = options.cmdOptions;
61 pm.addPass(createGpuXeVMAttachTarget(std::move(xevmTargetOptions)));
62 }
64 pm.addNestedPass<func::FuncOp>(createGpuAsyncRegionPass());
65}
66
67//===----------------------------------------------------------------------===//
68// GPUModule-specific stuff.
69//===----------------------------------------------------------------------===//
70void buildGPUPassPipeline(OpPassManager &pm,
72 xegpu::XeGPUPropagateLayoutOptions laneLayoutOptions;
73 laneLayoutOptions.indexBitWidth = options.use64bitIndex ? 64 : 32;
74 laneLayoutOptions.layoutKind = "lane";
75 pm.addNestedPass<ModuleOp>(createCSEPass());
76 if (options.enableVectorToXeGPU)
77 pm.addNestedPass<gpu::GPUModuleOp>(createConvertVectorToXeGPU());
78 if (options.xegpuOpLevel == "workgroup") {
80 sgLayoutOptions.layoutKind = "subgroup";
81 pm.addNestedPass<gpu::GPUModuleOp>(
82 xegpu::createXeGPUPropagateLayout(std::move(sgLayoutOptions)));
84 pm.addNestedPass<gpu::GPUModuleOp>(createCSEPass());
85 pm.addNestedPass<gpu::GPUModuleOp>(createLowerAffinePass());
86 pm.addNestedPass<gpu::GPUModuleOp>(createCSEPass());
88 instDataOptions.layoutKind = "inst";
89 pm.addNestedPass<gpu::GPUModuleOp>(
90 xegpu::createXeGPUPropagateLayout(std::move(instDataOptions)));
91 pm.addNestedPass<gpu::GPUModuleOp>(xegpu::createXeGPUBlocking());
92 pm.addNestedPass<gpu::GPUModuleOp>(createCSEPass());
93 }
94 if (options.xegpuOpLevel == "subgroup" ||
95 options.xegpuOpLevel == "workgroup") {
96 pm.addNestedPass<gpu::GPUModuleOp>(
97 xegpu::createXeGPUPropagateLayout(laneLayoutOptions));
99 pm.addNestedPass<gpu::GPUModuleOp>(createCSEPass());
100 pm.addNestedPass<gpu::GPUModuleOp>(
101 xegpu::createXeGPUPropagateLayout(std::move(laneLayoutOptions)));
103 pm.addNestedPass<gpu::GPUModuleOp>(createCanonicalizerPass());
104 pm.addNestedPass<gpu::GPUModuleOp>(createCSEPass());
105 pm.addNestedPass<gpu::GPUModuleOp>(createLoopInvariantCodeMotionPass());
106 pm.addNestedPass<gpu::GPUModuleOp>(createCSEPass());
107 pm.addNestedPass<gpu::GPUModuleOp>(xegpu::createXeGPUVectorLinearize());
108 pm.addNestedPass<gpu::GPUModuleOp>(createCanonicalizerPass());
109 pm.addNestedPass<gpu::GPUModuleOp>(createCSEPass());
110 }
111 // Break down high-level micro-scaling (MX) ops (arith.scaling_extf and
112 // arith.scaling_truncf) into standard arith ops (extf/truncf + mulf), and
113 // expand extf/truncf on f8E8M0FNU into integer bit manipulation. This runs
114 // before the XeVM/LLVM conversions. The f4E2M1FN expansion patterns are
115 // intentionally left disabled: f4E2M1FN extf/truncf are lowered by the XeVM
116 // conversions (xevm.extf), whereas f8E8M0FNU is not supported there and so
117 // must be expanded here.
118 {
119 arith::ArithExpandOpsPassOptions arithExpandOptions;
120 arithExpandOptions.includeF8E8M0 = true;
121 pm.addNestedPass<gpu::GPUModuleOp>(
122 arith::createArithExpandOpsPass(std::move(arithExpandOptions)));
123 }
124 pm.addNestedPass<gpu::GPUModuleOp>(createConvertMathToXeVM());
125 ConvertXeGPUToXeVMPassOptions xegpuToXeVMOptions;
126 xegpuToXeVMOptions.use64bitIndex = options.use64bitIndex;
127 pm.addNestedPass<gpu::GPUModuleOp>(
128 createConvertXeGPUToXeVMPass(std::move(xegpuToXeVMOptions)));
129 {
130 ConvertGpuOpsToLLVMSPVOpsOptions gpuToLLVMSPVOptions;
131 gpuToLLVMSPVOptions.use64bitIndex = options.use64bitIndex;
132 pm.addNestedPass<gpu::GPUModuleOp>(
133 createConvertGpuOpsToLLVMSPVOps(std::move(gpuToLLVMSPVOptions)));
134 }
135 // Legalize math/arith ops on floating-point types that the XeVM target
136 // cannot handle natively (e.g. bf16) by wrapping them with extf/truncf
137 // around a supported type (defaulting to f32).
138 {
140 mathExtendOptions.extraTypeStrs.assign(options.mathExtendExtraTypes.begin(),
141 options.mathExtendExtraTypes.end());
142 mathExtendOptions.targetTypeStr = options.supportedTargetTypes;
143 pm.addNestedPass<gpu::GPUModuleOp>(
144 math::createMathExtendToSupportedTypes(std::move(mathExtendOptions)));
145 }
146 {
148 arithEmulateOptions.sourceTypeStrs.assign(
149 options.unsupportedSourceTypes.begin(),
150 options.unsupportedSourceTypes.end());
151 arithEmulateOptions.targetTypeStr = options.supportedTargetTypes;
152 pm.addNestedPass<gpu::GPUModuleOp>(
154 std::move(arithEmulateOptions)));
155 }
156 pm.addNestedPass<gpu::GPUModuleOp>(createCSEPass());
158}
159
160//===----------------------------------------------------------------------===//
161// Post-GPU pipeline for both Host and GPU.
162//===----------------------------------------------------------------------===//
163void buildPostGPUCommonPassPipeline(
165 // builtin.module scope passes.
169 {
170 GpuToLLVMConversionPassOptions gpuToLLVMOptions;
171 gpuToLLVMOptions.hostBarePtrCallConv = options.hostBarePtrCallConv;
172 gpuToLLVMOptions.kernelBarePtrCallConv = options.kernelBarePtrCallConv;
173 pm.addPass(createGpuToLLVMConversionPass(std::move(gpuToLLVMOptions)));
174 }
179 pm.addNestedPass<gpu::GPUModuleOp>(createCanonicalizerPass());
180 pm.addNestedPass<gpu::GPUModuleOp>(createCSEPass());
181 // XeVM-to-LLVM must be the last pass before gpu-module-to-binary.
182 pm.addNestedPass<gpu::GPUModuleOp>(createConvertXeVMToLLVMPass());
183 // gpu-module-to-binary
184 {
185 GpuModuleToBinaryPassOptions gpuToModuleBinOptions;
186 gpuToModuleBinOptions.compilationTarget = options.binaryFormat;
187 gpuToModuleBinOptions.cmdOptions = options.cmdOptions;
188 std::string skipTarget("skip");
189 if (options.binaryFormat.compare(skipTarget) != 0)
190 pm.addPass(createGpuModuleToBinaryPass(std::move(gpuToModuleBinOptions)));
191 }
192}
193} // namespace
194
197 // Pre-GPU common pipelines.
198 buildPreGPUCommonPassPipeline(pm, options);
199
200 // GPUModule-specific stuff.
201 buildGPUPassPipeline(pm, options);
202
203 // Post-GPU pipeline for both Host and GPU.
204 buildPostGPUCommonPassPipeline(pm, options);
205}
206
209 "gpu-lower-to-xevm-pipeline",
210 "The default GPU to XeVM lowering pipeline. It starts by lowering GPU "
211 "code to the "
212 "specified compilation target (default is fatbin) then lowers the host "
213 "code.",
215}
static llvm::ManagedStatic< PassManagerOptions > options
This class represents a pass manager that runs passes on either a specific operation type,...
Definition PassManager.h:46
void addPass(std::unique_ptr< Pass > pass)
Add the given pass to this pass manager.
Definition Pass.cpp:393
void addNestedPass(std::unique_ptr< Pass > pass)
Add the given pass to a nested pass manager for the given operation kind OpT.
std::unique_ptr<::mlir::Pass > createArithEmulateUnsupportedFloats()
std::unique_ptr<::mlir::Pass > createArithExpandOpsPass()
void registerGPUToXeVMPipeline()
void buildLowerToXeVMPassPipeline(OpPassManager &pm, const GPUToXeVMPipelineOptions &options)
Adds the GPU to XeVM pipeline to the given pass manager.
std::unique_ptr<::mlir::Pass > createMathExtendToSupportedTypes()
std::unique_ptr<::mlir::Pass > createExpandStridedMetadataPass()
std::unique_ptr<::mlir::Pass > createXeGPUWgToSgDistribute()
std::unique_ptr<::mlir::Pass > createXeGPUVectorLinearize()
std::unique_ptr<::mlir::Pass > createXeGPUSgToLaneDistribute()
std::unique_ptr<::mlir::Pass > createXeGPUPeepHoleOptimizer()
std::unique_ptr<::mlir::Pass > createXeGPUBlocking()
std::unique_ptr<::mlir::Pass > createXeGPUPropagateLayout()
Include the generated interface declarations.
std::unique_ptr<::mlir::Pass > createConvertToLLVMPass()
std::unique_ptr<::mlir::Pass > createSCFToControlFlowPass()
std::unique_ptr<::mlir::Pass > createConvertGpuOpsToLLVMSPVOps()
std::unique_ptr<::mlir::Pass > createReconcileUnrealizedCastsPass()
std::unique_ptr<::mlir::Pass > createConvertVectorToLLVMPass()
std::unique_ptr<::mlir::Pass > createGpuAsyncRegionPass()
std::unique_ptr<::mlir::Pass > createCanonicalizerPass()
std::unique_ptr<::mlir::Pass > createConvertXeGPUToXeVMPass()
std::unique_ptr<::mlir::Pass > createLowerAffinePass()
std::unique_ptr<::mlir::Pass > createGpuXeVMAttachTarget()
std::unique_ptr<::mlir::Pass > createConvertVectorToXeGPU()
std::unique_ptr<::mlir::Pass > createConvertMathToXeVM()
std::unique_ptr<::mlir::Pass > createLoopInvariantCodeMotionPass()
std::unique_ptr<::mlir::Pass > createGpuToLLVMConversionPass()
std::unique_ptr<::mlir::Pass > createGpuModuleToBinaryPass()
std::unique_ptr< Pass > createConvertVectorToSCFPass(const VectorTransferToSCFOptions &options=VectorTransferToSCFOptions())
Create a pass to convert a subset of vector ops to SCF.
std::unique_ptr<::mlir::Pass > createConvertXeVMToLLVMPass()
std::unique_ptr<::mlir::Pass > createCSEPass()
Definition CSE.cpp:177
PassPipelineRegistration provides a global initializer that registers a Pass pipeline builder routine...
::llvm::SmallVector< std::string > sourceTypeStrs
Definition Passes.h:20
::llvm::SmallVector< std::string > extraTypeStrs
Definition Passes.h:114