mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
implement the last known missing feature: updating uses of results
of the matched pattern to use the newly created node results. Onto the "making it actually work" phase! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96724 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f1c6428164
commit
77f2e2724d
@ -101,7 +101,8 @@ void SelectRoot(SelectionDAG &DAG) {
|
||||
// a reference to the root node, preventing it from being deleted,
|
||||
// and tracking any changes of the root.
|
||||
HandleSDNode Dummy(CurDAG->getRoot());
|
||||
ISelPosition = llvm::next(SelectionDAG::allnodes_iterator(CurDAG->getRoot().getNode()));
|
||||
ISelPosition = SelectionDAG::allnodes_iterator(CurDAG->getRoot().getNode());
|
||||
++ISelPosition;
|
||||
|
||||
// The AllNodes list is now topological-sorted. Visit the
|
||||
// nodes by starting at the end of the list (the root of the
|
||||
@ -114,21 +115,15 @@ void SelectRoot(SelectionDAG &DAG) {
|
||||
// makes it theoretically possible to disable the DAGCombiner.
|
||||
if (Node->use_empty())
|
||||
continue;
|
||||
#if 0
|
||||
DAG.setSubgraphColor(Node, "red");
|
||||
#endif
|
||||
|
||||
SDNode *ResNode = Select(Node);
|
||||
// If node should not be replaced, continue with the next one.
|
||||
if (ResNode == Node)
|
||||
continue;
|
||||
// Replace node.
|
||||
if (ResNode) {
|
||||
#if 0
|
||||
DAG.setSubgraphColor(ResNode, "yellow");
|
||||
DAG.setSubgraphColor(ResNode, "black");
|
||||
#endif
|
||||
if (ResNode)
|
||||
ReplaceUses(Node, ResNode);
|
||||
}
|
||||
|
||||
// If after the replacement this node is not used any more,
|
||||
// remove this dead node.
|
||||
if (Node->use_empty()) { // Don't delete EntryToken, etc.
|
||||
@ -232,7 +227,8 @@ enum BuiltinOpcodes {
|
||||
OPC_EmitMergeInputChains,
|
||||
OPC_EmitCopyToReg,
|
||||
OPC_EmitNodeXForm,
|
||||
OPC_EmitNode
|
||||
OPC_EmitNode,
|
||||
OPC_CompleteMatch
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -572,6 +568,7 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
|
||||
if (NumChains == 1) {
|
||||
unsigned RecNo = MatcherTable[MatcherIndex++];
|
||||
assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
|
||||
ChainNodesMatched.push_back(RecordedNodes[RecNo].getNode());
|
||||
InputChain = RecordedNodes[RecNo].getOperand(0);
|
||||
assert(InputChain.getValueType() == MVT::Other && "Not a chain");
|
||||
continue;
|
||||
@ -707,6 +704,49 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
case OPC_CompleteMatch: {
|
||||
// The match has been completed, and any new nodes (if any) have been
|
||||
// created. Patch up references to the matched dag to use the newly
|
||||
// created nodes.
|
||||
unsigned NumResults = MatcherTable[MatcherIndex++];
|
||||
|
||||
for (unsigned i = 0; i != NumResults; ++i) {
|
||||
unsigned ResSlot = MatcherTable[MatcherIndex++];
|
||||
assert(ResSlot < RecordedNodes.size() && "Invalid CheckSame");
|
||||
SDValue Res = RecordedNodes[ResSlot];
|
||||
assert(NodeToMatch->getValueType(i) == Res.getValueType() &&
|
||||
"invalid replacement");
|
||||
ReplaceUses(SDValue(NodeToMatch, i), Res);
|
||||
}
|
||||
|
||||
// Now that all the normal results are replaced, we replace the chain and
|
||||
// flag results if present.
|
||||
if (!ChainNodesMatched.empty()) {
|
||||
assert(InputChain.getNode() != 0 &&
|
||||
"Matched input chains but didn't produce a chain");
|
||||
// Loop over all of the nodes we matched that produced a chain result.
|
||||
// Replace all the chain results with the final chain we ended up with.
|
||||
for (unsigned i = 0, e = ChainNodesMatched.size(); i != e; ++i) {
|
||||
SDNode *ChainNode = ChainNodesMatched[i];
|
||||
SDValue ChainVal = SDValue(ChainNode, ChainNode->getNumValues()-1);
|
||||
if (ChainVal.getValueType() == MVT::Flag)
|
||||
ChainVal = ChainVal.getValue(ChainVal->getNumValues()-2);
|
||||
assert(ChainVal.getValueType() == MVT::Other && "Not a chain?");
|
||||
ReplaceUses(ChainVal, InputChain);
|
||||
}
|
||||
}
|
||||
// If the root node produces a flag, make sure to replace its flag
|
||||
// result with the resultant flag.
|
||||
if (NodeToMatch->getValueType(NodeToMatch->getNumValues()-1) ==
|
||||
MVT::Flag)
|
||||
ReplaceUses(SDValue(NodeToMatch, NodeToMatch->getNumValues()-1),
|
||||
InputFlag);
|
||||
|
||||
// FIXME: We just return here, which interacts correctly with SelectRoot
|
||||
// above. We should fix this to not return an SDNode* anymore.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// If the code reached this point, then the match failed pop out to the next
|
||||
|
@ -1917,7 +1917,7 @@ void DAGISelEmitter::run(raw_ostream &OS) {
|
||||
// definitions. Emit the resultant instruction selector.
|
||||
EmitInstructionSelector(OS);
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
MatcherNode *Matcher = 0;
|
||||
// Walk the patterns backwards, building a matcher for each and adding it to
|
||||
// the matcher for the whole target.
|
||||
|
@ -180,7 +180,8 @@ void EmitNodeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void PatternMarkerMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void CompleteMatchMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "CompleteMatch <todo args>\n";
|
||||
OS.indent(indent) << "Src = " << *Pattern.getSrcPattern() << "\n";
|
||||
OS.indent(indent) << "Dst = " << *Pattern.getDstPattern() << "\n";
|
||||
printNext(OS, indent);
|
||||
|
@ -70,7 +70,7 @@ public:
|
||||
EmitCopyToReg, // Emit a copytoreg into a physreg.
|
||||
EmitNode, // Create a DAG node
|
||||
EmitNodeXForm, // Run a SDNodeXForm
|
||||
PatternMarker // Comment for printing.
|
||||
CompleteMatch // Finish a match and update the results.
|
||||
};
|
||||
const KindTy Kind;
|
||||
|
||||
@ -602,18 +602,24 @@ public:
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// PatternMarkerMatcherNode - This prints as a comment indicating the source
|
||||
/// and dest patterns.
|
||||
class PatternMarkerMatcherNode : public MatcherNode {
|
||||
/// CompleteMatchMatcherNode - Complete a match by replacing the results of the
|
||||
/// pattern with the newly generated nodes. This also prints a comment
|
||||
/// indicating the source and dest patterns.
|
||||
class CompleteMatchMatcherNode : public MatcherNode {
|
||||
SmallVector<unsigned, 2> Results;
|
||||
const PatternToMatch &Pattern;
|
||||
public:
|
||||
PatternMarkerMatcherNode(const PatternToMatch &pattern)
|
||||
: MatcherNode(PatternMarker), Pattern(pattern) {}
|
||||
CompleteMatchMatcherNode(const unsigned *results, unsigned numresults,
|
||||
const PatternToMatch &pattern)
|
||||
: MatcherNode(CompleteMatch), Results(results, results+numresults),
|
||||
Pattern(pattern) {}
|
||||
|
||||
unsigned getNumResults() const { return Results.size(); }
|
||||
unsigned getResult(unsigned R) const { return Results[R]; }
|
||||
const PatternToMatch &getPattern() const { return Pattern; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
return N->getKind() == PatternMarker;
|
||||
return N->getKind() == CompleteMatch;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
|
@ -305,13 +305,19 @@ EmitMatcher(const MatcherNode *N, unsigned Indent) {
|
||||
OS << '\n';
|
||||
return 5+EN->getNumVTs()+EN->getNumOperands();
|
||||
}
|
||||
case MatcherNode::PatternMarker:
|
||||
OS << "// Src: "
|
||||
<< *cast<PatternMarkerMatcherNode>(N)->getPattern().getSrcPattern() << '\n';
|
||||
case MatcherNode::CompleteMatch: {
|
||||
const CompleteMatchMatcherNode *CM = cast<CompleteMatchMatcherNode>(N);
|
||||
OS << "OPC_CompleteMatch, " << CM->getNumResults() << ", ";
|
||||
for (unsigned i = 0, e = CM->getNumResults(); i != e; ++i)
|
||||
OS << CM->getResult(i) << ", ";
|
||||
OS << '\n';
|
||||
OS.PadToColumn(Indent*2) << "// Src: "
|
||||
<< *CM->getPattern().getSrcPattern() << '\n';
|
||||
OS.PadToColumn(Indent*2) << "// Dst: "
|
||||
<< *cast<PatternMarkerMatcherNode>(N)->getPattern().getDstPattern() << '\n';
|
||||
<< *CM->getPattern().getDstPattern() << '\n';
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
assert(0 && "Unreachable");
|
||||
return 0;
|
||||
}
|
||||
|
@ -723,9 +723,9 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
|
||||
|
||||
// The newly emitted node gets recorded.
|
||||
// FIXME2: This should record all of the results except the (implicit) one.
|
||||
if (ResultVTs[0] != MVT::Other)
|
||||
OutputOps.push_back(NextRecordedOperandNo++);
|
||||
|
||||
|
||||
// FIXME2: Kill off all the SelectionDAG::SelectNodeTo and getMachineNode
|
||||
// variants. Call MorphNodeTo instead of SelectNodeTo.
|
||||
}
|
||||
@ -776,11 +776,11 @@ void MatcherGen::EmitResultCode() {
|
||||
// We know that the resulting pattern has exactly one result/
|
||||
// FIXME2: why? what about something like (set a,b,c, (complexpat))
|
||||
// FIXME2: Implicit results should be pushed here I guess?
|
||||
assert(Ops.size() == 1);
|
||||
assert(Ops.size() <= 1);
|
||||
// FIXME: Handle Ops.
|
||||
// FIXME: Handle (set EAX, (foo)) but not (implicit EFLAGS)
|
||||
|
||||
AddMatcherNode(new PatternMarkerMatcherNode(Pattern));
|
||||
AddMatcherNode(new CompleteMatchMatcherNode(Ops.data(), Ops.size(), Pattern));
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user