r321386 - [OPENMP] Captured arguments of the capturable clauses by value.

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Sun Dec 24 05:37:44 PST 2017


Sure, thanks for the report. 

Best regards,
Alexey Bataev

24 дек. 2017 г., в 8:27, Maxim Kuvyrkov <maxim.kuvyrkov at linaro.org> написал(а):

>> On Dec 23, 2017, at 12:01 AM, Alexey Bataev via cfe-commits <cfe-commits at lists.llvm.org> wrote:
>> 
>> Author: abataev
>> Date: Fri Dec 22 13:01:52 2017
>> New Revision: 321386
>> 
>> URL: https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fllvm.org%2Fviewvc%2Fllvm-project%3Frev%3D321386%26view%3Drev&data=02%7C01%7C%7C4bbee209c7424ec17ef908d54ad20f6c%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636497188414868889&sdata=4uGGwkVO9vEMdod3ZJ2c9QrzPC2GZXRkOweo2jBkNvM%3D&reserved=0
>> Log:
>> [OPENMP] Captured arguments of the capturable clauses by value.
>> 
>> If the clause is applied to the combined construct and has captured
>> expression, try to capture this expression by value rather than by
>> reference.
>> 
>> Modified:
>>   cfe/trunk/lib/Sema/SemaOpenMP.cpp
>>   cfe/trunk/test/OpenMP/parallel_for_codegen.cpp
>>   cfe/trunk/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp
>>   cfe/trunk/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp
> 
> Hi Alexey,
> 
> Changes to the teams_distribute_parallel_* tests break 32-bit ARM buildbots, e.g., https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Flab.llvm.org%3A8011%2Fbuilders%2Fclang-cmake-armv7-a15%2Fbuilds%2F14264&data=02%7C01%7C%7C4bbee209c7424ec17ef908d54ad20f6c%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636497188414868889&sdata=vp2zxOQa%2B0t7WeKV4255eNXy9A3jewY2SlBMT0OGN18%3D&reserved=0 .  Would you please investigate?
> 
> Thanks,
> 
> --
> Maxim Kuvyrkov
> https://nam04.safelinks.protection.outlook.com/?url=www.linaro.org&data=02%7C01%7C%7C4bbee209c7424ec17ef908d54ad20f6c%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636497188414868889&sdata=DzCf1pJo44ETXnttUW322oN40IwtK%2FNrxveBtOtAfT0%3D&reserved=0
> 
> 
>> 
>> Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
>> URL: https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fllvm.org%2Fviewvc%2Fllvm-project%2Fcfe%2Ftrunk%2Flib%2FSema%2FSemaOpenMP.cpp%3Frev%3D321386%26r1%3D321385%26r2%3D321386%26view%3Ddiff&data=02%7C01%7C%7C4bbee209c7424ec17ef908d54ad20f6c%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636497188414868889&sdata=omvXI%2Fct%2B%2BsGN2SZxlfd33cCISW6RIMa2wF7BK1Q%2FEY%3D&reserved=0
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Fri Dec 22 13:01:52 2017
>> @@ -1290,9 +1290,14 @@ bool Sema::IsOpenMPCapturedByRef(ValueDe
>>  }
>> 
>>  if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
>> -    IsByRef = !DSAStack->hasExplicitDSA(
>> -        D, [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
>> -        Level, /*NotLastprivate=*/true);
>> +    IsByRef =
>> +        !DSAStack->hasExplicitDSA(
>> +            D,
>> +            [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
>> +            Level, /*NotLastprivate=*/true) &&
>> +        // If the variable is artificial and must be captured by value - try to
>> +        // capture by value.
>> +        !(isa<OMPCapturedExprDecl>(D) && D->hasAttr<OMPCaptureKindAttr>());
>>  }
>> 
>>  // When passing data by copy, we need to make sure it fits the uintptr size
>> @@ -2321,10 +2326,11 @@ static OMPCapturedExprDecl *buildCapture
>>  ASTContext &C = S.getASTContext();
>>  Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
>>  QualType Ty = Init->getType();
>> +  Attr *OMPCaptureKind = nullptr;
>>  if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
>> -    if (S.getLangOpts().CPlusPlus)
>> +    if (S.getLangOpts().CPlusPlus) {
>>      Ty = C.getLValueReferenceType(Ty);
>> -    else {
>> +    } else {
>>      Ty = C.getPointerType(Ty);
>>      ExprResult Res =
>>          S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
>> @@ -2333,11 +2339,16 @@ static OMPCapturedExprDecl *buildCapture
>>      Init = Res.get();
>>    }
>>    WithInit = true;
>> +  } else if (AsExpression) {
>> +    // This variable must be captured by value.
>> +    OMPCaptureKind = OMPCaptureKindAttr::CreateImplicit(C, OMPC_unknown);
>>  }
>>  auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
>>                                          CaptureExpr->getLocStart());
>>  if (!WithInit)
>>    CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange()));
>> +  if (OMPCaptureKind)
>> +    CED->addAttr(OMPCaptureKind);
>>  S.CurContext->addHiddenDecl(CED);
>>  S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
>>  return CED;
>> @@ -2346,31 +2357,34 @@ static OMPCapturedExprDecl *buildCapture
>> static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
>>                                 bool WithInit) {
>>  OMPCapturedExprDecl *CD;
>> -  if (auto *VD = S.IsOpenMPCapturedDecl(D))
>> +  if (auto *VD = S.IsOpenMPCapturedDecl(D)) {
>>    CD = cast<OMPCapturedExprDecl>(VD);
>> -  else
>> +  } else {
>>    CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
>>                          /*AsExpression=*/false);
>> +  }
>>  return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
>>                          CaptureExpr->getExprLoc());
>> }
>> 
>> static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
>> +  CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
>>  if (!Ref) {
>> -    auto *CD =
>> -        buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."),
>> -                         CaptureExpr, /*WithInit=*/true, /*AsExpression=*/true);
>> +    OMPCapturedExprDecl *CD = buildCaptureDecl(
>> +        S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
>> +        /*WithInit=*/true, /*AsExpression=*/true);
>>    Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
>>                           CaptureExpr->getExprLoc());
>>  }
>>  ExprResult Res = Ref;
>>  if (!S.getLangOpts().CPlusPlus &&
>>      CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
>> -      Ref->getType()->isPointerType())
>> +      Ref->getType()->isPointerType()) {
>>    Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
>> -  if (!Res.isUsable())
>> -    return ExprError();
>> -  return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get());
>> +    if (!Res.isUsable())
>> +      return ExprError();
>> +  }
>> +  return S.DefaultLvalueConversion(Res.get());
>> }
>> 
>> namespace {
>> @@ -8117,12 +8131,13 @@ OMPClause *Sema::ActOnOpenMPIfClause(Ope
>>    if (Val.isInvalid())
>>      return nullptr;
>> 
>> -    ValExpr = MakeFullExpr(Val.get()).get();
>> +    ValExpr = Val.get();
>> 
>>    OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
>>    CaptureRegion =
>>        getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier);
>>    if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
>> +      ValExpr = MakeFullExpr(ValExpr).get();
>>      llvm::MapVector<Expr *, DeclRefExpr *> Captures;
>>      ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
>>      HelperValStmt = buildPreInits(Context, Captures);
>> @@ -8239,6 +8254,7 @@ OMPClause *Sema::ActOnOpenMPNumThreadsCl
>>  OpenMPDirectiveKind CaptureRegion =
>>      getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads);
>>  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
>> +    ValExpr = MakeFullExpr(ValExpr).get();
>>    llvm::MapVector<Expr *, DeclRefExpr *> Captures;
>>    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
>>    HelperValStmt = buildPreInits(Context, Captures);
>> @@ -8666,6 +8682,7 @@ OMPClause *Sema::ActOnOpenMPScheduleClau
>>                     DSAStack->getCurrentDirective(), OMPC_schedule) !=
>>                     OMPD_unknown &&
>>                 !CurContext->isDependentContext()) {
>> +        ValExpr = MakeFullExpr(ValExpr).get();
>>        llvm::MapVector<Expr *, DeclRefExpr *> Captures;
>>        ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
>>        HelperValStmt = buildPreInits(Context, Captures);
>> @@ -11355,6 +11372,7 @@ OMPClause *Sema::ActOnOpenMPDeviceClause
>>  OpenMPDirectiveKind CaptureRegion =
>>      getOpenMPCaptureRegionForClause(DKind, OMPC_device);
>>  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
>> +    ValExpr = MakeFullExpr(ValExpr).get();
>>    llvm::MapVector<Expr *, DeclRefExpr *> Captures;
>>    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
>>    HelperValStmt = buildPreInits(Context, Captures);
>> @@ -12378,6 +12396,7 @@ OMPClause *Sema::ActOnOpenMPNumTeamsClau
>>  OpenMPDirectiveKind CaptureRegion =
>>      getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams);
>>  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
>> +    ValExpr = MakeFullExpr(ValExpr).get();
>>    llvm::MapVector<Expr *, DeclRefExpr *> Captures;
>>    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
>>    HelperValStmt = buildPreInits(Context, Captures);
>> @@ -12404,6 +12423,7 @@ OMPClause *Sema::ActOnOpenMPThreadLimitC
>>  OpenMPDirectiveKind CaptureRegion =
>>      getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit);
>>  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
>> +    ValExpr = MakeFullExpr(ValExpr).get();
>>    llvm::MapVector<Expr *, DeclRefExpr *> Captures;
>>    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
>>    HelperValStmt = buildPreInits(Context, Captures);
>> @@ -12514,6 +12534,7 @@ OMPClause *Sema::ActOnOpenMPDistSchedule
>>                     DSAStack->getCurrentDirective(), OMPC_dist_schedule) !=
>>                     OMPD_unknown &&
>>                 !CurContext->isDependentContext()) {
>> +        ValExpr = MakeFullExpr(ValExpr).get();
>>        llvm::MapVector<Expr *, DeclRefExpr *> Captures;
>>        ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
>>        HelperValStmt = buildPreInits(Context, Captures);
>> 
>> Modified: cfe/trunk/test/OpenMP/parallel_for_codegen.cpp
>> URL: https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fllvm.org%2Fviewvc%2Fllvm-project%2Fcfe%2Ftrunk%2Ftest%2FOpenMP%2Fparallel_for_codegen.cpp%3Frev%3D321386%26r1%3D321385%26r2%3D321386%26view%3Ddiff&data=02%7C01%7C%7C4bbee209c7424ec17ef908d54ad20f6c%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636497188414868889&sdata=gO5%2FvKYM5xfegnQY4lTeu4LkXARKN2owh0O6hKOS2ag%3D&reserved=0
>> ==============================================================================
>> --- cfe/trunk/test/OpenMP/parallel_for_codegen.cpp (original)
>> +++ cfe/trunk/test/OpenMP/parallel_for_codegen.cpp Fri Dec 22 13:01:52 2017
>> @@ -15,10 +15,12 @@ void with_var_schedule() {
>>  double a = 5;
>> // CHECK: [[CHUNK_SIZE:%.+]] = fptosi double %{{.+}}to i8
>> // CHECK: store i8 %{{.+}}, i8* [[CHUNK:%.+]],
>> -// CHECK: call void {{.+}} @__kmpc_fork_call({{.+}}, i8* [[CHUNK]])
>> +// CHECK: [[VAL:%.+]] = load i8, i8* [[CHUNK]],
>> +// CHECK: store i8 [[VAL]], i8*
>> +// CHECK: [[CHUNK:%.+]] = load i64, i64* %
>> +// CHECK: call void {{.+}} @__kmpc_fork_call({{.+}}, i64 [[CHUNK]])
>> 
>> -// CHECK: [[CHUNK:%.+]] = load i8*, i8** %
>> -// CHECK: [[CHUNK_VAL:%.+]] = load i8, i8* [[CHUNK]],
>> +// CHECK: [[CHUNK_VAL:%.+]] = load i8, i8* %
>> // CHECK: [[CHUNK_SIZE:%.+]] = sext i8 [[CHUNK_VAL]] to i64
>> // CHECK: call void @__kmpc_for_static_init_8u([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID:%[^,]+]], i32 33, i32* [[IS_LAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]], i64 1, i64 [[CHUNK_SIZE]])
>> // CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID]])
>> 
>> Modified: cfe/trunk/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp
>> URL: https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fllvm.org%2Fviewvc%2Fllvm-project%2Fcfe%2Ftrunk%2Ftest%2FOpenMP%2Fteams_distribute_parallel_for_num_threads_codegen.cpp%3Frev%3D321386%26r1%3D321385%26r2%3D321386%26view%3Ddiff&data=02%7C01%7C%7C4bbee209c7424ec17ef908d54ad20f6c%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636497188414868889&sdata=OIh3m3LgKbVRT%2F8ptZ7dgou1iwmpgQOpSc52xboA9Jo%3D&reserved=0
>> ==============================================================================
>> --- cfe/trunk/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp (original)
>> +++ cfe/trunk/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp Fri Dec 22 13:01:52 2017
>> @@ -60,8 +60,8 @@ int main() {
>> #pragma omp teams distribute parallel for num_threads(a)
>>  for (int i = 0; i < 100; i++) {
>>    // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_1]](
>> -    // CHECK-DAG: [[A_ADDR:%.+]] = alloca i8*,
>> -    // CHECK-DAG: [[A_REF:%.+]] = load i8*, i8** [[A_ADDR]],
>> +    // CHECK-DAG: [[A_ADDR:%.+]] = alloca i64,
>> +    // CHECK-DAG: [[A_REF:%.+]] = bitcast i64* [[A_ADDR]] to i8*
>>    // CHECK-DAG: [[A_VAL:%.+]] = load i8, i8* [[A_REF]],
>>    // CHECK-DAG: [[A_EXT:%.+]] = sext i8 [[A_VAL]] to {{.+}}
>>    // CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 [[A_EXT]])
>> @@ -110,9 +110,9 @@ int main() {
>> // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 {{.+}}, {{.+}}* [[T_OMP_TEAMS_OUTLINED_3:@.+]] to {{.+}})
>> 
>> // CHECK: define{{.+}} void [[T_OMP_TEAMS_OUTLINED_3]]({{.+}}, {{.+}}, {{.+}} [[NUM_TH_CPT_IN:%.+]])
>> -// CHECK: [[NUM_TH_CPT:%.+]] = alloca i8*,
>> +// CHECK: [[NUM_TH_CPT:%.+]] = alloca i64,
>> // CHECK: store {{.+}} [[NUM_TH_CPT_IN]], {{.+}} [[NUM_TH_CPT]],
>> -// CHECK: [[NUM_TH_REF:%.+]] = load{{.+}}, {{.+}} [[NUM_TH_CPT]],
>> +// CHECK: [[NUM_TH_REF:%.+]] = bitcast i64* [[NUM_TH_CPT]] to i8*
>> // CHECK-DAG:   [[NUM_TH_VAL:%.+]] = load {{.+}}, {{.+}} [[NUM_TH_REF]],
>> // CHECK-DAG:   [[NUM_TH_SEXT:%.+]] = sext i8 [[NUM_TH_VAL]] to {{.+}}
>> // CHECK:       call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 [[NUM_TH_SEXT]])
>> 
>> Modified: cfe/trunk/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp
>> URL: https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fllvm.org%2Fviewvc%2Fllvm-project%2Fcfe%2Ftrunk%2Ftest%2FOpenMP%2Fteams_distribute_parallel_for_simd_num_threads_codegen.cpp%3Frev%3D321386%26r1%3D321385%26r2%3D321386%26view%3Ddiff&data=02%7C01%7C%7C4bbee209c7424ec17ef908d54ad20f6c%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636497188414868889&sdata=Si6%2FDw3Q0iVtrATDIXZ7j%2Fa5Ef1LbLsSV7y9011LsiI%3D&reserved=0
>> ==============================================================================
>> --- cfe/trunk/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp (original)
>> +++ cfe/trunk/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp Fri Dec 22 13:01:52 2017
>> @@ -60,8 +60,8 @@ int main() {
>> #pragma omp teams distribute parallel for simd num_threads(a)
>>  for (int i = 0; i < 100; i++) {
>>    // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_1]](
>> -    // CHECK-DAG: [[A_ADDR:%.+]] = alloca i8*,
>> -    // CHECK-DAG: [[A_REF:%.+]] = load i8*, i8** [[A_ADDR]],
>> +    // CHECK-DAG: [[A_ADDR:%.+]] = alloca i64,
>> +    // CHECK-DAG: [[A_REF:%.+]] = bitcast i64* [[A_ADDR]] to i8*
>>    // CHECK-DAG: [[A_VAL:%.+]] = load i8, i8* [[A_REF]],
>>    // CHECK-DAG: [[A_EXT:%.+]] = sext i8 [[A_VAL]] to {{.+}}
>>    // CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 [[A_EXT]])
>> @@ -110,9 +110,9 @@ int main() {
>> // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 {{.+}}, {{.+}}* [[T_OMP_TEAMS_OUTLINED_3:@.+]] to {{.+}})
>> 
>> // CHECK: define{{.+}} void [[T_OMP_TEAMS_OUTLINED_3]]({{.+}}, {{.+}}, {{.+}} [[NUM_TH_CPT_IN:%.+]])
>> -// CHECK: [[NUM_TH_CPT:%.+]] = alloca i8*,
>> +// CHECK: [[NUM_TH_CPT:%.+]] = alloca i64,
>> // CHECK: store {{.+}} [[NUM_TH_CPT_IN]], {{.+}} [[NUM_TH_CPT]],
>> -// CHECK: [[NUM_TH_REF:%.+]] = load{{.+}}, {{.+}} [[NUM_TH_CPT]],
>> +// CHECK: [[NUM_TH_REF:%.+]] = bitcast i64* [[NUM_TH_CPT]] to i8*
>> // CHECK-DAG:   [[NUM_TH_VAL:%.+]] = load {{.+}}, {{.+}} [[NUM_TH_REF]],
>> // CHECK-DAG:   [[NUM_TH_SEXT:%.+]] = sext i8 [[NUM_TH_VAL]] to {{.+}}
>> // CHECK:       call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 [[NUM_TH_SEXT]])
>> 
>> 
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at lists.llvm.org
>> https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Flists.llvm.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fcfe-commits&data=02%7C01%7C%7C4bbee209c7424ec17ef908d54ad20f6c%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636497188414868889&sdata=rjwuH4XMRAT%2BqxNEdudvp04tFTHCrwPoKOEvc6rPbAI%3D&reserved=0
> 


More information about the cfe-commits mailing list