[TableGen][RISCV][Hexagon][LoongArch] Add a list of Predicates to HwMode.

Use the predicate condition instead of checkFeatures in *GenDAGISel.inc.

This makes the code similar to isel pattern predicates.

checkFeatures is still used by code created by SubtargetEmitter so
we can't remove the string. Backends need to be careful to keep
the string and predicates in sync, but I don't think that's a big issue.

I haven't measured it, but this should be a compile time improvement
for isel since we don't have to do any of the string processing that's
inside checkFeatures.

Reviewed By: kparzysz

Differential Revision: https://reviews.llvm.org/D146012
This commit is contained in:
Craig Topper 2023-03-14 13:00:38 -07:00
parent f47404b012
commit 81a150656b
9 changed files with 39 additions and 16 deletions

View File

@ -14,11 +14,13 @@
// Include all information about LLVM intrinsics.
include "llvm/IR/Intrinsics.td"
class Predicate; // Forward def
//===----------------------------------------------------------------------===//
// Register file description - These classes are used to fill in the target
// description classes.
class HwMode<string FS> {
class HwMode<string FS, list<Predicate> Ps> {
// A string representing subtarget features that turn on this HW mode.
// For example, "+feat1,-feat2" will indicate that the mode is active
// when "feat1" is enabled and "feat2" is disabled at the same time.
@ -26,12 +28,15 @@ class HwMode<string FS> {
// When multiple modes are used, they should be mutually exclusive,
// otherwise the results are unpredictable.
string Features = FS;
// A list of predicates that turn on this HW mode.
list<Predicate> Predicates = Ps;
}
// A special mode recognized by tablegen. This mode is considered active
// when no other mode is active. For targets that do not use specific hw
// modes, this is the only mode.
def DefaultMode : HwMode<"">;
def DefaultMode : HwMode<"", []>;
// A class used to associate objects with HW modes. It is only intended to
// be used as a base class, where the derived class should contain a member
@ -446,8 +451,6 @@ include "llvm/Target/TargetInstrPredicate.td"
//
include "llvm/Target/TargetSchedule.td"
class Predicate; // Forward def
class InstructionEncoding {
// Size of encoded instruction.
int Size;

View File

@ -160,8 +160,8 @@ def UseSmallData : Predicate<"HST->useSmallData()">;
def UseCabac : Predicate<"HST->useCabac()">,
AssemblerPredicate<(any_of FeatureCabac)>;
def Hvx64: HwMode<"+hvx-length64b">;
def Hvx128: HwMode<"+hvx-length128b">;
def Hvx64: HwMode<"+hvx-length64b", [UseHVX64B]>;
def Hvx128: HwMode<"+hvx-length128b", [UseHVX128B]>;
//===----------------------------------------------------------------------===//
// Classes used for relation maps.

View File

@ -30,7 +30,7 @@ def IsLA32
"LA32 Basic Integer and Privilege Instruction Set">;
defvar LA32 = DefaultMode;
def LA64 : HwMode<"+64bit">;
def LA64 : HwMode<"+64bit", [IsLA64]>;
// Single Precision floating point
def FeatureBasicF

View File

@ -587,7 +587,7 @@ def IsRV32 : Predicate<"!Subtarget->is64Bit()">,
"RV32I Base Instruction Set">;
defvar RV32 = DefaultMode;
def RV64 : HwMode<"+64bit">;
def RV64 : HwMode<"+64bit", [IsRV64]>;
def FeatureRV32E
: SubtargetFeature<"e", "IsRV32E", "true",

View File

@ -13,8 +13,11 @@ def Myi32 : Operand<i32> {
let DecoderMethod = "DecodeMyi32";
}
def ModeA : HwMode<"+a">;
def ModeB : HwMode<"+b">;
def HasA : Predicate<"Subtarget->hasA()">;
def HasB : Predicate<"Subtarget->hasB()">;
def ModeA : HwMode<"+a", [HasA]>;
def ModeB : HwMode<"+b", [HasB]>;
def fooTypeEncA : InstructionEncoding {

View File

@ -18,8 +18,11 @@ def TestTarget : Target {
def TestReg : Register<"testreg">;
def TestClass : RegisterClass<"TestTarget", [i32], 32, (add TestReg)>;
def TestMode1 : HwMode<"+feat1">;
def TestMode2 : HwMode<"+feat2">;
def HasFeat1 : Predicate<"Subtarget->hasFeat1()">;
def HasFeat2 : Predicate<"Subtarget->hasFeat2()">;
def TestMode1 : HwMode<"+feat1", [HasFeat1]>;
def TestMode2 : HwMode<"+feat2", [HasFeat2]>;
def BadDef : ValueTypeByHwMode<[TestMode1, TestMode2, DefaultMode],
[i8, i16, i32, i64]>;

View File

@ -4451,14 +4451,14 @@ void CodeGenDAGPatterns::ExpandHwModeBasedTypes() {
// Fill the map entry for this mode.
const HwMode &HM = CGH.getMode(M);
AppendPattern(P, M, "(MF->getSubtarget().checkFeatures(\"" + HM.Features + "\"))");
AppendPattern(P, M, HM.Predicates);
// Add negations of the HM's predicates to the default predicate.
if (!DefaultCheck.empty())
DefaultCheck += " && ";
DefaultCheck += "(!(MF->getSubtarget().checkFeatures(\"";
DefaultCheck += HM.Features;
DefaultCheck += "\")))";
DefaultCheck += "!(";
DefaultCheck += HM.Predicates;
DefaultCheck += ")";
}
bool HasDefault = Modes.count(DefaultMode);

View File

@ -21,6 +21,19 @@ StringRef CodeGenHwModes::DefaultModeName = "DefaultMode";
HwMode::HwMode(Record *R) {
Name = R->getName();
Features = std::string(R->getValueAsString("Features"));
std::vector<Record *> PredicateRecs = R->getValueAsListOfDefs("Predicates");
SmallString<128> PredicateCheck;
raw_svector_ostream OS(PredicateCheck);
ListSeparator LS(" && ");
for (Record *Pred : PredicateRecs) {
StringRef CondString = Pred->getValueAsString("CondString");
if (CondString.empty())
continue;
OS << LS << '(' << CondString << ')';
}
Predicates = std::string(PredicateCheck);
}
LLVM_DUMP_METHOD

View File

@ -31,6 +31,7 @@ namespace llvm {
HwMode(Record *R);
StringRef Name;
std::string Features;
std::string Predicates;
void dump() const;
};