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
沒有留言:
張貼留言