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 {
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
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);
+}
CheckComplexPat,
CheckAndImm,
CheckOrImm,
- CheckFoldableChainNode
+ CheckFoldableChainNode,
+ CheckChainCompatible
};
const KindTy Kind;
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
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;
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;
}
// 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.