2015年10月31日 星期六

LLVM-RegisterAllocation The difference between defineVirtReg and definePhysReg

  In the Register allocation pass, there are two kinds of registers which could be deal with. Physical Register is represented the register of the real machine. Virtual register is represented the register which are not real one. The virtual register is an assumption in IR representation for making register allocation easily. One of target of register allocation pass is to transform the virtual register to physical register.  When defining physical register or virtual register, there are some different implementation in these functions.

In the definePhysReg, checking the state of physical register (see whether it is free or represented by one virtual register). If it is allocated to virtual register (it is possibly been used in the last instruction), we have to spill the value to the memory. Therefore, we create the instruction to store the value to memory, and set the physical register reserved for the instruction.

void RAFast::definePhysReg(MachineInstr *MI, unsigned PhysReg,
00408                            RegState NewState) {
00409   markRegUsedInInstr(PhysReg);
00410   switch (unsigned VirtReg = PhysRegState[PhysReg]) {
00411   case regDisabled:
00412     break;
00413   default:
00414     spillVirtReg(MI, VirtReg);
00415     // Fall through.
00416   case regFree:
00417   case regReserved:
00418     PhysRegState[PhysReg] = NewState;
00419     return;
00420   }
00421 
00422   // This is a disabled register, disable all aliases.
00423   PhysRegState[PhysReg] = NewState;
00424   for (MCRegAliasIterator AI(PhysReg, TRI, false); AI.isValid(); ++AI) {
00425     unsigned Alias = *AI;
00426     switch (unsigned VirtReg = PhysRegState[Alias]) {
00427     case regDisabled:
00428       break;
00429     default:
00430       spillVirtReg(MI, VirtReg);
00431       // Fall through.
00432     case regFree:
00433     case regReserved:
00434       PhysRegState[Alias] = regDisabled;
00435       if (TRI->isSuperRegister(PhysReg, Alias))
00436         return;
00437       break;
00438     }
00439   } 
                           
defineVirtReg is a little bit interesting, because it will map the virtual register to physical register. It firstly insert the new livereg to LiveRegMap, and know whether this is the new virtual register. LiveReg is the struct which contain the information about which physical register is held in the virtual register. LiveRegMap is the sparseSet to store LiveReg structs and track the available physical register. 
struct LiveReg {
00071       MachineInstr *LastUse;    // Last instr to use reg.
00072       unsigned VirtReg;         // Virtual register number.
00073       unsigned PhysReg;         // Currently held here.
00074       unsigned short LastOpNum; // OpNum on LastUse.
00075       bool Dirty;               // Register needs spill.
00076 
00077       explicit LiveReg(unsigned v)
00078         : LastUse(nullptr), VirtReg(v), PhysReg(0), LastOpNum(0), Dirty(false){}
00079 
00080       unsigned getSparseSetIndex() const {
00081         return TargetRegisterInfo::virtReg2Index(VirtReg);
00082       }
00083     };
  

If the LiveReg is new, it would allocate the physical register to the virtual register. Otherwise, it would determine whether the last use is the same instruction. if the last use is not the same instruction, it should kill it.

 RAFast::LiveRegMap::iterator
00590 RAFast::defineVirtReg(MachineInstr *MI, unsigned OpNum,
00591                       unsigned VirtReg, unsigned Hint) {
00592   assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
00593          "Not a virtual register");
00594   LiveRegMap::iterator LRI;
00595   bool New;
00596   std::tie(LRI, New) = LiveVirtRegs.insert(LiveReg(VirtReg));
00597   if (New) {
00598     // If there is no hint, peek at the only use of this register.
00599     if ((!Hint || !TargetRegisterInfo::isPhysicalRegister(Hint)) &&
00600         MRI->hasOneNonDBGUse(VirtReg)) {
00601       const MachineInstr &UseMI = *MRI->use_instr_nodbg_begin(VirtReg);
00602       // It's a copy, use the destination register as a hint.
00603       if (UseMI.isCopyLike())
00604         Hint = UseMI.getOperand(0).getReg();
00605     }
00606     LRI = allocVirtReg(MI, LRI, Hint);
00607   } else if (LRI->LastUse) {
00608     // Redefining a live register - kill at the last use, unless it is this
00609     // instruction defining VirtReg multiple times.
00610     if (LRI->LastUse != MI || LRI->LastUse->getOperand(LRI->LastOpNum).isUse())
00611       addKillFlag(*LRI);
00612   }
00613   assert(LRI->PhysReg && "Register not assigned");
00614   LRI->LastUse = MI;
00615   LRI->LastOpNum = OpNum;
00616   LRI->Dirty = true;
00617   markRegUsedInInstr(LRI->PhysReg);
00618   return LRI;
00619 }


Reference:
1. LLVM Document http://llvm.org/docs/index.html
2. http://llvm.org/doxygen/RegAllocFast_8cpp_source.html#l01122

沒有留言:

張貼留言