X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FVirtRegMap.h;h=8b494a7c617bc3de183a0b0bc31716b9b59b77dd;hb=58b1ac76d470eb5faa7e98feae97c4906d4d146e;hp=d1c14f662eef8da85c2c1f451772f44dcff162bb;hpb=d36531249a9a9500e516148e7e72d4c0a7a4d0ee;p=oota-llvm.git diff --git a/lib/CodeGen/VirtRegMap.h b/lib/CodeGen/VirtRegMap.h index d1c14f662ee..8b494a7c617 100644 --- a/lib/CodeGen/VirtRegMap.h +++ b/lib/CodeGen/VirtRegMap.h @@ -18,9 +18,10 @@ #define LLVM_CODEGEN_VIRTREGMAP_H #include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/IndexedMap.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/Streams.h" #include @@ -58,7 +59,7 @@ namespace llvm { /// at. IndexedMap Virt2StackSlotMap; - /// Virt2StackSlotMap - This is virtual register to rematerialization id + /// Virt2ReMatIdMap - This is virtual register to rematerialization id /// mapping. Each spilled virtual register that should be remat'd has an /// entry in it which corresponds to the remat id. IndexedMap Virt2ReMatIdMap; @@ -93,6 +94,17 @@ namespace llvm { /// splitting. std::map > RestorePt2VirtMap; + /// EmergencySpillMap - This records the physical registers that should + /// be spilled / restored around the MachineInstr since the register + /// allocator has run out of registers. + std::map > EmergencySpillMap; + + /// EmergencySpillSlots - This records emergency spill slots used to + /// spill physical registers when the register allocator runs out of + /// registers. Ideally only one stack slot is used per function per + /// register class. + std::map EmergencySpillSlots; + /// ReMatId - Instead of assigning a stack slot to a to be rematerialized /// virtual register, an unique id is being assigned. This keeps track of /// the highest id used so far. Note, this starts at (1<<18) to avoid @@ -105,6 +117,10 @@ namespace llvm { /// SpillSlotToUsesMap - Records uses for each register spill slot. SmallVector, 8> SpillSlotToUsesMap; + /// ImplicitDefed - One bit for each virtual register. If set it indicates + /// the register is implicitly defined. + BitVector ImplicitDefed; + VirtRegMap(const VirtRegMap&); // DO NOT IMPLEMENT void operator=(const VirtRegMap&); // DO NOT IMPLEMENT @@ -162,7 +178,7 @@ namespace llvm { return Virt2SplitMap[virtReg]; } - /// @brief returns true is the specified virtual register is not + /// @brief returns true if the specified virtual register is not /// mapped to a stack slot or rematerialized. bool isAssignedReg(unsigned virtReg) const { if (getStackSlot(virtReg) == NO_STACK_SLOT && @@ -257,6 +273,8 @@ namespace llvm { } } + /// @brief - transfer spill point information from one instruction to + /// another. void transferSpillPts(MachineInstr *Old, MachineInstr *New) { std::map > >::iterator I = SpillPt2VirtMap.find(Old); @@ -293,6 +311,8 @@ namespace llvm { } } + /// @brief - transfer restore point information from one instruction to + /// another. void transferRestorePts(MachineInstr *Old, MachineInstr *New) { std::map >::iterator I = RestorePt2VirtMap.find(Old); @@ -306,6 +326,48 @@ namespace llvm { RestorePt2VirtMap.erase(I); } + /// @brief records that the specified physical register must be spilled + /// around the specified machine instr. + void addEmergencySpill(unsigned PhysReg, MachineInstr *MI) { + if (EmergencySpillMap.find(MI) != EmergencySpillMap.end()) + EmergencySpillMap[MI].push_back(PhysReg); + else { + std::vector PhysRegs; + PhysRegs.push_back(PhysReg); + EmergencySpillMap.insert(std::make_pair(MI, PhysRegs)); + } + } + + /// @brief returns true if one or more physical registers must be spilled + /// around the specified instruction. + bool hasEmergencySpills(MachineInstr *MI) const { + return EmergencySpillMap.find(MI) != EmergencySpillMap.end(); + } + + /// @brief returns the physical registers to be spilled and restored around + /// the instruction. + std::vector &getEmergencySpills(MachineInstr *MI) { + return EmergencySpillMap[MI]; + } + + /// @brief - transfer emergency spill information from one instruction to + /// another. + void transferEmergencySpills(MachineInstr *Old, MachineInstr *New) { + std::map >::iterator I = + EmergencySpillMap.find(Old); + if (I == EmergencySpillMap.end()) + return; + while (!I->second.empty()) { + unsigned virtReg = I->second.back(); + I->second.pop_back(); + addEmergencySpill(virtReg, New); + } + EmergencySpillMap.erase(I); + } + + /// @brief return or get a emergency spill slot for the register class. + int getEmergencySpillSlot(const TargetRegisterClass *RC); + /// @brief Return lowest spill slot index. int getLowSpillSlot() const { return LowSpillSlot; @@ -325,6 +387,16 @@ namespace llvm { return !SpillSlotToUsesMap[FrameIndex-LowSpillSlot].empty(); } + /// @brief Mark the specified register as being implicitly defined. + void setIsImplicitlyDefined(unsigned VirtReg) { + ImplicitDefed.set(VirtReg-TargetRegisterInfo::FirstVirtualRegister); + } + + /// @brief Returns true if the virtual register is implicitly defined. + bool isImplicitlyDefined(unsigned VirtReg) const { + return ImplicitDefed[VirtReg-TargetRegisterInfo::FirstVirtualRegister]; + } + /// @brief Updates information about the specified virtual register's value /// folded into newMI machine instruction. void virtFolded(unsigned VirtReg, MachineInstr *OldMI, MachineInstr *NewMI,