[LLVMdev] The use iterator not working...
Jonathan Roelofs
jonathan at codesourcery.com
Wed Jun 10 10:09:51 PDT 2015
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