summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp59
-rw-r--r--utils/TableGen/DAGISelMatcherGen.cpp25
2 files changed, 44 insertions, 40 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 031e75eca8..ba9a98d8dd 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -775,10 +775,9 @@ static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) {
if (Operator->isSubClassOf("Instruction")) {
CodeGenInstruction &InstInfo = CDP.getTargetInfo().getInstruction(Operator);
-
- // FIXME: Handle implicit defs right.
- if (InstInfo.NumDefs != 0)
- return 1; // FIXME: Handle inst results right!
+
+ // FIXME: Should allow access to all the results here.
+ unsigned NumDefsToAdd = InstInfo.NumDefs ? 1 : 0;
if (!InstInfo.ImplicitDefs.empty()) {
// Add on one implicit def if it has a resolvable type.
@@ -787,9 +786,9 @@ static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) {
const std::vector<MVT::SimpleValueType> &RegVTs =
CDP.getTargetInfo().getRegisterVTs(FirstImplicitDef);
if (RegVTs.size() == 1)
- return 1;
+ return NumDefsToAdd+1;
}
- return 0;
+ return NumDefsToAdd;
}
if (Operator->isSubClassOf("SDNodeXForm"))
@@ -1250,21 +1249,20 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
if (getOperator()->isSubClassOf("Instruction")) {
const DAGInstruction &Inst = CDP.getInstruction(getOperator());
- unsigned ResNo = 0;
- assert(Inst.getNumResults() <= 1 &&
- "FIXME: Only supports zero or one result instrs!");
-
CodeGenInstruction &InstInfo =
CDP.getTargetInfo().getInstruction(getOperator());
- EEVT::TypeSet ResultType;
-
- // Apply the result type to the node
- if (InstInfo.NumDefs != 0) { // # of elements in (outs) list
- Record *ResultNode = Inst.getResult(0);
+ bool MadeChange = false;
+
+ // Apply the result types to the node, these come from the things in the
+ // (outs) list of the instruction.
+ // FIXME: Cap at one result so far.
+ unsigned NumResultsToAdd = InstInfo.NumDefs ? 1 : 0;
+ for (unsigned ResNo = 0; ResNo != NumResultsToAdd; ++ResNo) {
+ Record *ResultNode = Inst.getResult(ResNo);
if (ResultNode->isSubClassOf("PointerLikeRegClass")) {
- ResultType = EEVT::TypeSet(MVT::iPTR, TP);
+ MadeChange |= UpdateNodeType(ResNo, MVT::iPTR, TP);
} else if (ResultNode->getName() == "unknown") {
// Nothing to do.
} else {
@@ -1272,26 +1270,23 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
"Operands should be register classes!");
const CodeGenRegisterClass &RC =
CDP.getTargetInfo().getRegisterClass(ResultNode);
- ResultType = RC.getValueTypes();
+ MadeChange |= UpdateNodeType(ResNo, RC.getValueTypes(), TP);
}
- } else if (!InstInfo.ImplicitDefs.empty()) {
- // If the instruction has implicit defs, the first one defines the result
- // type.
+ }
+
+ // If the instruction has implicit defs, we apply the first one as a result.
+ // FIXME: This sucks, it should apply all implicit defs.
+ if (!InstInfo.ImplicitDefs.empty()) {
+ unsigned ResNo = NumResultsToAdd;
+
Record *FirstImplicitDef = InstInfo.ImplicitDefs[0];
assert(FirstImplicitDef->isSubClassOf("Register"));
const std::vector<MVT::SimpleValueType> &RegVTs =
CDP.getTargetInfo().getRegisterVTs(FirstImplicitDef);
if (RegVTs.size() == 1) // FIXME: Generalize.
- ResultType = EEVT::TypeSet(RegVTs);
- } else {
- // Otherwise, the instruction produces no value result.
+ MadeChange |= UpdateNodeType(ResNo, EEVT::TypeSet(RegVTs), TP);
}
- bool MadeChange = false;
-
- if (!ResultType.isCompletelyUnknown())
- MadeChange |= UpdateNodeType(ResNo, ResultType, TP);
-
// If this is an INSERT_SUBREG, constrain the source and destination VTs to
// be the same.
if (getOperator()->getName() == "INSERT_SUBREG") {
@@ -1319,17 +1314,17 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
MVT::SimpleValueType VT;
TreePatternNode *Child = getChild(ChildNo++);
- assert(Child->getNumTypes() == 1 && "Unknown case?");
+ unsigned ChildResNo = 0; // Instructions always use res #0 of their op.
if (OperandNode->isSubClassOf("RegisterClass")) {
const CodeGenRegisterClass &RC =
CDP.getTargetInfo().getRegisterClass(OperandNode);
- MadeChange |= Child->UpdateNodeType(0, RC.getValueTypes(), TP);
+ MadeChange |= Child->UpdateNodeType(ChildResNo, RC.getValueTypes(), TP);
} else if (OperandNode->isSubClassOf("Operand")) {
VT = getValueType(OperandNode->getValueAsDef("Type"));
- MadeChange |= Child->UpdateNodeType(0, VT, TP);
+ MadeChange |= Child->UpdateNodeType(ChildResNo, VT, TP);
} else if (OperandNode->isSubClassOf("PointerLikeRegClass")) {
- MadeChange |= Child->UpdateNodeType(0, MVT::iPTR, TP);
+ MadeChange |= Child->UpdateNodeType(ChildResNo, MVT::iPTR, TP);
} else if (OperandNode->getName() == "unknown") {
// Nothing to do.
} else {
diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp
index fda1d457b9..f7fd493cd3 100644
--- a/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/utils/TableGen/DAGISelMatcherGen.cpp
@@ -687,9 +687,19 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
continue;
}
+ const TreePatternNode *Child = N->getChild(ChildNo);
+
// Otherwise this is a normal operand or a predicate operand without
// 'execute always'; emit it.
- EmitResultOperand(N->getChild(ChildNo), InstOps);
+ unsigned BeforeAddingNumOps = InstOps.size();
+ EmitResultOperand(Child, InstOps);
+ assert(InstOps.size() > BeforeAddingNumOps && "Didn't add any operands");
+
+ // If the operand is an instruction and it produced multiple results, just
+ // take the first one.
+ if (!Child->isLeaf() && Child->getOperator()->isSubClassOf("Instruction"))
+ InstOps.resize(BeforeAddingNumOps+1);
+
++ChildNo;
}
@@ -711,12 +721,8 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
// Determine the result types.
SmallVector<MVT::SimpleValueType, 4> ResultVTs;
- if (N->getNumTypes()) {
- // FIXME2: If the node has multiple results, we should add them. For now,
- // preserve existing behavior?!
- assert(N->getNumTypes() == 1);
- ResultVTs.push_back(N->getType(0));
- }
+ for (unsigned i = 0, e = N->getNumTypes(); i != e; ++i)
+ ResultVTs.push_back(N->getType(i));
// If this is the root instruction of a pattern that has physical registers in
// its result pattern, add output VTs for them. For example, X86 has:
@@ -727,7 +733,7 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
// If the root came from an implicit def in the instruction handling stuff,
// don't re-add it.
Record *HandledReg = 0;
- if (NumResults == 0 && N->getNumTypes() != 0 &&
+ if (N->getNumTypes() != 0 &&
!II.ImplicitDefs.empty())
HandledReg = II.ImplicitDefs[0];
@@ -762,6 +768,9 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
bool NodeHasMemRefs =
isRoot && Pattern.getSrcPattern()->TreeHasProperty(SDNPMemOperand, CGP);
+ assert((!ResultVTs.empty() || TreeHasOutFlag || NodeHasChain) &&
+ "Node has no result");
+
AddMatcher(new EmitNodeMatcher(II.Namespace+"::"+II.TheDef->getName(),
ResultVTs.data(), ResultVTs.size(),
InstOps.data(), InstOps.size(),