[LLVMdev] The use iterator not working...
Daniel Berlin
dberlin at dberlin.org
Wed Jun 10 10:14:19 PDT 2015
I stand corrected :)
On Wed, Jun 10, 2015 at 10:09 AM, Jonathan Roelofs
<jonathan at codesourcery.com> wrote:
>
>
> On 6/10/15 11:01 AM, Zack Waters wrote:
>>
>> It appears dereferencing the use iterator returned the "user" in older
>> LLVM versions. See the following commit to Use.h. You can see that the
>> intention is to return the "user". So this is not the behavior anymore.
>>
>>
>> https://github.com/llvm-mirror/llvm/commit/d1fe495464e4abc384565813cbf1cb8b130e5a6d
>>
>> - // Retrieve a pointer to the current User.
>> - UserTy *operator*() const {
>> - assert(U && "Cannot dereference end iterator!");
>> - return U->getUser();
>> - }
>
>
> Looks like the change actually happened in:
> https://github.com/llvm-mirror/llvm/commit/36b699f2b139a30a2dfa4448223d6985b55daa8a
> (r203364), and from the commit message, it was deliberate. Whether or not
> that part of it was a "good" change is a different question.
>
>
> Jon
>
>>
>>
>> Zack
>>
>> On Wed, Jun 10, 2015 at 7:17 AM, Daniel Berlin <dberlin at dberlin.org
>> <mailto:dberlin at dberlin.org>> wrote:
>>
>> It has, AFAIK, always been this way.
>> It is also a common source of bugs, as I believe you have discovered.
>>
>> If we had llvm-specific "clang warnings", this would be one i added
>> (IE "Dereferencing use iterator of x gives x") :)
>>
>> In the past 6 months, i did this twice by accident in passes and then
>> spent hours tracking it down.
>>
>> It actually makes me wonder whether use_iterator should even have an
>> operator * for the use_iterator_impl<Use> case. ISTM to basically
>> always be a bug (though this is an idle thought, i haven't thought
>> through the implications at all).
>>
>>
>>
>> On Tue, Jun 9, 2015 at 7:54 PM, Zack Waters <zswaters at gmail.com
>> <mailto:zswaters at gmail.com>> wrote:
>> > Thanks Dan and Jon. I made an incorrect assumption that the "use"
>> iterator
>> > was actually giving me the "user" when de-referencing it.
>> >
>> > Did it always have this behavior in previous LLVM versions? I've
>> seen lots
>> > of examples of the "use" iterator being dereferenced and resulting
>> > Instruction pointer being treated as the "user"?
>> >
>> > Thanks,
>> > Zack
>> >
>> >
>> > On Tue, Jun 9, 2015 at 7:25 PM, Jonathan Roelofs
>> <jonathan at codesourcery.com <mailto:jonathan at codesourcery.com>>
>>
>> > wrote:
>> >>
>> >>
>> >>
>> >> On 6/9/15 8:02 PM, Zack Waters wrote:
>> >>>
>> >>> Hi,
>> >>>
>> >>> I'm having a problem with the use iterator. Each "use" that I
>> see, when
>> >>> using the use_iterator, is the same as the "def". Meaning, in
>> the code
>> >>> below the pDef is always equal to pUse pointer for every
>> instruction in
>> >>> all basic blocks (except terminators).
>> >>>
>> >>> for (auto i = inst_begin(f), ie = inst_end(f); i
>> != ie; ++i)
>> >>> Instruction* pDef = &(*i);
>> >>> errs() << "Def: " << *pDef << "\n";
>> >>>
>> >>> for (auto ui = pDef->use_begin(), uie =
>> >>> pDef->use_end(); ui != uie; ++ui)
>> >>> {
>> >>
>> >>
>> >> 'user' != 'use'.
>> >>
>> >> Think of llvm::Use as the edge between the place where a value is
>> >> produced, and the place where that value is consumed. The
>> consumer is the
>> >> 'User', and the Use points at it.
>> >>
>> >> http://llvm.org/docs/doxygen/html/classllvm_1_1Use.html
>> >>
>> >> The confusing thing that's happening below is that the llvm::Use
>> is
>> >> implicitly converted via `llvm::Use::operator Value *() const` to
>> a
>> >> `Value*`, and that `Value*` is `pDef`.
>> >>
>> >>
>> >> HTH,
>> >>
>> >> Jon
>> >>
>> >>> Instruction* pUse =
>> dyn_cast<Instruction>(*ui);
>> >>> errs() << " Use: \t" << *pUse << "\n";
>> >>> }
>> >>> }
>> >>>
>> >>> However, everything works as expected when using the
>> range-based use
>> >>> iterator with the following code.
>> >>>
>> >>> for (auto i = inst_begin(f), ie = inst_end(f); i
>> != ie; ++i)
>> >>> {
>> >>> Instruction* pDef = &(*i);
>> >>> errs() << "Def: " << *pDef << "\n";
>> >>>
>> >>> for (User* pUser : pDef->users())
>> >>> {
>> >>> Instruction* pUse =
>> dyn_cast<Instruction>(pUser);
>> >>> errs() << " Use: \t" << *pUse << "\n";
>> >>> }
>> >>> }
>> >>>
>> >>> Also, the code is executed inside a function pass. So was
>> initially
>> >>> thinking I somehow screwed up the use information in a previous
>> pass.
>> >>> However, I would assume the range-based iterator would not work
>> as well
>> >>> but it does.
>> >>>
>> >>> Finally, I'm currently using LLVM 3.5.1 built for Windows.
>> Google hasn't
>> >>> been much help. Anybody have any suggestions as to why the
>> first example
>> >>> above doesn't work?
>> >>>
>> >>> Thanks,
>> >>> Zack
>> >>>
>> >>>
>> >>> _______________________________________________
>> >>> LLVM Developers mailing list
>> >>> LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu>
>> http://llvm.cs.uiuc.edu
>> >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>> >>>
>> >>
>> >> --
>> >> Jon Roelofs
>> >> jonathan at codesourcery.com <mailto:jonathan at codesourcery.com>
>> >> CodeSourcery / Mentor Embedded
>> >
>> >
>> >
>> > _______________________________________________
>> > LLVM Developers mailing list
>> > LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu>
>> http://llvm.cs.uiuc.edu
>> > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>> >
>>
>>
>
> --
> Jon Roelofs
> jonathan at codesourcery.com
> CodeSourcery / Mentor Embedded
More information about the llvm-dev
mailing list