@@ -2985,6 +2985,91 @@ RValue CGOmpSsRuntime::emitTaskFunction(CodeGenFunction &CGF,
2985
2985
TaskInfo.emplace_back (getBundleStr (OSSB_shared), DSABundleList);
2986
2986
}
2987
2987
2988
+ // This class is used to inspect task outline clauses looking
2989
+ // for global variables, which have to be captured as shared.
2990
+ class OSSOutlineGlobalVarVisitor
2991
+ : public ConstStmtVisitor<OSSOutlineGlobalVarVisitor, void > {
2992
+ CodeGenFunction &CGF;
2993
+ llvm::SetVector<const DeclRefExpr *> SharedGlobals;
2994
+ public:
2995
+ OSSOutlineGlobalVarVisitor (CodeGenFunction &CGF)
2996
+ : CGF(CGF)
2997
+ {}
2998
+
2999
+ // ===--------------------------------------------------------------------===//
3000
+ // Visitor Methods
3001
+ // ===--------------------------------------------------------------------===//
3002
+
3003
+ void VisitStmt (const Stmt *S) {
3004
+ for (const Stmt *C : S->children ()) {
3005
+ if (C) {
3006
+ Visit (C);
3007
+ }
3008
+ }
3009
+ }
3010
+
3011
+ void VisitOSSMultiDepExpr (const OSSMultiDepExpr *E) {
3012
+ Visit (E->getDepExpr ());
3013
+
3014
+ for (size_t i = 0 ; i < E->getDepInits ().size (); ++i) {
3015
+ Visit (E->getDepInits ()[i]);
3016
+ if (E->getDepSizes ()[i])
3017
+ Visit (E->getDepSizes ()[i]);
3018
+ if (E->getDepSteps ()[i])
3019
+ Visit (E->getDepSteps ()[i]);
3020
+ }
3021
+ }
3022
+
3023
+ void VisitOSSArrayShapingExpr (const OSSArrayShapingExpr *E) {
3024
+ Visit (E->getBase ());
3025
+
3026
+ for (const Expr *S : E->getShapes ())
3027
+ Visit (S);
3028
+ }
3029
+
3030
+ void VisitOSSArraySectionExpr (const OSSArraySectionExpr *E) {
3031
+ Visit (E->getBase ());
3032
+
3033
+ if (E->getLowerBound ())
3034
+ Visit (E->getLowerBound ());
3035
+ if (E->getLengthUpper ())
3036
+ Visit (E->getLengthUpper ());
3037
+ }
3038
+
3039
+ void VisitArraySubscriptExpr (const ArraySubscriptExpr *E) {
3040
+ Visit (E->getBase ());
3041
+ Visit (E->getIdx ());
3042
+ }
3043
+
3044
+ void VisitUnaryOperator (const UnaryOperator *E) {
3045
+ Visit (E->getSubExpr ());
3046
+ }
3047
+
3048
+ void VisitMemberExpr (const MemberExpr *E) {
3049
+ Visit (E->getBase ());
3050
+ }
3051
+
3052
+ void VisitDeclRefExpr (const DeclRefExpr *E) {
3053
+ if (E->isNonOdrUse () == NOUR_Unevaluated)
3054
+ return ;
3055
+
3056
+ CodeGenFunction::ConstantEmission CE = CGF.tryEmitAsConstant (const_cast <DeclRefExpr*>(E));
3057
+ if (CE && !CE.isReference ())
3058
+ // Constant value, no need to annotate it.
3059
+ return ;
3060
+
3061
+ if (const VarDecl *VD = dyn_cast<VarDecl>(E->getDecl ())) {
3062
+ if (VD->hasGlobalStorage ())
3063
+ SharedGlobals.insert (E);
3064
+ }
3065
+ }
3066
+
3067
+ ArrayRef<const DeclRefExpr *> getSharedGlobals () const {
3068
+ return SharedGlobals.getArrayRef ();
3069
+ }
3070
+
3071
+ };
3072
+
2988
3073
// NOTE: this should do only one iteration
2989
3074
for (const auto *Attr : FD->specific_attrs <OSSTaskDeclAttr>()) {
2990
3075
SmallVector<llvm::Value*, 4 > CapturedList;
@@ -3004,6 +3089,9 @@ RValue CGOmpSsRuntime::emitTaskFunction(CodeGenFunction &CGF,
3004
3089
FpDataTy.Copy = FpDataTy.Init = nullptr ;
3005
3090
EmitDSAFirstprivate (CGF, FpDataTy, TaskInfo, CapturedList);
3006
3091
}
3092
+
3093
+ OSSOutlineGlobalVarVisitor OutlineGlobalVarVisitor (CGF);
3094
+
3007
3095
if (const Expr *E = Attr->getIfExpr ()) {
3008
3096
TaskInfo.emplace_back (getBundleStr (OSSB_if), CGF.EvaluateExprAsBool (E));
3009
3097
}
@@ -3056,126 +3144,175 @@ RValue CGOmpSsRuntime::emitTaskFunction(CodeGenFunction &CGF,
3056
3144
}
3057
3145
// in()
3058
3146
for (const Expr *E : Attr->ins ()) {
3147
+ OutlineGlobalVarVisitor.Visit (E);
3148
+
3059
3149
OSSDepDataTy Dep;
3060
3150
Dep.OSSSyntax = true ;
3061
3151
Dep.E = E;
3062
3152
EmitDependency (getBundleStr (OSSB_in), CGF, FD, Dep, TaskInfo);
3063
3153
}
3064
3154
for (const Expr *E : Attr->outs ()) {
3155
+ OutlineGlobalVarVisitor.Visit (E);
3156
+
3065
3157
OSSDepDataTy Dep;
3066
3158
Dep.OSSSyntax = true ;
3067
3159
Dep.E = E;
3068
3160
EmitDependency (getBundleStr (OSSB_out), CGF, FD, Dep, TaskInfo);
3069
3161
}
3070
3162
for (const Expr *E : Attr->inouts ()) {
3163
+ OutlineGlobalVarVisitor.Visit (E);
3164
+
3071
3165
OSSDepDataTy Dep;
3072
3166
Dep.OSSSyntax = true ;
3073
3167
Dep.E = E;
3074
3168
EmitDependency (getBundleStr (OSSB_inout), CGF, FD, Dep, TaskInfo);
3075
3169
}
3076
3170
for (const Expr *E : Attr->concurrents ()) {
3171
+ OutlineGlobalVarVisitor.Visit (E);
3172
+
3077
3173
OSSDepDataTy Dep;
3078
3174
Dep.OSSSyntax = true ;
3079
3175
Dep.E = E;
3080
3176
EmitDependency (getBundleStr (OSSB_concurrent), CGF, FD, Dep, TaskInfo);
3081
3177
}
3082
3178
for (const Expr *E : Attr->commutatives ()) {
3179
+ OutlineGlobalVarVisitor.Visit (E);
3180
+
3083
3181
OSSDepDataTy Dep;
3084
3182
Dep.OSSSyntax = true ;
3085
3183
Dep.E = E;
3086
3184
EmitDependency (getBundleStr (OSSB_commutative), CGF, FD, Dep, TaskInfo);
3087
3185
}
3088
3186
for (const Expr *E : Attr->weakIns ()) {
3187
+ OutlineGlobalVarVisitor.Visit (E);
3188
+
3089
3189
OSSDepDataTy Dep;
3090
3190
Dep.OSSSyntax = true ;
3091
3191
Dep.E = E;
3092
3192
EmitDependency (getBundleStr (OSSB_weakin), CGF, FD, Dep, TaskInfo);
3093
3193
}
3094
3194
for (const Expr *E : Attr->weakOuts ()) {
3195
+ OutlineGlobalVarVisitor.Visit (E);
3196
+
3095
3197
OSSDepDataTy Dep;
3096
3198
Dep.OSSSyntax = true ;
3097
3199
Dep.E = E;
3098
3200
EmitDependency (getBundleStr (OSSB_weakout), CGF, FD, Dep, TaskInfo);
3099
3201
}
3100
3202
for (const Expr *E : Attr->weakInouts ()) {
3203
+ OutlineGlobalVarVisitor.Visit (E);
3204
+
3101
3205
OSSDepDataTy Dep;
3102
3206
Dep.OSSSyntax = true ;
3103
3207
Dep.E = E;
3104
3208
EmitDependency (getBundleStr (OSSB_weakinout), CGF, FD, Dep, TaskInfo);
3105
3209
}
3106
3210
for (const Expr *E : Attr->weakConcurrents ()) {
3211
+ OutlineGlobalVarVisitor.Visit (E);
3212
+
3107
3213
OSSDepDataTy Dep;
3108
3214
Dep.OSSSyntax = true ;
3109
3215
Dep.E = E;
3110
3216
EmitDependency (getBundleStr (OSSB_weakconcurrent), CGF, FD, Dep, TaskInfo);
3111
3217
}
3112
3218
for (const Expr *E : Attr->weakCommutatives ()) {
3219
+ OutlineGlobalVarVisitor.Visit (E);
3220
+
3113
3221
OSSDepDataTy Dep;
3114
3222
Dep.OSSSyntax = true ;
3115
3223
Dep.E = E;
3116
3224
EmitDependency (getBundleStr (OSSB_weakcommutative), CGF, FD, Dep, TaskInfo);
3117
3225
}
3118
3226
// depend(in :)
3119
3227
for (const Expr *E : Attr->depIns ()) {
3228
+ OutlineGlobalVarVisitor.Visit (E);
3229
+
3120
3230
OSSDepDataTy Dep;
3121
3231
Dep.OSSSyntax = false ;
3122
3232
Dep.E = E;
3123
3233
EmitDependency (getBundleStr (OSSB_in), CGF, FD, Dep, TaskInfo);
3124
3234
}
3125
3235
for (const Expr *E : Attr->depOuts ()) {
3236
+ OutlineGlobalVarVisitor.Visit (E);
3237
+
3126
3238
OSSDepDataTy Dep;
3127
3239
Dep.OSSSyntax = false ;
3128
3240
Dep.E = E;
3129
3241
EmitDependency (getBundleStr (OSSB_out), CGF, FD, Dep, TaskInfo);
3130
3242
}
3131
3243
for (const Expr *E : Attr->depInouts ()) {
3244
+ OutlineGlobalVarVisitor.Visit (E);
3245
+
3132
3246
OSSDepDataTy Dep;
3133
3247
Dep.OSSSyntax = false ;
3134
3248
Dep.E = E;
3135
3249
EmitDependency (getBundleStr (OSSB_inout), CGF, FD, Dep, TaskInfo);
3136
3250
}
3137
3251
for (const Expr *E : Attr->depConcurrents ()) {
3252
+ OutlineGlobalVarVisitor.Visit (E);
3253
+
3138
3254
OSSDepDataTy Dep;
3139
3255
Dep.OSSSyntax = false ;
3140
3256
Dep.E = E;
3141
3257
EmitDependency (getBundleStr (OSSB_concurrent), CGF, FD, Dep, TaskInfo);
3142
3258
}
3143
3259
for (const Expr *E : Attr->depCommutatives ()) {
3260
+ OutlineGlobalVarVisitor.Visit (E);
3261
+
3144
3262
OSSDepDataTy Dep;
3145
3263
Dep.OSSSyntax = false ;
3146
3264
Dep.E = E;
3147
3265
EmitDependency (getBundleStr (OSSB_commutative), CGF, FD, Dep, TaskInfo);
3148
3266
}
3149
3267
for (const Expr *E : Attr->depWeakIns ()) {
3268
+ OutlineGlobalVarVisitor.Visit (E);
3269
+
3150
3270
OSSDepDataTy Dep;
3151
3271
Dep.OSSSyntax = false ;
3152
3272
Dep.E = E;
3153
3273
EmitDependency (getBundleStr (OSSB_weakin), CGF, FD, Dep, TaskInfo);
3154
3274
}
3155
3275
for (const Expr *E : Attr->depWeakOuts ()) {
3276
+ OutlineGlobalVarVisitor.Visit (E);
3277
+
3156
3278
OSSDepDataTy Dep;
3157
3279
Dep.OSSSyntax = false ;
3158
3280
Dep.E = E;
3159
3281
EmitDependency (getBundleStr (OSSB_weakout), CGF, FD, Dep, TaskInfo);
3160
3282
}
3161
3283
for (const Expr *E : Attr->depWeakInouts ()) {
3284
+ OutlineGlobalVarVisitor.Visit (E);
3285
+
3162
3286
OSSDepDataTy Dep;
3163
3287
Dep.OSSSyntax = false ;
3164
3288
Dep.E = E;
3165
3289
EmitDependency (getBundleStr (OSSB_weakinout), CGF, FD, Dep, TaskInfo);
3166
3290
}
3167
3291
for (const Expr *E : Attr->depWeakConcurrents ()) {
3292
+ OutlineGlobalVarVisitor.Visit (E);
3293
+
3168
3294
OSSDepDataTy Dep;
3169
3295
Dep.OSSSyntax = false ;
3170
3296
Dep.E = E;
3171
3297
EmitDependency (getBundleStr (OSSB_weakconcurrent), CGF, FD, Dep, TaskInfo);
3172
3298
}
3173
3299
for (const Expr *E : Attr->depWeakCommutatives ()) {
3300
+ OutlineGlobalVarVisitor.Visit (E);
3301
+
3174
3302
OSSDepDataTy Dep;
3175
3303
Dep.OSSSyntax = false ;
3176
3304
Dep.E = E;
3177
3305
EmitDependency (getBundleStr (OSSB_weakcommutative), CGF, FD, Dep, TaskInfo);
3178
3306
}
3307
+
3308
+ for (const Expr *E : OutlineGlobalVarVisitor.getSharedGlobals ()) {
3309
+ SmallVector<llvm::Value *> DSABundleList;
3310
+ llvm::Value *DSAValue = CGF.EmitLValue (E).getPointer (CGF);
3311
+ DSABundleList.push_back (DSAValue);
3312
+ DSABundleList.push_back (llvm::UndefValue::get (CGF.ConvertType (E->getType ())));
3313
+ TaskInfo.emplace_back (getBundleStr (OSSB_shared), DSABundleList);
3314
+ }
3315
+
3179
3316
assert (Attr->reductions_size () == Attr->reductionLHSs_size () &&
3180
3317
Attr->reductions_size () == Attr->reductionRHSs_size () &&
3181
3318
Attr->reductions_size () == Attr->reductionOps_size () &&
0 commit comments