[LLVMdev] problem trying to write an LLVM register-allocation pass
Susan Horwitz
horwitz at cs.wisc.edu
Fri Nov 9 11:15:46 PST 2012
Thanks Lang, we are making progress! I no longer get the failed
assertion, but the code I'm using for vregs that don't get allocated a
preg, and thus need to be spilled and re-loaded is causing assembler errors.
I suspect the problem is my code for allocating space in the stack, but
I don't know how to fix it.
I've attached a new version of the simple register-allocation code, a
test program that causes the bad assembler to be produced, and the bc
file. (I had to name everything with a .txt extension to copy the files
to my laptop.)
As always, thank you for your help!
Susan
On 11/7/2012 7:31 PM, Lang Hames wrote:
> Hi Susan,
>
> In x86-64 the REX prefix must be used to access an extended register
> (r8-r15 and their aliases), but cannot be used when accessing the high
> byte of the ABCD regs (AH, BH, CH, DH). In your test case you have
> hardcoded %vreg1 to R8B, and %vreg15 to AH, and the test case contains
> a copy between these registers. The copy simultaneously must have a
> REX prefix, and cannot have a REX prefix, hence the assertion.
>
> The problem is that not all registers in a class are allocable for all
> vregs. As you can see from the above constraint, which pregs are valid
> varies dynamically depending on the context that the register is used.
> The trick is to query the "allocation order" for a class (and as an
> added headache filter out any reserved registers). I've attached a
> test-case where I do this somewhat manually. In short:
>
> int regClass = MRI->getRegClass(vreg)->getID();
> const TargetRegisterClass *trc = TRI->getRegClass(regClass);
> ArrayRef<uint16_t> rawOrder = trc->getRawAllocationOrder(Fn);
> ArrayRef<uint16_t>::iterator rItr = rawOrder.begin();
> while (reservedRegs.test(*rItr))
> ++rItr;
> preg = *rItr;
>
> Alternatively, you could use the AllocationOrder class
> (lib/CodeGen/AllocationOrder.h). This has the benefit of considering
> register hints for improved coalescing too. It does, however, require
> you to use VirtRegMap.
>
> Hope this helps!
>
> Cheers,
> Lang.
>
>
>
> On Wed, Nov 7, 2012 at 2:56 PM, Lang Hames <lhames at gmail.com
> <mailto:lhames at gmail.com>> wrote:
>
> Hi Susan,
>
> Sorry for the delayed response. Thanks for the test cases - I'm
> looking in to this now.
>
> - Lang.
>
>
> On Mon, Nov 5, 2012 at 2:58 PM, Susan Horwitz <horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>> wrote:
>
> Hi Lang,
>
> I looked more into one of the problems I'm now having, and
> I've attached 3 files:
>
> Gcra.cpp is like your version except that for two specific
> vregs it uses hard-coded pregs instead of the first in the
> corresponding class.
>
> bug1.c is an input that causes the failed assertion for me.
> If I use the non-debug version of LLVM-3.1 I instead get
> assembler errors like this:
> Error: can't encode register '%ah' in an instruction
> requiring REX prefix.
>
> bug1.bc is my bitcode version of bug1.c.
>
> The problematic vregs are both in register class 0. One is
> replaced with preg 1 and the other with preg 74. Those are
> both in register class 0, and are not aliased. Any idea why
> using those pregs causes trouble?
>
> Thanks!
>
> Susan
>
>
> On 11/04/2012 06:19 PM, Lang Hames wrote:
>
> Hi Susan,
>
> With your bitcode file I am now able to reproduce the
> issue you're
> seeing. It looks like this is a problem with the naive
> rewriting from
> virtregs to physregs. It appears that the subreg field of
> physreg
> operands is ignored post-register allocation. In your testcase
> %vreg11:sub32 is being rewritten to RBX:sub32, but the
> :sub32 part is
> being quietly dropped when the assembly is written out. If
> this is
> expected behaviour, and is still happening in the
> development branch,
> then I'll add some sort of verification to catch it.
>
> The VirtRegMap::rewrite() method sidesteps this issue by
> rewriting
> physreg operands to remove the subreg field. The code for
> this is in
> VirtRegMap.cpp, around line 165. In short:
>
> PhysReg = MO.getReg();
> if (MO.getSubReg() != 0) {
> PhysReg = TRI->getSubReg(PhysReg, MO.getSubReg());
> MO.setSubReg(0);
> }
> MO.setReg(PhysReg);
>
> Adding this code to Gcra fixes the assembly issue for me.
> I've attached
> my updated copy. Hope this helps.
>
> Cheers,
> Lang.
>
>
> On Sun, Nov 4, 2012 at 2:08 PM, Susan Horwitz
> <horwitz at cs.wisc.edu <mailto:horwitz at cs.wisc.edu>
> <mailto:horwitz at cs.wisc.edu <mailto:horwitz at cs.wisc.edu>>>
> wrote:
>
> My tst.bc is attached. I had to use ssh to copy it
> from my office
> machine to my home laptop. In case that corrupts it,
> I also put a
> copy here:
> http://pages.cs.wisc.edu/~horwitz/LANG/tst.bc
> <http://pages.cs.wisc.edu/%7Ehorwitz/LANG/tst.bc>
>
> I created the file like this:
>
> clang -emit-llvm -O0 -c tst.c -o tst.bc
> opt -mem2reg tst.bc > tst.mem2reg
> mv tst.mem2reg tst.bc
>
>
> Susan
>
>
> On 11/4/2012 3:27 PM, Lang Hames wrote:
>
> Hi Susan,
>
> 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).
>
> 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:
>
> clang -O0 -emit-llvm -S -o tst.ll tst.c
>
> My clang version was built from a recent checkout
> from subversion.
>
> 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.
>
> - Lang.
>
>
> On Sat, Nov 3, 2012 at 4:34 PM, Susan Horwitz
> <horwitz at cs.wisc.edu <mailto:horwitz at cs.wisc.edu>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>>> wrote:
>
> Lang -
>
> 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:
>
> llc -march=x86 -regalloc=gc tst.bc
> gcc -m32 tst.s
>
> My machine is a 64-bit machine. Maybe you are
> working with a
> different architecture and that's why it
> worked for you?
>
> 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
>
> %r8d
>
> 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?
>
> Susan
>
>
> On 11/1/2012 5:28 PM, Lang Hames wrote:
>
> Hi Susan,
>
> Without debugging symbols I can't make
> much out of that stack
> trace I'm afraid.
>
> 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).
>
> With that setup, running your allocator on
> the tst.c file you
> attached previously yielded a sane
> assembly file.
>
> Cheers,
> Lang.
>
> On Thu, Nov 1, 2012 at 3:13 PM, Susan Horwitz
> <horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>>> wrote:
>
> I still get a coredump:
>
> 0 libLLVM-3.1.so
> <http://libLLVM-3.1.so> <http://libLLVM-3.1.so>
> 0x00007f0158a4e67f
> 1 libLLVM-3.1.so
> <http://libLLVM-3.1.so> <http://libLLVM-3.1.so>
> 0x00007f0158a500ca
> 2 libpthread.so.0 0x0000003a86c0f500
>
> 3 libLLVM-3.1.so
> <http://libLLVM-3.1.so> <http://libLLVM-3.1.so>
> 0x00007f01583c346c
> 4 libLLVM-3.1.so
> <http://libLLVM-3.1.so> <http://libLLVM-3.1.so>
> 0x00007f0158546349
>
> llvm::FPPassManager::runOnFunction(llvm::Function&) +
> 521
> 5 libLLVM-3.1.so
> <http://libLLVM-3.1.so> <http://libLLVM-3.1.so>
>
> 0x00007f01585463e3
>
> llvm::FPPassManager::runOnModule(llvm::Module&) + 51
> 6 libLLVM-3.1.so
> <http://libLLVM-3.1.so> <http://libLLVM-3.1.so>
>
> 0x00007f0158545fae
>
> llvm::MPPassManager::runOnModule(llvm::Module&) + 462
> 7 libLLVM-3.1.so
> <http://libLLVM-3.1.so> <http://libLLVM-3.1.so>
>
> 0x00007f01585460bd
>
> llvm::PassManagerImpl::run(llvm::Module&) + 125
> 8 llc 0x000000000040b012 main + 5218
> 9 libc.so.6 0x0000003a8601ecdd
> __libc_start_main + 253
> 10 llc 0x0000000000407d79
> Stack dump:
> 0. Program arguments: llc -load
> Debug/lib/P4.so
> -regalloc=gc tst.bc
> 1. Running pass 'Function Pass
> Manager' on module
> 'tst.bc'.
> 2. Running pass 'Machine Loop
> Invariant Code Motion'
> on function '@main'
> make: *** [tst.reg] Segmentation fault
> (core dumped)
>
>
>
> On 11/01/2012 04:59 PM, Lang Hames wrote:
>
> Hi Susan,
>
> Sorry - I had missed that you're
> using llvm-3.1,
> rather than the
> development branch. We encourage
> people to live on
> top-of-tree - it's
> well tested, easier for active
> developers to offer
> help with, and
> keeping up with incremental
> changes is often easier
> than porting between
> stable versions.
>
> It also sounds like you were
> building a Release
> version of LLVM. That
> will not have any asserts enabled
> (though it will
> have some other
> diagnostics). You will probably
> want to work with a
> Debug+Asserts
> version (<src>/configure
> --disable-optimized
> --enable-assertions) while
> you're developing your allocator
> and watch for any
> asserts that trigger.
>
> In your case the Assertion that is
> triggering in PEI
> indicates that the
> MachineRegisterInfo object still
> contained some
> virtregs post
> register-allocation. You need to call
> MRI->clearVirtRegs() at the end of
> your allocator.
>
> Hope this helps!
>
> Cheers,
> Lang.
>
> On Thu, Nov 1, 2012 at 2:41 PM,
> Susan Horwitz
> <horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>>>> wrote:
>
> Hi again Lang,
>
> I decided to try the approach
> you proposed to see
> whether it makes
> the assembly-code problem go
> away. Again, I
> tried a very simple
> register allocator (attached)
> that just calls
> vrm.assignVirt2Phys
> for every vreg in each
> function, mapping the vreg
> to the first preg
> in the register class. I
> tried two versions: one
> maps *every* vreg,
> and the other only maps those
> for which
> MRI->reg_empty(vreg) returns
> false. In both cases I get a
> core dump somewhere
> after my
> reg-allocation pass has run
> (when I use the
> "tst.c" file that I sent
> last time as input).
>
> Note also that there is no
> VirtRegMap.h in the
> "include" directory
> of my installed llvm-3.1. I
> had to copy that
> file from the source
> directory. That seems suspicious.
>
> Any thoughts?
>
> Thanks!
>
> Susan
>
>
> On 10/31/2012 07:51 PM, Lang
> Hames wrote:
>
> Hi Susan,
>
> I'm having trouble
> reproducing that error on
> my end, but I think the
> problem is probably that
> you're not using the
> VirtRegRewriter
> infrastructure. What your
> allocator needs to
> do is populate the
> virtual
> register mapping
> (VirtRegMap pass) with your
> allocation, rather than
> rewriting the registers
> directly through
> MachineRegisterInfo.
>
> Have your allocator
> require and preserve the
> VirtRegMap pass,
> then in
> your runOnMachineFunction
> pass grab a
> reference to the pass with:
>
> VirtRegMap &vrm =
> getAnalysis<VirtRegMap>();
>
> You can then describe your
> register
> allocations with:
>
> vrm.assignVirt2Phys(<virtreg>, <physreg>)
>
> The VirtRegRewriter pass
> (in VirtRegMap.cpp)
> will run after your
> allocator and apply the
> mapping that you
> described in the
> VirtRegMap.
>
> I hope this helps. Let me
> know if it doesn't
> fix your issue.
>
> Cheers,
> Lang.
>
> On Wed, Oct 31, 2012 at
> 3:54 PM, Susan Horwitz
> <horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>>>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>>>>> wrote:
>
> Thanks Lang!
>
> Here's another
> question: I'm trying to
> process this input:
>
> int main() {
> return 0;
> }
>
> but I'm getting an error
> Assertion
> `!Fn.getRegInfo().
> getNumVirtRegs() &&
> "Regalloc must
>
> assign all vregs"'
> failed.
>
> At the start of
> runOnMachineFunction I
> call Fn.getRegInfo().
> getNumVirtRegs();
> and find that there
> is 1 virtual
> register. However,
> MRI->reg_empty(vreg)
> tells me that it is
> not used or defined.
> So my
> register-allocation
> code never sees it,
> and thus can't
> allocate a preg for it.
> I tried
> using
> MRI->replaceRegWith(vreg, preg);
> (where preg is
> available to vreg's
> register class) but that
> didn't
> work. When I look,
> the number of vregs
> in the function is
> still 1.
>
> Can you help with this?
>
> Thanks again!
>
> Susan
>
>
> On 10/31/2012 04:55
> PM, Lang Hames wrote:
>
> Hi Susan,
>
> The meaning of
> "addRequired(X)" is
> that your pass needs
> X to be
> run, and
> for X to be
> preserved by all passes
> that run after X
> and before your
> pass. The
> PHIElemination and
> TwoAddressInstruction
> passes do not
> preserve each other, hence there's
> no way for the pass
> manager to
> schedule them for you if you
> addRequire(...) them.
>
> The trick is that
> CodeGen will
> schedule both of these
> passes to
> be run
> before _any_
> register allocation
> pass (see Passes.cpp),
> so you
> needn't
> require them
> explicitly - you can
> just assume they have
> been
> run. If you
> just remove those
> lines from your
> getAnalysisUsage
> method your pass
> should now run as
> you expect.
>
> Cheers,
> Lang.
>
> On Wed, Oct 31,
> 2012 at 1:46 PM,
> Susan Horwitz
> <horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>>>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>>>>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>>>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>
> <mailto:horwitz at cs.wisc.edu
> <mailto:horwitz at cs.wisc.edu>>>>>> wrote:
>
> I'm trying to write a
> MachineFunctionPass to do
> register
> allocation.
> I have code that worked with
> an old version of
> LLVM. It
> does not
> work with llvm-3.1. (or various
> other versions
> that I've
> tried).
>
> The first problem is that
> including this line:
>
> AU.addRequiredID(__
> TwoAddressInstructionPassID);
>
>
> in method
> getAnalysisUsage
> causes a runtime error:
>
> Unable to schedule 'Eliminate
> PHI nodes for register
> allocation'
> required by 'Unnamed pass:
> implement
> Pass::getPassName()'
> Unable to schedule pass
> UNREACHABLE executed at ...
>
> I'm invoking the pass like this
> (given input file
> foo.c):
>
> clang -emit-llvm -O0 -c foo.c
> -o foo.bc
> opt -mem2reg foo.bc > foo.ssa
> mv foo.ssa
> foo.bc
> llc -load Debug/lib/P4.so
> -regalloc=gc foo.bc
>
>
> I've attached my entire file
> (it's very short).
> Any help
> would be
> much appreciated!
>
> Susan Horwitz
>
> ______________________________
> _________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu>
> <mailto:LLVMdev at cs.uiuc.edu
> <mailto:LLVMdev at cs.uiuc.edu>>
> <mailto:LLVMdev at cs.uiuc.edu
> <mailto:LLVMdev at cs.uiuc.edu>
> <mailto:LLVMdev at cs.uiuc.edu
> <mailto:LLVMdev at cs.uiuc.edu>>>
> <mailto:LLVMdev at cs.uiuc.edu
> <mailto:LLVMdev at cs.uiuc.edu>
> <mailto:LLVMdev at cs.uiuc.edu
> <mailto:LLVMdev at cs.uiuc.edu>>
> <mailto:LLVMdev at cs.uiuc.edu
> <mailto:LLVMdev at cs.uiuc.edu>
> <mailto:LLVMdev at cs.uiuc.edu
> <mailto:LLVMdev at cs.uiuc.edu>>>>
> <mailto:LLVMdev at cs.uiuc.edu
> <mailto:LLVMdev at cs.uiuc.edu>
> <mailto:LLVMdev at cs.uiuc.edu
> <mailto:LLVMdev at cs.uiuc.edu>>
> <mailto:LLVMdev at cs.uiuc.edu
> <mailto:LLVMdev at cs.uiuc.edu>
> <mailto:LLVMdev at cs.uiuc.edu
> <mailto:LLVMdev at cs.uiuc.edu>>>
> <mailto:LLVMdev at cs.uiuc.edu
> <mailto:LLVMdev at cs.uiuc.edu>
> <mailto:LLVMdev at cs.uiuc.edu
> <mailto:LLVMdev at cs.uiuc.edu>>
> <mailto:LLVMdev at cs.uiuc.edu
> <mailto:LLVMdev at cs.uiuc.edu>
> <mailto:LLVMdev at cs.uiuc.edu
> <mailto:LLVMdev at cs.uiuc.edu>>>>>
>
> http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/ mailman/listinfo/llvmdev
>
> <http://lists.cs.uiuc.edu/__mailman/listinfo/llvmdev
>
> <http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev>>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20121109/898417a3/attachment.html>
-------------- next part --------------
//===-- Gcra.cpp - Graph-coloring Register Allocator --------------------===////// The LLVM Compiler Infrastructure//// This file is distributed under the University of Illinois Open Source// License. See LICENSE.TXT for details.////===--------------------------------------------------------------------===////// This file does Graph-coloring Register Allocation, for CS 701 Project 4.////===--------------------------------------------------------------------===//#define DEBUG_TYPE "gcra"#include <map>#include "llvm/CodeGen/Passes.h"#include "llvm/CodeGen/MachineFunctionPass.h"#include "llvm/CodeGen/MachineInstr.h"#include "llvm/CodeGen/MachineLoopInfo.h"#include "llvm/CodeGen/MachineFrameInfo.h"#include "llvm/CodeGen/MachineRegisterInfo.h"#include "llvm/CodeGen/RegAllocRegistry.h"#include "llvm/Target/TargetInstrInfo.h"#include "llvm/Target/TargetMachine.h"#include "llvm/Support/Debug.h"#include "llvm/Support/Compiler.h"#include "llvm/ADT/Statistic.h"#include <stack>#include <queue>#include <iostream>using namespace std;using namespace llvm;namespace { class Gcra : public MachineFunctionPass { private: MachineRegisterInfo *MRI; const TargetRegisterInfo *TRI; MachineFunction *MF; const TargetMachine *TM; const TargetInstrInfo *TII; static const bool DEBUG_VREG = true; map<MachineInstr *, unsigned> InstrToNumMap; public: static char ID; // Pass identification, replacement for typeid //********************************************************************** // constructor //********************************************************************** Gcra() : MachineFunctionPass(ID) { } //********************************************************************** // runOnMachineFunction //********************************************************************** bool runOnMachineFunction(MachineFunction &Fn) { if (DEBUG_VREG) { std::cerr << "START " << Fn.getFunction()->getName().str() << "\n"; } // get pointers to stuff that doesn't change over this fn // e.g., the register info classes MRI = &Fn.getRegInfo(); TRI = Fn.getTarget().getRegisterInfo(); MF = &Fn; TM = &Fn.getTarget(); TII = TM->getInstrInfo(); // STEP 1: get instruction-to-number map doInit(Fn); // STEP 2: get all vregs in this fn std::set<unsigned> vregSet = getAllVreg(Fn); // STEP 3: handle all vregs setAllVreg(Fn, vregSet); return true; } virtual void getAnalysisUsage(AnalysisUsage &AU) const { MachineFunctionPass::getAnalysisUsage(AU); } private: //********************************************************************** // doInit // // fill in // InstrToNumMap: map from instruction to unique # (for debugging) //********************************************************************** void doInit(MachineFunction &Fn) { // iterate over all basic blocks, all instructions in a block, // all operands in an instruction int insNum = 1; for (MachineFunction::iterator MFIt = Fn.begin(), MFendIt = Fn.end(); MFIt != MFendIt; MFIt++) { for (MachineBasicBlock::iterator MBBIt = MFIt->begin(), MBBendIt = MFIt->end(); MBBIt != MBBendIt; MBBIt++) { //*MBBIt is a MachineInstr InstrToNumMap[MBBIt] = insNum; insNum++; } // end iterate over all instructions in 1 basic block } // end iterate over all basic blocks in this fn } // end doInit //********************************************************************** // getAllVreg // // find and return the set of all vregs that occur in instructions // in this function // ********************************************************************** std::set<unsigned> getAllVreg(MachineFunction &Fn) { std::set<unsigned> vregSet; // vregs defined in this fn vregSet.clear(); // iterate over all basic blocks, all instructions in a block, // all operands in an instruction for (MachineFunction::iterator MFIt = Fn.begin(), MFendIt = Fn.end(); MFIt != MFendIt; MFIt++) { for (MachineBasicBlock::iterator MBBIt = MFIt->begin(), MBBendIt = MFIt->end(); MBBIt != MBBendIt; MBBIt++) { int numOp = MBBIt->getNumOperands(); for (int i = 0; i < numOp; i++) { MachineOperand MOp = MBBIt->getOperand(i); if (MOp.isReg() && MOp.getReg()) { unsigned reg = MOp.getReg(); // Here if this operand is // (a) a register // (b) not special reg 0 if (TargetRegisterInfo::isVirtualRegister(reg)) { vregSet.insert(reg); } } // end if operand is a reg } // end iterate over operands } // end iterate over instructions } // end iterate over blocks return vregSet; } //********************************************************************** // setAllVreg // // for each vreg in the given set: // 1. Allocate stackspace // 2. iterate over all instructions in this fn // for each, iterate over all operands // if an operand is a vreg // then set it to an appropriate preg and add a load/spill // depending on whether the vreg was a def or a use //********************************************************************** void setAllVreg(MachineFunction &Fn, std::set<unsigned> vregSet) { for (std::set<unsigned>::iterator it = vregSet.begin(); it != vregSet.end(); it++) { unsigned vreg = *it; // Allocate a new stack object for this vreg const TargetRegisterClass *RC = MRI->getRegClass(vreg); MachineFunction *MF = &Fn; int frameIndex = MF->getFrameInfo()->CreateSpillStackObject(RC->getSize(), RC->getAlignment()); // iterate over all basic blocks, all instructions in a block, // all operands in an instruction for (MachineFunction::iterator MFIt = Fn.begin(), MFendIt = Fn.end(); MFIt != MFendIt; MFIt++) { for (MachineBasicBlock::iterator MBBIt = MFIt->begin(), MBBendIt = MFIt->end(); MBBIt != MBBendIt; MBBIt++) { MachineInstr *oneInst = MBBIt; MachineBasicBlock *parentBlock = oneInst->getParent(); int numOp = MBBIt->getNumOperands(); unsigned preg = -1; // iterate over the operands in this instruction for (int i = 0; i<numOp; i++) { MachineOperand &MOp = MBBIt->getOperand(i); if (MOp.isReg() && (MOp.getReg() == vreg)) { // found an instance of the crrent vreg // replace it with an appropriate preg // then add a load or store depending on whether // it is a use or a def if (preg == -1) { // get an appropriate preg for vreg int regClass = MRI->getRegClass(vreg)->getID(); const TargetRegisterClass *trc = TRI->getRegClass(regClass); TargetRegisterClass::iterator rItr = trc->begin(); preg = *rItr; // remove the sub-register field if (MOp.getSubReg()) { preg = TRI->getSubReg(preg, MOp.getSubReg()); MOp.setSubReg(0); } } // end we didn't have a preg yet for this instruction // replace vreg with preg MOp.setReg(preg); // add a store after curr instruction or a load before if (MOp.isDef()) { MachineBasicBlock::iterator IT = oneInst; IT++; TII->storeRegToStackSlot(*parentBlock, IT, preg, true, frameIndex, RC, TRI); } else { TII->loadRegFromStackSlot(*parentBlock, oneInst, preg, frameIndex, RC, TRI ); } // end if this was a def... else... } // end found an instance of curr vreg } // end iterate over all operands in this instruction } // end iterate over all instructions in 1 basic block } // end iterate over all basic blocks in this fn } // end iterate over all vregs in this fn MRI->clearVirtRegs(); } // end setAllVreg }; // The library-inclusion mechanism requires the following: char Gcra::ID = 0; FunctionPass *createGcra() { return new Gcra(); } static RegisterRegAlloc register_gcra("gc", "graph-coloring register allocator", createGcra);}
-------------- next part --------------
/* CAUSES UNREACHABLE executed error */
#include <stdlib.h>
int main(int argc, char **argv) {
int a, b, c, x, y, z;
x = rand();
printf("x: %d\n", x);
while (x > 1000) x = x/1000;
printf("x: %d\n", x);
y = x + 5;
z = x * 2 - 1;
a = x+y*z;
b = a/x - (5+y);
c = a+b+x+y+z;
printf("a: %d\nb: %d\nc: %d\nx: %d\ny: %d\nz: %d\n", a,b,c,x,y,z);
}
-------------- next part --------------
BCÀÞ!
ñ ?#?AÈI29??
%
?b?EB?
B¤28I
2D$H
?!#ÄR?
!r$ÈHb¨ ¨@Æð I
?ÿÿÿÿÀA?Âÿÿÿÿ` ? 2"H d??"¤??"ã?¡?L??
?¤LDsH
YhÌ?2e(å*A!U?b?M? Ì 0|À;ø; ?6¨wXwx?{p?6`?tp?zÀ?68w¨?
1Qm z`t v@z`tÐéz?z?m?x x xÐév q`zvÐé0r s z0rÐé`t v@z`tÐæ0r s z0rÐæ`t v@z`tÐö`t v@z`tÐör?zr?zr?mp p v@m0p v@z`tÐæ?p q x q xÐî?zv s z`tгr?:dH #DB?
?I @°#!?# ?( 0DY? ?!J d? 2
?
L?? &GÆC
jàu YACÉ ¬?È
±T"+Æ:P?¬Àë@%²"¯?È
½T"+ y
3?
Äá
f=?C8?Ã?B?yxs?q
æ íô?3
B
ÂÁ
Ρ
q F`<ÒL?
?46 at D@3 áKSd?/MQ
a I D, TF
ú¡? È
e@?ÉPI? #?
# 4K
T@ Ã
?b³
Â0?¤Ð,A0bP áH&- 0??]MÌÂD`R?Ò$²Å?m\Lë@`?û,` 1P ?x´.
$
Ë$
% ÆA Ã ?
o0
ý (Ö?,?8fÃåÓv@ ?!ØÄ 0?Q
RYÁPËm0
?1HTp?u
á
N3XH
C][D! ËR[E! ËbDFeC-PÍaR ÃPÓÖAHT°Û1 Un? ,?iÀ0à7?X²>Ñ
&bÀ²Ô6
More information about the llvm-dev
mailing list