aboutsummaryrefslogtreecommitdiffstats
path: root/utils/TableGen/CodeGenDAGPatterns.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen/CodeGenDAGPatterns.cpp')
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp60
1 files changed, 40 insertions, 20 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index a750aa9..4e3e588 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -53,7 +53,7 @@ EEVT::TypeSet::TypeSet(MVT::SimpleValueType VT, TreePattern &TP) {
EnforceVector(TP);
else {
assert((VT < MVT::LAST_VALUETYPE || VT == MVT::iPTR ||
- VT == MVT::iPTRAny) && "Not a concrete type!");
+ VT == MVT::iPTRAny || VT == MVT::Any) && "Not a concrete type!");
TypeVec.push_back(VT);
}
}
@@ -1113,6 +1113,8 @@ static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) {
// FIXME: Should allow access to all the results here.
unsigned NumDefsToAdd = InstInfo.Operands.NumDefs ? 1 : 0;
+ if (InstInfo.hasTwoExplicitDefs)
+ ++NumDefsToAdd;
// Add on one implicit def if it has a resolvable type.
if (InstInfo.HasOneImplicitDefWithKnownVT(CDP.getTargetInfo()) !=MVT::Other)
@@ -1539,6 +1541,22 @@ static bool isOperandClass(const TreePatternNode *N, StringRef Class) {
return false;
}
+
+static void emitTooManyOperandsError(TreePattern &TP,
+ StringRef InstName,
+ unsigned Expected,
+ unsigned Actual) {
+ TP.error("Instruction '" + InstName + "' was provided " + Twine(Actual) +
+ " operands but expected only " + Twine(Expected) + "!");
+}
+
+static void emitTooFewOperandsError(TreePattern &TP,
+ StringRef InstName,
+ unsigned Actual) {
+ TP.error("Instruction '" + InstName +
+ "' expects more than the provided " + Twine(Actual) + " operands!");
+}
+
/// ApplyTypeConstraints - Apply all of the type constraints relevant to
/// this node and its children in the tree. This returns true if it makes a
/// change, false otherwise. If a type contradiction is found, flag an error.
@@ -1593,11 +1611,20 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
assert(getNumTypes() == 0 && "Set doesn't produce a value");
assert(getNumChildren() >= 2 && "Missing RHS of a set?");
unsigned NC = getNumChildren();
+ unsigned NumOfSrcs = NC-1;
+ // destination
TreePatternNode *SetVal = getChild(NC-1);
bool MadeChange = SetVal->ApplyTypeConstraints(TP, NotRegisters);
- for (unsigned i = 0; i < NC-1; ++i) {
+ // second explicit destination
+ if (TP.getRecord()->getValueAsBit("hasTwoExplicitDefs")) {
+ TreePatternNode *Set2Val = getChild(NC-2);
+ MadeChange = Set2Val->ApplyTypeConstraints(TP, NotRegisters);
+ NumOfSrcs --;
+ }
+
+ for (unsigned i = 0; i < NumOfSrcs; ++i) {
TreePatternNode *Child = getChild(i);
MadeChange |= Child->ApplyTypeConstraints(TP, NotRegisters);
@@ -1741,8 +1768,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
// Verify that we didn't run out of provided operands.
if (ChildNo >= getNumChildren()) {
- TP.error("Instruction '" + getOperator()->getName() +
- "' expects more operands than were provided.");
+ emitTooFewOperandsError(TP, getOperator()->getName(), getNumChildren());
return false;
}
@@ -1766,8 +1792,8 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
// And the remaining sub-operands against subsequent children.
for (unsigned Arg = 1; Arg < NumArgs; ++Arg) {
if (ChildNo >= getNumChildren()) {
- TP.error("Instruction '" + getOperator()->getName() +
- "' expects more operands than were provided.");
+ emitTooFewOperandsError(TP, getOperator()->getName(),
+ getNumChildren());
return false;
}
Child = getChild(ChildNo++);
@@ -1787,8 +1813,8 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
}
if (!InstInfo.Operands.isVariadic && ChildNo != getNumChildren()) {
- TP.error("Instruction '" + getOperator()->getName() +
- "' was provided too many operands!");
+ emitTooManyOperandsError(TP, getOperator()->getName(),
+ ChildNo, getNumChildren());
return false;
}
@@ -2554,8 +2580,10 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
I->error("set destination should be a register!");
DefInit *Val = dyn_cast<DefInit>(Dest->getLeafValue());
- if (!Val)
+ if (!Val) {
I->error("set destination should be a register!");
+ continue;
+ }
if (Val->getDef()->isSubClassOf("RegisterClass") ||
Val->getDef()->isSubClassOf("ValueType") ||
@@ -2839,7 +2867,7 @@ const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern(
// Check that all of the results occur first in the list.
std::vector<Record*> Results;
- TreePatternNode *Res0Node = nullptr;
+ SmallVector<TreePatternNode *, 2> ResNode;
for (unsigned i = 0; i != NumResults; ++i) {
if (i == CGI.Operands.size())
I->error("'" + InstResults.begin()->first +
@@ -2851,8 +2879,7 @@ const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern(
if (!RNode)
I->error("Operand $" + OpName + " does not exist in operand list!");
- if (i == 0)
- Res0Node = RNode;
+ ResNode.push_back(RNode);
Record *R = cast<DefInit>(RNode->getLeafValue())->getDef();
if (!R)
I->error("Operand $" + OpName + " should be a set destination: all "
@@ -2929,7 +2956,7 @@ const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern(
GetNumNodeResults(I->getRecord(), *this));
// Copy fully inferred output node type to instruction result pattern.
for (unsigned i = 0; i != NumResults; ++i)
- ResultPattern->setType(i, Res0Node->getExtType(i));
+ ResultPattern->setType(i, ResNode[i]->getExtType(0));
// Create and insert the instruction.
// FIXME: InstImpResults should not be part of DAGInstruction.
@@ -3111,13 +3138,6 @@ void CodeGenDAGPatterns::InferInstructionFlags() {
CodeGenInstruction &InstInfo =
const_cast<CodeGenInstruction &>(*Instructions[i]);
- // Treat neverHasSideEffects = 1 as the equivalent of hasSideEffects = 0.
- // This flag is obsolete and will be removed.
- if (InstInfo.neverHasSideEffects) {
- assert(!InstInfo.hasSideEffects);
- InstInfo.hasSideEffects_Unset = false;
- }
-
// Get the primary instruction pattern.
const TreePattern *Pattern = getInstruction(InstInfo.TheDef).getPattern();
if (!Pattern) {