mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-27 14:34:58 +00:00
add plumbing for handling multiple result nodes
in some more places. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@99366 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
92d7b35bd0
commit
084df627c8
@ -713,10 +713,11 @@ SDNodeInfo::SDNodeInfo(Record *R) : Def(R) {
|
|||||||
/// getKnownType - If the type constraints on this node imply a fixed type
|
/// getKnownType - If the type constraints on this node imply a fixed type
|
||||||
/// (e.g. all stores return void, etc), then return it as an
|
/// (e.g. all stores return void, etc), then return it as an
|
||||||
/// MVT::SimpleValueType. Otherwise, return EEVT::Other.
|
/// MVT::SimpleValueType. Otherwise, return EEVT::Other.
|
||||||
MVT::SimpleValueType SDNodeInfo::getKnownType() const {
|
MVT::SimpleValueType SDNodeInfo::getKnownType(unsigned ResNo) const {
|
||||||
unsigned NumResults = getNumResults();
|
unsigned NumResults = getNumResults();
|
||||||
assert(NumResults <= 1 &&
|
assert(NumResults <= 1 &&
|
||||||
"We only work with nodes with zero or one result so far!");
|
"We only work with nodes with zero or one result so far!");
|
||||||
|
assert(ResNo == 0 && "Only handles single result nodes so far");
|
||||||
|
|
||||||
for (unsigned i = 0, e = TypeConstraints.size(); i != e; ++i) {
|
for (unsigned i = 0, e = TypeConstraints.size(); i != e; ++i) {
|
||||||
// Make sure that this applies to the correct node result.
|
// Make sure that this applies to the correct node result.
|
||||||
|
@ -211,7 +211,7 @@ public:
|
|||||||
/// getKnownType - If the type constraints on this node imply a fixed type
|
/// getKnownType - If the type constraints on this node imply a fixed type
|
||||||
/// (e.g. all stores return void, etc), then return it as an
|
/// (e.g. all stores return void, etc), then return it as an
|
||||||
/// MVT::SimpleValueType. Otherwise, return MVT::Other.
|
/// MVT::SimpleValueType. Otherwise, return MVT::Other.
|
||||||
MVT::SimpleValueType getKnownType() const;
|
MVT::SimpleValueType getKnownType(unsigned ResNo) const;
|
||||||
|
|
||||||
/// hasProperty - Return true if this node has the specified property.
|
/// hasProperty - Return true if this node has the specified property.
|
||||||
///
|
///
|
||||||
|
@ -147,7 +147,8 @@ void SwitchOpcodeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
|
|||||||
|
|
||||||
|
|
||||||
void CheckTypeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
|
void CheckTypeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
|
||||||
OS.indent(indent) << "CheckType " << getEnumName(Type) << '\n';
|
OS.indent(indent) << "CheckType " << getEnumName(Type) << ", ResNo="
|
||||||
|
<< ResNo << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwitchTypeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
|
void SwitchTypeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
|
||||||
@ -356,12 +357,11 @@ bool CheckOpcodeMatcher::isContradictoryImpl(const Matcher *M) const {
|
|||||||
// different, then we know they contradict. For example, a check for
|
// 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.
|
// ISD::STORE will never be true at the same time a check for Type i32 is.
|
||||||
if (const CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(M)) {
|
if (const CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(M)) {
|
||||||
// FIXME: What result is this referring to?
|
// If checking for a result the opcode doesn't have, it can't match.
|
||||||
MVT::SimpleValueType NodeType;
|
if (CT->getResNo() >= getOpcode().getNumResults())
|
||||||
if (getOpcode().getNumResults() == 0)
|
return true;
|
||||||
NodeType = MVT::isVoid;
|
|
||||||
else
|
MVT::SimpleValueType NodeType = getOpcode().getKnownType(CT->getResNo());
|
||||||
NodeType = getOpcode().getKnownType();
|
|
||||||
if (NodeType != MVT::Other)
|
if (NodeType != MVT::Other)
|
||||||
return TypesAreContradictory(NodeType, CT->getType());
|
return TypesAreContradictory(NodeType, CT->getType());
|
||||||
}
|
}
|
||||||
|
@ -492,14 +492,16 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// CheckTypeMatcher - This checks to see if the current node has the
|
/// CheckTypeMatcher - This checks to see if the current node has the
|
||||||
/// specified type, if not it fails to match.
|
/// specified type at the specified result, if not it fails to match.
|
||||||
class CheckTypeMatcher : public Matcher {
|
class CheckTypeMatcher : public Matcher {
|
||||||
MVT::SimpleValueType Type;
|
MVT::SimpleValueType Type;
|
||||||
|
unsigned ResNo;
|
||||||
public:
|
public:
|
||||||
CheckTypeMatcher(MVT::SimpleValueType type)
|
CheckTypeMatcher(MVT::SimpleValueType type, unsigned resno)
|
||||||
: Matcher(CheckType), Type(type) {}
|
: Matcher(CheckType), Type(type), ResNo(resno) {}
|
||||||
|
|
||||||
MVT::SimpleValueType getType() const { return Type; }
|
MVT::SimpleValueType getType() const { return Type; }
|
||||||
|
unsigned getResNo() const { return ResNo; }
|
||||||
|
|
||||||
static inline bool classof(const Matcher *N) {
|
static inline bool classof(const Matcher *N) {
|
||||||
return N->getKind() == CheckType;
|
return N->getKind() == CheckType;
|
||||||
|
@ -341,6 +341,8 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case Matcher::CheckType:
|
case Matcher::CheckType:
|
||||||
|
assert(cast<CheckTypeMatcher>(N)->getResNo() == 0 &&
|
||||||
|
"FIXME: Add support for CheckType of resno != 0");
|
||||||
OS << "OPC_CheckType, "
|
OS << "OPC_CheckType, "
|
||||||
<< getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n";
|
<< getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n";
|
||||||
return 2;
|
return 2;
|
||||||
|
@ -408,13 +408,13 @@ void MatcherGen::EmitMatchCode(const TreePatternNode *N,
|
|||||||
// If N and NodeNoTypes don't agree on a type, then this is a case where we
|
// If N and NodeNoTypes don't agree on a type, then this is a case where we
|
||||||
// need to do a type check. Emit the check, apply the tyep to NodeNoTypes and
|
// need to do a type check. Emit the check, apply the tyep to NodeNoTypes and
|
||||||
// reinfer any correlated types.
|
// reinfer any correlated types.
|
||||||
bool DoTypeCheck = false;
|
SmallVector<unsigned, 2> ResultsToTypeCheck;
|
||||||
if (NodeNoTypes->getNumTypes() != 0 &&
|
|
||||||
NodeNoTypes->getExtType(0) != N->getExtType(0)) {
|
for (unsigned i = 0, e = NodeNoTypes->getNumTypes(); i != e; ++i) {
|
||||||
assert(NodeNoTypes->getNumTypes() == 1 && "FIXME: Handle multiple results");
|
if (NodeNoTypes->getExtType(i) == N->getExtType(i)) continue;
|
||||||
NodeNoTypes->setType(0, N->getExtType(0));
|
NodeNoTypes->setType(i, N->getExtType(i));
|
||||||
InferPossibleTypes();
|
InferPossibleTypes();
|
||||||
DoTypeCheck = true;
|
ResultsToTypeCheck.push_back(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this node has a name associated with it, capture it in VariableMap. If
|
// If this node has a name associated with it, capture it in VariableMap. If
|
||||||
@ -444,10 +444,9 @@ void MatcherGen::EmitMatchCode(const TreePatternNode *N,
|
|||||||
for (unsigned i = 0, e = N->getPredicateFns().size(); i != e; ++i)
|
for (unsigned i = 0, e = N->getPredicateFns().size(); i != e; ++i)
|
||||||
AddMatcher(new CheckPredicateMatcher(N->getPredicateFns()[i]));
|
AddMatcher(new CheckPredicateMatcher(N->getPredicateFns()[i]));
|
||||||
|
|
||||||
if (DoTypeCheck) {
|
for (unsigned i = 0, e = ResultsToTypeCheck.size(); i != e; ++i)
|
||||||
assert(N->getNumTypes() == 1);
|
AddMatcher(new CheckTypeMatcher(N->getType(ResultsToTypeCheck[i]),
|
||||||
AddMatcher(new CheckTypeMatcher(N->getType(0)));
|
ResultsToTypeCheck[i]));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EmitMatcherCode - Generate the code that matches the predicate of this
|
/// EmitMatcherCode - Generate the code that matches the predicate of this
|
||||||
|
@ -48,8 +48,9 @@ static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
|
|||||||
New = new RecordChildMatcher(MC->getChildNo(), RM->getWhatFor(),
|
New = new RecordChildMatcher(MC->getChildNo(), RM->getWhatFor(),
|
||||||
RM->getResultNo());
|
RM->getResultNo());
|
||||||
|
|
||||||
if (CheckTypeMatcher *CT= dyn_cast<CheckTypeMatcher>(MC->getNext()))
|
if (CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(MC->getNext()))
|
||||||
if (MC->getChildNo() < 8) // Only have CheckChildType0...7
|
if (MC->getChildNo() < 8 && // Only have CheckChildType0...7
|
||||||
|
CT->getResNo() == 0) // CheckChildType checks res #0
|
||||||
New = new CheckChildTypeMatcher(MC->getChildNo(), CT->getType());
|
New = new CheckChildTypeMatcher(MC->getChildNo(), CT->getType());
|
||||||
|
|
||||||
if (New) {
|
if (New) {
|
||||||
@ -420,10 +421,12 @@ static void FactorNodes(OwningPtr<Matcher> &MatcherPtr) {
|
|||||||
CheckTypeMatcher *CTM =
|
CheckTypeMatcher *CTM =
|
||||||
cast_or_null<CheckTypeMatcher>(FindNodeWithKind(NewOptionsToMatch[i],
|
cast_or_null<CheckTypeMatcher>(FindNodeWithKind(NewOptionsToMatch[i],
|
||||||
Matcher::CheckType));
|
Matcher::CheckType));
|
||||||
if (CTM == 0 ||
|
if (CTM == 0 ||
|
||||||
// iPTR checks could alias any other case without us knowing, don't
|
// iPTR checks could alias any other case without us knowing, don't
|
||||||
// bother with them.
|
// bother with them.
|
||||||
CTM->getType() == MVT::iPTR ||
|
CTM->getType() == MVT::iPTR ||
|
||||||
|
// SwitchType only works for result #0.
|
||||||
|
CTM->getResNo() != 0 ||
|
||||||
// If the CheckType isn't at the start of the list, see if we can move
|
// If the CheckType isn't at the start of the list, see if we can move
|
||||||
// it there.
|
// it there.
|
||||||
!CTM->canMoveBefore(NewOptionsToMatch[i])) {
|
!CTM->canMoveBefore(NewOptionsToMatch[i])) {
|
||||||
@ -488,7 +491,7 @@ static void FactorNodes(OwningPtr<Matcher> &MatcherPtr) {
|
|||||||
MatcherPtr.reset(new SwitchTypeMatcher(&Cases[0], Cases.size()));
|
MatcherPtr.reset(new SwitchTypeMatcher(&Cases[0], Cases.size()));
|
||||||
} else {
|
} else {
|
||||||
// If we factored and ended up with one case, create it now.
|
// If we factored and ended up with one case, create it now.
|
||||||
MatcherPtr.reset(new CheckTypeMatcher(Cases[0].first));
|
MatcherPtr.reset(new CheckTypeMatcher(Cases[0].first, 0));
|
||||||
MatcherPtr->setNext(Cases[0].second);
|
MatcherPtr->setNext(Cases[0].second);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -296,9 +296,11 @@ void FastISelMap::CollectPatterns(CodeGenDAGPatterns &CGP) {
|
|||||||
if (!InstPatNode) continue;
|
if (!InstPatNode) continue;
|
||||||
if (InstPatNode->isLeaf()) continue;
|
if (InstPatNode->isLeaf()) continue;
|
||||||
|
|
||||||
|
// Ignore multiple result nodes for now.
|
||||||
|
if (InstPatNode->getNumTypes() > 1) continue;
|
||||||
|
|
||||||
Record *InstPatOp = InstPatNode->getOperator();
|
Record *InstPatOp = InstPatNode->getOperator();
|
||||||
std::string OpcodeName = getOpcodeName(InstPatOp, CGP);
|
std::string OpcodeName = getOpcodeName(InstPatOp, CGP);
|
||||||
assert(InstPatNode->getNumTypes() <= 1);
|
|
||||||
MVT::SimpleValueType RetVT = MVT::isVoid;
|
MVT::SimpleValueType RetVT = MVT::isVoid;
|
||||||
if (InstPatNode->getNumTypes()) RetVT = InstPatNode->getType(0);
|
if (InstPatNode->getNumTypes()) RetVT = InstPatNode->getType(0);
|
||||||
MVT::SimpleValueType VT = RetVT;
|
MVT::SimpleValueType VT = RetVT;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user