Skip to content

Commit

Permalink
[TableGen][RISCV][Hexagon][LoongArch] Add a list of Predicates to HwM…
Browse files Browse the repository at this point in the history
…ode.

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
  • Loading branch information
topperc committed Mar 14, 2023
1 parent f47404b commit 81a1506
Show file tree
Hide file tree
Showing 9 changed files with 39 additions and 16 deletions.
11 changes: 7 additions & 4 deletions llvm/include/llvm/Target/Target.td
Expand Up @@ -14,24 +14,29 @@
// 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.
// Any other features are not checked.
// 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
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/Hexagon/Hexagon.td
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/LoongArch/LoongArch.td
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/RISCV/RISCVFeatures.td
Expand Up @@ -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",
Expand Down
7 changes: 5 additions & 2 deletions llvm/test/TableGen/HwModeEncodeDecode.td
Expand Up @@ -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 {
Expand Down
7 changes: 5 additions & 2 deletions llvm/test/TableGen/HwModeSelect.td
Expand Up @@ -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]>;
Expand Down
8 changes: 4 additions & 4 deletions llvm/utils/TableGen/CodeGenDAGPatterns.cpp
Expand Up @@ -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);
Expand Down
13 changes: 13 additions & 0 deletions llvm/utils/TableGen/CodeGenHwModes.cpp
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions llvm/utils/TableGen/CodeGenHwModes.h
Expand Up @@ -31,6 +31,7 @@ namespace llvm {
HwMode(Record *R);
StringRef Name;
std::string Features;
std::string Predicates;
void dump() const;
};

Expand Down

0 comments on commit 81a1506

Please sign in to comment.