diff options
author | Dominik Adamski <dominik.adamski@amd.com> | 2023-12-06 09:47:09 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-06 09:47:09 +0100 |
commit | bb4484d41e1ee7856ce71ae0572a724c20d989f2 (patch) | |
tree | c879dca8123cbf04cea413154ecc540583cc2dfb /llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp | |
parent | de21308f78f3b0f0910638dbdac90967150d19f0 (diff) | |
download | llvm-bb4484d41e1ee7856ce71ae0572a724c20d989f2.zip llvm-bb4484d41e1ee7856ce71ae0572a724c20d989f2.tar.gz llvm-bb4484d41e1ee7856ce71ae0572a724c20d989f2.tar.bz2 |
[OpenMPIRBuilder] Add support for target workshare loops (#73360)
The workshare loop for target region uses the new OpenMP device runtime.
The code generation scheme for the new device runtime is presented
below:
Input code:
```
workshare-loop {
loop-body
}
```
Output code:
helper function which represents loop body:
```
function-loop-body(counter, loop-body-args) {
loop-body
}
```
workshare-loop is replaced by the proper device runtime call:
```
call __kmpc_new_worksharing_rtl(function-loop-body, loop-body-args,
loop-tripcount, ...)
```
This PR uses the new device runtime functions which were added in PR:
https://github.com/llvm/llvm-project/pull/73225
Diffstat (limited to 'llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp')
-rw-r--r-- | llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp index 2876aa4..193ada3 100644 --- a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp +++ b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp @@ -2228,9 +2228,77 @@ TEST_F(OpenMPIRBuilderTest, UnrollLoopHeuristic) { EXPECT_TRUE(getBooleanLoopAttribute(L, "llvm.loop.unroll.enable")); } +TEST_F(OpenMPIRBuilderTest, StaticWorkshareLoopTarget) { + using InsertPointTy = OpenMPIRBuilder::InsertPointTy; + std::string oldDLStr = M->getDataLayoutStr(); + M->setDataLayout( + "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:" + "256:256:32-p8:128:128-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:" + "256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8"); + OpenMPIRBuilder OMPBuilder(*M); + OMPBuilder.Config.IsTargetDevice = true; + OMPBuilder.initialize(); + IRBuilder<> Builder(BB); + OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL}); + InsertPointTy AllocaIP = Builder.saveIP(); + + Type *LCTy = Type::getInt32Ty(Ctx); + Value *StartVal = ConstantInt::get(LCTy, 10); + Value *StopVal = ConstantInt::get(LCTy, 52); + Value *StepVal = ConstantInt::get(LCTy, 2); + auto LoopBodyGen = [&](InsertPointTy, Value *) {}; + + CanonicalLoopInfo *CLI = OMPBuilder.createCanonicalLoop( + Loc, LoopBodyGen, StartVal, StopVal, StepVal, false, false); + BasicBlock *Preheader = CLI->getPreheader(); + Value *TripCount = CLI->getTripCount(); + + Builder.SetInsertPoint(BB, BB->getFirstInsertionPt()); + + IRBuilder<>::InsertPoint AfterIP = OMPBuilder.applyWorkshareLoop( + DL, CLI, AllocaIP, true, OMP_SCHEDULE_Static, nullptr, false, false, + false, false, WorksharingLoopType::ForStaticLoop); + Builder.restoreIP(AfterIP); + Builder.CreateRetVoid(); + + OMPBuilder.finalize(); + EXPECT_FALSE(verifyModule(*M, &errs())); + + CallInst *WorkshareLoopRuntimeCall = nullptr; + int WorkshareLoopRuntimeCallCnt = 0; + for (auto Inst = Preheader->begin(); Inst != Preheader->end(); ++Inst) { + CallInst *Call = dyn_cast<CallInst>(Inst); + if (!Call) + continue; + if (!Call->getCalledFunction()) + continue; + + if (Call->getCalledFunction()->getName() == "__kmpc_for_static_loop_4u") { + WorkshareLoopRuntimeCall = Call; + WorkshareLoopRuntimeCallCnt++; + } + } + EXPECT_NE(WorkshareLoopRuntimeCall, nullptr); + // Verify that there is only one call to workshare loop function + EXPECT_EQ(WorkshareLoopRuntimeCallCnt, 1); + // Check that pointer to loop body function is passed as second argument + Value *LoopBodyFuncArg = WorkshareLoopRuntimeCall->getArgOperand(1); + EXPECT_EQ(Builder.getPtrTy(), LoopBodyFuncArg->getType()); + Function *ArgFunction = dyn_cast<Function>(LoopBodyFuncArg); + EXPECT_NE(ArgFunction, nullptr); + EXPECT_EQ(ArgFunction->arg_size(), 1u); + EXPECT_EQ(ArgFunction->getArg(0)->getType(), TripCount->getType()); + // Check that no variables except for loop counter are used in loop body + EXPECT_EQ(Constant::getNullValue(Builder.getPtrTy()), + WorkshareLoopRuntimeCall->getArgOperand(2)); + // Check loop trip count argument + EXPECT_EQ(TripCount, WorkshareLoopRuntimeCall->getArgOperand(3)); +} + TEST_F(OpenMPIRBuilderTest, StaticWorkShareLoop) { using InsertPointTy = OpenMPIRBuilder::InsertPointTy; OpenMPIRBuilder OMPBuilder(*M); + OMPBuilder.Config.IsTargetDevice = false; OMPBuilder.initialize(); IRBuilder<> Builder(BB); OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL}); @@ -2331,6 +2399,7 @@ TEST_P(OpenMPIRBuilderTestWithIVBits, StaticChunkedWorkshareLoop) { using InsertPointTy = OpenMPIRBuilder::InsertPointTy; OpenMPIRBuilder OMPBuilder(*M); + OMPBuilder.Config.IsTargetDevice = false; BasicBlock *Body; CallInst *Call; @@ -2405,6 +2474,7 @@ INSTANTIATE_TEST_SUITE_P(IVBits, OpenMPIRBuilderTestWithIVBits, TEST_P(OpenMPIRBuilderTestWithParams, DynamicWorkShareLoop) { using InsertPointTy = OpenMPIRBuilder::InsertPointTy; OpenMPIRBuilder OMPBuilder(*M); + OMPBuilder.Config.IsTargetDevice = false; OMPBuilder.initialize(); IRBuilder<> Builder(BB); OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL}); @@ -2562,6 +2632,7 @@ INSTANTIATE_TEST_SUITE_P( TEST_F(OpenMPIRBuilderTest, DynamicWorkShareLoopOrdered) { using InsertPointTy = OpenMPIRBuilder::InsertPointTy; OpenMPIRBuilder OMPBuilder(*M); + OMPBuilder.Config.IsTargetDevice = false; OMPBuilder.initialize(); IRBuilder<> Builder(BB); OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL}); |