[llvm-branch-commits] [mlir] c11d868 - [MLIR, OpenMP] Added support for lowering MasterOp to LLVMIR
Sourabh Singh Tomar via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Dec 6 20:58:58 PST 2020
Author: Sourabh Singh Tomar
Date: 2020-12-07T10:23:54+05:30
New Revision: c11d868a39cbb7ff535eed906e181a18c02001eb
URL: https://github.com/llvm/llvm-project/commit/c11d868a39cbb7ff535eed906e181a18c02001eb
DIFF: https://github.com/llvm/llvm-project/commit/c11d868a39cbb7ff535eed906e181a18c02001eb.diff
LOG: [MLIR,OpenMP] Added support for lowering MasterOp to LLVMIR
Some Ops in OMP dialect have regions associated with them i.e
`ParallelOp` `MasterOp`. Lowering of these regions involves interfacing
with `OMPIRBuilder` using callbacks, yet there still exist opportunities
for sharing common code in between.
This patch factors out common code into a separate function and adds
support for lowering `MasterOp` using that. Lowering of `ParallelOp` is
also modified appropriately.
Reviewed By: ftynse
Differential Revision: https://reviews.llvm.org/D87247
Added:
Modified:
mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
mlir/test/Target/openmp-llvm.mlir
Removed:
################################################################################
diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
index 45c09ce83d26..996c8de06e37 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
@@ -91,7 +91,15 @@ class ModuleTranslation {
llvm::IRBuilder<> &builder);
virtual LogicalResult convertOmpParallel(Operation &op,
llvm::IRBuilder<> &builder);
-
+ virtual LogicalResult convertOmpMaster(Operation &op,
+ llvm::IRBuilder<> &builder);
+ void convertOmpOpRegions(Region ®ion,
+ DenseMap<Value, llvm::Value *> &valueMapping,
+ DenseMap<Block *, llvm::BasicBlock *> &blockMapping,
+ llvm::Instruction *codeGenIPBBTI,
+ llvm::BasicBlock &continuationIP,
+ llvm::IRBuilder<> &builder,
+ LogicalResult &bodyGenStatus);
/// Converts the type from MLIR LLVM dialect to LLVM.
llvm::Type *convertType(LLVMType type);
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index e73ac109079d..c20b19f2d5ca 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -385,6 +385,9 @@ LogicalResult
ModuleTranslation::convertOmpParallel(Operation &opInst,
llvm::IRBuilder<> &builder) {
using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
+ // TODO: support error propagation in OpenMPIRBuilder and use it instead of
+ // relying on captured variables.
+ LogicalResult bodyGenStatus = success();
auto bodyGenCB = [&](InsertPointTy allocaIP, InsertPointTy codeGenIP,
llvm::BasicBlock &continuationIP) {
@@ -402,31 +405,10 @@ ModuleTranslation::convertOmpParallel(Operation &opInst,
blockMapping[&bb] = llvmBB;
}
- // Then, convert blocks one by one in topological order to ensure
- // defs are converted before uses.
- llvm::SetVector<Block *> blocks = topologicalSort(region);
- for (auto indexedBB : llvm::enumerate(blocks)) {
- Block *bb = indexedBB.value();
- llvm::BasicBlock *curLLVMBB = blockMapping[bb];
- if (bb->isEntryBlock()) {
- assert(codeGenIPBBTI->getNumSuccessors() == 1 &&
- "OpenMPIRBuilder provided entry block has multiple successors");
- assert(codeGenIPBBTI->getSuccessor(0) == &continuationIP &&
- "ContinuationIP is not the successor of OpenMPIRBuilder "
- "provided entry block");
- codeGenIPBBTI->setSuccessor(0, curLLVMBB);
- }
-
- // TODO: Error not returned up the hierarchy
- if (failed(convertBlock(*bb, /*ignoreArguments=*/indexedBB.index() == 0)))
- return;
- }
-
+ convertOmpOpRegions(region, valueMapping, blockMapping, codeGenIPBBTI,
+ continuationIP, builder, bodyGenStatus);
ompContinuationIPStack.pop_back();
- // Finally, after all blocks have been traversed and values mapped,
- // connect the PHI nodes to the results of preceding blocks.
- connectPHINodes(region, valueMapping, blockMapping);
};
// TODO: Perform appropriate actions according to the data-sharing
@@ -459,12 +441,79 @@ ModuleTranslation::convertOmpParallel(Operation &opInst,
// entry or the alloca insertion point as provided by the body callback
// above.
llvm::OpenMPIRBuilder::InsertPointTy allocaIP(builder.saveIP());
+ if (failed(bodyGenStatus))
+ return failure();
builder.restoreIP(
ompBuilder->createParallel(builder, allocaIP, bodyGenCB, privCB, finiCB,
ifCond, numThreads, pbKind, isCancellable));
return success();
}
+void ModuleTranslation::convertOmpOpRegions(
+ Region ®ion, DenseMap<Value, llvm::Value *> &valueMapping,
+ DenseMap<Block *, llvm::BasicBlock *> &blockMapping,
+ llvm::Instruction *codeGenIPBBTI, llvm::BasicBlock &continuationIP,
+ llvm::IRBuilder<> &builder, LogicalResult &bodyGenStatus) {
+ // Convert blocks one by one in topological order to ensure
+ // defs are converted before uses.
+ llvm::SetVector<Block *> blocks = topologicalSort(region);
+ for (auto indexedBB : llvm::enumerate(blocks)) {
+ Block *bb = indexedBB.value();
+ llvm::BasicBlock *curLLVMBB = blockMapping[bb];
+ if (bb->isEntryBlock()) {
+ assert(codeGenIPBBTI->getNumSuccessors() == 1 &&
+ "OpenMPIRBuilder provided entry block has multiple successors");
+ assert(codeGenIPBBTI->getSuccessor(0) == &continuationIP &&
+ "ContinuationIP is not the successor of OpenMPIRBuilder "
+ "provided entry block");
+ codeGenIPBBTI->setSuccessor(0, curLLVMBB);
+ }
+
+ if (failed(convertBlock(*bb, /*ignoreArguments=*/indexedBB.index() == 0))) {
+ bodyGenStatus = failure();
+ return;
+ }
+ }
+ // Finally, after all blocks have been traversed and values mapped,
+ // connect the PHI nodes to the results of preceding blocks.
+ connectPHINodes(region, valueMapping, blockMapping);
+}
+
+LogicalResult ModuleTranslation::convertOmpMaster(Operation &opInst,
+ llvm::IRBuilder<> &builder) {
+ using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
+ // TODO: support error propagation in OpenMPIRBuilder and use it instead of
+ // relying on captured variables.
+ LogicalResult bodyGenStatus = success();
+
+ auto bodyGenCB = [&](InsertPointTy allocaIP, InsertPointTy codeGenIP,
+ llvm::BasicBlock &continuationIP) {
+ llvm::LLVMContext &llvmContext = llvmModule->getContext();
+
+ llvm::BasicBlock *codeGenIPBB = codeGenIP.getBlock();
+ llvm::Instruction *codeGenIPBBTI = codeGenIPBB->getTerminator();
+ ompContinuationIPStack.push_back(&continuationIP);
+
+ // MasterOp has only `1` region associated with it.
+ auto ®ion = cast<omp::MasterOp>(opInst).getRegion();
+ for (auto &bb : region) {
+ auto *llvmBB = llvm::BasicBlock::Create(
+ llvmContext, "omp.master.region", codeGenIP.getBlock()->getParent());
+ blockMapping[&bb] = llvmBB;
+ }
+ convertOmpOpRegions(region, valueMapping, blockMapping, codeGenIPBBTI,
+ continuationIP, builder, bodyGenStatus);
+ ompContinuationIPStack.pop_back();
+ };
+
+ // TODO: Perform finalization actions for variables. This has to be
+ // called for variables which have destructors/finalizers.
+ auto finiCB = [&](InsertPointTy codeGenIP) {};
+
+ builder.restoreIP(ompBuilder->createMaster(builder, bodyGenCB, finiCB));
+ return success();
+}
+
/// Given an OpenMP MLIR operation, create the corresponding LLVM IR
/// (including OpenMP runtime calls).
LogicalResult
@@ -505,6 +554,7 @@ ModuleTranslation::convertOmpOperation(Operation &opInst,
})
.Case(
[&](omp::ParallelOp) { return convertOmpParallel(opInst, builder); })
+ .Case([&](omp::MasterOp) { return convertOmpMaster(opInst, builder); })
.Default([&](Operation *inst) {
return inst->emitError("unsupported OpenMP operation: ")
<< inst->getName();
diff --git a/mlir/test/Target/openmp-llvm.mlir b/mlir/test/Target/openmp-llvm.mlir
index 4b3de0b052e5..0651c6f5df40 100644
--- a/mlir/test/Target/openmp-llvm.mlir
+++ b/mlir/test/Target/openmp-llvm.mlir
@@ -264,3 +264,30 @@ llvm.func @test_omp_parallel_5() -> () {
}
llvm.return
}
+
+// CHECK-LABEL: define void @test_omp_master()
+llvm.func @test_omp_master() -> () {
+// CHECK: call void {{.*}}@__kmpc_fork_call{{.*}} @{{.*}} to
+// CHECK: omp.par.region1:
+ omp.parallel {
+ omp.master {
+// CHECK: [[OMP_THREAD_3_4:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @{{[0-9]+}})
+// CHECK: {{[0-9]+}} = call i32 @__kmpc_master(%struct.ident_t* @{{[0-9]+}}, i32 [[OMP_THREAD_3_4]])
+// CHECK: omp.master.region
+// CHECK: call void @__kmpc_end_master(%struct.ident_t* @{{[0-9]+}}, i32 [[OMP_THREAD_3_4]])
+// CHECK: br label %omp_region.end
+ omp.terminator
+ }
+ omp.terminator
+ }
+ omp.parallel {
+ omp.parallel {
+ omp.master {
+ omp.terminator
+ }
+ omp.terminator
+ }
+ omp.terminator
+ }
+ llvm.return
+}
More information about the llvm-branch-commits
mailing list