forked from OSchip/llvm-project
parent
8092e80095
commit
f7f9e8c978
|
@ -107,8 +107,8 @@ void RecordMemRefMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
|
|||
OS.indent(indent) << "RecordMemRef\n";
|
||||
}
|
||||
|
||||
void CaptureFlagInputMatcher::printImpl(raw_ostream &OS, unsigned indent) const{
|
||||
OS.indent(indent) << "CaptureFlagInput\n";
|
||||
void CaptureGlueInputMatcher::printImpl(raw_ostream &OS, unsigned indent) const{
|
||||
OS.indent(indent) << "CaptureGlueInput\n";
|
||||
}
|
||||
|
||||
void MoveChildMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
|
||||
|
@ -246,8 +246,8 @@ void EmitNodeMatcherCommon::printImpl(raw_ostream &OS, unsigned indent) const {
|
|||
OS << ")\n";
|
||||
}
|
||||
|
||||
void MarkFlagResultsMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "MarkFlagResults <todo: args>\n";
|
||||
void MarkGlueResultsMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "MarkGlueResults <todo: args>\n";
|
||||
}
|
||||
|
||||
void CompleteMatchMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
|
||||
|
@ -316,8 +316,8 @@ unsigned EmitNodeMatcherCommon::getHashImpl() const {
|
|||
}
|
||||
|
||||
|
||||
unsigned MarkFlagResultsMatcher::getHashImpl() const {
|
||||
return HashUnsigneds(FlagResultNodes.begin(), FlagResultNodes.end());
|
||||
unsigned MarkGlueResultsMatcher::getHashImpl() const {
|
||||
return HashUnsigneds(GlueResultNodes.begin(), GlueResultNodes.end());
|
||||
}
|
||||
|
||||
unsigned CompleteMatchMatcher::getHashImpl() const {
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
RecordNode, // Record the current node.
|
||||
RecordChild, // Record a child of the current node.
|
||||
RecordMemRef, // Record the memref in the current node.
|
||||
CaptureFlagInput, // If the current node has an input flag, save it.
|
||||
CaptureGlueInput, // If the current node has an input glue, save it.
|
||||
MoveChild, // Move current node to specified child.
|
||||
MoveParent, // Move current node to parent.
|
||||
|
||||
|
@ -75,7 +75,7 @@ public:
|
|||
EmitCopyToReg, // Emit a copytoreg into a physreg.
|
||||
EmitNode, // Create a DAG node
|
||||
EmitNodeXForm, // Run a SDNodeXForm
|
||||
MarkFlagResults, // Indicate which interior nodes have flag results.
|
||||
MarkGlueResults, // Indicate which interior nodes have glue results.
|
||||
CompleteMatch, // Finish a match and update the results.
|
||||
MorphNodeTo // Build a node, finish a match and update results.
|
||||
};
|
||||
|
@ -306,14 +306,14 @@ private:
|
|||
};
|
||||
|
||||
|
||||
/// CaptureFlagInputMatcher - If the current record has a flag input, record
|
||||
/// CaptureGlueInputMatcher - If the current record has a glue input, record
|
||||
/// it so that it is used as an input to the generated code.
|
||||
class CaptureFlagInputMatcher : public Matcher {
|
||||
class CaptureGlueInputMatcher : public Matcher {
|
||||
public:
|
||||
CaptureFlagInputMatcher() : Matcher(CaptureFlagInput) {}
|
||||
CaptureGlueInputMatcher() : Matcher(CaptureGlueInput) {}
|
||||
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == CaptureFlagInput;
|
||||
return N->getKind() == CaptureGlueInput;
|
||||
}
|
||||
|
||||
virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
|
||||
|
@ -893,7 +893,7 @@ private:
|
|||
};
|
||||
|
||||
/// EmitCopyToRegMatcher - Emit a CopyToReg node from a value to a physreg,
|
||||
/// pushing the chain and flag results.
|
||||
/// pushing the chain and glue results.
|
||||
///
|
||||
class EmitCopyToRegMatcher : public Matcher {
|
||||
unsigned SrcSlot; // Value to copy into the physreg.
|
||||
|
@ -965,12 +965,12 @@ public:
|
|||
EmitNodeMatcherCommon(const std::string &opcodeName,
|
||||
const MVT::SimpleValueType *vts, unsigned numvts,
|
||||
const unsigned *operands, unsigned numops,
|
||||
bool hasChain, bool hasInFlag, bool hasOutFlag,
|
||||
bool hasChain, bool hasInGlue, bool hasOutGlue,
|
||||
bool hasmemrefs,
|
||||
int numfixedarityoperands, bool isMorphNodeTo)
|
||||
: Matcher(isMorphNodeTo ? MorphNodeTo : EmitNode), OpcodeName(opcodeName),
|
||||
VTs(vts, vts+numvts), Operands(operands, operands+numops),
|
||||
HasChain(hasChain), HasInFlag(hasInFlag), HasOutFlag(hasOutFlag),
|
||||
HasChain(hasChain), HasInFlag(hasInGlue), HasOutFlag(hasOutGlue),
|
||||
HasMemRefs(hasmemrefs), NumFixedArityOperands(numfixedarityoperands) {}
|
||||
|
||||
const std::string &getOpcodeName() const { return OpcodeName; }
|
||||
|
@ -1052,30 +1052,30 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// MarkFlagResultsMatcher - This node indicates which non-root nodes in the
|
||||
/// pattern produce flags. This allows CompleteMatchMatcher to update them
|
||||
/// with the output flag of the resultant code.
|
||||
class MarkFlagResultsMatcher : public Matcher {
|
||||
SmallVector<unsigned, 3> FlagResultNodes;
|
||||
/// MarkGlueResultsMatcher - This node indicates which non-root nodes in the
|
||||
/// pattern produce glue. This allows CompleteMatchMatcher to update them
|
||||
/// with the output glue of the resultant code.
|
||||
class MarkGlueResultsMatcher : public Matcher {
|
||||
SmallVector<unsigned, 3> GlueResultNodes;
|
||||
public:
|
||||
MarkFlagResultsMatcher(const unsigned *nodes, unsigned NumNodes)
|
||||
: Matcher(MarkFlagResults), FlagResultNodes(nodes, nodes+NumNodes) {}
|
||||
MarkGlueResultsMatcher(const unsigned *nodes, unsigned NumNodes)
|
||||
: Matcher(MarkGlueResults), GlueResultNodes(nodes, nodes+NumNodes) {}
|
||||
|
||||
unsigned getNumNodes() const { return FlagResultNodes.size(); }
|
||||
unsigned getNumNodes() const { return GlueResultNodes.size(); }
|
||||
|
||||
unsigned getNode(unsigned i) const {
|
||||
assert(i < FlagResultNodes.size());
|
||||
return FlagResultNodes[i];
|
||||
assert(i < GlueResultNodes.size());
|
||||
return GlueResultNodes[i];
|
||||
}
|
||||
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == MarkFlagResults;
|
||||
return N->getKind() == MarkGlueResults;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void printImpl(raw_ostream &OS, unsigned indent) const;
|
||||
virtual bool isEqualImpl(const Matcher *M) const {
|
||||
return cast<MarkFlagResultsMatcher>(M)->FlagResultNodes == FlagResultNodes;
|
||||
return cast<MarkGlueResultsMatcher>(M)->GlueResultNodes == GlueResultNodes;
|
||||
}
|
||||
virtual unsigned getHashImpl() const;
|
||||
};
|
||||
|
|
|
@ -220,7 +220,7 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
|
|||
OS << "OPC_RecordMemRef,\n";
|
||||
return 1;
|
||||
|
||||
case Matcher::CaptureFlagInput:
|
||||
case Matcher::CaptureGlueInput:
|
||||
OS << "OPC_CaptureFlagInput,\n";
|
||||
return 1;
|
||||
|
||||
|
@ -531,8 +531,8 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
|
|||
|
||||
return 6+EN->getNumVTs()+NumOperandBytes;
|
||||
}
|
||||
case Matcher::MarkFlagResults: {
|
||||
const MarkFlagResultsMatcher *CFR = cast<MarkFlagResultsMatcher>(N);
|
||||
case Matcher::MarkGlueResults: {
|
||||
const MarkGlueResultsMatcher *CFR = cast<MarkGlueResultsMatcher>(N);
|
||||
OS << "OPC_MarkFlagResults, " << CFR->getNumNodes() << ", ";
|
||||
unsigned NumOperandBytes = 0;
|
||||
for (unsigned i = 0, e = CFR->getNumNodes(); i != e; ++i)
|
||||
|
@ -742,7 +742,7 @@ void MatcherTableEmitter::EmitHistogram(const Matcher *M,
|
|||
case Matcher::RecordNode: OS << "OPC_RecordNode"; break;
|
||||
case Matcher::RecordChild: OS << "OPC_RecordChild"; break;
|
||||
case Matcher::RecordMemRef: OS << "OPC_RecordMemRef"; break;
|
||||
case Matcher::CaptureFlagInput: OS << "OPC_CaptureFlagInput"; break;
|
||||
case Matcher::CaptureGlueInput: OS << "OPC_CaptureFlagInput"; break;
|
||||
case Matcher::MoveChild: OS << "OPC_MoveChild"; break;
|
||||
case Matcher::MoveParent: OS << "OPC_MoveParent"; break;
|
||||
case Matcher::CheckSame: OS << "OPC_CheckSame"; break;
|
||||
|
@ -771,7 +771,7 @@ void MatcherTableEmitter::EmitHistogram(const Matcher *M,
|
|||
case Matcher::EmitNode: OS << "OPC_EmitNode"; break;
|
||||
case Matcher::MorphNodeTo: OS << "OPC_MorphNodeTo"; break;
|
||||
case Matcher::EmitNodeXForm: OS << "OPC_EmitNodeXForm"; break;
|
||||
case Matcher::MarkFlagResults: OS << "OPC_MarkFlagResults"; break;
|
||||
case Matcher::MarkGlueResults: OS << "OPC_MarkFlagResults"; break;
|
||||
case Matcher::CompleteMatch: OS << "OPC_CompleteMatch"; break;
|
||||
}
|
||||
|
||||
|
|
|
@ -68,9 +68,9 @@ namespace {
|
|||
/// array of all of the recorded input nodes that have chains.
|
||||
SmallVector<unsigned, 2> MatchedChainNodes;
|
||||
|
||||
/// MatchedFlagResultNodes - This maintains the position in the recorded
|
||||
/// nodes array of all of the recorded input nodes that have flag results.
|
||||
SmallVector<unsigned, 2> MatchedFlagResultNodes;
|
||||
/// MatchedGlueResultNodes - This maintains the position in the recorded
|
||||
/// nodes array of all of the recorded input nodes that have glue results.
|
||||
SmallVector<unsigned, 2> MatchedGlueResultNodes;
|
||||
|
||||
/// MatchedComplexPatterns - This maintains a list of all of the
|
||||
/// ComplexPatterns that we need to check. The patterns are known to have
|
||||
|
@ -356,7 +356,7 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
|
|||
// If it *is* an immediate child of the root, we can still need a check if
|
||||
// the root SDNode has multiple inputs. For us, this means that it is an
|
||||
// intrinsic, has multiple operands, or has other inputs like chain or
|
||||
// flag).
|
||||
// glue).
|
||||
if (!NeedCheck) {
|
||||
const SDNodeInfo &PInfo = CGP.getSDNodeInfo(Root->getOperator());
|
||||
NeedCheck =
|
||||
|
@ -374,24 +374,24 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
|
|||
}
|
||||
}
|
||||
|
||||
// If this node has an output flag and isn't the root, remember it.
|
||||
// If this node has an output glue and isn't the root, remember it.
|
||||
if (N->NodeHasProperty(SDNPOutFlag, CGP) &&
|
||||
N != Pattern.getSrcPattern()) {
|
||||
// TODO: This redundantly records nodes with both flags and chains.
|
||||
// TODO: This redundantly records nodes with both glues and chains.
|
||||
|
||||
// Record the node and remember it in our chained nodes list.
|
||||
AddMatcher(new RecordMatcher("'" + N->getOperator()->getName() +
|
||||
"' flag output node",
|
||||
"' glue output node",
|
||||
NextRecordedOperandNo));
|
||||
// Remember all of the nodes with output flags our pattern will match.
|
||||
MatchedFlagResultNodes.push_back(NextRecordedOperandNo++);
|
||||
// Remember all of the nodes with output glue our pattern will match.
|
||||
MatchedGlueResultNodes.push_back(NextRecordedOperandNo++);
|
||||
}
|
||||
|
||||
// If this node is known to have an input flag or if it *might* have an input
|
||||
// flag, capture it as the flag input of the pattern.
|
||||
// If this node is known to have an input glue or if it *might* have an input
|
||||
// glue, capture it as the glue input of the pattern.
|
||||
if (N->NodeHasProperty(SDNPOptInFlag, CGP) ||
|
||||
N->NodeHasProperty(SDNPInFlag, CGP))
|
||||
AddMatcher(new CaptureFlagInputMatcher());
|
||||
AddMatcher(new CaptureGlueInputMatcher());
|
||||
|
||||
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
|
||||
// Get the code suitable for matching this child. Move to the child, check
|
||||
|
@ -514,7 +514,7 @@ bool MatcherGen::EmitMatcherCode(unsigned Variant) {
|
|||
MatchedChainNodes.push_back(NextRecordedOperandNo-1);
|
||||
}
|
||||
|
||||
// TODO: Complex patterns can't have output flags, if they did, we'd want
|
||||
// TODO: Complex patterns can't have output glues, if they did, we'd want
|
||||
// to record them.
|
||||
}
|
||||
|
||||
|
@ -655,16 +655,16 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
|
|||
|
||||
bool isRoot = N == Pattern.getDstPattern();
|
||||
|
||||
// TreeHasOutFlag - True if this tree has a flag.
|
||||
bool TreeHasInFlag = false, TreeHasOutFlag = false;
|
||||
// TreeHasOutGlue - True if this tree has glue.
|
||||
bool TreeHasInGlue = false, TreeHasOutGlue = false;
|
||||
if (isRoot) {
|
||||
const TreePatternNode *SrcPat = Pattern.getSrcPattern();
|
||||
TreeHasInFlag = SrcPat->TreeHasProperty(SDNPOptInFlag, CGP) ||
|
||||
TreeHasInGlue = SrcPat->TreeHasProperty(SDNPOptInFlag, CGP) ||
|
||||
SrcPat->TreeHasProperty(SDNPInFlag, CGP);
|
||||
|
||||
// FIXME2: this is checking the entire pattern, not just the node in
|
||||
// question, doing this just for the root seems like a total hack.
|
||||
TreeHasOutFlag = SrcPat->TreeHasProperty(SDNPOutFlag, CGP);
|
||||
TreeHasOutGlue = SrcPat->TreeHasProperty(SDNPOutFlag, CGP);
|
||||
}
|
||||
|
||||
// NumResults - This is the number of results produced by the instruction in
|
||||
|
@ -711,8 +711,8 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
|
|||
++ChildNo;
|
||||
}
|
||||
|
||||
// If this node has an input flag or explicitly specified input physregs, we
|
||||
// need to add chained and flagged copyfromreg nodes and materialize the flag
|
||||
// If this node has input glue or explicitly specified input physregs, we
|
||||
// need to add chained and glued copyfromreg nodes and materialize the glue
|
||||
// input.
|
||||
if (isRoot && !PhysRegInputs.empty()) {
|
||||
// Emit all of the CopyToReg nodes for the input physical registers. These
|
||||
|
@ -720,12 +720,12 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
|
|||
for (unsigned i = 0, e = PhysRegInputs.size(); i != e; ++i)
|
||||
AddMatcher(new EmitCopyToRegMatcher(PhysRegInputs[i].second,
|
||||
PhysRegInputs[i].first));
|
||||
// Even if the node has no other flag inputs, the resultant node must be
|
||||
// flagged to the CopyFromReg nodes we just generated.
|
||||
TreeHasInFlag = true;
|
||||
// Even if the node has no other glue inputs, the resultant node must be
|
||||
// glued to the CopyFromReg nodes we just generated.
|
||||
TreeHasInGlue = true;
|
||||
}
|
||||
|
||||
// Result order: node results, chain, flags
|
||||
// Result order: node results, chain, glue
|
||||
|
||||
// Determine the result types.
|
||||
SmallVector<MVT::SimpleValueType, 4> ResultVTs;
|
||||
|
@ -775,17 +775,17 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
|
|||
bool NodeHasMemRefs =
|
||||
isRoot && Pattern.getSrcPattern()->TreeHasProperty(SDNPMemOperand, CGP);
|
||||
|
||||
assert((!ResultVTs.empty() || TreeHasOutFlag || NodeHasChain) &&
|
||||
assert((!ResultVTs.empty() || TreeHasOutGlue || NodeHasChain) &&
|
||||
"Node has no result");
|
||||
|
||||
AddMatcher(new EmitNodeMatcher(II.Namespace+"::"+II.TheDef->getName(),
|
||||
ResultVTs.data(), ResultVTs.size(),
|
||||
InstOps.data(), InstOps.size(),
|
||||
NodeHasChain, TreeHasInFlag, TreeHasOutFlag,
|
||||
NodeHasChain, TreeHasInGlue, TreeHasOutGlue,
|
||||
NodeHasMemRefs, NumFixedArityOperands,
|
||||
NextRecordedOperandNo));
|
||||
|
||||
// The non-chain and non-flag results of the newly emitted node get recorded.
|
||||
// The non-chain and non-glue results of the newly emitted node get recorded.
|
||||
for (unsigned i = 0, e = ResultVTs.size(); i != e; ++i) {
|
||||
if (ResultVTs[i] == MVT::Other || ResultVTs[i] == MVT::Glue) break;
|
||||
OutputOps.push_back(NextRecordedOperandNo++);
|
||||
|
@ -846,7 +846,7 @@ void MatcherGen::EmitResultCode() {
|
|||
// At this point, we have however many values the result pattern produces.
|
||||
// However, the input pattern might not need all of these. If there are
|
||||
// excess values at the end (such as implicit defs of condition codes etc)
|
||||
// just lop them off. This doesn't need to worry about flags or chains, just
|
||||
// just lop them off. This doesn't need to worry about glue or chains, just
|
||||
// explicit results.
|
||||
//
|
||||
unsigned NumSrcResults = Pattern.getSrcPattern()->getNumTypes();
|
||||
|
@ -875,11 +875,11 @@ void MatcherGen::EmitResultCode() {
|
|||
assert(Ops.size() >= NumSrcResults && "Didn't provide enough results");
|
||||
Ops.resize(NumSrcResults);
|
||||
|
||||
// If the matched pattern covers nodes which define a flag result, emit a node
|
||||
// If the matched pattern covers nodes which define a glue result, emit a node
|
||||
// that tells the matcher about them so that it can update their results.
|
||||
if (!MatchedFlagResultNodes.empty())
|
||||
AddMatcher(new MarkFlagResultsMatcher(MatchedFlagResultNodes.data(),
|
||||
MatchedFlagResultNodes.size()));
|
||||
if (!MatchedGlueResultNodes.empty())
|
||||
AddMatcher(new MarkGlueResultsMatcher(MatchedGlueResultNodes.data(),
|
||||
MatchedGlueResultNodes.size()));
|
||||
|
||||
AddMatcher(new CompleteMatchMatcher(Ops.data(), Ops.size(), Pattern));
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
|
|||
// MarkFlagResults->EmitNode->CompleteMatch when we can to encourage
|
||||
// MorphNodeTo formation. This is safe because MarkFlagResults never refers
|
||||
// to the root of the pattern.
|
||||
if (isa<EmitNodeMatcher>(N) && isa<MarkFlagResultsMatcher>(N->getNext()) &&
|
||||
if (isa<EmitNodeMatcher>(N) && isa<MarkGlueResultsMatcher>(N->getNext()) &&
|
||||
isa<CompleteMatchMatcher>(N->getNext()->getNext())) {
|
||||
// Unlink the two nodes from the list.
|
||||
Matcher *EmitNode = MatcherPtr.take();
|
||||
|
@ -100,7 +100,7 @@ static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
|
|||
if (CM->getResult(i) != RootResultFirst+i)
|
||||
ResultsMatch = false;
|
||||
|
||||
// If the selected node defines a subset of the flag/chain results, we
|
||||
// If the selected node defines a subset of the glue/chain results, we
|
||||
// can't use MorphNodeTo. For example, we can't use MorphNodeTo if the
|
||||
// matched pattern has a chain but the root node doesn't.
|
||||
const PatternToMatch &Pattern = CM->getPattern();
|
||||
|
@ -109,10 +109,10 @@ static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
|
|||
Pattern.getSrcPattern()->NodeHasProperty(SDNPHasChain, CGP))
|
||||
ResultsMatch = false;
|
||||
|
||||
// If the matched node has a flag and the output root doesn't, we can't
|
||||
// If the matched node has glue and the output root doesn't, we can't
|
||||
// use MorphNodeTo.
|
||||
//
|
||||
// NOTE: Strictly speaking, we don't have to check for the flag here
|
||||
// NOTE: Strictly speaking, we don't have to check for glue here
|
||||
// because the code in the pattern generator doesn't handle it right. We
|
||||
// do it anyway for thoroughness.
|
||||
if (!EN->hasOutFlag() &&
|
||||
|
@ -121,11 +121,11 @@ static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
|
|||
|
||||
|
||||
// If the root result node defines more results than the source root node
|
||||
// *and* has a chain or flag input, then we can't match it because it
|
||||
// would end up replacing the extra result with the chain/flag.
|
||||
// *and* has a chain or glue input, then we can't match it because it
|
||||
// would end up replacing the extra result with the chain/glue.
|
||||
#if 0
|
||||
if ((EN->hasFlag() || EN->hasChain()) &&
|
||||
EN->getNumNonChainFlagVTs() > ... need to get no results reliably ...)
|
||||
if ((EN->hasGlue() || EN->hasChain()) &&
|
||||
EN->getNumNonChainGlueVTs() > ... need to get no results reliably ...)
|
||||
ResultMatch = false;
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue