summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/Target.td6
-rw-r--r--lib/Target/TargetSelectionDAG.td3
-rw-r--r--lib/Target/X86/X86InstrInfo.td4
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp2
-rw-r--r--utils/TableGen/CodeGenInstruction.cpp3
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp81
-rw-r--r--utils/TableGen/DAGISelEmitter.h4
-rw-r--r--utils/TableGen/InstrInfoEmitter.cpp12
8 files changed, 59 insertions, 56 deletions
diff --git a/lib/Target/Target.td b/lib/Target/Target.td
index 92c40570af..a268e16410 100644
--- a/lib/Target/Target.td
+++ b/lib/Target/Target.td
@@ -259,12 +259,6 @@ def ins;
/// of operands.
def variable_ops;
-/// discard definition - Mark this operand as being matched in the input
-/// but omitted from the output. This is necessary in some situations
-/// involving variable_ops to help the pattern matcher determine which
-/// input nodes to forward on to the variable_ops portion of the output.
-def discard;
-
/// ptr_rc definition - Mark this operand as being a pointer value whose
/// register class is resolved dynamically via a callback to TargetInstrInfo.
/// FIXME: We should probably change this to a class which contain a list of
diff --git a/lib/Target/TargetSelectionDAG.td b/lib/Target/TargetSelectionDAG.td
index 9def220337..474f910026 100644
--- a/lib/Target/TargetSelectionDAG.td
+++ b/lib/Target/TargetSelectionDAG.td
@@ -62,7 +62,7 @@ class SDTCisIntVectorOfSameSize<int ThisOp, int OtherOp>
/// SDTCisEltOfVec - This indicates that ThisOp is a scalar type of the same
/// type as the element type of OtherOp, which is a vector type.
-class SDTCisEltOfVec<int ThisOp, int OtherOp>
+class SDTCisEltOfVec<int ThisOp, int OtherOp>
: SDTypeConstraint<ThisOp> {
int OtherOpNum = OtherOp;
}
@@ -470,7 +470,6 @@ class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm>
def vtInt : PatLeaf<(vt), [{ return MVT::isInteger(N->getVT()); }]>;
def vtFP : PatLeaf<(vt), [{ return MVT::isFloatingPoint(N->getVT()); }]>;
-def immAllZeros : PatLeaf<(imm), [{ return N->isNullValue(); }]>;
def immAllOnes : PatLeaf<(imm), [{ return N->isAllOnesValue(); }]>;
def immAllOnesV: PatLeaf<(build_vector), [{
return ISD::isBuildVectorAllOnes(N);
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 4ffc303c37..4b8dc100b9 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -322,9 +322,9 @@ let neverHasSideEffects = 1, isNotDuplicable = 1 in
// Return instructions.
let isTerminator = 1, isReturn = 1, isBarrier = 1,
hasCtrlDep = 1, FPForm = SpecialFP, FPFormBits = SpecialFP.Value in {
- def RET : I <0xC3, RawFrm, (outs), (ins discard:$amt, variable_ops),
+ def RET : I <0xC3, RawFrm, (outs), (ins variable_ops),
"ret",
- [(X86retflag immAllZeros:$amt)]>;
+ [(X86retflag 0)]>;
def RETI : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt, variable_ops),
"ret\t$amt",
[(X86retflag imm:$amt)]>;
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 006c067e8f..8c46b35fa1 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -916,8 +916,6 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
MadeChange |= Child->UpdateNodeType(MVT::iPTR, TP);
} else if (OperandNode->getName() == "unknown") {
MadeChange |= Child->UpdateNodeType(MVT::isUnknown, TP);
- } else if (OperandNode->getName() == "discard") {
- MadeChange |= Child->UpdateNodeType(MVT::isUnknown, TP);
} else {
assert(0 && "Unknown operand type!");
abort();
diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp
index d52037823f..37c2069ec7 100644
--- a/utils/TableGen/CodeGenInstruction.cpp
+++ b/utils/TableGen/CodeGenInstruction.cpp
@@ -163,8 +163,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
isVariadic = true;
continue;
} else if (!Rec->isSubClassOf("RegisterClass") &&
- Rec->getName() != "ptr_rc" && Rec->getName() != "unknown" &&
- Rec->getName() != "discard")
+ Rec->getName() != "ptr_rc" && Rec->getName() != "unknown")
throw "Unknown operand class '" + Rec->getName() +
"' in instruction '" + R->getName() + "' instruction!";
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index cf8c6272ba..29fec09515 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -331,6 +331,15 @@ private:
/// instructions.
std::vector<std::string> &TargetOpcodes;
std::vector<std::string> &TargetVTs;
+ /// OutputIsVariadic - Records whether the instruction output pattern uses
+ /// variable_ops. This requires that the Emit function be passed an
+ /// additional argument to indicate where the input varargs operands
+ /// begin.
+ bool &OutputIsVariadic;
+ /// NumInputRootOps - Records the number of operands the root node of the
+ /// input pattern has. This information is used in the generated code to
+ /// pass to Emit functions when variable_ops processing is needed.
+ unsigned &NumInputRootOps;
std::string ChainName;
unsigned TmpNo;
@@ -367,10 +376,13 @@ public:
std::vector<std::pair<unsigned, std::string> > &gc,
std::set<std::string> &gd,
std::vector<std::string> &to,
- std::vector<std::string> &tv)
+ std::vector<std::string> &tv,
+ bool &oiv,
+ unsigned &niro)
: CGP(cgp), Predicates(preds), Pattern(pattern), Instruction(instr),
GeneratedCode(gc), GeneratedDecl(gd),
TargetOpcodes(to), TargetVTs(tv),
+ OutputIsVariadic(oiv), NumInputRootOps(niro),
TmpNo(0), OpcNo(0), VTNo(0) {}
/// EmitMatchCode - Emit a matcher for N, going to the label for PatternNo
@@ -392,6 +404,9 @@ public:
bool isRoot = (P == NULL);
// Emit instruction predicates. Each predicate is just a string for now.
if (isRoot) {
+ // Record input varargs info.
+ NumInputRootOps = N->getNumChildren();
+
std::string PredicateCheck;
for (unsigned i = 0, e = Predicates->getSize(); i != e; ++i) {
if (DefInit *Pred = dynamic_cast<DefInit*>(Predicates->getElement(i))) {
@@ -887,7 +902,7 @@ public:
if (InstPatNode && InstPatNode->getOperator()->getName() == "set") {
InstPatNode = InstPatNode->getChild(InstPatNode->getNumChildren()-1);
}
- bool HasVarOps = isRoot && II.isVariadic;
+ bool IsVariadic = isRoot && II.isVariadic;
// FIXME: fix how we deal with physical register operands.
bool HasImpInputs = isRoot && Inst.getNumImpOperands() > 0;
bool HasImpResults = isRoot && DstRegs.size() > 0;
@@ -904,11 +919,14 @@ public:
unsigned NumResults = Inst.getNumResults();
unsigned NumDstRegs = HasImpResults ? DstRegs.size() : 0;
+ // Record output varargs info.
+ OutputIsVariadic = IsVariadic;
+
if (NodeHasOptInFlag) {
emitCode("bool HasInFlag = "
"(N.getOperand(N.getNumOperands()-1).getValueType() == MVT::Flag);");
}
- if (HasVarOps)
+ if (IsVariadic)
emitCode("SmallVector<SDOperand, 8> Ops" + utostr(OpcNo) + ";");
// How many results is this pattern expected to produce?
@@ -946,20 +964,15 @@ public:
// in the 'execute always' values. Match up the node operands to the
// instruction operands to do this.
std::vector<std::string> AllOps;
- unsigned NumEAInputs = 0; // # of synthesized 'execute always' inputs.
- unsigned InputIndex = 0;
for (unsigned ChildNo = 0, InstOpNo = NumResults;
InstOpNo != II.OperandList.size(); ++InstOpNo) {
std::vector<std::string> Ops;
// Determine what to emit for this operand.
Record *OperandNode = II.OperandList[InstOpNo].Rec;
- if (OperandNode->getName() == "discard") {
- // This is a "discard" operand; emit nothing. Just note it.
- ++InputIndex;
- } else if ((OperandNode->isSubClassOf("PredicateOperand") ||
- OperandNode->isSubClassOf("OptionalDefOperand")) &&
- !CGP.getDefaultOperand(OperandNode).DefaultOps.empty()) {
+ if ((OperandNode->isSubClassOf("PredicateOperand") ||
+ OperandNode->isSubClassOf("OptionalDefOperand")) &&
+ !CGP.getDefaultOperand(OperandNode).DefaultOps.empty()) {
// This is a predicate or optional def operand; emit the
// 'default ops' operands.
const DAGDefaultOperand &DefaultOp =
@@ -968,9 +981,7 @@ public:
Ops = EmitResultCode(DefaultOp.DefaultOps[i], DstRegs,
InFlagDecled, ResNodeDecled);
AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
- NumEAInputs += Ops.size();
}
- ++InputIndex;
} else {
// Otherwise this is a normal operand or a predicate operand without
// 'execute always'; emit it.
@@ -978,7 +989,6 @@ public:
InFlagDecled, ResNodeDecled);
AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
++ChildNo;
- ++InputIndex;
}
}
@@ -1057,15 +1067,7 @@ public:
Code += ", MVT::Flag";
// Inputs.
- if (HasVarOps) {
- // Figure out how many fixed inputs the node has. This is important
- // to know which inputs are the variable ones if present. Include
- // the 'discard' and chain inputs in the count, and adjust for the
- // number of operands that are 'execute always'. This is the index
- // where we should start copying operands into the 'variable_ops'
- // portion of the output.
- InputIndex += NodeHasChain - NumEAInputs;
-
+ if (IsVariadic) {
for (unsigned i = 0, e = AllOps.size(); i != e; ++i)
emitCode("Ops" + utostr(OpsNo) + ".push_back(" + AllOps[i] + ");");
AllOps.clear();
@@ -1078,7 +1080,7 @@ public:
else if (NodeHasOptInFlag)
EndAdjust = "-(HasInFlag?1:0)"; // May have a flag.
- emitCode("for (unsigned i = " + utostr(InputIndex) +
+ emitCode("for (unsigned i = NumInputRootOps + " + utostr(NodeHasChain) +
", e = N.getNumOperands()" + EndAdjust + "; i != e; ++i) {");
emitCode(" AddToISelQueue(N.getOperand(i));");
@@ -1087,13 +1089,13 @@ public:
}
if (NodeHasChain) {
- if (HasVarOps)
+ if (IsVariadic)
emitCode("Ops" + utostr(OpsNo) + ".push_back(" + ChainName + ");");
else
AllOps.push_back(ChainName);
}
- if (HasVarOps) {
+ if (IsVariadic) {
if (NodeHasInFlag || HasImpInputs)
emitCode("Ops" + utostr(OpsNo) + ".push_back(InFlag);");
else if (NodeHasOptInFlag) {
@@ -1358,11 +1360,17 @@ void DAGISelEmitter::GenerateCodeForPattern(const PatternToMatch &Pattern,
std::vector<std::pair<unsigned, std::string> > &GeneratedCode,
std::set<std::string> &GeneratedDecl,
std::vector<std::string> &TargetOpcodes,
- std::vector<std::string> &TargetVTs) {
+ std::vector<std::string> &TargetVTs,
+ bool &OutputIsVariadic,
+ unsigned &NumInputRootOps) {
+ OutputIsVariadic = false;
+ NumInputRootOps = 0;
+
PatternCodeEmitter Emitter(CGP, Pattern.getPredicates(),
Pattern.getSrcPattern(), Pattern.getDstPattern(),
GeneratedCode, GeneratedDecl,
- TargetOpcodes, TargetVTs);
+ TargetOpcodes, TargetVTs,
+ OutputIsVariadic, NumInputRootOps);
// Emit the matcher, capturing named arguments in VariableMap.
bool FoundChain = false;
@@ -1652,17 +1660,24 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
std::vector<std::vector<std::string> > PatternOpcodes;
std::vector<std::vector<std::string> > PatternVTs;
std::vector<std::set<std::string> > PatternDecls;
+ std::vector<bool> OutputIsVariadicFlags;
+ std::vector<unsigned> NumInputRootOpsCounts;
for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
CodeList GeneratedCode;
std::set<std::string> GeneratedDecl;
std::vector<std::string> TargetOpcodes;
std::vector<std::string> TargetVTs;
+ bool OutputIsVariadic;
+ unsigned NumInputRootOps;
GenerateCodeForPattern(*Patterns[i], GeneratedCode, GeneratedDecl,
- TargetOpcodes, TargetVTs);
+ TargetOpcodes, TargetVTs,
+ OutputIsVariadic, NumInputRootOps);
CodeForPatterns.push_back(std::make_pair(Patterns[i], GeneratedCode));
PatternDecls.push_back(GeneratedDecl);
PatternOpcodes.push_back(TargetOpcodes);
PatternVTs.push_back(TargetVTs);
+ OutputIsVariadicFlags.push_back(OutputIsVariadic);
+ NumInputRootOpsCounts.push_back(NumInputRootOps);
}
// Scan the code to see if all of the patterns are reachable and if it is
@@ -1697,6 +1712,8 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
std::vector<std::string> &TargetOpcodes = PatternOpcodes[i];
std::vector<std::string> &TargetVTs = PatternVTs[i];
std::set<std::string> Decls = PatternDecls[i];
+ bool OutputIsVariadic = OutputIsVariadicFlags[i];
+ unsigned NumInputRootOps = NumInputRootOpsCounts[i];
std::vector<std::string> AddedInits;
int CodeSize = (int)GeneratedCode.size();
int LastPred = -1;
@@ -1723,6 +1740,12 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
CalleeCode += ", SDOperand &" + Name;
CallerCode += ", " + Name;
}
+
+ if (OutputIsVariadic) {
+ CalleeCode += ", unsigned NumInputRootOps";
+ CallerCode += ", " + utostr(NumInputRootOps);
+ }
+
CallerCode += ");";
CalleeCode += ") ";
// Prevent emission routines from being inlined to reduce selection
diff --git a/utils/TableGen/DAGISelEmitter.h b/utils/TableGen/DAGISelEmitter.h
index 1b47bcc156..2f626f6b86 100644
--- a/utils/TableGen/DAGISelEmitter.h
+++ b/utils/TableGen/DAGISelEmitter.h
@@ -41,7 +41,9 @@ private:
std::vector<std::pair<unsigned, std::string> > &GeneratedCode,
std::set<std::string> &GeneratedDecl,
std::vector<std::string> &TargetOpcodes,
- std::vector<std::string> &TargetVTs);
+ std::vector<std::string> &TargetVTs,
+ bool &OutputIsVariadic,
+ unsigned &NumInputRootOps);
void EmitPatterns(std::vector<std::pair<const PatternToMatch*,
std::vector<std::pair<unsigned, std::string> > > > &Patterns,
unsigned Indent, std::ostream &OS);
diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp
index 8390c90660..fb8dd371ef 100644
--- a/utils/TableGen/InstrInfoEmitter.cpp
+++ b/utils/TableGen/InstrInfoEmitter.cpp
@@ -85,10 +85,6 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
Record *OpR = OperandList[j].Rec;
std::string Res;
- // Discard "discard" operands.
- if (OpR->getName() == "discard")
- continue;
-
if (OpR->isSubClassOf("RegisterClass"))
Res += getQualifiedName(OpR) + "RegClassID, ";
else
@@ -206,14 +202,6 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
MinOperands = Inst.OperandList.back().MIOperandNo +
Inst.OperandList.back().MINumOperands;
- // Subtract the number of "discard" operands, which we'll be skipping
- // when emitting OperandInfo records.
- for (unsigned j = 0, e = Inst.OperandList.size(); j != e; ++j) {
- Record *OpR = Inst.OperandList[j].Rec;
- if (OpR->getName() == "discard")
- --MinOperands;
- }
-
OS << " { ";
OS << Num << ",\t" << MinOperands << ",\t"
<< Inst.NumDefs << ",\t" << getItinClassNumber(Inst.TheDef)