[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