[clang-tools-extra] r225629 - Make LoopConvert work with containers that are used like arrays.

Daniel Jasper djasper at google.com
Tue Jan 13 06:59:49 PST 2015


I see. At any rate, the patch merely simplifies the loop variable for such
containers. It does not change the behavior wrt. whether or not a loop is
transformed.

On Mon, Jan 12, 2015 at 7:36 PM, David Blaikie <dblaikie at gmail.com> wrote:

>
>
> On Mon, Jan 12, 2015 at 9:44 AM, Daniel Jasper <djasper at google.com> wrote:
>
>> Thanks for checking. I'll look into it.
>>
>
> For more context/my thoughts: I think there will be cases we just can't
> detect/get right (if there's a function call in the loop and the container
> leaks somehow (it's a member variable, etc) we can't know if the user wants
> the special behavior or it's just a normal every day loop). I think
> clang-modernize has buckets for degree-of-risk for different
> transformations & this one may just need to go in a slightly risky bucket.
>
> I'm not sure if there's a nice way for a user to annotate such a loop to
> make it clear to tools that this extra behavior is required.
>
>
>> Do you have specific examples?
>>
>
> greping around I did find at least one, in
> llvm/lib/Analysis/IPA/InlineCost.cpp:
>
>   // Note that we *must not* cache the size, this loop grows the worklist.
>   for (unsigned Idx = 0; Idx != BBWorklist.size(); ++Idx) {
>
> Finding the second kind (the one that caches size() deliberately so as to
> only visit the existing elements while new ones are being added) is harder
> to find, since it's more idiomatic in LLVM to cache the size. I know I ran
> into at least one such loop in the last few weeks, though.
>
> - David
>
>
>>
>> On Mon, Jan 12, 2015 at 6:41 PM, David Blaikie <dblaikie at gmail.com>
>> wrote:
>>
>>>
>>>
>>> On Mon, Jan 12, 2015 at 5:17 AM, Daniel Jasper <djasper at google.com>
>>> wrote:
>>>
>>>> Author: djasper
>>>> Date: Mon Jan 12 07:17:56 2015
>>>> New Revision: 225629
>>>>
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=225629&view=rev
>>>> Log:
>>>> Make LoopConvert work with containers that are used like arrays.
>>>>
>>>
>>> Are these transformations classified as 'risky' in some way? These sort
>>> of loops appear in a few places in LLVM deliberately because we're adding
>>> elements to the sequence as we're iterating - so we check size each time
>>> through and we access the vector with [] because its buffer might've been
>>> invalidated by new insertions. (even with size() accessed once and cached,
>>> we sometimes do this to visit pre-existing elements and ignore newly added
>>> elements - which would still be broken by a transformation to
>>> range-based-for/iterators)
>>>
>>>
>>>>
>>>> Modified:
>>>>     clang-tools-extra/trunk/clang-modernize/LoopConvert/LoopActions.cpp
>>>>
>>>> clang-tools-extra/trunk/test/clang-modernize/LoopConvert/naming-alias.cpp
>>>>
>>>> Modified:
>>>> clang-tools-extra/trunk/clang-modernize/LoopConvert/LoopActions.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-modernize/LoopConvert/LoopActions.cpp?rev=225629&r1=225628&r2=225629&view=diff
>>>>
>>>> ==============================================================================
>>>> --- clang-tools-extra/trunk/clang-modernize/LoopConvert/LoopActions.cpp
>>>> (original)
>>>> +++ clang-tools-extra/trunk/clang-modernize/LoopConvert/LoopActions.cpp
>>>> Mon Jan 12 07:17:56 2015
>>>> @@ -450,9 +450,16 @@ static bool isAliasDecl(const Decl *TheD
>>>>        const CXXOperatorCallExpr *OpCall =
>>>> cast<CXXOperatorCallExpr>(Init);
>>>>        if (OpCall->getOperator() == OO_Star)
>>>>          return isDereferenceOfOpCall(OpCall, IndexVar);
>>>> +      if (OpCall->getOperator() == OO_Subscript) {
>>>> +        assert(OpCall->getNumArgs() == 2);
>>>> +        return true;
>>>> +      }
>>>>        break;
>>>>    }
>>>>
>>>> +  case Stmt::CXXMemberCallExprClass:
>>>> +    return true;
>>>> +
>>>>    default:
>>>>      break;
>>>>    }
>>>>
>>>> Modified:
>>>> clang-tools-extra/trunk/test/clang-modernize/LoopConvert/naming-alias.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-modernize/LoopConvert/naming-alias.cpp?rev=225629&r1=225628&r2=225629&view=diff
>>>>
>>>> ==============================================================================
>>>> ---
>>>> clang-tools-extra/trunk/test/clang-modernize/LoopConvert/naming-alias.cpp
>>>> (original)
>>>> +++
>>>> clang-tools-extra/trunk/test/clang-modernize/LoopConvert/naming-alias.cpp
>>>> Mon Jan 12 07:17:56 2015
>>>> @@ -7,6 +7,8 @@
>>>>  const int N = 10;
>>>>
>>>>  Val Arr[N];
>>>> +dependent<Val> v;
>>>> +dependent<Val> *pv;
>>>>  Val &func(Val &);
>>>>  void sideEffect(int);
>>>>
>>>> @@ -50,6 +52,25 @@ void aliasing() {
>>>>    // CHECK-NEXT: int y = t.x;
>>>>    // CHECK-NEXT: int z = elem.x + t.x;
>>>>
>>>> +  // The same for pseudo-arrays like std::vector<T> (or here
>>>> dependent<Val>)
>>>> +  // which provide a subscript operator[].
>>>> +  for (int i = 0; i < v.size(); ++i) {
>>>> +    Val &t = v[i]; { }
>>>> +    int y = t.x;
>>>> +  }
>>>> +  // CHECK: for (auto & t : v)
>>>> +  // CHECK-NEXT: { }
>>>> +  // CHECK-NEXT: int y = t.x;
>>>> +
>>>> +  // The same with a call to at()
>>>> +  for (int i = 0; i < pv->size(); ++i) {
>>>> +    Val &t = pv->at(i); { }
>>>> +    int y = t.x;
>>>> +  }
>>>> +  // CHECK: for (auto & t : *pv)
>>>> +  // CHECK-NEXT: { }
>>>> +  // CHECK-NEXT: int y = t.x;
>>>> +
>>>>    for (int i = 0; i < N; ++i) {
>>>>      Val &t = func(Arr[i]);
>>>>      int y = t.x;
>>>>
>>>>
>>>> _______________________________________________
>>>> cfe-commits mailing list
>>>> cfe-commits at cs.uiuc.edu
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>>
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150113/328f5f0c/attachment.html>


More information about the cfe-commits mailing list