initial
This commit is contained in:
148
thirdparty/clang/include/llvm/CodeGen/LiveRegMatrix.h
vendored
Normal file
148
thirdparty/clang/include/llvm/CodeGen/LiveRegMatrix.h
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
//===-- 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 "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/CodeGen/LiveIntervalUnion.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
|
||||
Reference in New Issue
Block a user