Skip to content

Commit 59c39dc

Browse files
author
Evan Cheng
committed
Initial support for multi-result patterns:
1. [(set GR32:$dst, (add GR32:$src1, GR32:$src2)), (modify EFLAGS)] This indicates the source pattern expects the instruction would produce 2 values. The first is the result of the addition. The second is an implicit definition in register EFLAGS. 2. def : Pat<(parallel (addc GR32:$src1, GR32:$src2), (modify EFLAGS)), ()> Similar to #1 except this is used for def : Pat patterns. llvm-svn: 41897
1 parent 3aa4efb commit 59c39dc

File tree

3 files changed

+102
-57
lines changed

3 files changed

+102
-57
lines changed

llvm/lib/Target/TargetSelectionDAG.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ class SDNode<string opcode, SDTypeProfile typeprof,
197197
}
198198

199199
def set;
200+
def modify;
201+
def parallel;
200202
def node;
201203
def srcvalue;
202204

llvm/utils/TableGen/DAGISelEmitter.cpp

Lines changed: 95 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,13 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
691691
MadeChange |= UpdateNodeType(MVT::isVoid, TP);
692692
}
693693
return MadeChange;
694+
} else if (getOperator()->getName() == "modify" ||
695+
getOperator()->getName() == "parallel") {
696+
bool MadeChange = false;
697+
for (unsigned i = 0; i < getNumChildren(); ++i)
698+
MadeChange = getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
699+
MadeChange |= UpdateNodeType(MVT::isVoid, TP);
700+
return MadeChange;
694701
} else if (getOperator() == ISE.get_intrinsic_void_sdnode() ||
695702
getOperator() == ISE.get_intrinsic_w_chain_sdnode() ||
696703
getOperator() == ISE.get_intrinsic_wo_chain_sdnode()) {
@@ -968,7 +975,9 @@ TreePatternNode *TreePattern::ParseTreePattern(DagInit *Dag) {
968975
!Operator->isSubClassOf("Instruction") &&
969976
!Operator->isSubClassOf("SDNodeXForm") &&
970977
!Operator->isSubClassOf("Intrinsic") &&
971-
Operator->getName() != "set")
978+
Operator->getName() != "set" &&
979+
Operator->getName() != "modify" &&
980+
Operator->getName() != "parallel")
972981
error("Unrecognized node '" + Operator->getName() + "'!");
973982

974983
// Check to see if this is something that is illegal in an input pattern.
@@ -1376,6 +1385,18 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
13761385
if (!isUse && Pat->getTransformFn())
13771386
I->error("Cannot specify a transform function for a non-input value!");
13781387
return;
1388+
} else if (Pat->getOperator()->getName() == "modify") {
1389+
for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) {
1390+
TreePatternNode *Dest = Pat->getChild(i);
1391+
if (!Dest->isLeaf())
1392+
I->error("modify value should be a register!");
1393+
1394+
DefInit *Val = dynamic_cast<DefInit*>(Dest->getLeafValue());
1395+
if (!Val || !Val->getDef()->isSubClassOf("Register"))
1396+
I->error("modify value should be a register!");
1397+
InstImpResults.push_back(Val->getDef());
1398+
}
1399+
return;
13791400
} else if (Pat->getOperator()->getName() != "set") {
13801401
// If this is not a set, verify that the children nodes are not void typed,
13811402
// and recurse.
@@ -1424,7 +1445,6 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
14241445
InstResults[Dest->getName()] = Dest;
14251446
} else if (Val->getDef()->isSubClassOf("Register")) {
14261447
InstImpResults.push_back(Val->getDef());
1427-
;
14281448
} else {
14291449
I->error("set destination should be a register!");
14301450
}
@@ -1621,6 +1641,8 @@ void DAGISelEmitter::ParseInstructions() {
16211641
ResultPattern->setTypes(Res0Node->getExtTypes());
16221642

16231643
// Create and insert the instruction.
1644+
// FIXME: InstImpResults and InstImpInputs should not be part of
1645+
// DAGInstruction.
16241646
DAGInstruction TheInst(I, Results, Operands, InstImpResults, InstImpInputs);
16251647
Instructions.insert(std::make_pair(I->getRecord(), TheInst));
16261648

@@ -1643,10 +1665,8 @@ void DAGISelEmitter::ParseInstructions() {
16431665
TreePattern *I = TheInst.getPattern();
16441666
if (I == 0) continue; // No pattern.
16451667

1646-
if (I->getNumTrees() != 1) {
1647-
cerr << "CANNOT HANDLE: " << I->getRecord()->getName() << " yet!";
1648-
continue;
1649-
}
1668+
// FIXME: Assume only the first tree is the pattern. The others are clobber
1669+
// nodes.
16501670
TreePatternNode *Pattern = I->getTree(0);
16511671
TreePatternNode *SrcPattern;
16521672
if (Pattern->getOperator()->getName() == "set") {
@@ -1664,7 +1684,7 @@ void DAGISelEmitter::ParseInstructions() {
16641684
TreePatternNode *DstPattern = TheInst.getResultPattern();
16651685
PatternsToMatch.
16661686
push_back(PatternToMatch(Instr->getValueAsListInit("Predicates"),
1667-
SrcPattern, DstPattern,
1687+
SrcPattern, DstPattern, TheInst.getImpResults(),
16681688
Instr->getValueAsInt("AddedComplexity")));
16691689
}
16701690
}
@@ -1674,7 +1694,18 @@ void DAGISelEmitter::ParsePatterns() {
16741694

16751695
for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
16761696
DagInit *Tree = Patterns[i]->getValueAsDag("PatternToMatch");
1677-
TreePattern *Pattern = new TreePattern(Patterns[i], Tree, true, *this);
1697+
DefInit *OpDef = dynamic_cast<DefInit*>(Tree->getOperator());
1698+
Record *Operator = OpDef->getDef();
1699+
TreePattern *Pattern;
1700+
if (Operator->getName() != "parallel")
1701+
Pattern = new TreePattern(Patterns[i], Tree, true, *this);
1702+
else {
1703+
std::vector<Init*> Values;
1704+
for (unsigned j = 0, ee = Tree->getNumArgs(); j != ee; ++j)
1705+
Values.push_back(Tree->getArg(j));
1706+
ListInit *LI = new ListInit(Values);
1707+
Pattern = new TreePattern(Patterns[i], LI, true, *this);
1708+
}
16781709

16791710
// Inline pattern fragments into it.
16801711
Pattern->InlinePatternFragments();
@@ -1707,10 +1738,10 @@ void DAGISelEmitter::ParsePatterns() {
17071738
// resolve cases where the input type is known to be a pointer type (which
17081739
// is considered resolved), but the result knows it needs to be 32- or
17091740
// 64-bits. Infer the other way for good measure.
1710-
IterateInference = Pattern->getOnlyTree()->
1711-
UpdateNodeType(Result->getOnlyTree()->getExtTypes(), *Result);
1712-
IterateInference |= Result->getOnlyTree()->
1713-
UpdateNodeType(Pattern->getOnlyTree()->getExtTypes(), *Result);
1741+
IterateInference = Pattern->getTree(0)->
1742+
UpdateNodeType(Result->getTree(0)->getExtTypes(), *Result);
1743+
IterateInference |= Result->getTree(0)->
1744+
UpdateNodeType(Pattern->getTree(0)->getExtTypes(), *Result);
17141745
} while (IterateInference);
17151746

17161747
// Verify that we inferred enough types that we can do something with the
@@ -1721,19 +1752,18 @@ void DAGISelEmitter::ParsePatterns() {
17211752
Result->error("Could not infer all types in pattern result!");
17221753

17231754
// Validate that the input pattern is correct.
1724-
{
1725-
std::map<std::string, TreePatternNode*> InstInputs;
1726-
std::map<std::string, TreePatternNode*> InstResults;
1727-
std::vector<Record*> InstImpInputs;
1728-
std::vector<Record*> InstImpResults;
1729-
FindPatternInputsAndOutputs(Pattern, Pattern->getOnlyTree(),
1755+
std::map<std::string, TreePatternNode*> InstInputs;
1756+
std::map<std::string, TreePatternNode*> InstResults;
1757+
std::vector<Record*> InstImpInputs;
1758+
std::vector<Record*> InstImpResults;
1759+
for (unsigned j = 0, ee = Pattern->getNumTrees(); j != ee; ++j)
1760+
FindPatternInputsAndOutputs(Pattern, Pattern->getTree(j),
17301761
InstInputs, InstResults,
17311762
InstImpInputs, InstImpResults);
1732-
}
17331763

17341764
// Promote the xform function to be an explicit node if set.
1735-
std::vector<TreePatternNode*> ResultNodeOperands;
17361765
TreePatternNode *DstPattern = Result->getOnlyTree();
1766+
std::vector<TreePatternNode*> ResultNodeOperands;
17371767
for (unsigned ii = 0, ee = DstPattern->getNumChildren(); ii != ee; ++ii) {
17381768
TreePatternNode *OpNode = DstPattern->getChild(ii);
17391769
if (Record *Xform = OpNode->getTransformFn()) {
@@ -1753,13 +1783,13 @@ void DAGISelEmitter::ParsePatterns() {
17531783
Temp.InferAllTypes();
17541784

17551785
std::string Reason;
1756-
if (!Pattern->getOnlyTree()->canPatternMatch(Reason, *this))
1786+
if (!Pattern->getTree(0)->canPatternMatch(Reason, *this))
17571787
Pattern->error("Pattern can never match: " + Reason);
17581788

17591789
PatternsToMatch.
17601790
push_back(PatternToMatch(Patterns[i]->getValueAsListInit("Predicates"),
1761-
Pattern->getOnlyTree(),
1762-
Temp.getOnlyTree(),
1791+
Pattern->getTree(0),
1792+
Temp.getOnlyTree(), InstImpResults,
17631793
Patterns[i]->getValueAsInt("AddedComplexity")));
17641794
}
17651795
}
@@ -2017,6 +2047,7 @@ void DAGISelEmitter::GenerateVariants() {
20172047
PatternsToMatch.
20182048
push_back(PatternToMatch(PatternsToMatch[i].getPredicates(),
20192049
Variant, PatternsToMatch[i].getDstPattern(),
2050+
PatternsToMatch[i].getDstRegs(),
20202051
PatternsToMatch[i].getAddedComplexity()));
20212052
}
20222053

@@ -2617,7 +2648,8 @@ class PatternCodeEmitter {
26172648
/// EmitResultCode - Emit the action for a pattern. Now that it has matched
26182649
/// we actually have to build a DAG!
26192650
std::vector<std::string>
2620-
EmitResultCode(TreePatternNode *N, bool RetSelected,
2651+
EmitResultCode(TreePatternNode *N, std::vector<Record*> DstRegs,
2652+
bool RetSelected,
26212653
bool InFlagDecled, bool ResNodeDecled,
26222654
bool LikeLeaf = false, bool isRoot = false) {
26232655
// List of arguments of getTargetNode() or SelectNodeTo().
@@ -2758,15 +2790,17 @@ class PatternCodeEmitter {
27582790
CodeGenInstruction &II = CGT.getInstruction(Op->getName());
27592791
const DAGInstruction &Inst = ISE.getInstruction(Op);
27602792
TreePattern *InstPat = Inst.getPattern();
2793+
// FIXME: Assume actual pattern comes before "modify".
27612794
TreePatternNode *InstPatNode =
2762-
isRoot ? (InstPat ? InstPat->getOnlyTree() : Pattern)
2763-
: (InstPat ? InstPat->getOnlyTree() : NULL);
2795+
isRoot ? (InstPat ? InstPat->getTree(0) : Pattern)
2796+
: (InstPat ? InstPat->getTree(0) : NULL);
27642797
if (InstPatNode && InstPatNode->getOperator()->getName() == "set") {
27652798
InstPatNode = InstPatNode->getChild(InstPatNode->getNumChildren()-1);
27662799
}
27672800
bool HasVarOps = isRoot && II.hasVariableNumberOfOperands;
2801+
// FIXME: fix how we deal with physical register operands.
27682802
bool HasImpInputs = isRoot && Inst.getNumImpOperands() > 0;
2769-
bool HasImpResults = isRoot && Inst.getNumImpResults() > 0;
2803+
bool HasImpResults = isRoot && DstRegs.size() > 0;
27702804
bool NodeHasOptInFlag = isRoot &&
27712805
PatternHasProperty(Pattern, SDNPOptInFlag, ISE);
27722806
bool NodeHasInFlag = isRoot &&
@@ -2778,6 +2812,7 @@ class PatternCodeEmitter {
27782812
bool InputHasChain = isRoot &&
27792813
NodeHasProperty(Pattern, SDNPHasChain, ISE);
27802814
unsigned NumResults = Inst.getNumResults();
2815+
unsigned NumDstRegs = HasImpResults ? DstRegs.size() : 0;
27812816

27822817
if (NodeHasOptInFlag) {
27832818
emitCode("bool HasInFlag = "
@@ -2787,11 +2822,11 @@ class PatternCodeEmitter {
27872822
emitCode("SmallVector<SDOperand, 8> Ops" + utostr(OpcNo) + ";");
27882823

27892824
// How many results is this pattern expected to produce?
2790-
unsigned PatResults = 0;
2825+
unsigned NumPatResults = 0;
27912826
for (unsigned i = 0, e = Pattern->getExtTypes().size(); i != e; i++) {
27922827
MVT::ValueType VT = Pattern->getTypeNum(i);
27932828
if (VT != MVT::isVoid && VT != MVT::Flag)
2794-
PatResults++;
2829+
NumPatResults++;
27952830
}
27962831

27972832
if (OrigChains.size() > 0) {
@@ -2832,7 +2867,7 @@ class PatternCodeEmitter {
28322867
if ((!OperandNode->isSubClassOf("PredicateOperand") &&
28332868
!OperandNode->isSubClassOf("OptionalDefOperand")) ||
28342869
ISE.getDefaultOperand(OperandNode).DefaultOps.empty()) {
2835-
Ops = EmitResultCode(N->getChild(ChildNo), RetSelected,
2870+
Ops = EmitResultCode(N->getChild(ChildNo), DstRegs, RetSelected,
28362871
InFlagDecled, ResNodeDecled);
28372872
AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
28382873
++ChildNo;
@@ -2842,7 +2877,7 @@ class PatternCodeEmitter {
28422877
const DAGDefaultOperand &DefaultOp =
28432878
ISE.getDefaultOperand(II.OperandList[InstOpNo].Rec);
28442879
for (unsigned i = 0, e = DefaultOp.DefaultOps.size(); i != e; ++i) {
2845-
Ops = EmitResultCode(DefaultOp.DefaultOps[i], RetSelected,
2880+
Ops = EmitResultCode(DefaultOp.DefaultOps[i], DstRegs, RetSelected,
28462881
InFlagDecled, ResNodeDecled);
28472882
AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
28482883
NumEAInputs += Ops.size();
@@ -2888,7 +2923,7 @@ class PatternCodeEmitter {
28882923
Code2 = NodeName + " = ";
28892924
}
28902925

2891-
Code = "CurDAG->getTargetNode(Opc" + utostr(OpcNo);
2926+
Code += "CurDAG->getTargetNode(Opc" + utostr(OpcNo);
28922927
unsigned OpsNo = OpcNo;
28932928
emitOpcode(II.Namespace + "::" + II.TheDef->getName());
28942929

@@ -2900,14 +2935,11 @@ class PatternCodeEmitter {
29002935
}
29012936
// Add types for implicit results in physical registers, scheduler will
29022937
// care of adding copyfromreg nodes.
2903-
if (HasImpResults) {
2904-
for (unsigned i = 0, e = Inst.getNumImpResults(); i < e; i++) {
2905-
Record *RR = Inst.getImpResult(i);
2906-
if (RR->isSubClassOf("Register")) {
2907-
MVT::ValueType RVT = getRegisterValueType(RR, CGT);
2908-
Code += ", " + getEnumName(RVT);
2909-
++NumResults;
2910-
}
2938+
for (unsigned i = 0; i < NumDstRegs; i++) {
2939+
Record *RR = DstRegs[i];
2940+
if (RR->isSubClassOf("Register")) {
2941+
MVT::ValueType RVT = getRegisterValueType(RR, CGT);
2942+
Code += ", " + getEnumName(RVT);
29112943
}
29122944
}
29132945
if (NodeHasChain)
@@ -2961,7 +2993,7 @@ class PatternCodeEmitter {
29612993
Code += ", &Ops" + utostr(OpsNo) + "[0], Ops" + utostr(OpsNo) +
29622994
".size()";
29632995
} else if (NodeHasInFlag || NodeHasOptInFlag || HasImpInputs)
2964-
AllOps.push_back("InFlag");
2996+
AllOps.push_back("InFlag");
29652997

29662998
unsigned NumOps = AllOps.size();
29672999
if (NumOps) {
@@ -2993,10 +3025,10 @@ class PatternCodeEmitter {
29933025
// Remember which op produces the chain.
29943026
if (!isRoot)
29953027
emitCode(ChainName + " = SDOperand(" + NodeName +
2996-
".Val, " + utostr(PatResults) + ");");
3028+
".Val, " + utostr(NumResults+NumDstRegs) + ");");
29973029
else
29983030
emitCode(ChainName + " = SDOperand(" + NodeName +
2999-
", " + utostr(PatResults) + ");");
3031+
", " + utostr(NumResults+NumDstRegs) + ");");
30003032

30013033
if (!isRoot) {
30023034
NodeOps.push_back("Tmp" + utostr(ResNo));
@@ -3007,11 +3039,11 @@ class PatternCodeEmitter {
30073039
if (NodeHasOutFlag) {
30083040
if (!InFlagDecled) {
30093041
emitCode("SDOperand InFlag(ResNode, " +
3010-
utostr(NumResults + (unsigned)NodeHasChain) + ");");
3042+
utostr(NumResults+NumDstRegs+(unsigned)NodeHasChain) + ");");
30113043
InFlagDecled = true;
30123044
} else
30133045
emitCode("InFlag = SDOperand(ResNode, " +
3014-
utostr(NumResults + (unsigned)NodeHasChain) + ");");
3046+
utostr(NumResults+NumDstRegs+(unsigned)NodeHasChain) + ");");
30153047
}
30163048

30173049
if (FoldedChains.size() > 0) {
@@ -3020,23 +3052,23 @@ class PatternCodeEmitter {
30203052
emitCode("ReplaceUses(SDOperand(" +
30213053
FoldedChains[j].first + ".Val, " +
30223054
utostr(FoldedChains[j].second) + "), SDOperand(ResNode, " +
3023-
utostr(NumResults) + "));");
3055+
utostr(NumResults+NumDstRegs) + "));");
30243056
NeedReplace = true;
30253057
}
30263058

30273059
if (NodeHasOutFlag) {
30283060
emitCode("ReplaceUses(SDOperand(N.Val, " +
3029-
utostr(PatResults + (unsigned)InputHasChain) +"), InFlag);");
3061+
utostr(NumPatResults + (unsigned)InputHasChain) +"), InFlag);");
30303062
NeedReplace = true;
30313063
}
30323064

30333065
if (NeedReplace) {
3034-
for (unsigned i = 0; i < NumResults; i++)
3066+
for (unsigned i = 0; i < NumPatResults; i++)
30353067
emitCode("ReplaceUses(SDOperand(N.Val, " +
30363068
utostr(i) + "), SDOperand(ResNode, " + utostr(i) + "));");
30373069
if (InputHasChain)
30383070
emitCode("ReplaceUses(SDOperand(N.Val, " +
3039-
utostr(PatResults) + "), SDOperand(" + ChainName + ".Val, "
3071+
utostr(NumPatResults) + "), SDOperand(" + ChainName + ".Val, "
30403072
+ ChainName + ".ResNo" + "));");
30413073
} else
30423074
RetSelected = true;
@@ -3047,12 +3079,12 @@ class PatternCodeEmitter {
30473079
} else if (InputHasChain && !NodeHasChain) {
30483080
// One of the inner node produces a chain.
30493081
if (NodeHasOutFlag)
3050-
emitCode("ReplaceUses(SDOperand(N.Val, " + utostr(PatResults+1) +
3082+
emitCode("ReplaceUses(SDOperand(N.Val, " + utostr(NumPatResults+1) +
30513083
"), SDOperand(ResNode, N.ResNo-1));");
3052-
for (unsigned i = 0; i < PatResults; ++i)
3084+
for (unsigned i = 0; i < NumPatResults; ++i)
30533085
emitCode("ReplaceUses(SDOperand(N.Val, " + utostr(i) +
30543086
"), SDOperand(ResNode, " + utostr(i) + "));");
3055-
emitCode("ReplaceUses(SDOperand(N.Val, " + utostr(PatResults) +
3087+
emitCode("ReplaceUses(SDOperand(N.Val, " + utostr(NumPatResults) +
30563088
"), " + ChainName + ");");
30573089
RetSelected = false;
30583090
}
@@ -3101,7 +3133,7 @@ class PatternCodeEmitter {
31013133
// PatLeaf node - the operand may or may not be a leaf node. But it should
31023134
// behave like one.
31033135
std::vector<std::string> Ops =
3104-
EmitResultCode(N->getChild(0), RetSelected, InFlagDecled,
3136+
EmitResultCode(N->getChild(0), DstRegs, RetSelected, InFlagDecled,
31053137
ResNodeDecled, true);
31063138
unsigned ResNo = TmpNo++;
31073139
emitCode("SDOperand Tmp" + utostr(ResNo) + " = Transform_" + Op->getName()
@@ -3267,7 +3299,7 @@ void DAGISelEmitter::GenerateCodeForPattern(PatternToMatch &Pattern,
32673299
// otherwise we are done.
32683300
} while (Emitter.InsertOneTypeCheck(Pat, Pattern.getSrcPattern(), "N", true));
32693301

3270-
Emitter.EmitResultCode(Pattern.getDstPattern(),
3302+
Emitter.EmitResultCode(Pattern.getDstPattern(), Pattern.getDstRegs(),
32713303
false, false, false, false, true);
32723304
delete Pat;
32733305
}
@@ -3924,8 +3956,15 @@ OS << " unsigned NumKilled = ISelKilled.size();\n";
39243956
OS << " setSelected(F.Val->getNodeId());\n";
39253957
OS << " RemoveKilled();\n";
39263958
OS << "}\n";
3927-
OS << "inline void ReplaceUses(SDNode *F, SDNode *T) {\n";
3928-
OS << " CurDAG->ReplaceAllUsesWith(F, T, &ISelKilled);\n";
3959+
OS << "void ReplaceUses(SDNode *F, SDNode *T) DISABLE_INLINE {\n";
3960+
OS << " unsigned NumVals = F->getNumValues();\n";
3961+
OS << " if (NumVals < T->getNumValues()) {\n";
3962+
OS << " for (unsigned i = 0; i < NumVals; ++i)\n";
3963+
OS << " CurDAG->ReplaceAllUsesOfValueWith(SDOperand(F, i), "
3964+
<< "SDOperand(T, i), ISelKilled);\n";
3965+
OS << " } else {\n";
3966+
OS << " CurDAG->ReplaceAllUsesWith(F, T, &ISelKilled);\n";
3967+
OS << " }\n";
39293968
OS << " setSelected(F->getNodeId());\n";
39303969
OS << " RemoveKilled();\n";
39313970
OS << "}\n\n";

0 commit comments

Comments
 (0)