Skip to content

Commit

Permalink
TableGen: Replace IntrinsicEmitter::ComputeFixedEncoding() and cleanup
Browse files Browse the repository at this point in the history
Depends on D146915

Differential Revision: https://reviews.llvm.org/D145937
  • Loading branch information
chapuni committed Apr 26, 2023
1 parent 91b80ce commit 24706af
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 476 deletions.
2 changes: 0 additions & 2 deletions llvm/include/llvm/IR/Intrinsics.td
Expand Up @@ -386,7 +386,6 @@ class LLVMAnyType<ValueType vt> : LLVMType<vt> {
class LLVMQualPointerType<LLVMType elty, int addrspace>
: LLVMType<iPTR>{
LLVMType ElTy = elty;
int AddrSpace = addrspace;
assert !and(!le(0, addrspace), !le(addrspace, 255)),
"Address space exceeds 255";

Expand Down Expand Up @@ -449,7 +448,6 @@ class LLVMTruncatedType<int num> : LLVMMatchType<num, IIT_TRUNC_ARG>;
// number of elements.
class LLVMScalarOrSameVectorWidth<int idx, LLVMType elty>
: LLVMMatchType<idx, IIT_SAME_VEC_WIDTH_ARG> {
ValueType ElTy = elty.VT;
let Sig = !listconcat([
IIT_SAME_VEC_WIDTH_ARG.Number,
EncSameWidth<idx>.ret,
Expand Down
14 changes: 8 additions & 6 deletions llvm/utils/TableGen/CodeGenDAGPatterns.cpp
Expand Up @@ -1858,7 +1858,7 @@ static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) {
return 0; // All return nothing.

if (Operator->isSubClassOf("Intrinsic"))
return CDP.getIntrinsic(Operator).IS.RetVTs.size();
return CDP.getIntrinsic(Operator).IS.RetTys.size();

if (Operator->isSubClassOf("SDNode"))
return CDP.getSDNodeInfo(Operator).getNumResults();
Expand Down Expand Up @@ -2511,11 +2511,12 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
bool MadeChange = false;

// Apply the result type to the node.
unsigned NumRetVTs = Int->IS.RetVTs.size();
unsigned NumParamVTs = Int->IS.ParamVTs.size();
unsigned NumRetVTs = Int->IS.RetTys.size();
unsigned NumParamVTs = Int->IS.ParamTys.size();

for (unsigned i = 0, e = NumRetVTs; i != e; ++i)
MadeChange |= UpdateNodeType(i, Int->IS.RetVTs[i], TP);
MadeChange |= UpdateNodeType(
i, getValueType(Int->IS.RetTys[i]->getValueAsDef("VT")), TP);

if (getNumChildren() != NumParamVTs + 1) {
TP.error("Intrinsic '" + Int->Name + "' expects " + Twine(NumParamVTs) +
Expand All @@ -2529,7 +2530,8 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
for (unsigned i = 0, e = getNumChildren()-1; i != e; ++i) {
MadeChange |= getChild(i+1)->ApplyTypeConstraints(TP, NotRegisters);

MVT::SimpleValueType OpVT = Int->IS.ParamVTs[i];
MVT::SimpleValueType OpVT =
getValueType(Int->IS.ParamTys[i]->getValueAsDef("VT"));
assert(getChild(i + 1)->getNumTypes() == 1 && "Unhandled case");
MadeChange |= getChild(i + 1)->UpdateNodeType(0, OpVT, TP);
}
Expand Down Expand Up @@ -2983,7 +2985,7 @@ TreePatternNodePtr TreePattern::ParseTreePattern(Init *TheInit,

// If this intrinsic returns void, it must have side-effects and thus a
// chain.
if (Int.IS.RetVTs.empty())
if (Int.IS.RetTys.empty())
Operator = getDAGPatterns().get_intrinsic_void_sdnode();
else if (!Int.ME.doesNotAccessMemory() || Int.hasSideEffects)
// Has side-effects, requires chain.
Expand Down
124 changes: 5 additions & 119 deletions llvm/utils/TableGen/CodeGenIntrinsics.cpp
Expand Up @@ -20,13 +20,6 @@
#include <algorithm>
#include <cassert>
using namespace llvm;
using namespace llvm::tmp;

/// getValueType - Return the MVT::SimpleValueType that the specified TableGen
/// record corresponds to.
MVT::SimpleValueType llvm::tmp::getValueType(Record *Rec) {
return (MVT::SimpleValueType)Rec->getValueAsInt("Value");
}

//===----------------------------------------------------------------------===//
// CodeGenIntrinsic Implementation
Expand Down Expand Up @@ -120,123 +113,16 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R,
TargetPrefix + ".'!");
}

#define OLD 1

#if OLD
ListInit *RetTypes = R->getValueAsListInit("RetTypes");
ListInit *ParamTypes = R->getValueAsListInit("ParamTypes");

// First collate a list of overloaded types.
std::vector<MVT::SimpleValueType> OverloadedVTs;
for (ListInit *TypeList : {RetTypes, ParamTypes}) {
for (unsigned i = 0, e = TypeList->size(); i != e; ++i) {
Record *TyEl = TypeList->getElementAsRecord(i);
assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");

if (TyEl->isSubClassOf("LLVMMatchType"))
continue;

MVT::SimpleValueType VT = getValueType(TyEl->getValueAsDef("VT"));
if (MVT(VT).isOverloaded()) {
OverloadedVTs.push_back(VT);
isOverloaded = true;
}
}
}

// Parse the list of return types.
ListInit *TypeList = RetTypes;
for (unsigned i = 0, e = TypeList->size(); i != e; ++i) {
Record *TyEl = TypeList->getElementAsRecord(i);
assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
MVT::SimpleValueType VT;
if (TyEl->isSubClassOf("LLVMMatchType")) {
unsigned MatchTy = TyEl->getValueAsInt("Number");
assert(MatchTy < OverloadedVTs.size() && "Invalid matching number!");
VT = OverloadedVTs[MatchTy];
// It only makes sense to use the extended and truncated vector element
// variants with iAny types; otherwise, if the intrinsic is not
// overloaded, all the types can be specified directly.
assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
!TyEl->isSubClassOf("LLVMTruncatedType")) ||
VT == MVT::iAny || VT == MVT::vAny) &&
"Expected iAny or vAny type");
} else {
VT = getValueType(TyEl->getValueAsDef("VT"));
}

// Reject invalid types.
if (VT == MVT::isVoid)
PrintFatalError(DefLoc, "Intrinsic '" + DefName +
" has void in result type list!");

IS.RetVTs.push_back(VT);
IS.RetTypeDefs.push_back(TyEl);
}

// Parse the list of parameter types.
TypeList = ParamTypes;
for (unsigned i = 0, e = TypeList->size(); i != e; ++i) {
Record *TyEl = TypeList->getElementAsRecord(i);
assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
MVT::SimpleValueType VT;
if (TyEl->isSubClassOf("LLVMMatchType")) {
unsigned MatchTy = TyEl->getValueAsInt("Number");
if (MatchTy >= OverloadedVTs.size()) {
PrintError(R->getLoc(), "Parameter #" + Twine(i) +
" has out of bounds matching "
"number " +
Twine(MatchTy));
PrintFatalError(DefLoc,
Twine("ParamTypes is ") + TypeList->getAsString());
}
VT = OverloadedVTs[MatchTy];
// It only makes sense to use the extended and truncated vector element
// variants with iAny types; otherwise, if the intrinsic is not
// overloaded, all the types can be specified directly.
assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
!TyEl->isSubClassOf("LLVMTruncatedType")) ||
VT == MVT::iAny || VT == MVT::vAny) &&
"Expected iAny or vAny type");
} else
VT = getValueType(TyEl->getValueAsDef("VT"));

// Reject invalid types.
if (VT == MVT::isVoid && i != e - 1 /*void at end means varargs*/)
PrintFatalError(DefLoc, "Intrinsic '" + DefName +
" has void in result type list!");

IS.ParamVTs.push_back(VT);
IS.ParamTypeDefs.push_back(TyEl);
}
#endif // OLD

if (auto *Types = R->getValue("Types")) {
#if OLD
auto OrigRetVTs = std::move(IS.RetVTs);
auto OrigParamVTs = std::move(IS.ParamVTs);
auto OrigOverloaded = isOverloaded;
IS.RetVTs.clear();
IS.ParamVTs.clear();
#endif // OLD

auto *TypeList = cast<ListInit>(Types->getValue());
isOverloaded = R->getValueAsBit("isOverloaded");

unsigned I = 0;
for (unsigned E = R->getValueAsListInit("RetTypes")->size(); I < E; ++I)
IS.RetVTs.push_back(
getValueType(TypeList->getElementAsRecord(I)->getValueAsDef("VT")));
IS.RetTys.push_back(TypeList->getElementAsRecord(I));

for (unsigned E = TypeList->size(); I < E; ++I)
IS.ParamVTs.push_back(
getValueType(TypeList->getElementAsRecord(I)->getValueAsDef("VT")));

#if OLD
assert(IS.RetVTs == OrigRetVTs);
assert(IS.ParamVTs == OrigParamVTs);
assert(OrigOverloaded == isOverloaded);
#endif
IS.ParamTys.push_back(TypeList->getElementAsRecord(I));
}

// Parse the intrinsic properties.
Expand Down Expand Up @@ -353,10 +239,10 @@ void CodeGenIntrinsic::setProperty(Record *R) {
}

bool CodeGenIntrinsic::isParamAPointer(unsigned ParamIdx) const {
if (ParamIdx >= IS.ParamVTs.size())
if (ParamIdx >= IS.ParamTys.size())
return false;
MVT ParamType = MVT(IS.ParamVTs[ParamIdx]);
return ParamType == MVT::iPTR || ParamType == MVT::iPTRAny;
return (IS.ParamTys[ParamIdx]->isSubClassOf("LLVMQualPointerType") ||
IS.ParamTys[ParamIdx]->isSubClassOf("LLVMAnyPointerType"));
}

bool CodeGenIntrinsic::isParamImmArg(unsigned ParamIdx) const {
Expand Down
18 changes: 2 additions & 16 deletions llvm/utils/TableGen/CodeGenIntrinsics.h
Expand Up @@ -15,7 +15,6 @@

#include "SDNodeProperties.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/MachineValueType.h"
#include "llvm/Support/ModRef.h"
#include <string>
#include <tuple>
Expand All @@ -25,13 +24,6 @@ namespace llvm {
class Record;
class RecordKeeper;

// FIXME: Sweep this in the near future.
namespace tmp {
/// getValueType - Return the MVT::SimpleValueType that the specified TableGen
/// record corresponds to.
MVT::SimpleValueType getValueType(Record *Rec);
} // namespace tmp

struct CodeGenIntrinsic {
Record *TheDef; // The actual record defining this intrinsic.
std::string Name; // The name of the LLVM function "llvm.bswap.i32"
Expand All @@ -50,19 +42,13 @@ struct CodeGenIntrinsic {
/// only populated when in the context of a target .td file. When building
/// Intrinsics.td, this isn't available, because we don't know the target
/// pointer size.
std::vector<MVT::SimpleValueType> RetVTs;

/// The records for each return type.
std::vector<Record *> RetTypeDefs;
std::vector<Record *> RetTys;

/// The MVT::SimpleValueType for each parameter type. Note that this list is
/// only populated when in the context of a target .td file. When building
/// Intrinsics.td, this isn't available, because we don't know the target
/// pointer size.
std::vector<MVT::SimpleValueType> ParamVTs;

/// The records for each parameter type.
std::vector<Record *> ParamTypeDefs;
std::vector<Record *> ParamTys;
};

IntrinsicSignature IS;
Expand Down

0 comments on commit 24706af

Please sign in to comment.