mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-26 05:00:39 +00:00
Generalize my hack to use SDNodeInfo to find out when a
node is always guaranteed to have a particular type instead of hacking in ISD::STORE explicitly. This allows us to use implied types for a broad range of nodes, even target specific ones. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97355 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
874cadaf21
commit
225798143d
@ -447,6 +447,30 @@ SDNodeInfo::SDNodeInfo(Record *R) : Def(R) {
|
||||
TypeConstraints.assign(ConstraintList.begin(), ConstraintList.end());
|
||||
}
|
||||
|
||||
/// getKnownType - If the type constraints on this node imply a fixed type
|
||||
/// (e.g. all stores return void, etc), then return it as an
|
||||
/// MVT::SimpleValueType. Otherwise, return EEVT::isUnknown.
|
||||
unsigned SDNodeInfo::getKnownType() const {
|
||||
unsigned NumResults = getNumResults();
|
||||
assert(NumResults <= 1 &&
|
||||
"We only work with nodes with zero or one result so far!");
|
||||
|
||||
for (unsigned i = 0, e = TypeConstraints.size(); i != e; ++i) {
|
||||
// Make sure that this applies to the correct node result.
|
||||
if (TypeConstraints[i].OperandNo >= NumResults) // FIXME: need value #
|
||||
continue;
|
||||
|
||||
switch (TypeConstraints[i].ConstraintType) {
|
||||
default: break;
|
||||
case SDTypeConstraint::SDTCisVT:
|
||||
return TypeConstraints[i].x.SDTCisVT_Info.VT;
|
||||
case SDTypeConstraint::SDTCisPtrTy:
|
||||
return MVT::iPTR;
|
||||
}
|
||||
}
|
||||
return EEVT::isUnknown;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// TreePatternNode implementation
|
||||
//
|
||||
|
@ -125,6 +125,11 @@ public:
|
||||
return TypeConstraints;
|
||||
}
|
||||
|
||||
/// getKnownType - If the type constraints on this node imply a fixed type
|
||||
/// (e.g. all stores return void, etc), then return it as an
|
||||
/// MVT::SimpleValueType. Otherwise, return EEVT::isUnknown.
|
||||
unsigned getKnownType() const;
|
||||
|
||||
/// hasProperty - Return true if this node has the specified property.
|
||||
///
|
||||
bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); }
|
||||
|
@ -260,25 +260,6 @@ unsigned CompleteMatchMatcher::getHashImpl() const {
|
||||
|
||||
// isContradictoryImpl Implementations.
|
||||
|
||||
bool CheckOpcodeMatcher::isContradictoryImpl(const Matcher *M) const {
|
||||
if (const CheckOpcodeMatcher *COM = dyn_cast<CheckOpcodeMatcher>(M)) {
|
||||
// One node can't have two different opcodes!
|
||||
return &COM->getOpcode() != &getOpcode();
|
||||
}
|
||||
|
||||
// TODO: CheckMultiOpcodeMatcher?
|
||||
|
||||
// This is a special common case we see a lot in the X86 backend, we know that
|
||||
// ISD::STORE nodes can't have non-void type.
|
||||
if (const CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(M))
|
||||
// FIXME: This sucks, get void nodes from type constraints.
|
||||
return (getOpcode().getEnumName() == "ISD::STORE" ||
|
||||
getOpcode().getEnumName() == "ISD::INTRINSIC_VOID") &&
|
||||
CT->getType() != MVT::isVoid;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool TypesAreContradictory(MVT::SimpleValueType T1,
|
||||
MVT::SimpleValueType T2) {
|
||||
// If the two types are the same, then they are the same, so they don't
|
||||
@ -297,6 +278,32 @@ static bool TypesAreContradictory(MVT::SimpleValueType T1,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CheckOpcodeMatcher::isContradictoryImpl(const Matcher *M) const {
|
||||
if (const CheckOpcodeMatcher *COM = dyn_cast<CheckOpcodeMatcher>(M)) {
|
||||
// One node can't have two different opcodes!
|
||||
return &COM->getOpcode() != &getOpcode();
|
||||
}
|
||||
|
||||
// TODO: CheckMultiOpcodeMatcher?
|
||||
|
||||
// If the node has a known type, and if the type we're checking for is
|
||||
// different, then we know they contradict. For example, a check for
|
||||
// ISD::STORE will never be true at the same time a check for Type i32 is.
|
||||
if (const CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(M)) {
|
||||
// FIXME: What result is this referring to?
|
||||
unsigned NodeType;
|
||||
if (getOpcode().getNumResults() == 0)
|
||||
NodeType = MVT::isVoid;
|
||||
else
|
||||
NodeType = getOpcode().getKnownType();
|
||||
if (NodeType != EEVT::isUnknown)
|
||||
return TypesAreContradictory((MVT::SimpleValueType)NodeType,
|
||||
CT->getType());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckTypeMatcher::isContradictoryImpl(const Matcher *M) const {
|
||||
if (const CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(M))
|
||||
return TypesAreContradictory(getType(), CT->getType());
|
||||
|
Loading…
Reference in New Issue
Block a user