Hi Susan,<div><br></div><div>I tested the version of Gcra.cpp that I sent you on x86-64 systems running MacOS 10.8 and Ubuntu 12.04 (Linux 3.2.0).</div><div><br></div><div>Could you send me the bitcode file you're compiling? Different bitcodes (due to different clang versions or applied optimizations) could account for the different results we're seeing. For reference I've attached the *.ll file that I have tested with, which was compiled from your tst.c file with:</div>
<div><br></div><div>clang -O0 -emit-llvm -S -o tst.ll tst.c</div><div><br></div><div>My clang version was built from a recent checkout from subversion.</div><div><br></div><div>It's unlikely that there is any fundamental problem with the register allocation APIs or the code generator that would prevent you from building a working allocator. The APIs certainly could have changed in a way that would break existing allocators though.</div>
<div><br></div><div>- Lang.</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sat, Nov 3, 2012 at 4:34 PM, Susan Horwitz <span dir="ltr"><<a href="mailto:horwitz@cs.wisc.edu" target="_blank">horwitz@cs.wisc.edu</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div bgcolor="#FFFFFF" text="#000000">
    <div>Lang -<br>
      <br>
      Your version does NOT work for me (i.e., I still get an error from
      the assembler when I run your code on my tst.c) unless I force
      compilation and assembly for a 32-bit X86 machine:<br>
      <pre> llc -march=x86 -regalloc=gc tst.bc
 gcc -m32 tst.s
</pre>
      My machine is a 64-bit machine.  Maybe you are working with a
      different architecture and that's why it worked for you?  <br>
      <br>
      I would be happy if the above worked in general, but when I try
      other C code (with my "real" register allocator, not the naive one
      I sent you) I get assembly that includes<br>
      <br>
          %r8d<br>
      <br>
      which seems to be invalid for a 32-bit machine.  Sigh.  It looks
      to me like there's a problem with the LLVM-3.1 API for register
      allocation and/or the code-generation phase.  What do you think?<span class="HOEnZb"><font color="#888888"><br>
      <br>
      Susan</font></span><div><div class="h5"><br>
      <br>
      On 11/1/2012 5:28 PM, Lang Hames wrote:<br>
    </div></div></div><div><div class="h5">
    <blockquote type="cite">
      
      Hi Susan,
      <div><br>
      </div>
      <div>Without debugging symbols I can't make much out of that stack
        trace I'm afraid.</div>
      <div><br>
      </div>
      <div>I've attached my modified version of Gcra.cpp. I built llvm
        3.1 by dropping this file into lib/CodeGen, and adding
        references to createGcra to include/lib/CodeGen/Passes.h and
        include/lib/CodeGen/LinkAllCodeGenComponents.h. (If you search
        for createRegAllocPBQP you'll see where to add the
        declarations).</div>
      <div><br>
      </div>
      <div>With that setup, running your allocator on the tst.c file you
        attached previously yielded a sane assembly file.</div>
      <div><br>
      </div>
      <div>Cheers,</div>
      <div>Lang.</div>
      <div><br>
        <div class="gmail_quote">On Thu, Nov 1, 2012 at 3:13 PM, Susan
          Horwitz <span dir="ltr"><<a href="mailto:horwitz@cs.wisc.edu" target="_blank">horwitz@cs.wisc.edu</a>></span>
          wrote:<br>
          <blockquote class="gmail_quote">I still get a coredump:<br>
            <br>
            0  <a href="http://libLLVM-3.1.so" target="_blank">libLLVM-3.1.so</a>  0x00007f0158a4e67f<br>
            1  <a href="http://libLLVM-3.1.so" target="_blank">libLLVM-3.1.so</a>  0x00007f0158a500ca<br>
            2  libpthread.so.0 0x0000003a86c0f500<br>
            3  <a href="http://libLLVM-3.1.so" target="_blank">libLLVM-3.1.so</a>  0x00007f01583c346c<br>
            4  <a href="http://libLLVM-3.1.so" target="_blank">libLLVM-3.1.so</a>  0x00007f0158546349
            llvm::FPPassManager::runOnFunction(llvm::Function&) +
            521<br>
            5  <a href="http://libLLVM-3.1.so" target="_blank">libLLVM-3.1.so</a>  0x00007f01585463e3
            llvm::FPPassManager::runOnModule(llvm::Module&) + 51<br>
            6  <a href="http://libLLVM-3.1.so" target="_blank">libLLVM-3.1.so</a>  0x00007f0158545fae
            llvm::MPPassManager::runOnModule(llvm::Module&) + 462<br>
            7  <a href="http://libLLVM-3.1.so" target="_blank">libLLVM-3.1.so</a>  0x00007f01585460bd
            llvm::PassManagerImpl::run(llvm::Module&) + 125<br>
            8  llc             0x000000000040b012 main + 5218<br>
            9  libc.so.6       0x0000003a8601ecdd __libc_start_main +
            253<br>
            10 llc             0x0000000000407d79<br>
            Stack dump:<br>
            0.      Program arguments: llc -load Debug/lib/P4.so
            -regalloc=gc tst.bc<br>
            1.      Running pass 'Function Pass Manager' on module
            'tst.bc'.<br>
            2.      Running pass 'Machine Loop Invariant Code Motion' on
            function '@main'<br>
            make: *** [tst.reg] Segmentation fault (core dumped)
            <div><br>
              <br>
              <br>
              On 11/01/2012 04:59 PM, Lang Hames wrote:<br>
            </div>
            <blockquote class="gmail_quote">
              Hi Susan,<br>
              <br>
              <div>
                Sorry - I had missed that you're using llvm-3.1, rather
                than the<br>
                development branch. We encourage people to live on
                top-of-tree - it's<br>
                well tested, easier for active developers to offer help
                with, and<br>
                keeping up with incremental changes is often easier than
                porting between<br>
                stable versions.<br>
                <br>
                It also sounds like you were building a Release version
                of LLVM. That<br>
                will not have any asserts enabled (though it will have
                some other<br>
                diagnostics). You will probably want to work with a
                Debug+Asserts<br>
                version (<src>/configure --disable-optimized
                --enable-assertions) while<br>
                you're developing your allocator and watch for any
                asserts that trigger.<br>
                <br>
                In your case the Assertion that is triggering in PEI
                indicates that the<br>
                MachineRegisterInfo object still contained some virtregs
                post<br>
                register-allocation. You need to call
                MRI->clearVirtRegs() at the end of<br>
                your allocator.<br>
                <br>
                Hope this helps!<br>
                <br>
                Cheers,<br>
                Lang.<br>
                <br>
                On Thu, Nov 1, 2012 at 2:41 PM, Susan Horwitz <<a href="mailto:horwitz@cs.wisc.edu" target="_blank">horwitz@cs.wisc.edu</a><br>
              </div>
              <div>
                <div>
                  <mailto:<a href="mailto:horwitz@cs.wisc.edu" target="_blank">horwitz@cs.wisc.edu</a>>>
                  wrote:<br>
                  <br>
                      Hi again Lang,<br>
                  <br>
                      I decided to try the approach you proposed to see
                  whether it makes<br>
                      the assembly-code problem go away.  Again, I tried
                  a very simple<br>
                      register allocator (attached) that just calls
                  vrm.assignVirt2Phys<br>
                      for every vreg in each function, mapping the vreg
                  to the first preg<br>
                      in the register class.  I tried two versions: one
                  maps *every* vreg,<br>
                      and the other only maps those for which
                  MRI->reg_empty(vreg) returns<br>
                      false.  In both cases I get a core dump somewhere
                  after my<br>
                      reg-allocation pass has run (when I use the
                  "tst.c" file that I sent<br>
                      last time as input).<br>
                  <br>
                      Note also that there is no VirtRegMap.h in the
                  "include" directory<br>
                      of my installed llvm-3.1.  I had to copy that file
                  from the source<br>
                      directory.  That seems suspicious.<br>
                  <br>
                      Any thoughts?<br>
                  <br>
                      Thanks!<br>
                  <br>
                      Susan<br>
                  <br>
                  <br>
                      On 10/31/2012 07:51 PM, Lang Hames wrote:<br>
                  <br>
                          Hi Susan,<br>
                  <br>
                          I'm having trouble reproducing that error on
                  my end, but I think the<br>
                          problem is probably that you're not using the
                  VirtRegRewriter<br>
                          infrastructure. What your allocator needs to
                  do is populate the<br>
                          virtual<br>
                          register mapping (VirtRegMap pass) with your
                  allocation, rather than<br>
                          rewriting the registers directly through
                  MachineRegisterInfo.<br>
                  <br>
                          Have your allocator require and preserve the
                  VirtRegMap pass,<br>
                          then in<br>
                          your runOnMachineFunction pass grab a
                  reference to the pass with:<br>
                  <br>
                          VirtRegMap &vrm =
                  getAnalysis<VirtRegMap>();<br>
                  <br>
                          You can then describe your register
                  allocations with:<br>
                  <br>
                          vrm.assignVirt2Phys(<virtreg>,
                  <physreg>)<br>
                  <br>
                          The VirtRegRewriter pass (in VirtRegMap.cpp)
                  will run after your<br>
                          allocator and apply the mapping that you
                  described in the<br>
                          VirtRegMap.<br>
                  <br>
                          I hope this helps. Let me know if it doesn't
                  fix your issue.<br>
                  <br>
                          Cheers,<br>
                          Lang.<br>
                  <br>
                          On Wed, Oct 31, 2012 at 3:54 PM, Susan Horwitz<br>
                          <<a href="mailto:horwitz@cs.wisc.edu" target="_blank">horwitz@cs.wisc.edu</a>
                  <mailto:<a href="mailto:horwitz@cs.wisc.edu" target="_blank">horwitz@cs.wisc.edu</a>><br>
                </div>
              </div>
              <div>
                <div>
                          <mailto:<a href="mailto:horwitz@cs.wisc.edu" target="_blank">horwitz@cs.wisc.edu</a>
                  <mailto:<a href="mailto:horwitz@cs.wisc.edu" target="_blank">horwitz@cs.wisc.edu</a>>>>
                  wrote:<br>
                  <br>
                               Thanks Lang!<br>
                  <br>
                               Here's another question: I'm trying to
                  process this input:<br>
                  <br>
                               int main() {<br>
                                  return 0;<br>
                               }<br>
                  <br>
                               but I'm getting an error<br>
                                 Assertion `!Fn.getRegInfo().
                  getNumVirtRegs() &&<br>
                          "Regalloc must<br>
                  <br>
                               assign all vregs"' failed.<br>
                  <br>
                               At the start of runOnMachineFunction I
                  call Fn.getRegInfo().<br>
                               getNumVirtRegs();<br>
                               and find that there is 1 virtual
                  register.  However,<br>
                                 MRI->reg_empty(vreg)<br>
                               tells me that it is not used or defined.
                   So my<br>
                          register-allocation<br>
                               code never sees it, and thus can't
                  allocate a preg for it.<br>
                            I tried<br>
                               using MRI->replaceRegWith(vreg, preg);<br>
                               (where preg is available to vreg's
                  register class) but that<br>
                          didn't<br>
                               work.  When I look, the number of vregs
                  in the function is<br>
                          still 1.<br>
                  <br>
                               Can you help with this?<br>
                  <br>
                               Thanks again!<br>
                  <br>
                               Susan<br>
                  <br>
                  <br>
                               On 10/31/2012 04:55 PM, Lang Hames wrote:<br>
                  <br>
                                   Hi Susan,<br>
                  <br>
                                   The meaning of "addRequired(X)" is
                  that your pass needs<br>
                          X to be<br>
                                   run, and<br>
                                   for X to be preserved by all passes
                  that run after X<br>
                          and before your<br>
                                   pass. The PHIElemination and
                  TwoAddressInstruction<br>
                          passes do not<br>
                                   preserve each other, hence there's no
                  way for the pass<br>
                          manager to<br>
                                   schedule them for you if you
                  addRequire(...) them.<br>
                  <br>
                                   The trick is that CodeGen will
                  schedule both of these<br>
                          passes to<br>
                                   be run<br>
                                   before _any_ register allocation pass
                  (see Passes.cpp),<br>
                          so you<br>
                                   needn't<br>
                                   require them explicitly - you can
                  just assume they have<br>
                          been<br>
                                   run. If you<br>
                                   just remove those lines from your
                  getAnalysisUsage<br>
                          method your pass<br>
                                   should now run as you expect.<br>
                  <br>
                                   Cheers,<br>
                                   Lang.<br>
                  <br>
                                   On Wed, Oct 31, 2012 at 1:46 PM,
                  Susan Horwitz<br>
                          <<a href="mailto:horwitz@cs.wisc.edu" target="_blank">horwitz@cs.wisc.edu</a>
                  <mailto:<a href="mailto:horwitz@cs.wisc.edu" target="_blank">horwitz@cs.wisc.edu</a>><br>
                          <mailto:<a href="mailto:horwitz@cs.wisc.edu" target="_blank">horwitz@cs.wisc.edu</a>
                  <mailto:<a href="mailto:horwitz@cs.wisc.edu" target="_blank">horwitz@cs.wisc.edu</a>>><br>
                          <mailto:<a href="mailto:horwitz@cs.wisc.edu" target="_blank">horwitz@cs.wisc.edu</a>
                  <mailto:<a href="mailto:horwitz@cs.wisc.edu" target="_blank">horwitz@cs.wisc.edu</a>><br>
                          <mailto:<a href="mailto:horwitz@cs.wisc.edu" target="_blank">horwitz@cs.wisc.edu</a>
                  <mailto:<a href="mailto:horwitz@cs.wisc.edu" target="_blank">horwitz@cs.wisc.edu</a>>>>>
                  wrote:<br>
                  <br>
                                        I'm trying to write a
                  MachineFunctionPass to do<br>
                          register<br>
                                   allocation.<br>
                                          I have code that worked with
                  an old version of<br>
                          LLVM.  It<br>
                                   does not<br>
                                        work with llvm-3.1. (or various
                  other versions<br>
                          that I've<br>
                                   tried).<br>
                  <br>
                                        The first problem is that
                  including this line:<br>
                  <br>
                                          AU.addRequiredID(__
                  TwoAddressInstructionPassID);<br>
                  <br>
                  <br>
                                        in method getAnalysisUsage
                  causes a runtime error:<br>
                  <br>
                                        Unable to schedule 'Eliminate
                  PHI nodes for register<br>
                                   allocation'<br>
                                        required by 'Unnamed pass:
                  implement<br>
                          Pass::getPassName()'<br>
                                        Unable to schedule pass<br>
                                        UNREACHABLE executed at ...<br>
                  <br>
                                        I'm invoking the pass like this
                  (given input file<br>
                          foo.c):<br>
                  <br>
                                        clang -emit-llvm -O0 -c foo.c -o
                  foo.bc<br>
                                        opt -mem2reg foo.bc > foo.ssa<br>
                                        mv foo.ssa foo.bc<br>
                                        llc -load Debug/lib/P4.so
                  -regalloc=gc foo.bc<br>
                  <br>
                  <br>
                                        I've attached my entire file
                  (it's very short).<br>
                            Any help<br>
                                   would be<br>
                                        much appreciated!<br>
                  <br>
                                        Susan Horwitz<br>
                  <br>
                                        ______________________________
                  _________________<br>
                                        LLVM Developers mailing list<br>
                          <a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>
                  <mailto:<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>><br>
                          <mailto:<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>
                  <mailto:<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>>><br>
                          <mailto:<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>
                  <mailto:<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>><br>
                          <mailto:<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>
                  <mailto:<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>>>><br>
                  <br>
                          <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
                          <a href="http://lists.cs.uiuc.edu/" target="_blank">http://lists.cs.uiuc.edu/</a>
                  mailman/listinfo/llvmdev<br>
                </div>
              </div>
                      <<a href="http://lists.cs.uiuc.edu/__mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/__mailman/listinfo/llvmdev</a><br>
                      <<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a>>><br>
              <br>
              <br>
              <br>
              <br>
              <br>
              <br>
            </blockquote>
            <br>
          </blockquote>
        </div>
        <br>
      </div>
    </blockquote>
    <br>
  </div></div></div>

</blockquote></div><br></div>