Emulate the current isel's "IsChainCompatible" logic for now.

I'd like to eventually rip it out, but for now producing the
same selections as the old matcher is more important.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96458 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2010-02-17 06:23:39 +00:00
parent 8dc4f2bb60
commit 9a747f1305
5 changed files with 57 additions and 6 deletions

View File

@ -217,7 +217,8 @@ enum BuiltinOpcodes {
OPC_CheckComplexPat,
OPC_CheckAndImm1, OPC_CheckAndImm2, OPC_CheckAndImm4, OPC_CheckAndImm8,
OPC_CheckOrImm1, OPC_CheckOrImm2, OPC_CheckOrImm4, OPC_CheckOrImm8,
OPC_CheckFoldableChainNode
OPC_CheckFoldableChainNode,
OPC_CheckChainCompatible
};
struct MatchScope {
@ -409,6 +410,13 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
continue;
}
case OPC_CheckChainCompatible: {
unsigned PrevNode = MatcherTable[MatcherIndex++];
assert(PrevNode < RecordedNodes.size() && "Invalid CheckChainCompatible");
if (!IsChainCompatible(RecordedNodes[PrevNode].getNode(), N.getNode()))
break;
continue;
}
}
// If the code reached this point, then the match failed pop out to the next

View File

@ -111,3 +111,9 @@ void CheckFoldableChainNodeMatcherNode::print(raw_ostream &OS,
OS.indent(indent) << "CheckFoldableChainNode\n";
printChild(OS, indent);
}
void CheckChainCompatibleMatcherNode::print(raw_ostream &OS,
unsigned indent) const {
OS.indent(indent) << "CheckChainCompatibleMatcherNode " << PreviousOp << "\n";
printChild(OS, indent);
}

View File

@ -50,7 +50,8 @@ public:
CheckComplexPat,
CheckAndImm,
CheckOrImm,
CheckFoldableChainNode
CheckFoldableChainNode,
CheckChainCompatible
};
const KindTy Kind;
@ -380,6 +381,25 @@ public:
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
};
/// CheckChainCompatibleMatcherNode - Verify that the current node's chain
/// operand is 'compatible' with the specified recorded node's.
class CheckChainCompatibleMatcherNode : public MatcherNodeWithChild {
unsigned PreviousOp;
public:
CheckChainCompatibleMatcherNode(unsigned previousop)
: MatcherNodeWithChild(CheckChainCompatible), PreviousOp(previousop) {}
unsigned getPreviousOp() const { return PreviousOp; }
static inline bool classof(const MatcherNode *N) {
return N->getKind() == CheckChainCompatible;
}
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
};
} // end namespace llvm
#endif

View File

@ -204,6 +204,10 @@ EmitMatcher(const MatcherNode *N, unsigned Indent) {
case MatcherNode::CheckFoldableChainNode:
OS << "OPC_CheckFoldableChainNode,\n";
return 1;
case MatcherNode::CheckChainCompatible:
OS << "OPC_CheckChainCompatible, "
<< cast<CheckChainCompatibleMatcherNode>(N)->getPreviousOp() << ",\n";
return 2;
}
assert(0 && "Unreachable");
return 0;

View File

@ -165,6 +165,16 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
assert(NextRecordedOperandNo > 1 &&
"Should have recorded input/result chains at least!");
InputChains.push_back(NextRecordedOperandNo-1);
// IF we need to check chains, do so, see comment for
// "NodeHasProperty(SDNPHasChain" below.
if (InputChains.size() > 1) {
// FIXME: This is broken, we should eliminate this nonsense completely,
// but we want to produce the same selections that the old matcher does
// for now.
unsigned PrevOp = InputChains[InputChains.size()-2];
AddMatcherNode(new CheckChainCompatibleMatcherNode(PrevOp));
}
}
return;
}
@ -229,10 +239,13 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
// sure that folding the chain won't induce cycles in the DAG. This could
// happen if there were an intermediate node between the indbr and load, for
// example.
// FIXME: Emit "IsChainCompatible(lastchain.getNode(), CurrentNode)".
// Rename IsChainCompatible -> IsChainUnreachable, add comment about
// complexity.
if (InputChains.size() > 1) {
// FIXME: This is broken, we should eliminate this nonsense completely,
// but we want to produce the same selections that the old matcher does
// for now.
unsigned PrevOp = InputChains[InputChains.size()-2];
AddMatcherNode(new CheckChainCompatibleMatcherNode(PrevOp));
}
// Don't look at the input chain when matching the tree pattern to the
// SDNode.