-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[CodeGen][MRI] Introduce synthetic register classes #86006
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Currently register classes can only be defined statically. There is no way targets can define classes during codegen for a specific period of time. This patch includes a new field named `Synthetic` in the regclass definition with value false by default. This field, when set to true, indicates that such regclasses are disabled by default and won't take part in various regclass queries like getAllocatableClass, getMinimalPhysRegClass, etc. and in fact, they won't be allocatable, but targets can enable them dynamically so that they behave like other register classes. The static definition of such classes are done in *RegisterInfo.td file like other classes for tablegen to include them in all the tables it auto-generates. The Synthetic field would be set to true for such classes.
@llvm/pr-subscribers-backend-webassembly @llvm/pr-subscribers-backend-amdgpu Author: Christudasan Devadasan (cdevadas) ChangesCurrently register classes can only be defined statically. There is no way targets can define classes during codegen for a specific period of time. This patch includes a new field named The static definition of such classes are done in *RegisterInfo.td file like other classes for tablegen to include them in all the tables it auto-generates. The Synthetic field would be set to true for such classes. Patch is 135.37 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/86006.diff 86 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/LiveStacks.h b/llvm/include/llvm/CodeGen/LiveStacks.h
index 2edc2985f0ee66..b9e55987383901 100644
--- a/llvm/include/llvm/CodeGen/LiveStacks.h
+++ b/llvm/include/llvm/CodeGen/LiveStacks.h
@@ -34,6 +34,7 @@ class TargetRegisterInfo;
class LiveStacks : public MachineFunctionPass {
const TargetRegisterInfo *TRI = nullptr;
+ const MachineRegisterInfo *MRI = nullptr;
/// Special pool allocator for VNInfo's (LiveInterval val#).
///
diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h
index fcdd73d8b65fdd..c7067d90a3ce06 100644
--- a/llvm/include/llvm/CodeGen/MachineInstr.h
+++ b/llvm/include/llvm/CodeGen/MachineInstr.h
@@ -1586,7 +1586,7 @@ class MachineInstr
const TargetRegisterClass *getRegClassConstraintEffectForVReg(
Register Reg, const TargetRegisterClass *CurRC,
const TargetInstrInfo *TII, const TargetRegisterInfo *TRI,
- bool ExploreBundle = false) const;
+ const MachineRegisterInfo &MRI, bool ExploreBundle = false) const;
/// Applies the constraints (def/use) implied by the \p OpIdx operand
/// to the given \p CurRC.
@@ -1600,7 +1600,8 @@ class MachineInstr
const TargetRegisterClass *
getRegClassConstraintEffect(unsigned OpIdx, const TargetRegisterClass *CurRC,
const TargetInstrInfo *TII,
- const TargetRegisterInfo *TRI) const;
+ const TargetRegisterInfo *TRI,
+ const MachineRegisterInfo &MRI) const;
/// Add a tie between the register operands at DefIdx and UseIdx.
/// The tie will cause the register allocator to ensure that the two
@@ -2005,7 +2006,8 @@ class MachineInstr
/// If the related operand does not constrained Reg, this returns CurRC.
const TargetRegisterClass *getRegClassConstraintEffectForVRegImpl(
unsigned OpIdx, Register Reg, const TargetRegisterClass *CurRC,
- const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const;
+ const TargetInstrInfo *TII, const TargetRegisterInfo *TRI,
+ const MachineRegisterInfo &MRI) const;
/// Stores extra instruction information inline or allocates as ExtraInfo
/// based on the number of pointers.
diff --git a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
index 09d9a0b4ec402f..71a3baef70e8cd 100644
--- a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -94,6 +94,10 @@ class MachineRegisterInfo {
/// all registers that were disabled are removed from the list.
SmallVector<MCPhysReg, 16> UpdatedCSRs;
+ /// The Synthetic field of regclasses. Targets can alter this vector
+ /// to enable classes dynamically during codegen.
+ BitVector RegClassSyntheticInfo;
+
/// RegAllocHints - This vector records register allocation hints for
/// virtual registers. For each virtual register, it keeps a pair of hint
/// type and hints vector making up the allocation hints. Only the first
@@ -257,6 +261,18 @@ class MachineRegisterInfo {
/// Notice that it will override ant previously disabled/saved CSRs.
void setCalleeSavedRegs(ArrayRef<MCPhysReg> CSRs);
+ /// Initialize the RegClassSyntheticInfo. It sets the bit position as
+ /// exactly as the tablegened Synthetic field. Targets can later flip this
+ /// field to enable/disable the regclass whenever required.
+ void initializeRegClassSyntheticInfo();
+
+ /// Change the synthetic info for the regclass \p RC from \p Value.
+ void changeSyntheticInfoForRC(const TargetRegisterClass *RC, bool Value);
+
+ /// This function checks if \p RC is enabled or not so that it can be included
+ /// in various regclass related queries.
+ bool isEnabled(const TargetRegisterClass *RC) const;
+
// Strictly for use by MachineInstr.cpp.
void addRegOperandToUseList(MachineOperand *MO);
diff --git a/llvm/include/llvm/CodeGen/RegisterBankInfo.h b/llvm/include/llvm/CodeGen/RegisterBankInfo.h
index 62c4a57a605d68..117f381512a1c6 100644
--- a/llvm/include/llvm/CodeGen/RegisterBankInfo.h
+++ b/llvm/include/llvm/CodeGen/RegisterBankInfo.h
@@ -445,7 +445,8 @@ class RegisterBankInfo {
/// Get the MinimalPhysRegClass for Reg.
/// \pre Reg is a physical register.
const TargetRegisterClass *
- getMinimalPhysRegClass(Register Reg, const TargetRegisterInfo &TRI) const;
+ getMinimalPhysRegClass(Register Reg, const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI) const;
/// Try to get the mapping of \p MI.
/// See getInstrMapping for more details on what a mapping represents.
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 59fad88f91b1d1..5ef963cae55286 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -4384,6 +4384,7 @@ class TargetLowering : public TargetLoweringBase {
/// Returns 'true' is the edge is necessary, 'false' otherwise
virtual bool checkForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
const TargetRegisterInfo *TRI,
+ const MachineRegisterInfo &MRI,
const TargetInstrInfo *TII,
unsigned &PhysReg, int &Cost) const {
return false;
diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index 117d3f71829747..a3d68d6743ede5 100644
--- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -121,6 +121,9 @@ class TargetRegisterClass {
/// Return true if this register class has a defined BaseClassOrder.
bool isBaseClass() const { return MC->isBaseClass(); }
+ /// Return true if this register class is marked synthetic.
+ bool isSynthetic() const { return MC->isSynthetic(); }
+
/// Return true if the specified TargetRegisterClass
/// is a proper sub-class of this TargetRegisterClass.
bool hasSubClass(const TargetRegisterClass *RC) const {
@@ -338,20 +341,23 @@ class TargetRegisterInfo : public MCRegisterInfo {
/// Returns the Register Class of a physical register of the given type,
/// picking the most sub register class of the right type that contains this
/// physreg.
- const TargetRegisterClass *getMinimalPhysRegClass(MCRegister Reg,
- MVT VT = MVT::Other) const;
+ const TargetRegisterClass *
+ getMinimalPhysRegClass(MCRegister Reg, const MachineRegisterInfo &MRI,
+ MVT VT = MVT::Other) const;
/// Returns the Register Class of a physical register of the given type,
/// picking the most sub register class of the right type that contains this
/// physreg. If there is no register class compatible with the given type,
/// returns nullptr.
- const TargetRegisterClass *getMinimalPhysRegClassLLT(MCRegister Reg,
- LLT Ty = LLT()) const;
+ const TargetRegisterClass *
+ getMinimalPhysRegClassLLT(MCRegister Reg, const MachineRegisterInfo &MRI,
+ LLT Ty = LLT()) const;
/// Return the maximal subclass of the given register class that is
/// allocatable or NULL.
const TargetRegisterClass *
- getAllocatableClass(const TargetRegisterClass *RC) const;
+ getAllocatableClass(const TargetRegisterClass *RC,
+ const MachineRegisterInfo &MRI) const;
/// Returns a bitset indexed by register number indicating if a register is
/// allocatable or not. If a register class is specified, returns the subset
@@ -630,7 +636,8 @@ class TargetRegisterInfo : public MCRegisterInfo {
/// TableGen will synthesize missing A sub-classes.
virtual const TargetRegisterClass *
getMatchingSuperRegClass(const TargetRegisterClass *A,
- const TargetRegisterClass *B, unsigned Idx) const;
+ const TargetRegisterClass *B, unsigned Idx,
+ const MachineRegisterInfo &MRI) const;
// For a copy-like instruction that defines a register of class DefRC with
// subreg index DefSubReg, reading from another source with class SrcRC and
@@ -639,7 +646,8 @@ class TargetRegisterInfo : public MCRegisterInfo {
virtual bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
unsigned DefSubReg,
const TargetRegisterClass *SrcRC,
- unsigned SrcSubReg) const;
+ unsigned SrcSubReg,
+ const MachineRegisterInfo &MRI) const;
/// Returns the largest legal sub-class of RC that
/// supports the sub-register index Idx.
@@ -769,10 +777,11 @@ class TargetRegisterInfo : public MCRegisterInfo {
/// corresponding argument register class.
///
/// The function returns NULL if no register class can be found.
- const TargetRegisterClass*
+ const TargetRegisterClass *
getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA,
const TargetRegisterClass *RCB, unsigned SubB,
- unsigned &PreA, unsigned &PreB) const;
+ unsigned &PreA, unsigned &PreB,
+ const MachineRegisterInfo &MRI) const;
//===--------------------------------------------------------------------===//
// Register Class Information
@@ -809,8 +818,8 @@ class TargetRegisterInfo : public MCRegisterInfo {
/// Find the largest common subclass of A and B.
/// Return NULL if there is no common subclass.
const TargetRegisterClass *
- getCommonSubClass(const TargetRegisterClass *A,
- const TargetRegisterClass *B) const;
+ getCommonSubClass(const TargetRegisterClass *A, const TargetRegisterClass *B,
+ const MachineRegisterInfo &MRI) const;
/// Returns a TargetRegisterClass used for pointer values.
/// If a target supports multiple different pointer register classes,
diff --git a/llvm/include/llvm/MC/MCRegisterInfo.h b/llvm/include/llvm/MC/MCRegisterInfo.h
index fb4d11ec1d4d16..1a2ff58c31f5a6 100644
--- a/llvm/include/llvm/MC/MCRegisterInfo.h
+++ b/llvm/include/llvm/MC/MCRegisterInfo.h
@@ -47,6 +47,7 @@ class MCRegisterClass {
const int8_t CopyCost;
const bool Allocatable;
const bool BaseClass;
+ const bool Synthetic;
/// getID() - Return the register class ID number.
///
@@ -101,6 +102,9 @@ class MCRegisterClass {
/// Return true if this register class has a defined BaseClassOrder.
bool isBaseClass() const { return BaseClass; }
+ /// isSynthetic - Return true if this is a synthetic class. This field helps
+ /// targets to dynamically enable the regclass during codegen.
+ bool isSynthetic() const { return Synthetic; }
};
/// MCRegisterDesc - This record contains information about a particular
diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td
index cb1c0ed2513d45..0cf9159030bc52 100644
--- a/llvm/include/llvm/Target/Target.td
+++ b/llvm/include/llvm/Target/Target.td
@@ -338,6 +338,12 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
// Target-specific flags. This becomes the TSFlags field in TargetRegisterClass.
bits<8> TSFlags = 0;
+ // If set to true, the register class won't take part in various regclass queries
+ // by default. This allows targets to dynamically enable classes for a period
+ // during codegen so that they can be turned allocatable, copyable, spillable,
+ // and/or make them available for various regclass queries.
+ bit Synthetic = false;
+
// If set then consider this register class to be the base class for registers in
// its MemberList. The base class for registers present in multiple base register
// classes will be resolved in the order defined by this value, with lower values
diff --git a/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp
index ed6ce6bc73d38c..93860aae8acfdf 100644
--- a/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp
+++ b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp
@@ -604,7 +604,7 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
// check every use of the register and find the largest register class
// that can be used in all of them.
const TargetRegisterClass *SuperRC =
- TRI->getMinimalPhysRegClass(SuperReg, MVT::Other);
+ TRI->getMinimalPhysRegClass(SuperReg, MRI, MVT::Other);
ArrayRef<MCPhysReg> Order = RegClassInfo.getOrder(SuperRC);
if (Order.empty()) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 14f2a363f9be61..7b403fee7ed120 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -813,7 +813,7 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
auto AddEntry = [&](const DbgValueLocEntry &Entry,
DIExpressionCursor &Cursor) {
if (Entry.isLocation()) {
- if (!DwarfExpr.addMachineRegExpression(TRI, Cursor,
+ if (!DwarfExpr.addMachineRegExpression(TRI, Asm->MF->getRegInfo(), Cursor,
Entry.getLoc().getReg()))
return false;
} else if (Entry.isInt()) {
@@ -910,7 +910,8 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes(const Loc::MMI &MMI,
addOpAddress(*Loc, FrameSymbol);
else
DwarfExpr.addMachineRegExpression(
- *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg);
+ *Asm->MF->getSubtarget().getRegisterInfo(), Asm->MF->getRegInfo(),
+ Cursor, FrameReg);
DwarfExpr.addExpression(std::move(Cursor));
}
if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
@@ -940,7 +941,8 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
DIExpressionCursor Cursor(Expr.getElements());
DwarfExpr.beginEntryValueExpression(Cursor);
DwarfExpr.addMachineRegExpression(
- *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, Register);
+ *Asm->MF->getSubtarget().getRegisterInfo(), Asm->MF->getRegInfo(),
+ Cursor, Register);
DwarfExpr.addExpression(std::move(Cursor));
}
addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
@@ -1557,7 +1559,8 @@ void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,
DIExpressionCursor Cursor({});
const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
- if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
+ if (!DwarfExpr.addMachineRegExpression(TRI, Asm->MF->getRegInfo(), Cursor,
+ Location.getReg()))
return;
DwarfExpr.addExpression(std::move(Cursor));
@@ -1587,7 +1590,8 @@ void DwarfCompileUnit::addComplexAddress(const DIExpression *DIExpr, DIE &Die,
DwarfExpr.beginEntryValueExpression(Cursor);
const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
- if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
+ if (!DwarfExpr.addMachineRegExpression(TRI, Asm->MF->getRegInfo(), Cursor,
+ Location.getReg()))
return;
DwarfExpr.addExpression(std::move(Cursor));
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 6b5ad62e083e3b..0b372d7b0e1bf1 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -2652,7 +2652,8 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
DwarfExpr.beginEntryValueExpression(ExprCursor);
const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
- if (!DwarfExpr.addMachineRegExpression(TRI, ExprCursor, Location.getReg()))
+ if (!DwarfExpr.addMachineRegExpression(TRI, AP.MF->getRegInfo(), ExprCursor,
+ Location.getReg()))
return;
return DwarfExpr.addExpression(std::move(ExprCursor));
}
@@ -2673,7 +2674,8 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
DwarfExpr.setMemoryLocationKind();
const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
- if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
+ if (!DwarfExpr.addMachineRegExpression(TRI, AP.MF->getRegInfo(), Cursor,
+ Location.getReg()))
return false;
} else if (Entry.isTargetIndexLocation()) {
TargetIndexLocation Loc = Entry.getTargetIndexLocation();
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index a74d43897d45b3..6d4794d27effbd 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -97,6 +97,7 @@ void DwarfExpression::addAnd(unsigned Mask) {
}
bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI,
llvm::Register MachineReg,
unsigned MaxSize) {
if (!MachineReg.isPhysical()) {
@@ -134,7 +135,7 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
// For example, Q0 on ARM is a composition of D0+D1.
unsigned CurPos = 0;
// The size of the register in bits.
- const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg);
+ const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg, MRI);
unsigned RegSize = TRI.getRegSizeInBits(*RC);
// Keep track of the bits in the register we already emitted, so we
// can avoid emitting redundant aliasing subregs. Because this is
@@ -248,11 +249,13 @@ void DwarfExpression::addConstantFP(const APFloat &APF, const AsmPrinter &AP) {
}
bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI,
DIExpressionCursor &ExprCursor,
llvm::Register MachineReg,
unsigned FragmentOffsetInBits) {
auto Fragment = ExprCursor.getFragmentInfo();
- if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) {
+ if (!addMachineReg(TRI, MRI, MachineReg,
+ Fragment ? Fragment->SizeInBits : ~1U)) {
LocationKind = Unknown;
return false;
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 667a9efc6f6c04..70ab73b5996b48 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -245,7 +245,8 @@ class DwarfExpression {
/// multiple subregisters that alias the register.
///
/// \return false if no DWARF register exists for MachineReg.
- bool addMachineReg(const TargetRegisterInfo &TRI, llvm::Register MachineReg,
+ bool addMachineReg(const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI, llvm::Register MachineReg,
unsigned MaxSize = ~1U);
/// Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment.
@@ -325,6 +326,7 @@ class DwarfExpression {
/// \return false if no DWARF register exists
/// for MachineReg.
bool addMachineRegExpression(const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI,
DIExpressionCursor &Expr,
llvm::Register MachineReg,
unsigned FragmentOffsetInBits = 0);
diff --git a/llvm/lib/CodeGen/DetectDeadLanes.cpp b/llvm/lib/CodeGen/DetectDeadLanes.cpp
index 86e9f3abe010d7..57c5466129162e 100644
--- a/llvm/lib/CodeGen/DetectDeadLanes.cpp
+++ b/llvm/lib/CodeGen/DetectDeadLanes.cpp
@@ -97,12 +97,12 @@ static bool isCr...
[truncated]
|
@llvm/pr-subscribers-backend-systemz Author: Christudasan Devadasan (cdevadas) ChangesCurrently register classes can only be defined statically. There is no way targets can define classes during codegen for a specific period of time. This patch includes a new field named The static definition of such classes are done in *RegisterInfo.td file like other classes for tablegen to include them in all the tables it auto-generates. The Synthetic field would be set to true for such classes. Patch is 135.37 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/86006.diff 86 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/LiveStacks.h b/llvm/include/llvm/CodeGen/LiveStacks.h
index 2edc2985f0ee66..b9e55987383901 100644
--- a/llvm/include/llvm/CodeGen/LiveStacks.h
+++ b/llvm/include/llvm/CodeGen/LiveStacks.h
@@ -34,6 +34,7 @@ class TargetRegisterInfo;
class LiveStacks : public MachineFunctionPass {
const TargetRegisterInfo *TRI = nullptr;
+ const MachineRegisterInfo *MRI = nullptr;
/// Special pool allocator for VNInfo's (LiveInterval val#).
///
diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h
index fcdd73d8b65fdd..c7067d90a3ce06 100644
--- a/llvm/include/llvm/CodeGen/MachineInstr.h
+++ b/llvm/include/llvm/CodeGen/MachineInstr.h
@@ -1586,7 +1586,7 @@ class MachineInstr
const TargetRegisterClass *getRegClassConstraintEffectForVReg(
Register Reg, const TargetRegisterClass *CurRC,
const TargetInstrInfo *TII, const TargetRegisterInfo *TRI,
- bool ExploreBundle = false) const;
+ const MachineRegisterInfo &MRI, bool ExploreBundle = false) const;
/// Applies the constraints (def/use) implied by the \p OpIdx operand
/// to the given \p CurRC.
@@ -1600,7 +1600,8 @@ class MachineInstr
const TargetRegisterClass *
getRegClassConstraintEffect(unsigned OpIdx, const TargetRegisterClass *CurRC,
const TargetInstrInfo *TII,
- const TargetRegisterInfo *TRI) const;
+ const TargetRegisterInfo *TRI,
+ const MachineRegisterInfo &MRI) const;
/// Add a tie between the register operands at DefIdx and UseIdx.
/// The tie will cause the register allocator to ensure that the two
@@ -2005,7 +2006,8 @@ class MachineInstr
/// If the related operand does not constrained Reg, this returns CurRC.
const TargetRegisterClass *getRegClassConstraintEffectForVRegImpl(
unsigned OpIdx, Register Reg, const TargetRegisterClass *CurRC,
- const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const;
+ const TargetInstrInfo *TII, const TargetRegisterInfo *TRI,
+ const MachineRegisterInfo &MRI) const;
/// Stores extra instruction information inline or allocates as ExtraInfo
/// based on the number of pointers.
diff --git a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
index 09d9a0b4ec402f..71a3baef70e8cd 100644
--- a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -94,6 +94,10 @@ class MachineRegisterInfo {
/// all registers that were disabled are removed from the list.
SmallVector<MCPhysReg, 16> UpdatedCSRs;
+ /// The Synthetic field of regclasses. Targets can alter this vector
+ /// to enable classes dynamically during codegen.
+ BitVector RegClassSyntheticInfo;
+
/// RegAllocHints - This vector records register allocation hints for
/// virtual registers. For each virtual register, it keeps a pair of hint
/// type and hints vector making up the allocation hints. Only the first
@@ -257,6 +261,18 @@ class MachineRegisterInfo {
/// Notice that it will override ant previously disabled/saved CSRs.
void setCalleeSavedRegs(ArrayRef<MCPhysReg> CSRs);
+ /// Initialize the RegClassSyntheticInfo. It sets the bit position as
+ /// exactly as the tablegened Synthetic field. Targets can later flip this
+ /// field to enable/disable the regclass whenever required.
+ void initializeRegClassSyntheticInfo();
+
+ /// Change the synthetic info for the regclass \p RC from \p Value.
+ void changeSyntheticInfoForRC(const TargetRegisterClass *RC, bool Value);
+
+ /// This function checks if \p RC is enabled or not so that it can be included
+ /// in various regclass related queries.
+ bool isEnabled(const TargetRegisterClass *RC) const;
+
// Strictly for use by MachineInstr.cpp.
void addRegOperandToUseList(MachineOperand *MO);
diff --git a/llvm/include/llvm/CodeGen/RegisterBankInfo.h b/llvm/include/llvm/CodeGen/RegisterBankInfo.h
index 62c4a57a605d68..117f381512a1c6 100644
--- a/llvm/include/llvm/CodeGen/RegisterBankInfo.h
+++ b/llvm/include/llvm/CodeGen/RegisterBankInfo.h
@@ -445,7 +445,8 @@ class RegisterBankInfo {
/// Get the MinimalPhysRegClass for Reg.
/// \pre Reg is a physical register.
const TargetRegisterClass *
- getMinimalPhysRegClass(Register Reg, const TargetRegisterInfo &TRI) const;
+ getMinimalPhysRegClass(Register Reg, const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI) const;
/// Try to get the mapping of \p MI.
/// See getInstrMapping for more details on what a mapping represents.
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 59fad88f91b1d1..5ef963cae55286 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -4384,6 +4384,7 @@ class TargetLowering : public TargetLoweringBase {
/// Returns 'true' is the edge is necessary, 'false' otherwise
virtual bool checkForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
const TargetRegisterInfo *TRI,
+ const MachineRegisterInfo &MRI,
const TargetInstrInfo *TII,
unsigned &PhysReg, int &Cost) const {
return false;
diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index 117d3f71829747..a3d68d6743ede5 100644
--- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -121,6 +121,9 @@ class TargetRegisterClass {
/// Return true if this register class has a defined BaseClassOrder.
bool isBaseClass() const { return MC->isBaseClass(); }
+ /// Return true if this register class is marked synthetic.
+ bool isSynthetic() const { return MC->isSynthetic(); }
+
/// Return true if the specified TargetRegisterClass
/// is a proper sub-class of this TargetRegisterClass.
bool hasSubClass(const TargetRegisterClass *RC) const {
@@ -338,20 +341,23 @@ class TargetRegisterInfo : public MCRegisterInfo {
/// Returns the Register Class of a physical register of the given type,
/// picking the most sub register class of the right type that contains this
/// physreg.
- const TargetRegisterClass *getMinimalPhysRegClass(MCRegister Reg,
- MVT VT = MVT::Other) const;
+ const TargetRegisterClass *
+ getMinimalPhysRegClass(MCRegister Reg, const MachineRegisterInfo &MRI,
+ MVT VT = MVT::Other) const;
/// Returns the Register Class of a physical register of the given type,
/// picking the most sub register class of the right type that contains this
/// physreg. If there is no register class compatible with the given type,
/// returns nullptr.
- const TargetRegisterClass *getMinimalPhysRegClassLLT(MCRegister Reg,
- LLT Ty = LLT()) const;
+ const TargetRegisterClass *
+ getMinimalPhysRegClassLLT(MCRegister Reg, const MachineRegisterInfo &MRI,
+ LLT Ty = LLT()) const;
/// Return the maximal subclass of the given register class that is
/// allocatable or NULL.
const TargetRegisterClass *
- getAllocatableClass(const TargetRegisterClass *RC) const;
+ getAllocatableClass(const TargetRegisterClass *RC,
+ const MachineRegisterInfo &MRI) const;
/// Returns a bitset indexed by register number indicating if a register is
/// allocatable or not. If a register class is specified, returns the subset
@@ -630,7 +636,8 @@ class TargetRegisterInfo : public MCRegisterInfo {
/// TableGen will synthesize missing A sub-classes.
virtual const TargetRegisterClass *
getMatchingSuperRegClass(const TargetRegisterClass *A,
- const TargetRegisterClass *B, unsigned Idx) const;
+ const TargetRegisterClass *B, unsigned Idx,
+ const MachineRegisterInfo &MRI) const;
// For a copy-like instruction that defines a register of class DefRC with
// subreg index DefSubReg, reading from another source with class SrcRC and
@@ -639,7 +646,8 @@ class TargetRegisterInfo : public MCRegisterInfo {
virtual bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
unsigned DefSubReg,
const TargetRegisterClass *SrcRC,
- unsigned SrcSubReg) const;
+ unsigned SrcSubReg,
+ const MachineRegisterInfo &MRI) const;
/// Returns the largest legal sub-class of RC that
/// supports the sub-register index Idx.
@@ -769,10 +777,11 @@ class TargetRegisterInfo : public MCRegisterInfo {
/// corresponding argument register class.
///
/// The function returns NULL if no register class can be found.
- const TargetRegisterClass*
+ const TargetRegisterClass *
getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA,
const TargetRegisterClass *RCB, unsigned SubB,
- unsigned &PreA, unsigned &PreB) const;
+ unsigned &PreA, unsigned &PreB,
+ const MachineRegisterInfo &MRI) const;
//===--------------------------------------------------------------------===//
// Register Class Information
@@ -809,8 +818,8 @@ class TargetRegisterInfo : public MCRegisterInfo {
/// Find the largest common subclass of A and B.
/// Return NULL if there is no common subclass.
const TargetRegisterClass *
- getCommonSubClass(const TargetRegisterClass *A,
- const TargetRegisterClass *B) const;
+ getCommonSubClass(const TargetRegisterClass *A, const TargetRegisterClass *B,
+ const MachineRegisterInfo &MRI) const;
/// Returns a TargetRegisterClass used for pointer values.
/// If a target supports multiple different pointer register classes,
diff --git a/llvm/include/llvm/MC/MCRegisterInfo.h b/llvm/include/llvm/MC/MCRegisterInfo.h
index fb4d11ec1d4d16..1a2ff58c31f5a6 100644
--- a/llvm/include/llvm/MC/MCRegisterInfo.h
+++ b/llvm/include/llvm/MC/MCRegisterInfo.h
@@ -47,6 +47,7 @@ class MCRegisterClass {
const int8_t CopyCost;
const bool Allocatable;
const bool BaseClass;
+ const bool Synthetic;
/// getID() - Return the register class ID number.
///
@@ -101,6 +102,9 @@ class MCRegisterClass {
/// Return true if this register class has a defined BaseClassOrder.
bool isBaseClass() const { return BaseClass; }
+ /// isSynthetic - Return true if this is a synthetic class. This field helps
+ /// targets to dynamically enable the regclass during codegen.
+ bool isSynthetic() const { return Synthetic; }
};
/// MCRegisterDesc - This record contains information about a particular
diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td
index cb1c0ed2513d45..0cf9159030bc52 100644
--- a/llvm/include/llvm/Target/Target.td
+++ b/llvm/include/llvm/Target/Target.td
@@ -338,6 +338,12 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
// Target-specific flags. This becomes the TSFlags field in TargetRegisterClass.
bits<8> TSFlags = 0;
+ // If set to true, the register class won't take part in various regclass queries
+ // by default. This allows targets to dynamically enable classes for a period
+ // during codegen so that they can be turned allocatable, copyable, spillable,
+ // and/or make them available for various regclass queries.
+ bit Synthetic = false;
+
// If set then consider this register class to be the base class for registers in
// its MemberList. The base class for registers present in multiple base register
// classes will be resolved in the order defined by this value, with lower values
diff --git a/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp
index ed6ce6bc73d38c..93860aae8acfdf 100644
--- a/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp
+++ b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp
@@ -604,7 +604,7 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
// check every use of the register and find the largest register class
// that can be used in all of them.
const TargetRegisterClass *SuperRC =
- TRI->getMinimalPhysRegClass(SuperReg, MVT::Other);
+ TRI->getMinimalPhysRegClass(SuperReg, MRI, MVT::Other);
ArrayRef<MCPhysReg> Order = RegClassInfo.getOrder(SuperRC);
if (Order.empty()) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 14f2a363f9be61..7b403fee7ed120 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -813,7 +813,7 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
auto AddEntry = [&](const DbgValueLocEntry &Entry,
DIExpressionCursor &Cursor) {
if (Entry.isLocation()) {
- if (!DwarfExpr.addMachineRegExpression(TRI, Cursor,
+ if (!DwarfExpr.addMachineRegExpression(TRI, Asm->MF->getRegInfo(), Cursor,
Entry.getLoc().getReg()))
return false;
} else if (Entry.isInt()) {
@@ -910,7 +910,8 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes(const Loc::MMI &MMI,
addOpAddress(*Loc, FrameSymbol);
else
DwarfExpr.addMachineRegExpression(
- *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg);
+ *Asm->MF->getSubtarget().getRegisterInfo(), Asm->MF->getRegInfo(),
+ Cursor, FrameReg);
DwarfExpr.addExpression(std::move(Cursor));
}
if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
@@ -940,7 +941,8 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
DIExpressionCursor Cursor(Expr.getElements());
DwarfExpr.beginEntryValueExpression(Cursor);
DwarfExpr.addMachineRegExpression(
- *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, Register);
+ *Asm->MF->getSubtarget().getRegisterInfo(), Asm->MF->getRegInfo(),
+ Cursor, Register);
DwarfExpr.addExpression(std::move(Cursor));
}
addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
@@ -1557,7 +1559,8 @@ void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,
DIExpressionCursor Cursor({});
const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
- if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
+ if (!DwarfExpr.addMachineRegExpression(TRI, Asm->MF->getRegInfo(), Cursor,
+ Location.getReg()))
return;
DwarfExpr.addExpression(std::move(Cursor));
@@ -1587,7 +1590,8 @@ void DwarfCompileUnit::addComplexAddress(const DIExpression *DIExpr, DIE &Die,
DwarfExpr.beginEntryValueExpression(Cursor);
const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
- if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
+ if (!DwarfExpr.addMachineRegExpression(TRI, Asm->MF->getRegInfo(), Cursor,
+ Location.getReg()))
return;
DwarfExpr.addExpression(std::move(Cursor));
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 6b5ad62e083e3b..0b372d7b0e1bf1 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -2652,7 +2652,8 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
DwarfExpr.beginEntryValueExpression(ExprCursor);
const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
- if (!DwarfExpr.addMachineRegExpression(TRI, ExprCursor, Location.getReg()))
+ if (!DwarfExpr.addMachineRegExpression(TRI, AP.MF->getRegInfo(), ExprCursor,
+ Location.getReg()))
return;
return DwarfExpr.addExpression(std::move(ExprCursor));
}
@@ -2673,7 +2674,8 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
DwarfExpr.setMemoryLocationKind();
const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
- if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
+ if (!DwarfExpr.addMachineRegExpression(TRI, AP.MF->getRegInfo(), Cursor,
+ Location.getReg()))
return false;
} else if (Entry.isTargetIndexLocation()) {
TargetIndexLocation Loc = Entry.getTargetIndexLocation();
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index a74d43897d45b3..6d4794d27effbd 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -97,6 +97,7 @@ void DwarfExpression::addAnd(unsigned Mask) {
}
bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI,
llvm::Register MachineReg,
unsigned MaxSize) {
if (!MachineReg.isPhysical()) {
@@ -134,7 +135,7 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
// For example, Q0 on ARM is a composition of D0+D1.
unsigned CurPos = 0;
// The size of the register in bits.
- const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg);
+ const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg, MRI);
unsigned RegSize = TRI.getRegSizeInBits(*RC);
// Keep track of the bits in the register we already emitted, so we
// can avoid emitting redundant aliasing subregs. Because this is
@@ -248,11 +249,13 @@ void DwarfExpression::addConstantFP(const APFloat &APF, const AsmPrinter &AP) {
}
bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI,
DIExpressionCursor &ExprCursor,
llvm::Register MachineReg,
unsigned FragmentOffsetInBits) {
auto Fragment = ExprCursor.getFragmentInfo();
- if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) {
+ if (!addMachineReg(TRI, MRI, MachineReg,
+ Fragment ? Fragment->SizeInBits : ~1U)) {
LocationKind = Unknown;
return false;
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 667a9efc6f6c04..70ab73b5996b48 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -245,7 +245,8 @@ class DwarfExpression {
/// multiple subregisters that alias the register.
///
/// \return false if no DWARF register exists for MachineReg.
- bool addMachineReg(const TargetRegisterInfo &TRI, llvm::Register MachineReg,
+ bool addMachineReg(const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI, llvm::Register MachineReg,
unsigned MaxSize = ~1U);
/// Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment.
@@ -325,6 +326,7 @@ class DwarfExpression {
/// \return false if no DWARF register exists
/// for MachineReg.
bool addMachineRegExpression(const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI,
DIExpressionCursor &Expr,
llvm::Register MachineReg,
unsigned FragmentOffsetInBits = 0);
diff --git a/llvm/lib/CodeGen/DetectDeadLanes.cpp b/llvm/lib/CodeGen/DetectDeadLanes.cpp
index 86e9f3abe010d7..57c5466129162e 100644
--- a/llvm/lib/CodeGen/DetectDeadLanes.cpp
+++ b/llvm/lib/CodeGen/DetectDeadLanes.cpp
@@ -97,12 +97,12 @@ static bool isCr...
[truncated]
|
@llvm/pr-subscribers-backend-aarch64 Author: Christudasan Devadasan (cdevadas) ChangesCurrently register classes can only be defined statically. There is no way targets can define classes during codegen for a specific period of time. This patch includes a new field named The static definition of such classes are done in *RegisterInfo.td file like other classes for tablegen to include them in all the tables it auto-generates. The Synthetic field would be set to true for such classes. Patch is 135.37 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/86006.diff 86 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/LiveStacks.h b/llvm/include/llvm/CodeGen/LiveStacks.h
index 2edc2985f0ee66..b9e55987383901 100644
--- a/llvm/include/llvm/CodeGen/LiveStacks.h
+++ b/llvm/include/llvm/CodeGen/LiveStacks.h
@@ -34,6 +34,7 @@ class TargetRegisterInfo;
class LiveStacks : public MachineFunctionPass {
const TargetRegisterInfo *TRI = nullptr;
+ const MachineRegisterInfo *MRI = nullptr;
/// Special pool allocator for VNInfo's (LiveInterval val#).
///
diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h
index fcdd73d8b65fdd..c7067d90a3ce06 100644
--- a/llvm/include/llvm/CodeGen/MachineInstr.h
+++ b/llvm/include/llvm/CodeGen/MachineInstr.h
@@ -1586,7 +1586,7 @@ class MachineInstr
const TargetRegisterClass *getRegClassConstraintEffectForVReg(
Register Reg, const TargetRegisterClass *CurRC,
const TargetInstrInfo *TII, const TargetRegisterInfo *TRI,
- bool ExploreBundle = false) const;
+ const MachineRegisterInfo &MRI, bool ExploreBundle = false) const;
/// Applies the constraints (def/use) implied by the \p OpIdx operand
/// to the given \p CurRC.
@@ -1600,7 +1600,8 @@ class MachineInstr
const TargetRegisterClass *
getRegClassConstraintEffect(unsigned OpIdx, const TargetRegisterClass *CurRC,
const TargetInstrInfo *TII,
- const TargetRegisterInfo *TRI) const;
+ const TargetRegisterInfo *TRI,
+ const MachineRegisterInfo &MRI) const;
/// Add a tie between the register operands at DefIdx and UseIdx.
/// The tie will cause the register allocator to ensure that the two
@@ -2005,7 +2006,8 @@ class MachineInstr
/// If the related operand does not constrained Reg, this returns CurRC.
const TargetRegisterClass *getRegClassConstraintEffectForVRegImpl(
unsigned OpIdx, Register Reg, const TargetRegisterClass *CurRC,
- const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const;
+ const TargetInstrInfo *TII, const TargetRegisterInfo *TRI,
+ const MachineRegisterInfo &MRI) const;
/// Stores extra instruction information inline or allocates as ExtraInfo
/// based on the number of pointers.
diff --git a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
index 09d9a0b4ec402f..71a3baef70e8cd 100644
--- a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -94,6 +94,10 @@ class MachineRegisterInfo {
/// all registers that were disabled are removed from the list.
SmallVector<MCPhysReg, 16> UpdatedCSRs;
+ /// The Synthetic field of regclasses. Targets can alter this vector
+ /// to enable classes dynamically during codegen.
+ BitVector RegClassSyntheticInfo;
+
/// RegAllocHints - This vector records register allocation hints for
/// virtual registers. For each virtual register, it keeps a pair of hint
/// type and hints vector making up the allocation hints. Only the first
@@ -257,6 +261,18 @@ class MachineRegisterInfo {
/// Notice that it will override ant previously disabled/saved CSRs.
void setCalleeSavedRegs(ArrayRef<MCPhysReg> CSRs);
+ /// Initialize the RegClassSyntheticInfo. It sets the bit position as
+ /// exactly as the tablegened Synthetic field. Targets can later flip this
+ /// field to enable/disable the regclass whenever required.
+ void initializeRegClassSyntheticInfo();
+
+ /// Change the synthetic info for the regclass \p RC from \p Value.
+ void changeSyntheticInfoForRC(const TargetRegisterClass *RC, bool Value);
+
+ /// This function checks if \p RC is enabled or not so that it can be included
+ /// in various regclass related queries.
+ bool isEnabled(const TargetRegisterClass *RC) const;
+
// Strictly for use by MachineInstr.cpp.
void addRegOperandToUseList(MachineOperand *MO);
diff --git a/llvm/include/llvm/CodeGen/RegisterBankInfo.h b/llvm/include/llvm/CodeGen/RegisterBankInfo.h
index 62c4a57a605d68..117f381512a1c6 100644
--- a/llvm/include/llvm/CodeGen/RegisterBankInfo.h
+++ b/llvm/include/llvm/CodeGen/RegisterBankInfo.h
@@ -445,7 +445,8 @@ class RegisterBankInfo {
/// Get the MinimalPhysRegClass for Reg.
/// \pre Reg is a physical register.
const TargetRegisterClass *
- getMinimalPhysRegClass(Register Reg, const TargetRegisterInfo &TRI) const;
+ getMinimalPhysRegClass(Register Reg, const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI) const;
/// Try to get the mapping of \p MI.
/// See getInstrMapping for more details on what a mapping represents.
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 59fad88f91b1d1..5ef963cae55286 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -4384,6 +4384,7 @@ class TargetLowering : public TargetLoweringBase {
/// Returns 'true' is the edge is necessary, 'false' otherwise
virtual bool checkForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
const TargetRegisterInfo *TRI,
+ const MachineRegisterInfo &MRI,
const TargetInstrInfo *TII,
unsigned &PhysReg, int &Cost) const {
return false;
diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index 117d3f71829747..a3d68d6743ede5 100644
--- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -121,6 +121,9 @@ class TargetRegisterClass {
/// Return true if this register class has a defined BaseClassOrder.
bool isBaseClass() const { return MC->isBaseClass(); }
+ /// Return true if this register class is marked synthetic.
+ bool isSynthetic() const { return MC->isSynthetic(); }
+
/// Return true if the specified TargetRegisterClass
/// is a proper sub-class of this TargetRegisterClass.
bool hasSubClass(const TargetRegisterClass *RC) const {
@@ -338,20 +341,23 @@ class TargetRegisterInfo : public MCRegisterInfo {
/// Returns the Register Class of a physical register of the given type,
/// picking the most sub register class of the right type that contains this
/// physreg.
- const TargetRegisterClass *getMinimalPhysRegClass(MCRegister Reg,
- MVT VT = MVT::Other) const;
+ const TargetRegisterClass *
+ getMinimalPhysRegClass(MCRegister Reg, const MachineRegisterInfo &MRI,
+ MVT VT = MVT::Other) const;
/// Returns the Register Class of a physical register of the given type,
/// picking the most sub register class of the right type that contains this
/// physreg. If there is no register class compatible with the given type,
/// returns nullptr.
- const TargetRegisterClass *getMinimalPhysRegClassLLT(MCRegister Reg,
- LLT Ty = LLT()) const;
+ const TargetRegisterClass *
+ getMinimalPhysRegClassLLT(MCRegister Reg, const MachineRegisterInfo &MRI,
+ LLT Ty = LLT()) const;
/// Return the maximal subclass of the given register class that is
/// allocatable or NULL.
const TargetRegisterClass *
- getAllocatableClass(const TargetRegisterClass *RC) const;
+ getAllocatableClass(const TargetRegisterClass *RC,
+ const MachineRegisterInfo &MRI) const;
/// Returns a bitset indexed by register number indicating if a register is
/// allocatable or not. If a register class is specified, returns the subset
@@ -630,7 +636,8 @@ class TargetRegisterInfo : public MCRegisterInfo {
/// TableGen will synthesize missing A sub-classes.
virtual const TargetRegisterClass *
getMatchingSuperRegClass(const TargetRegisterClass *A,
- const TargetRegisterClass *B, unsigned Idx) const;
+ const TargetRegisterClass *B, unsigned Idx,
+ const MachineRegisterInfo &MRI) const;
// For a copy-like instruction that defines a register of class DefRC with
// subreg index DefSubReg, reading from another source with class SrcRC and
@@ -639,7 +646,8 @@ class TargetRegisterInfo : public MCRegisterInfo {
virtual bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
unsigned DefSubReg,
const TargetRegisterClass *SrcRC,
- unsigned SrcSubReg) const;
+ unsigned SrcSubReg,
+ const MachineRegisterInfo &MRI) const;
/// Returns the largest legal sub-class of RC that
/// supports the sub-register index Idx.
@@ -769,10 +777,11 @@ class TargetRegisterInfo : public MCRegisterInfo {
/// corresponding argument register class.
///
/// The function returns NULL if no register class can be found.
- const TargetRegisterClass*
+ const TargetRegisterClass *
getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA,
const TargetRegisterClass *RCB, unsigned SubB,
- unsigned &PreA, unsigned &PreB) const;
+ unsigned &PreA, unsigned &PreB,
+ const MachineRegisterInfo &MRI) const;
//===--------------------------------------------------------------------===//
// Register Class Information
@@ -809,8 +818,8 @@ class TargetRegisterInfo : public MCRegisterInfo {
/// Find the largest common subclass of A and B.
/// Return NULL if there is no common subclass.
const TargetRegisterClass *
- getCommonSubClass(const TargetRegisterClass *A,
- const TargetRegisterClass *B) const;
+ getCommonSubClass(const TargetRegisterClass *A, const TargetRegisterClass *B,
+ const MachineRegisterInfo &MRI) const;
/// Returns a TargetRegisterClass used for pointer values.
/// If a target supports multiple different pointer register classes,
diff --git a/llvm/include/llvm/MC/MCRegisterInfo.h b/llvm/include/llvm/MC/MCRegisterInfo.h
index fb4d11ec1d4d16..1a2ff58c31f5a6 100644
--- a/llvm/include/llvm/MC/MCRegisterInfo.h
+++ b/llvm/include/llvm/MC/MCRegisterInfo.h
@@ -47,6 +47,7 @@ class MCRegisterClass {
const int8_t CopyCost;
const bool Allocatable;
const bool BaseClass;
+ const bool Synthetic;
/// getID() - Return the register class ID number.
///
@@ -101,6 +102,9 @@ class MCRegisterClass {
/// Return true if this register class has a defined BaseClassOrder.
bool isBaseClass() const { return BaseClass; }
+ /// isSynthetic - Return true if this is a synthetic class. This field helps
+ /// targets to dynamically enable the regclass during codegen.
+ bool isSynthetic() const { return Synthetic; }
};
/// MCRegisterDesc - This record contains information about a particular
diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td
index cb1c0ed2513d45..0cf9159030bc52 100644
--- a/llvm/include/llvm/Target/Target.td
+++ b/llvm/include/llvm/Target/Target.td
@@ -338,6 +338,12 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
// Target-specific flags. This becomes the TSFlags field in TargetRegisterClass.
bits<8> TSFlags = 0;
+ // If set to true, the register class won't take part in various regclass queries
+ // by default. This allows targets to dynamically enable classes for a period
+ // during codegen so that they can be turned allocatable, copyable, spillable,
+ // and/or make them available for various regclass queries.
+ bit Synthetic = false;
+
// If set then consider this register class to be the base class for registers in
// its MemberList. The base class for registers present in multiple base register
// classes will be resolved in the order defined by this value, with lower values
diff --git a/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp
index ed6ce6bc73d38c..93860aae8acfdf 100644
--- a/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp
+++ b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp
@@ -604,7 +604,7 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
// check every use of the register and find the largest register class
// that can be used in all of them.
const TargetRegisterClass *SuperRC =
- TRI->getMinimalPhysRegClass(SuperReg, MVT::Other);
+ TRI->getMinimalPhysRegClass(SuperReg, MRI, MVT::Other);
ArrayRef<MCPhysReg> Order = RegClassInfo.getOrder(SuperRC);
if (Order.empty()) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 14f2a363f9be61..7b403fee7ed120 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -813,7 +813,7 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
auto AddEntry = [&](const DbgValueLocEntry &Entry,
DIExpressionCursor &Cursor) {
if (Entry.isLocation()) {
- if (!DwarfExpr.addMachineRegExpression(TRI, Cursor,
+ if (!DwarfExpr.addMachineRegExpression(TRI, Asm->MF->getRegInfo(), Cursor,
Entry.getLoc().getReg()))
return false;
} else if (Entry.isInt()) {
@@ -910,7 +910,8 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes(const Loc::MMI &MMI,
addOpAddress(*Loc, FrameSymbol);
else
DwarfExpr.addMachineRegExpression(
- *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg);
+ *Asm->MF->getSubtarget().getRegisterInfo(), Asm->MF->getRegInfo(),
+ Cursor, FrameReg);
DwarfExpr.addExpression(std::move(Cursor));
}
if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
@@ -940,7 +941,8 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
DIExpressionCursor Cursor(Expr.getElements());
DwarfExpr.beginEntryValueExpression(Cursor);
DwarfExpr.addMachineRegExpression(
- *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, Register);
+ *Asm->MF->getSubtarget().getRegisterInfo(), Asm->MF->getRegInfo(),
+ Cursor, Register);
DwarfExpr.addExpression(std::move(Cursor));
}
addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
@@ -1557,7 +1559,8 @@ void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,
DIExpressionCursor Cursor({});
const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
- if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
+ if (!DwarfExpr.addMachineRegExpression(TRI, Asm->MF->getRegInfo(), Cursor,
+ Location.getReg()))
return;
DwarfExpr.addExpression(std::move(Cursor));
@@ -1587,7 +1590,8 @@ void DwarfCompileUnit::addComplexAddress(const DIExpression *DIExpr, DIE &Die,
DwarfExpr.beginEntryValueExpression(Cursor);
const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
- if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
+ if (!DwarfExpr.addMachineRegExpression(TRI, Asm->MF->getRegInfo(), Cursor,
+ Location.getReg()))
return;
DwarfExpr.addExpression(std::move(Cursor));
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 6b5ad62e083e3b..0b372d7b0e1bf1 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -2652,7 +2652,8 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
DwarfExpr.beginEntryValueExpression(ExprCursor);
const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
- if (!DwarfExpr.addMachineRegExpression(TRI, ExprCursor, Location.getReg()))
+ if (!DwarfExpr.addMachineRegExpression(TRI, AP.MF->getRegInfo(), ExprCursor,
+ Location.getReg()))
return;
return DwarfExpr.addExpression(std::move(ExprCursor));
}
@@ -2673,7 +2674,8 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
DwarfExpr.setMemoryLocationKind();
const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
- if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
+ if (!DwarfExpr.addMachineRegExpression(TRI, AP.MF->getRegInfo(), Cursor,
+ Location.getReg()))
return false;
} else if (Entry.isTargetIndexLocation()) {
TargetIndexLocation Loc = Entry.getTargetIndexLocation();
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index a74d43897d45b3..6d4794d27effbd 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -97,6 +97,7 @@ void DwarfExpression::addAnd(unsigned Mask) {
}
bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI,
llvm::Register MachineReg,
unsigned MaxSize) {
if (!MachineReg.isPhysical()) {
@@ -134,7 +135,7 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
// For example, Q0 on ARM is a composition of D0+D1.
unsigned CurPos = 0;
// The size of the register in bits.
- const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg);
+ const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg, MRI);
unsigned RegSize = TRI.getRegSizeInBits(*RC);
// Keep track of the bits in the register we already emitted, so we
// can avoid emitting redundant aliasing subregs. Because this is
@@ -248,11 +249,13 @@ void DwarfExpression::addConstantFP(const APFloat &APF, const AsmPrinter &AP) {
}
bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI,
DIExpressionCursor &ExprCursor,
llvm::Register MachineReg,
unsigned FragmentOffsetInBits) {
auto Fragment = ExprCursor.getFragmentInfo();
- if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) {
+ if (!addMachineReg(TRI, MRI, MachineReg,
+ Fragment ? Fragment->SizeInBits : ~1U)) {
LocationKind = Unknown;
return false;
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 667a9efc6f6c04..70ab73b5996b48 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -245,7 +245,8 @@ class DwarfExpression {
/// multiple subregisters that alias the register.
///
/// \return false if no DWARF register exists for MachineReg.
- bool addMachineReg(const TargetRegisterInfo &TRI, llvm::Register MachineReg,
+ bool addMachineReg(const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI, llvm::Register MachineReg,
unsigned MaxSize = ~1U);
/// Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment.
@@ -325,6 +326,7 @@ class DwarfExpression {
/// \return false if no DWARF register exists
/// for MachineReg.
bool addMachineRegExpression(const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI,
DIExpressionCursor &Expr,
llvm::Register MachineReg,
unsigned FragmentOffsetInBits = 0);
diff --git a/llvm/lib/CodeGen/DetectDeadLanes.cpp b/llvm/lib/CodeGen/DetectDeadLanes.cpp
index 86e9f3abe010d7..57c5466129162e 100644
--- a/llvm/lib/CodeGen/DetectDeadLanes.cpp
+++ b/llvm/lib/CodeGen/DetectDeadLanes.cpp
@@ -97,12 +97,12 @@ static bool isCr...
[truncated]
|
You can test this locally with the following command:git-clang-format --diff 1f1f569b29f42161ea978328aea60044f16eee49 a5bb710e7899ae06e195618ad0aa459b9d35bf57 -- llvm/include/llvm/CodeGen/LiveStacks.h llvm/include/llvm/CodeGen/MachineInstr.h llvm/include/llvm/CodeGen/MachineRegisterInfo.h llvm/include/llvm/CodeGen/RegisterBankInfo.h llvm/include/llvm/CodeGen/TargetLowering.h llvm/include/llvm/CodeGen/TargetRegisterInfo.h llvm/include/llvm/MC/MCRegisterInfo.h llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h llvm/lib/CodeGen/DetectDeadLanes.cpp llvm/lib/CodeGen/FixupStatepointCallerSaved.cpp llvm/lib/CodeGen/GlobalISel/Utils.cpp llvm/lib/CodeGen/LiveStacks.cpp llvm/lib/CodeGen/MIRParser/MIRParser.cpp llvm/lib/CodeGen/MachineCSE.cpp llvm/lib/CodeGen/MachineCombiner.cpp llvm/lib/CodeGen/MachineInstr.cpp llvm/lib/CodeGen/MachineRegisterInfo.cpp llvm/lib/CodeGen/MachineVerifier.cpp llvm/lib/CodeGen/PeepholeOptimizer.cpp llvm/lib/CodeGen/PrologEpilogInserter.cpp llvm/lib/CodeGen/RegAllocGreedy.cpp llvm/lib/CodeGen/RegisterBank.cpp llvm/lib/CodeGen/RegisterBankInfo.cpp llvm/lib/CodeGen/RegisterCoalescer.cpp llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/CodeGen/StackMaps.cpp llvm/lib/CodeGen/TailDuplicator.cpp llvm/lib/CodeGen/TargetLoweringBase.cpp llvm/lib/CodeGen/TargetRegisterInfo.cpp llvm/lib/CodeGen/TwoAddressInstructionPass.cpp llvm/lib/Target/AArch64/AArch64FrameLowering.cpp llvm/lib/Target/AArch64/AArch64InstrInfo.cpp llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp llvm/lib/Target/AMDGPU/GCNRewritePartialRegUses.cpp llvm/lib/Target/AMDGPU/SIISelLowering.cpp llvm/lib/Target/AMDGPU/SIISelLowering.h llvm/lib/Target/AMDGPU/SIInstrInfo.cpp llvm/lib/Target/AMDGPU/SIInstrInfo.h llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp llvm/lib/Target/AMDGPU/SIRegisterInfo.h llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp llvm/lib/Target/ARM/ARMBaseRegisterInfo.h llvm/lib/Target/AVR/AVRAsmPrinter.cpp llvm/lib/Target/AVR/AVRFrameLowering.cpp llvm/lib/Target/CSKY/CSKYFrameLowering.cpp llvm/lib/Target/Hexagon/BitTracker.cpp llvm/lib/Target/Hexagon/HexagonBitTracker.cpp llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp llvm/lib/Target/Hexagon/RDFCopy.cpp llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp llvm/lib/Target/Mips/MipsFrameLowering.cpp llvm/lib/Target/Mips/MipsSEFrameLowering.cpp llvm/lib/Target/PowerPC/PPCFrameLowering.cpp llvm/lib/Target/PowerPC/PPCInstrInfo.cpp llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp llvm/lib/Target/RISCV/RISCVFrameLowering.cpp llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp llvm/lib/Target/X86/X86FrameLowering.cpp llvm/lib/Target/X86/X86InstrInfo.cpp llvm/lib/Target/X86/X86RegisterInfo.cpp llvm/lib/Target/X86/X86RegisterInfo.h llvm/lib/Target/XCore/XCoreFrameLowering.cpp llvm/unittests/CodeGen/MFCommon.inc llvm/unittests/CodeGen/MachineInstrTest.cpp llvm/utils/TableGen/CodeGenRegisters.cpp llvm/utils/TableGen/CodeGenRegisters.h llvm/utils/TableGen/RegisterInfoEmitter.cpp View the diff from clang-format here.diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 982d1a0c44..25b0f5688a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -9738,11 +9738,10 @@ void SelectionDAGBuilder::visitInlineAsm(const CallBase &Call,
Register TiedReg = R->getReg();
MVT RegVT = R->getSimpleValueType(0);
const TargetRegisterClass *RC =
- TiedReg.isVirtual()
- ? MRI.getRegClass(TiedReg)
- : RegVT != MVT::Untyped
- ? TLI.getRegClassFor(RegVT)
- : TRI.getMinimalPhysRegClass(TiedReg, MRI);
+ TiedReg.isVirtual() ? MRI.getRegClass(TiedReg)
+ : RegVT != MVT::Untyped
+ ? TLI.getRegClassFor(RegVT)
+ : TRI.getMinimalPhysRegClass(TiedReg, MRI);
for (unsigned i = 0, e = Flag.getNumOperandRegisters(); i != e; ++i)
Regs.push_back(MRI.createVirtualRegister(RC));
diff --git a/llvm/unittests/CodeGen/MFCommon.inc b/llvm/unittests/CodeGen/MFCommon.inc
index 8db39e384d..7bf78ab41a 100644
--- a/llvm/unittests/CodeGen/MFCommon.inc
+++ b/llvm/unittests/CodeGen/MFCommon.inc
@@ -19,11 +19,7 @@ public:
// Dummy regclass fields ...
namespace {
-enum {
- NoRegister,
- GPR0 = 1,
- NUM_TARGET_REGS
-};
+enum { NoRegister, GPR0 = 1, NUM_TARGET_REGS };
enum {
GPRsRegClassID = 0,
@@ -31,16 +27,17 @@ enum {
const MCPhysReg GPRs[] = {GPR0};
-const uint8_t GPRsBits[] = { 0x00 };
+const uint8_t GPRsBits[] = {0x00};
static const uint32_t GPRsSubClassMask[] = {
- 0x00000001,
+ 0x00000001,
};
} // namespace
-static const TargetRegisterClass *const NullRegClasses[] = { nullptr };
-static const MCRegisterClass BogusMCRegisterClasses[] = {{ GPRs, GPRsBits, 0, 1,
- sizeof(GPRsBits), GPRsRegClassID, 1, -1, false, true ,false }};
+static const TargetRegisterClass *const NullRegClasses[] = {nullptr};
+static const MCRegisterClass BogusMCRegisterClasses[] = {
+ {GPRs, GPRsBits, 0, 1, sizeof(GPRsBits), GPRsRegClassID, 1, -1, false, true,
+ false}};
static const TargetRegisterClass GPRsRegClass = {
&BogusMCRegisterClasses[GPRsRegClassID],
GPRsSubClassMask,
@@ -52,16 +49,17 @@ static const TargetRegisterClass GPRsRegClass = {
false,
false,
NullRegClasses,
- nullptr
-};
+ nullptr};
- static const TargetRegisterClass *const BogusRegisterClasses[] = {&GPRsRegClass};
+static const TargetRegisterClass *const BogusRegisterClasses[] = {
+ &GPRsRegClass};
class BogusRegisterInfo : public TargetRegisterInfo {
public:
BogusRegisterInfo()
- : TargetRegisterInfo(nullptr, BogusRegisterClasses, BogusRegisterClasses+1,
- nullptr, nullptr, LaneBitmask(~0u), nullptr, nullptr) {
+ : TargetRegisterInfo(nullptr, BogusRegisterClasses,
+ BogusRegisterClasses + 1, nullptr, nullptr,
+ LaneBitmask(~0u), nullptr, nullptr) {
InitMCRegisterInfo(nullptr, 0, 0, 0, nullptr, 0, nullptr, 0, nullptr,
nullptr, nullptr, nullptr, nullptr, 0, nullptr, nullptr);
}
|
@@ -47,6 +47,7 @@ class MCRegisterClass { | |||
const int8_t CopyCost; | |||
const bool Allocatable; | |||
const bool BaseClass; | |||
const bool Synthetic; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe those should be bitfields/a mask?
@@ -101,6 +102,9 @@ class MCRegisterClass { | |||
|
|||
/// Return true if this register class has a defined BaseClassOrder. | |||
bool isBaseClass() const { return BaseClass; } | |||
/// isSynthetic - Return true if this is a synthetic class. This field helps | |||
/// targets to dynamically enable the regclass during codegen. | |||
bool isSynthetic() const { return Synthetic; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the reasoning for the "syntethic" name? I feel like "dynamic" suits it more, no?
When I see synthetic I imagine a capability to generate a RC using C++, but these still need to be defined in .td
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We want to express a software constraint. Every other class is expressing a hardware constraint. We want to express a synthetic allocation window
@@ -333,6 +333,7 @@ class CodeGenRegisterClass { | |||
uint8_t AllocationPriority; | |||
bool GlobalPriority; | |||
uint8_t TSFlags; | |||
bool Synthetic; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doc comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see Doc comments for other fields here. See Target.td
for a detailed description for it.
void MachineRegisterInfo::changeSyntheticInfoForRC( | ||
const TargetRegisterClass *RC, bool Value) { | ||
assert(RC->isSynthetic() && "Regclasses can be enabled/disabled dynamically " | ||
"only if marked synthetic."); | ||
|
||
if (Value) | ||
RegClassSyntheticInfo.set(RC->getID()); | ||
else | ||
RegClassSyntheticInfo.reset(RC->getID()); | ||
} | ||
|
||
bool MachineRegisterInfo::isEnabled(const TargetRegisterClass *RC) const { | ||
return !RegClassSyntheticInfo.test(RC->getID()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These functions feel out of place in this PR, no one is calling them, they aren't being tested. I haven't looked at the rest of the PRs yet. 1) Can you tell more about how they will be used? 2) Can there be unittests for them here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This patch sets up the whole machinery for the new field Synthetic that I'm introducing.
The test llvm/unittests/CodeGen/MachineInstrTest.cpp covers it. The helper function isEnabled
, is used in the regclass queries in MRI and TRI interfaces in this patch itself.
Ping. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code wise changes LGTM.
|
||
/// This function checks if \p RC is enabled or not so that it can be included | ||
/// in various regclass related queries. | ||
bool isEnabled(const TargetRegisterClass *RC) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can it be better named? isEnabled
sounds very generic to just check synthetic info. Perhaps isSyntheticallyDisabled(RC)
?
Before looking into the patch, I'd like to see more consensus on the approach itself. I feel that the RFC did not reach that point yet. |
Ping |
Implemented wwm-register allocation using the alternate PR #93526 and this patch no longer needed. |
Currently register classes can only be defined statically. There is no way targets can define classes during codegen for a specific period of time.
This patch includes a new field named
Synthetic
in the regclass definition with value false by default. This field, when set to true, indicates that such regclasses are disabled by default and won't take part in various regclass queries like getAllocatableClass, getMinimalPhysRegClass, etc. and in fact, they won't be allocatable, but targets can enable them dynamically so that they behave like other register classes.The static definition of such classes are done in *RegisterInfo.td file like other classes for tablegen to include them in all the tables it auto-generates. The Synthetic field would be set to true for such classes.