[LLVMdev] The use iterator not working...

Zack Waters zswaters at gmail.com
Wed Jun 10 10:22:55 PDT 2015


This kind of change can really make it difficult to migrate a large LLVM
based compiler from an older version to the latest when you're not aware of
it and its a silent error.

On Wed, Jun 10, 2015 at 10:14 AM, Daniel Berlin <dberlin at dberlin.org> wrote:

> 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150610/256f8854/attachment.html>


More information about the llvm-dev mailing list