|  | //===-- LiveRegMatrix.h - Track register interference ---------*- C++ -*---===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // The LiveRegMatrix analysis pass keeps track of virtual register interference | 
|  | // along two dimensions: Slot indexes and register units. The matrix is used by | 
|  | // register allocators to ensure that no interfering virtual registers get | 
|  | // assigned to overlapping physical registers. | 
|  | // | 
|  | // Register units are defined in MCRegisterInfo.h, they represent the smallest | 
|  | // unit of interference when dealing with overlapping physical registers. The | 
|  | // LiveRegMatrix is represented as a LiveIntervalUnion per register unit. When | 
|  | // a virtual register is assigned to a physicval register, the live range for | 
|  | // the virtual register is inserted into the LiveIntervalUnion for each regunit | 
|  | // in the physreg. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #ifndef LLVM_CODEGEN_LIVEREGMATRIX_H | 
|  | #define LLVM_CODEGEN_LIVEREGMATRIX_H | 
|  |  | 
|  | #include "LiveIntervalUnion.h" | 
|  | #include "llvm/ADT/BitVector.h" | 
|  | #include "llvm/ADT/OwningPtr.h" | 
|  | #include "llvm/CodeGen/MachineFunctionPass.h" | 
|  |  | 
|  | namespace llvm { | 
|  |  | 
|  | class LiveInterval; | 
|  | class LiveIntervalAnalysis; | 
|  | class MachineRegisterInfo; | 
|  | class TargetRegisterInfo; | 
|  | class VirtRegMap; | 
|  |  | 
|  | class LiveRegMatrix : public MachineFunctionPass { | 
|  | const TargetRegisterInfo *TRI; | 
|  | MachineRegisterInfo *MRI; | 
|  | LiveIntervals *LIS; | 
|  | VirtRegMap *VRM; | 
|  |  | 
|  | // UserTag changes whenever virtual registers have been modified. | 
|  | unsigned UserTag; | 
|  |  | 
|  | // The matrix is represented as a LiveIntervalUnion per register unit. | 
|  | LiveIntervalUnion::Allocator LIUAlloc; | 
|  | LiveIntervalUnion::Array Matrix; | 
|  |  | 
|  | // Cached queries per register unit. | 
|  | OwningArrayPtr<LiveIntervalUnion::Query> Queries; | 
|  |  | 
|  | // Cached register mask interference info. | 
|  | unsigned RegMaskTag; | 
|  | unsigned RegMaskVirtReg; | 
|  | BitVector RegMaskUsable; | 
|  |  | 
|  | // MachineFunctionPass boilerplate. | 
|  | virtual void getAnalysisUsage(AnalysisUsage&) const; | 
|  | virtual bool runOnMachineFunction(MachineFunction&); | 
|  | virtual void releaseMemory(); | 
|  | public: | 
|  | static char ID; | 
|  | LiveRegMatrix(); | 
|  |  | 
|  | //===--------------------------------------------------------------------===// | 
|  | // High-level interface. | 
|  | //===--------------------------------------------------------------------===// | 
|  | // | 
|  | // Check for interference before assigning virtual registers to physical | 
|  | // registers. | 
|  | // | 
|  |  | 
|  | /// Invalidate cached interference queries after modifying virtual register | 
|  | /// live ranges. Interference checks may return stale information unless | 
|  | /// caches are invalidated. | 
|  | void invalidateVirtRegs() { ++UserTag; } | 
|  |  | 
|  | enum InterferenceKind { | 
|  | /// No interference, go ahead and assign. | 
|  | IK_Free = 0, | 
|  |  | 
|  | /// Virtual register interference. There are interfering virtual registers | 
|  | /// assigned to PhysReg or its aliases. This interference could be resolved | 
|  | /// by unassigning those other virtual registers. | 
|  | IK_VirtReg, | 
|  |  | 
|  | /// Register unit interference. A fixed live range is in the way, typically | 
|  | /// argument registers for a call. This can't be resolved by unassigning | 
|  | /// other virtual registers. | 
|  | IK_RegUnit, | 
|  |  | 
|  | /// RegMask interference. The live range is crossing an instruction with a | 
|  | /// regmask operand that doesn't preserve PhysReg. This typically means | 
|  | /// VirtReg is live across a call, and PhysReg isn't call-preserved. | 
|  | IK_RegMask | 
|  | }; | 
|  |  | 
|  | /// Check for interference before assigning VirtReg to PhysReg. | 
|  | /// If this function returns IK_Free, it is legal to assign(VirtReg, PhysReg). | 
|  | /// When there is more than one kind of interference, the InterferenceKind | 
|  | /// with the highest enum value is returned. | 
|  | InterferenceKind checkInterference(LiveInterval &VirtReg, unsigned PhysReg); | 
|  |  | 
|  | /// Assign VirtReg to PhysReg. | 
|  | /// This will mark VirtReg's live range as occupied in the LiveRegMatrix and | 
|  | /// update VirtRegMap. The live range is expected to be available in PhysReg. | 
|  | void assign(LiveInterval &VirtReg, unsigned PhysReg); | 
|  |  | 
|  | /// Unassign VirtReg from its PhysReg. | 
|  | /// Assuming that VirtReg was previously assigned to a PhysReg, this undoes | 
|  | /// the assignment and updates VirtRegMap accordingly. | 
|  | void unassign(LiveInterval &VirtReg); | 
|  |  | 
|  | //===--------------------------------------------------------------------===// | 
|  | // Low-level interface. | 
|  | //===--------------------------------------------------------------------===// | 
|  | // | 
|  | // Provide access to the underlying LiveIntervalUnions. | 
|  | // | 
|  |  | 
|  | /// Check for regmask interference only. | 
|  | /// Return true if VirtReg crosses a regmask operand that clobbers PhysReg. | 
|  | /// If PhysReg is null, check if VirtReg crosses any regmask operands. | 
|  | bool checkRegMaskInterference(LiveInterval &VirtReg, unsigned PhysReg = 0); | 
|  |  | 
|  | /// Check for regunit interference only. | 
|  | /// Return true if VirtReg overlaps a fixed assignment of one of PhysRegs's | 
|  | /// register units. | 
|  | bool checkRegUnitInterference(LiveInterval &VirtReg, unsigned PhysReg); | 
|  |  | 
|  | /// Query a line of the assigned virtual register matrix directly. | 
|  | /// Use MCRegUnitIterator to enumerate all regunits in the desired PhysReg. | 
|  | /// This returns a reference to an internal Query data structure that is only | 
|  | /// valid until the next query() call. | 
|  | LiveIntervalUnion::Query &query(LiveInterval &VirtReg, unsigned RegUnit); | 
|  |  | 
|  | /// Directly access the live interval unions per regunit. | 
|  | /// This returns an array indexed by the regunit number. | 
|  | LiveIntervalUnion *getLiveUnions() { return &Matrix[0]; } | 
|  | }; | 
|  |  | 
|  | } // end namespace llvm | 
|  |  | 
|  | #endif // LLVM_CODEGEN_LIVEREGMATRIX_H |