//===-- 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 physical 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 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