<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p>Hi, TB,</p>
    <p>Just to be clear, are you using the new pass manager or the old
      one? You can't do this from the old pass manager - this was one of
      the motivations to create the new pass manager.</p>
    <p> -Hal<br>
    </p>
    <br>
    <div class="moz-cite-prefix">On 08/11/2018 09:16 AM, TB Schardl via
      llvm-dev wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAGAvDYhfuUBTbpjrVv4gkbnwPusDSdkULxyOhJMiyKVgj_SCjw@mail.gmail.com">
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <div dir="ltr">Hey LLVMDev,
        <div><br>
        </div>
        <div>I'm working on a ModulePass that uses ScalarEvolution along
          with several other analyses.  After some debugging, it looks
          to me like ScalarEvolutionWrapperPass does not handle memory
          correctly for this case.  Here's my current understanding of
          the problem.</div>
        <div><br>
        </div>
        <div>ScalarEvolutionWrapperPass maintains a unique_ptr to a
          ScalarEvolution.  Calling getSE() dereferences this pointer. 
          Meanwhile runOnFunction() resets the pointer to point to a new
          ScalarEvolution.  As a result, runOnFunction destructs and
          frees any ScalarEvolution the unique_ptr pointed to before.</div>
        <div><br>
        </div>
        <div>The ModulePass I'm working on uses ScalarEvolution and
          several other analysis FunctionPasses, including
          DominatorTree, LoopInfo, OptimizationRemarkEmitter, and a
          custom analysis pass I'm working on, which resembles
          LoopInfo.  To run ScalarEvolution and these other analysis
          FunctionPasses in a ModulePass, the ModulePass creates lambdas
          to get the analysis for a particular function, e.g.,</div>
        <div>
          <div><br>
          </div>
        </div>
        <blockquote style="margin:0 0 0 40px;border:none;padding:0px">
          <div>
            <div><font face="monospace, monospace">auto GetSE =
                [this](Function &F) -> ScalarEvolution & {</font></div>
          </div>
          <div>
            <div><font face="monospace, monospace">  return
                this->getAnalysis<ScalarEvolutionWrapperPass>(F).getSE();</font></div>
          </div>
          <div>
            <div><font face="monospace, monospace">};</font></div>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>Later, when the ModulePass examines a particular Function,
          it calls the appropriate lambda to get the analysis for that
          Function.</div>
        <div><br>
        </div>
        <div>The problem seems to arise when lambdas for other analysis
          FunctionPasses run after calling the GetSE lambda, e.g., when
          evaluating a statement like this:</div>
        <div><font face="monospace, monospace"><br>
          </font></div>
        <blockquote style="margin:0 0 0 40px;border:none;padding:0px">
          <div><font face="monospace, monospace">for (Function &F :
              M)</font></div>
          <div><font face="monospace, monospace">  Changed |=
              MyPassImpl(F, GetSE(F), GetDT(F), GetLI(F), GetORE(F),
              ...).run();</font></div>
        </blockquote>
        <div><br>
        </div>
        <div>It appears that these other analysis FunctionPasses can
          cause ScalarEvolutionWrapperPass::runOnFunction() to rerun
          after GetSE() returns a pointer to a ScalarEvolution, which
          changes the underlying ScalarEvolution object that the wrapper
          pass points to.  As a result, the pointer originally obtained
          from GetSE() points to invalid memory, and chaos ensues. 
          Running valgrind on the "opt -mypass" indicates that the
          ScalarEvolution object used by MyPassImpl points to freed
          memory.</div>
        <div><br>
        </div>
        <div>I've been able to work around this problem, but I figured I
          should raise the issue and see if you might have more insights
          into this problem.  For example, I'm not totally sure why the
          other analysis FunctionPasses cause
          ScalarEvolutionWrapperPass::runOnFunction() to rerun.  I'm
          also concerned about other analysis FunctionPasses, that might
          suffer from the same problem.  MemorySSAWrapperPass, for
          example, uses a unique_ptr similarly to ScalarEvolution.</div>
        <div><br>
        </div>
        <div>Cheers,</div>
        <div>TB</div>
      </div>
      <!--'"--><br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
LLVM Developers mailing list
<a class="moz-txt-link-abbreviated" href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>
<a class="moz-txt-link-freetext" href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a>
</pre>
    </blockquote>
    <br>
    <pre class="moz-signature" cols="72">-- 
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory</pre>
  </body>
</html>