-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[mlir][spirv] Allow disabling control flow structurization #140561
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[mlir][spirv] Allow disabling control flow structurization #140561
Conversation
Currently some control flow patterns cannot be structurized into current SPIR-V MLIR constructs, e.g., conditional early exits (break). Since the support for early exit cannot be currently added (llvm#138688 (review) in see llvm#138688) this patch enables structurizer to be disabled to keep the control flow unstructurized. By default, the control flow is structurized.
@llvm/pr-subscribers-mlir-spirv @llvm/pr-subscribers-mlir Author: Igor Wodiany (IgWod-IMG) ChangesCurrently some control flow patterns cannot be structurized into existing SPIR-V MLIR constructs, e.g., conditional early exits (break). Since the support for early exit cannot be currently added (#138688 (review) in see #138688) this patch enables structurizer to be disabled to keep the control flow unstructurized. By default, the control flow is structurized. Full diff: https://github.com/llvm/llvm-project/pull/140561.diff 5 Files Affected:
diff --git a/mlir/include/mlir/Target/SPIRV/Deserialization.h b/mlir/include/mlir/Target/SPIRV/Deserialization.h
index a346a7fd1e5f7..adff26298c4cc 100644
--- a/mlir/include/mlir/Target/SPIRV/Deserialization.h
+++ b/mlir/include/mlir/Target/SPIRV/Deserialization.h
@@ -27,8 +27,9 @@ class ModuleOp;
/// in the given `context`. Returns the ModuleOp on success; otherwise, reports
/// errors to the error handler registered with `context` and returns a null
/// module.
-OwningOpRef<spirv::ModuleOp> deserialize(ArrayRef<uint32_t> binary,
- MLIRContext *context);
+OwningOpRef<spirv::ModuleOp>
+deserialize(ArrayRef<uint32_t> binary, MLIRContext *context,
+ bool enableControlFlowStructurization = true);
} // namespace spirv
} // namespace mlir
diff --git a/mlir/lib/Target/SPIRV/Deserialization/Deserialization.cpp b/mlir/lib/Target/SPIRV/Deserialization/Deserialization.cpp
index 7bb8762660599..11a9de91060a8 100644
--- a/mlir/lib/Target/SPIRV/Deserialization/Deserialization.cpp
+++ b/mlir/lib/Target/SPIRV/Deserialization/Deserialization.cpp
@@ -12,9 +12,10 @@
using namespace mlir;
-OwningOpRef<spirv::ModuleOp> spirv::deserialize(ArrayRef<uint32_t> binary,
- MLIRContext *context) {
- Deserializer deserializer(binary, context);
+OwningOpRef<spirv::ModuleOp>
+spirv::deserialize(ArrayRef<uint32_t> binary, MLIRContext *context,
+ bool enableControlFlowStructurization) {
+ Deserializer deserializer(binary, context, enableControlFlowStructurization);
if (failed(deserializer.deserialize()))
return nullptr;
diff --git a/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp b/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp
index 7afd6e9b25b77..1aa647485496d 100644
--- a/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp
+++ b/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp
@@ -49,9 +49,11 @@ static inline bool isFnEntryBlock(Block *block) {
//===----------------------------------------------------------------------===//
spirv::Deserializer::Deserializer(ArrayRef<uint32_t> binary,
- MLIRContext *context)
+ MLIRContext *context,
+ bool enableControlFlowStructurization)
: binary(binary), context(context), unknownLoc(UnknownLoc::get(context)),
- module(createModuleOp()), opBuilder(module->getRegion())
+ module(createModuleOp()), opBuilder(module->getRegion()),
+ enableControlFlowStructurization(enableControlFlowStructurization)
#ifndef NDEBUG
,
logger(llvm::dbgs())
@@ -2361,6 +2363,16 @@ LogicalResult spirv::Deserializer::splitConditionalBlocks() {
}
LogicalResult spirv::Deserializer::structurizeControlFlow() {
+ if (!enableControlFlowStructurization) {
+ LLVM_DEBUG(
+ {
+ logger.startLine()
+ << "//----- [cf] skip structurizing control flow -----//\n";
+ logger.indent();
+ });
+ return success();
+ }
+
LLVM_DEBUG({
logger.startLine()
<< "//----- [cf] start structurizing control flow -----//\n";
diff --git a/mlir/lib/Target/SPIRV/Deserialization/Deserializer.h b/mlir/lib/Target/SPIRV/Deserialization/Deserializer.h
index bcc78e3e6508d..c1df77ba7b647 100644
--- a/mlir/lib/Target/SPIRV/Deserialization/Deserializer.h
+++ b/mlir/lib/Target/SPIRV/Deserialization/Deserializer.h
@@ -121,7 +121,10 @@ class Deserializer {
public:
/// Creates a deserializer for the given SPIR-V `binary` module.
/// The SPIR-V ModuleOp will be created into `context.
- explicit Deserializer(ArrayRef<uint32_t> binary, MLIRContext *context);
+ /// `enableControlFlowStructurization` is used to enable control flow
+ /// structurization.
+ explicit Deserializer(ArrayRef<uint32_t> binary, MLIRContext *context,
+ bool enableControlFlowStructurization);
/// Deserializes the remembered SPIR-V binary module.
LogicalResult deserialize();
@@ -622,6 +625,9 @@ class Deserializer {
/// A list of all structs which have unresolved member types.
SmallVector<DeferredStructTypeInfo, 0> deferredStructTypesInfos;
+ /// A flag to enable or disable structurizer
+ bool enableControlFlowStructurization;
+
#ifndef NDEBUG
/// A logger used to emit information during the deserialzation process.
llvm::ScopedPrinter logger;
diff --git a/mlir/lib/Target/SPIRV/TranslateRegistration.cpp b/mlir/lib/Target/SPIRV/TranslateRegistration.cpp
index ff34f02d07b73..90e5b684607be 100644
--- a/mlir/lib/Target/SPIRV/TranslateRegistration.cpp
+++ b/mlir/lib/Target/SPIRV/TranslateRegistration.cpp
@@ -37,7 +37,8 @@ using namespace mlir;
// Deserializes the SPIR-V binary module stored in the file named as
// `inputFilename` and returns a module containing the SPIR-V module.
static OwningOpRef<Operation *>
-deserializeModule(const llvm::MemoryBuffer *input, MLIRContext *context) {
+deserializeModule(const llvm::MemoryBuffer *input, MLIRContext *context,
+ bool enableControlFlowStructurization) {
context->loadDialect<spirv::SPIRVDialect>();
// Make sure the input stream can be treated as a stream of SPIR-V words
@@ -51,17 +52,24 @@ deserializeModule(const llvm::MemoryBuffer *input, MLIRContext *context) {
auto binary = llvm::ArrayRef(reinterpret_cast<const uint32_t *>(start),
size / sizeof(uint32_t));
- return spirv::deserialize(binary, context);
+ return spirv::deserialize(binary, context, enableControlFlowStructurization);
}
namespace mlir {
void registerFromSPIRVTranslation() {
+ static llvm::cl::opt<bool> noControlFlowStructurization(
+ "spirv-no-control-flow-structurization",
+ llvm::cl::desc("Disable control flow structurization to enable "
+ "deserialization of early exits (see #138688)"),
+ llvm::cl::init(false));
+
TranslateToMLIRRegistration fromBinary(
"deserialize-spirv", "deserializes the SPIR-V module",
[](llvm::SourceMgr &sourceMgr, MLIRContext *context) {
assert(sourceMgr.getNumBuffers() == 1 && "expected one buffer");
return deserializeModule(
- sourceMgr.getMemoryBuffer(sourceMgr.getMainFileID()), context);
+ sourceMgr.getMemoryBuffer(sourceMgr.getMainFileID()), context,
+ !noControlFlowStructurization);
});
}
} // namespace mlir
|
Currently some control flow patterns cannot be structurized into existing SPIR-V MLIR constructs, e.g., conditional early exits (break). Since the support for early exit cannot be currently added (#138688 (review) in see #138688) this patch enables structurizer to be disabled to keep the control flow unstructurized. By default, the control flow is structurized.