Skip to content

Commit

Permalink
TableGen: Add size only type matchers
Browse files Browse the repository at this point in the history
  • Loading branch information
arsenm committed Mar 23, 2020
1 parent 2ad5fc1 commit eb1de38
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 10 deletions.
15 changes: 15 additions & 0 deletions llvm/include/llvm/CodeGen/ValueTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,21 @@ def iPTR : ValueType<0 , 254>;
// Pseudo valuetype to represent "any type of any size".
def Any : ValueType<0 , 255>;

// Pseudo valuetypes to represent any type of a specific size.
class AnySizedVT<int Size, int EnumVal> : ValueType<Size, EnumVal>;

def vtAny16 : AnySizedVT<16, 237>;
def vtAny32 : AnySizedVT<32, 238>;
def vtAny64 : AnySizedVT<64, 239>;
def vtAny96 : AnySizedVT<96, 240>;
def vtAny128 : AnySizedVT<128, 241>;
def vtAny160 : AnySizedVT<160, 242>;
def vtAny192 : AnySizedVT<192, 243>;
def vtAny224 : AnySizedVT<225, 244>;
def vtAny256 : AnySizedVT<256, 245>;
def vtAny512 : AnySizedVT<512, 246>;
def vtAny1024 : AnySizedVT<1024, 247>;

/// This class is for targets that want to use pointer types in patterns
/// with the GlobalISelEmitter. Targets must define their own pointer
/// derived from this class. The scalar argument should be an
Expand Down
29 changes: 26 additions & 3 deletions llvm/include/llvm/Support/MachineValueType.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,23 @@ namespace llvm {
// This value must be a multiple of 32.
MAX_ALLOWED_VALUETYPE = 160,

// Any type of value as long as the bit size matches. This should only be
// used in tablegen patterns.
vtAny16 = 237,
vtAny32 = 238,
vtAny64 = 239,
vtAny96 = 240,
vtAny128 = 241,
vtAny160 = 242,
vtAny192 = 243,
vtAny224 = 244,
vtAny256 = 245,
vtAny512 = 246,
vtAny1024 = 247,

FIRST_VTANY_VALUETYPE = 237,
LAST_VTANY_VALUETYPE = 247,

// A value of type llvm::TokenTy
token = 248,

Expand Down Expand Up @@ -383,11 +400,17 @@ namespace llvm {
SimpleTy == MVT::v64i32 || SimpleTy == MVT::v32i64);
}

bool isAnySizedVT() const {
return (SimpleTy >= MVT::FIRST_VTANY_VALUETYPE &&
SimpleTy <= MVT::LAST_VTANY_VALUETYPE);
}

/// Return true if this is an overloaded type for TableGen.
bool isOverloaded() const {
return (SimpleTy==MVT::Any ||
SimpleTy==MVT::iAny || SimpleTy==MVT::fAny ||
SimpleTy==MVT::vAny || SimpleTy==MVT::iPTRAny);
return SimpleTy == MVT::Any ||
SimpleTy == MVT::iAny || SimpleTy == MVT::fAny ||
SimpleTy == MVT::vAny || SimpleTy == MVT::iPTRAny ||
isAnySizedVT();
}

/// Return a VT for a vector type with the same element type but
Expand Down
4 changes: 1 addition & 3 deletions llvm/lib/Target/AMDGPU/DSInstructions.td
Original file line number Diff line number Diff line change
Expand Up @@ -655,9 +655,7 @@ defm : DSReadPat_mc <DS_READ_U16, i32, "extloadi16_local">;
defm : DSReadPat_mc <DS_READ_U16, i32, "zextloadi16_local">;
defm : DSReadPat_mc <DS_READ_U16, i16, "load_local">;

foreach vt = Reg32Types.types in {
defm : DSReadPat_mc <DS_READ_B32, vt, "load_local">;
}
defm : DSReadPat_mc <DS_READ_B32, vtAny32, "load_local">;

defm : DSReadPat_mc <DS_READ_B32, i32, "atomic_load_32_local">;
defm : DSReadPat_mc <DS_READ_B64, i64, "atomic_load_64_local">;
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/TableGen/Common/GlobalISelEmitterCommon.td
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class MyTargetGenericInstruction : GenericInstruction {
}

def R0 : Register<"r0"> { let Namespace = "MyTarget"; }
def GPR32 : RegisterClass<"MyTarget", [i32], 32, (add R0)>;
def GPR32 : RegisterClass<"MyTarget", [i32, v2i16], 32, (add R0)>;
def GPR32Op : RegisterOperand<GPR32>;
def F0 : Register<"f0"> { let Namespace = "MyTarget"; }
def FPR32 : RegisterClass<"MyTarget", [f32], 32, (add F0)>;
Expand Down
34 changes: 32 additions & 2 deletions llvm/utils/TableGen/CodeGenDAGPatterns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,32 @@ void TypeInfer::expandOverloads(TypeSetByHwMode &VTS) {
void TypeInfer::expandOverloads(TypeSetByHwMode::SetType &Out,
const TypeSetByHwMode::SetType &Legal) {
std::set<MVT> Ovs;

auto handleVTAny = [&](unsigned Size) {

for (MVT T : MVT::integer_valuetypes()) {
if (T.getSizeInBits() == Size)
Out.insert(T);
}

for (MVT T : MVT::fp_valuetypes()) {
if (T.getSizeInBits() == Size)
Out.insert(T);
}

for (MVT T : MVT::fp_fixedlen_vector_valuetypes()) {
if (T.getSizeInBits() == Size)
Out.insert(T);
}

for (MVT T : MVT::integer_fixedlen_vector_valuetypes()) {
if (T.getSizeInBits() == Size)
Out.insert(T);
}
};



for (MVT T : Out) {
if (!T.isOverloaded())
continue;
Expand Down Expand Up @@ -808,8 +834,12 @@ void TypeInfer::expandOverloads(TypeSetByHwMode::SetType &Out,
if (Legal.count(T))
Out.insert(T);
return;
default:
break;
case MVT::vtAny32:
handleVTAny(32);
return;

default:
break;
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions llvm/utils/TableGen/CodeGenTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ StringRef llvm::getEnumName(MVT::SimpleValueType T) {
case MVT::iPTRAny: return "MVT::iPTRAny";
case MVT::Untyped: return "MVT::Untyped";
case MVT::exnref: return "MVT::exnref";
case MVT::vtAny16: return "MVT::vtAny16";
case MVT::vtAny32: return "MVT::vtAny32";
default: llvm_unreachable("ILLEGAL VALUE TYPE!");
}
}
Expand Down
40 changes: 40 additions & 0 deletions llvm/utils/TableGen/DAGISelMatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class Matcher {
CheckOpcode, // Fail if not opcode.
SwitchOpcode, // Dispatch based on opcode.
CheckType, // Fail if not correct type.
CheckTypeSize, // Fail if not correct size type
SwitchType, // Dispatch based on type.
CheckChildType, // Fail if child has wrong type.
CheckInteger, // Fail if wrong val.
Expand Down Expand Up @@ -510,6 +511,45 @@ class CheckTypeMatcher : public Matcher {
bool isContradictoryImpl(const Matcher *M) const override;
};


/// CheckTypeSizeMatcher - This checks to see if the current node has the
/// specified type at the specified result, if not it fails to match.
class CheckTypeSizeMatcher : public Matcher {
MVT::SimpleValueType Type;
unsigned ResNo;
public:
CheckTypeSizeMatcher(MVT::SimpleValueType type, unsigned resno)
: Matcher(CheckTypeSize), Type(type), ResNo(resno) {
assert(MVT(type).isAnySizedVT());
}

//MVT::SimpleValueType getType() const { return Type; }
unsigned getSizeInBits() const {
switch (Type) {
case MVT::vtAny16:
return 16;
case MVT::vtAny32:
return 32;
default:
llvm_unreachable("unhandled");
}
}

unsigned getResNo() const { return ResNo; }

static bool classof(const Matcher *N) {
return N->getKind() == CheckTypeSize;
}

private:
void printImpl(raw_ostream &OS, unsigned indent) const override;
bool isEqualImpl(const Matcher *M) const override {
return cast<CheckTypeSizeMatcher>(M)->Type == Type;
}
bool isContradictoryImpl(const Matcher *M) const override;
};


/// SwitchTypeMatcher - Switch based on the current node's type, dispatching
/// to one matcher per case. If the type doesn't match any of the cases,
/// then the match fails. This is semantically equivalent to a Scope node where
Expand Down
11 changes: 11 additions & 0 deletions llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,16 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
<< ", " << getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n";
return 3;

case Matcher::CheckTypeSize: {
if (cast<CheckTypeMatcher>(N)->getResNo() == 0) {
OS << "OPC_CheckTypeSize, "
<< cast<CheckTypeSizeMatcher>(N)->getSizeInBits() << ",\n";
return 2;
}
OS << "OPC_CheckTypeSizeRes, " << cast<CheckTypeMatcher>(N)->getResNo()
<< ", " << cast<CheckTypeSizeMatcher>(N)->getSizeInBits() << ",\n";
return 3;
}
case Matcher::CheckChildType:
OS << "OPC_CheckChild"
<< cast<CheckChildTypeMatcher>(N)->getChildNo() << "Type, "
Expand Down Expand Up @@ -1014,6 +1024,7 @@ static StringRef getOpcodeString(Matcher::KindTy Kind) {
case Matcher::CheckOpcode: return "OPC_CheckOpcode"; break;
case Matcher::SwitchOpcode: return "OPC_SwitchOpcode"; break;
case Matcher::CheckType: return "OPC_CheckType"; break;
case Matcher::CheckTypeSize: return "OPC_CheckTypeSize"; break;
case Matcher::SwitchType: return "OPC_SwitchType"; break;
case Matcher::CheckChildType: return "OPC_CheckChildType"; break;
case Matcher::CheckInteger: return "OPC_CheckInteger"; break;
Expand Down
15 changes: 14 additions & 1 deletion llvm/utils/TableGen/DAGISelMatcherGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,9 +503,22 @@ void MatcherGen::EmitMatchCode(const TreePatternNode *N,
// need to do a type check. Emit the check, apply the type to NodeNoTypes and
// reinfer any correlated types.
SmallVector<unsigned, 2> ResultsToTypeCheck;
SmallVector<unsigned, 2> ResultsToTypeSizeCheck;

for (unsigned i = 0, e = NodeNoTypes->getNumTypes(); i != e; ++i) {
if (NodeNoTypes->getExtType(i) == N->getExtType(i)) continue;
if (NodeNoTypes->getExtType(i) == N->getExtType(i))
continue;

if (N->getExtType(i).isMachineValueType()) {
if (N->getExtType(i).getMachineValueType().isAnySizedVT()) {
ResultsToTypeSizeCheck.push_back(i);
continue;
}
} else {
dbgs() << "Not MVT\n";
dbgs() << "Default only: " << N->getExtType(i).isDefaultOnly() << '\n';
}

NodeNoTypes->setType(i, N->getExtType(i));
InferPossibleTypes(ForceMode);
ResultsToTypeCheck.push_back(i);
Expand Down

0 comments on commit eb1de38

Please sign in to comment.