@@ -1030,6 +1030,99 @@ mapInitializationArgs(T loop, LLVM::ModuleTranslation &moduleTranslation,
1030
1030
}
1031
1031
}
1032
1032
1033
+ template <typename OP>
1034
+ static LogicalResult
1035
+ initReductionVars (OP op, ArrayRef<BlockArgument> reductionArgs,
1036
+ llvm::IRBuilderBase &builder,
1037
+ LLVM::ModuleTranslation &moduleTranslation,
1038
+ llvm::BasicBlock *latestAllocaBlock,
1039
+ SmallVectorImpl<omp::DeclareReductionOp> &reductionDecls,
1040
+ SmallVectorImpl<llvm::Value *> &privateReductionVariables,
1041
+ DenseMap<Value, llvm::Value *> &reductionVariableMap,
1042
+ llvm::ArrayRef<bool > isByRef,
1043
+ SmallVectorImpl<DeferredStore> &deferredStores) {
1044
+ if (op.getNumReductionVars () == 0 )
1045
+ return success ();
1046
+
1047
+ llvm::IRBuilderBase::InsertPointGuard guard (builder);
1048
+
1049
+ builder.SetInsertPoint (latestAllocaBlock->getTerminator ());
1050
+ llvm::BasicBlock *initBlock = splitBB (builder, true , " omp.reduction.init" );
1051
+ auto allocaIP = llvm::IRBuilderBase::InsertPoint (
1052
+ latestAllocaBlock, latestAllocaBlock->getTerminator ()->getIterator ());
1053
+ builder.restoreIP (allocaIP);
1054
+ SmallVector<llvm::Value *> byRefVars (op.getNumReductionVars ());
1055
+
1056
+ for (unsigned i = 0 ; i < op.getNumReductionVars (); ++i) {
1057
+ if (isByRef[i]) {
1058
+ if (!reductionDecls[i].getAllocRegion ().empty ())
1059
+ continue ;
1060
+
1061
+ // TODO: remove after all users of by-ref are updated to use the alloc
1062
+ // region: Allocate reduction variable (which is a pointer to the real
1063
+ // reduciton variable allocated in the inlined region)
1064
+ byRefVars[i] = builder.CreateAlloca (
1065
+ moduleTranslation.convertType (reductionDecls[i].getType ()));
1066
+ }
1067
+ }
1068
+
1069
+ builder.SetInsertPoint (&*initBlock->getFirstNonPHIOrDbgOrAlloca ());
1070
+
1071
+ // store result of the alloc region to the allocated pointer to the real
1072
+ // reduction variable
1073
+ for (auto [data, addr] : deferredStores)
1074
+ builder.CreateStore (data, addr);
1075
+
1076
+ // Before the loop, store the initial values of reductions into reduction
1077
+ // variables. Although this could be done after allocas, we don't want to mess
1078
+ // up with the alloca insertion point.
1079
+ for (unsigned i = 0 ; i < op.getNumReductionVars (); ++i) {
1080
+ SmallVector<llvm::Value *, 1 > phis;
1081
+
1082
+ // map block argument to initializer region
1083
+ mapInitializationArgs (op, moduleTranslation, reductionDecls,
1084
+ reductionVariableMap, i);
1085
+
1086
+ if (failed (inlineConvertOmpRegions (reductionDecls[i].getInitializerRegion (),
1087
+ " omp.reduction.neutral" , builder,
1088
+ moduleTranslation, &phis)))
1089
+ return failure ();
1090
+
1091
+ assert (phis.size () == 1 && " expected one value to be yielded from the "
1092
+ " reduction neutral element declaration region" );
1093
+
1094
+ builder.SetInsertPoint (builder.GetInsertBlock ()->getTerminator ());
1095
+
1096
+ if (isByRef[i]) {
1097
+ if (!reductionDecls[i].getAllocRegion ().empty ())
1098
+ // done in allocReductionVars
1099
+ continue ;
1100
+
1101
+ // TODO: this path can be removed once all users of by-ref are updated to
1102
+ // use an alloc region
1103
+
1104
+ // Store the result of the inlined region to the allocated reduction var
1105
+ // ptr
1106
+ builder.CreateStore (phis[0 ], byRefVars[i]);
1107
+
1108
+ privateReductionVariables[i] = byRefVars[i];
1109
+ moduleTranslation.mapValue (reductionArgs[i], phis[0 ]);
1110
+ reductionVariableMap.try_emplace (op.getReductionVars ()[i], phis[0 ]);
1111
+ } else {
1112
+ // for by-ref case the store is inside of the reduction region
1113
+ builder.CreateStore (phis[0 ], privateReductionVariables[i]);
1114
+ // the rest was handled in allocByValReductionVars
1115
+ }
1116
+
1117
+ // forget the mapping for the initializer region because we might need a
1118
+ // different mapping if this reduction declaration is re-used for a
1119
+ // different variable
1120
+ moduleTranslation.forgetMapping (reductionDecls[i].getInitializerRegion ());
1121
+ }
1122
+
1123
+ return success ();
1124
+ }
1125
+
1033
1126
// / Collect reduction info
1034
1127
template <typename T>
1035
1128
static void collectReductionInfo (
@@ -1183,6 +1276,7 @@ static LogicalResult allocAndInitializeReductionVars(
1183
1276
if (op.getNumReductionVars () == 0 )
1184
1277
return success ();
1185
1278
1279
+ llvm::IRBuilderBase::InsertPointGuard guard (builder);
1186
1280
SmallVector<DeferredStore> deferredStores;
1187
1281
1188
1282
if (failed (allocReductionVars (op, reductionArgs, builder, moduleTranslation,
@@ -1191,59 +1285,10 @@ static LogicalResult allocAndInitializeReductionVars(
1191
1285
deferredStores, isByRef)))
1192
1286
return failure ();
1193
1287
1194
- // store result of the alloc region to the allocated pointer to the real
1195
- // reduction variable
1196
- for (auto [data, addr] : deferredStores)
1197
- builder.CreateStore (data, addr);
1198
-
1199
- // Before the loop, store the initial values of reductions into reduction
1200
- // variables. Although this could be done after allocas, we don't want to mess
1201
- // up with the alloca insertion point.
1202
- for (unsigned i = 0 ; i < op.getNumReductionVars (); ++i) {
1203
- SmallVector<llvm::Value *, 1 > phis;
1204
-
1205
- // map block argument to initializer region
1206
- mapInitializationArgs (op, moduleTranslation, reductionDecls,
1207
- reductionVariableMap, i);
1208
-
1209
- if (failed (inlineConvertOmpRegions (reductionDecls[i].getInitializerRegion (),
1210
- " omp.reduction.neutral" , builder,
1211
- moduleTranslation, &phis)))
1212
- return failure ();
1213
- assert (phis.size () == 1 && " expected one value to be yielded from the "
1214
- " reduction neutral element declaration region" );
1215
- if (isByRef[i]) {
1216
- if (!reductionDecls[i].getAllocRegion ().empty ())
1217
- // done in allocReductionVars
1218
- continue ;
1219
-
1220
- // TODO: this path can be removed once all users of by-ref are updated to
1221
- // use an alloc region
1222
-
1223
- // Allocate reduction variable (which is a pointer to the real reduction
1224
- // variable allocated in the inlined region)
1225
- llvm::Value *var = builder.CreateAlloca (
1226
- moduleTranslation.convertType (reductionDecls[i].getType ()));
1227
- // Store the result of the inlined region to the allocated reduction var
1228
- // ptr
1229
- builder.CreateStore (phis[0 ], var);
1230
-
1231
- privateReductionVariables[i] = var;
1232
- moduleTranslation.mapValue (reductionArgs[i], phis[0 ]);
1233
- reductionVariableMap.try_emplace (op.getReductionVars ()[i], phis[0 ]);
1234
- } else {
1235
- // for by-ref case the store is inside of the reduction region
1236
- builder.CreateStore (phis[0 ], privateReductionVariables[i]);
1237
- // the rest was handled in allocByValReductionVars
1238
- }
1239
-
1240
- // forget the mapping for the initializer region because we might need a
1241
- // different mapping if this reduction declaration is re-used for a
1242
- // different variable
1243
- moduleTranslation.forgetMapping (reductionDecls[i].getInitializerRegion ());
1244
- }
1245
-
1246
- return success ();
1288
+ return initReductionVars (op, reductionArgs, builder, moduleTranslation,
1289
+ allocaIP.getBlock (), reductionDecls,
1290
+ privateReductionVariables, reductionVariableMap,
1291
+ isByRef, deferredStores);
1247
1292
}
1248
1293
1249
1294
// / Allocate delayed private variables. Returns the basic block which comes
@@ -1929,6 +1974,7 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder,
1929
1974
splitBB (builder, /* CreateBranch=*/ true , " omp.private.copy" );
1930
1975
builder.SetInsertPoint (copyBlock->getFirstNonPHIOrDbgOrAlloca ());
1931
1976
}
1977
+
1932
1978
for (auto [decl, mlirVar, llvmVar] :
1933
1979
llvm::zip_equal (privateDecls, mlirPrivateVars, llvmPrivateVars)) {
1934
1980
if (decl.getDataSharingType () != omp::DataSharingClauseType::FirstPrivate)
@@ -1960,76 +2006,12 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder,
1960
2006
moduleTranslation.forgetMapping (copyRegion);
1961
2007
}
1962
2008
1963
- // Initialize reduction vars
1964
- builder.SetInsertPoint (builder.GetInsertBlock ()->getTerminator ());
1965
- llvm::BasicBlock *initBlock = splitBB (builder, true , " omp.reduction.init" );
1966
- allocaIP =
1967
- InsertPointTy (allocaIP.getBlock (),
1968
- allocaIP.getBlock ()->getTerminator ()->getIterator ());
1969
-
1970
- builder.restoreIP (allocaIP);
1971
- SmallVector<llvm::Value *> byRefVars (opInst.getNumReductionVars ());
1972
- for (unsigned i = 0 ; i < opInst.getNumReductionVars (); ++i) {
1973
- if (isByRef[i]) {
1974
- if (!reductionDecls[i].getAllocRegion ().empty ())
1975
- continue ;
1976
-
1977
- // TODO: remove after all users of by-ref are updated to use the alloc
1978
- // region: Allocate reduction variable (which is a pointer to the real
1979
- // reduciton variable allocated in the inlined region)
1980
- byRefVars[i] = builder.CreateAlloca (
1981
- moduleTranslation.convertType (reductionDecls[i].getType ()));
1982
- }
1983
- }
1984
-
1985
- builder.SetInsertPoint (initBlock->getFirstNonPHIOrDbgOrAlloca ());
1986
-
1987
- // insert stores deferred until after all allocas
1988
- // these store the results of the alloc region into the allocation for the
1989
- // pointer to the reduction variable
1990
- for (auto [data, addr] : deferredStores)
1991
- builder.CreateStore (data, addr);
1992
-
1993
- for (unsigned i = 0 ; i < opInst.getNumReductionVars (); ++i) {
1994
- SmallVector<llvm::Value *> phis;
1995
-
1996
- // map the block argument
1997
- mapInitializationArgs (opInst, moduleTranslation, reductionDecls,
1998
- reductionVariableMap, i);
1999
- if (failed (inlineConvertOmpRegions (
2000
- reductionDecls[i].getInitializerRegion (), " omp.reduction.neutral" ,
2001
- builder, moduleTranslation, &phis)))
2002
- return llvm::createStringError (
2003
- " failed to inline `init` region of `omp.declare_reduction`" );
2004
- assert (phis.size () == 1 &&
2005
- " expected one value to be yielded from the "
2006
- " reduction neutral element declaration region" );
2007
-
2008
- builder.SetInsertPoint (builder.GetInsertBlock ()->getTerminator ());
2009
-
2010
- if (isByRef[i]) {
2011
- if (!reductionDecls[i].getAllocRegion ().empty ())
2012
- continue ;
2013
-
2014
- // TODO: remove after all users of by-ref are updated to use the alloc
2015
-
2016
- // Store the result of the inlined region to the allocated reduction var
2017
- // ptr
2018
- builder.CreateStore (phis[0 ], byRefVars[i]);
2019
-
2020
- privateReductionVariables[i] = byRefVars[i];
2021
- moduleTranslation.mapValue (reductionArgs[i], phis[0 ]);
2022
- reductionVariableMap.try_emplace (opInst.getReductionVars ()[i], phis[0 ]);
2023
- } else {
2024
- // for by-ref case the store is inside of the reduction init region
2025
- builder.CreateStore (phis[0 ], privateReductionVariables[i]);
2026
- // the rest is done in allocByValReductionVars
2027
- }
2028
-
2029
- // clear block argument mapping in case it needs to be re-created with a
2030
- // different source for another use of the same reduction decl
2031
- moduleTranslation.forgetMapping (reductionDecls[i].getInitializerRegion ());
2032
- }
2009
+ if (failed (
2010
+ initReductionVars (opInst, reductionArgs, builder, moduleTranslation,
2011
+ afterAllocas.get ()->getSinglePredecessor (),
2012
+ reductionDecls, privateReductionVariables,
2013
+ reductionVariableMap, isByRef, deferredStores)))
2014
+ return llvm::make_error<PreviouslyReportedError>();
2033
2015
2034
2016
// Store the mapping between reduction variables and their private copies on
2035
2017
// ModuleTranslation stack. It can be then recovered when translating
0 commit comments