mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 19:31:58 +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,
|
// a reference to the root node, preventing it from being deleted,
|
||||||
// and tracking any changes of the root.
|
// and tracking any changes of the root.
|
||||||
HandleSDNode Dummy(CurDAG->getRoot());
|
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
|
// The AllNodes list is now topological-sorted. Visit the
|
||||||
// nodes by starting at the end of the list (the root of 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.
|
// makes it theoretically possible to disable the DAGCombiner.
|
||||||
if (Node->use_empty())
|
if (Node->use_empty())
|
||||||
continue;
|
continue;
|
||||||
#if 0
|
|
||||||
DAG.setSubgraphColor(Node, "red");
|
|
||||||
#endif
|
|
||||||
SDNode *ResNode = Select(Node);
|
SDNode *ResNode = Select(Node);
|
||||||
// If node should not be replaced, continue with the next one.
|
// If node should not be replaced, continue with the next one.
|
||||||
if (ResNode == Node)
|
if (ResNode == Node)
|
||||||
continue;
|
continue;
|
||||||
// Replace node.
|
// Replace node.
|
||||||
if (ResNode) {
|
if (ResNode)
|
||||||
#if 0
|
|
||||||
DAG.setSubgraphColor(ResNode, "yellow");
|
|
||||||
DAG.setSubgraphColor(ResNode, "black");
|
|
||||||
#endif
|
|
||||||
ReplaceUses(Node, ResNode);
|
ReplaceUses(Node, ResNode);
|
||||||
}
|
|
||||||
// If after the replacement this node is not used any more,
|
// If after the replacement this node is not used any more,
|
||||||
// remove this dead node.
|
// remove this dead node.
|
||||||
if (Node->use_empty()) { // Don't delete EntryToken, etc.
|
if (Node->use_empty()) { // Don't delete EntryToken, etc.
|
||||||
@ -232,7 +227,8 @@ enum BuiltinOpcodes {
|
|||||||
OPC_EmitMergeInputChains,
|
OPC_EmitMergeInputChains,
|
||||||
OPC_EmitCopyToReg,
|
OPC_EmitCopyToReg,
|
||||||
OPC_EmitNodeXForm,
|
OPC_EmitNodeXForm,
|
||||||
OPC_EmitNode
|
OPC_EmitNode,
|
||||||
|
OPC_CompleteMatch
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -572,6 +568,7 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
|
|||||||
if (NumChains == 1) {
|
if (NumChains == 1) {
|
||||||
unsigned RecNo = MatcherTable[MatcherIndex++];
|
unsigned RecNo = MatcherTable[MatcherIndex++];
|
||||||
assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
|
assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
|
||||||
|
ChainNodesMatched.push_back(RecordedNodes[RecNo].getNode());
|
||||||
InputChain = RecordedNodes[RecNo].getOperand(0);
|
InputChain = RecordedNodes[RecNo].getOperand(0);
|
||||||
assert(InputChain.getValueType() == MVT::Other && "Not a chain");
|
assert(InputChain.getValueType() == MVT::Other && "Not a chain");
|
||||||
continue;
|
continue;
|
||||||
@ -707,6 +704,49 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
|
|||||||
}
|
}
|
||||||
continue;
|
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
|
// 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.
|
// definitions. Emit the resultant instruction selector.
|
||||||
EmitInstructionSelector(OS);
|
EmitInstructionSelector(OS);
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
MatcherNode *Matcher = 0;
|
MatcherNode *Matcher = 0;
|
||||||
// Walk the patterns backwards, building a matcher for each and adding it to
|
// Walk the patterns backwards, building a matcher for each and adding it to
|
||||||
// the matcher for the whole target.
|
// the matcher for the whole target.
|
||||||
|
@ -180,7 +180,8 @@ void EmitNodeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
|||||||
printNext(OS, indent);
|
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) << "Src = " << *Pattern.getSrcPattern() << "\n";
|
||||||
OS.indent(indent) << "Dst = " << *Pattern.getDstPattern() << "\n";
|
OS.indent(indent) << "Dst = " << *Pattern.getDstPattern() << "\n";
|
||||||
printNext(OS, indent);
|
printNext(OS, indent);
|
||||||
|
@ -70,7 +70,7 @@ public:
|
|||||||
EmitCopyToReg, // Emit a copytoreg into a physreg.
|
EmitCopyToReg, // Emit a copytoreg into a physreg.
|
||||||
EmitNode, // Create a DAG node
|
EmitNode, // Create a DAG node
|
||||||
EmitNodeXForm, // Run a SDNodeXForm
|
EmitNodeXForm, // Run a SDNodeXForm
|
||||||
PatternMarker // Comment for printing.
|
CompleteMatch // Finish a match and update the results.
|
||||||
};
|
};
|
||||||
const KindTy Kind;
|
const KindTy Kind;
|
||||||
|
|
||||||
@ -601,19 +601,25 @@ public:
|
|||||||
|
|
||||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// PatternMarkerMatcherNode - This prints as a comment indicating the source
|
/// CompleteMatchMatcherNode - Complete a match by replacing the results of the
|
||||||
/// and dest patterns.
|
/// pattern with the newly generated nodes. This also prints a comment
|
||||||
class PatternMarkerMatcherNode : public MatcherNode {
|
/// indicating the source and dest patterns.
|
||||||
|
class CompleteMatchMatcherNode : public MatcherNode {
|
||||||
|
SmallVector<unsigned, 2> Results;
|
||||||
const PatternToMatch &Pattern;
|
const PatternToMatch &Pattern;
|
||||||
public:
|
public:
|
||||||
PatternMarkerMatcherNode(const PatternToMatch &pattern)
|
CompleteMatchMatcherNode(const unsigned *results, unsigned numresults,
|
||||||
: MatcherNode(PatternMarker), Pattern(pattern) {}
|
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; }
|
const PatternToMatch &getPattern() const { return Pattern; }
|
||||||
|
|
||||||
static inline bool classof(const MatcherNode *N) {
|
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;
|
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||||
|
@ -305,13 +305,19 @@ EmitMatcher(const MatcherNode *N, unsigned Indent) {
|
|||||||
OS << '\n';
|
OS << '\n';
|
||||||
return 5+EN->getNumVTs()+EN->getNumOperands();
|
return 5+EN->getNumVTs()+EN->getNumOperands();
|
||||||
}
|
}
|
||||||
case MatcherNode::PatternMarker:
|
case MatcherNode::CompleteMatch: {
|
||||||
OS << "// Src: "
|
const CompleteMatchMatcherNode *CM = cast<CompleteMatchMatcherNode>(N);
|
||||||
<< *cast<PatternMarkerMatcherNode>(N)->getPattern().getSrcPattern() << '\n';
|
OS << "OPC_CompleteMatch, " << CM->getNumResults() << ", ";
|
||||||
OS.PadToColumn(Indent*2) << "// Dst: "
|
for (unsigned i = 0, e = CM->getNumResults(); i != e; ++i)
|
||||||
<< *cast<PatternMarkerMatcherNode>(N)->getPattern().getDstPattern() << '\n';
|
OS << CM->getResult(i) << ", ";
|
||||||
|
OS << '\n';
|
||||||
|
OS.PadToColumn(Indent*2) << "// Src: "
|
||||||
|
<< *CM->getPattern().getSrcPattern() << '\n';
|
||||||
|
OS.PadToColumn(Indent*2) << "// Dst: "
|
||||||
|
<< *CM->getPattern().getDstPattern() << '\n';
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
assert(0 && "Unreachable");
|
assert(0 && "Unreachable");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -723,8 +723,8 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
|
|||||||
|
|
||||||
// The newly emitted node gets recorded.
|
// The newly emitted node gets recorded.
|
||||||
// FIXME2: This should record all of the results except the (implicit) one.
|
// FIXME2: This should record all of the results except the (implicit) one.
|
||||||
OutputOps.push_back(NextRecordedOperandNo++);
|
if (ResultVTs[0] != MVT::Other)
|
||||||
|
OutputOps.push_back(NextRecordedOperandNo++);
|
||||||
|
|
||||||
// FIXME2: Kill off all the SelectionDAG::SelectNodeTo and getMachineNode
|
// FIXME2: Kill off all the SelectionDAG::SelectNodeTo and getMachineNode
|
||||||
// variants. Call MorphNodeTo instead of SelectNodeTo.
|
// variants. Call MorphNodeTo instead of SelectNodeTo.
|
||||||
@ -776,11 +776,11 @@ void MatcherGen::EmitResultCode() {
|
|||||||
// We know that the resulting pattern has exactly one result/
|
// We know that the resulting pattern has exactly one result/
|
||||||
// FIXME2: why? what about something like (set a,b,c, (complexpat))
|
// FIXME2: why? what about something like (set a,b,c, (complexpat))
|
||||||
// FIXME2: Implicit results should be pushed here I guess?
|
// FIXME2: Implicit results should be pushed here I guess?
|
||||||
assert(Ops.size() == 1);
|
assert(Ops.size() <= 1);
|
||||||
// FIXME: Handle Ops.
|
// FIXME: Handle Ops.
|
||||||
// FIXME: Handle (set EAX, (foo)) but not (implicit EFLAGS)
|
// 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