diff --git a/lib/Target/Target.td b/lib/Target/Target.td index 92c40570af3..a268e164107 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 9def220337f..474f9100263 100644 --- a/lib/Target/TargetSelectionDAG.td +++ b/lib/Target/TargetSelectionDAG.td @@ -62,7 +62,7 @@ class SDTCisIntVectorOfSameSize /// 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 +class SDTCisEltOfVec : SDTypeConstraint { int OtherOpNum = OtherOp; } @@ -470,7 +470,6 @@ class PatLeaf 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 4ffc303c372..4b8dc100b9e 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 006c067e8fd..8c46b35fa19 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 d52037823f6..37c2069ec72 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 cf8c6272bac..29fec09515f 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -331,6 +331,15 @@ private: /// instructions. std::vector &TargetOpcodes; std::vector &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 > &gc, std::set &gd, std::vector &to, - std::vector &tv) + std::vector &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(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 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 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 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 > &GeneratedCode, std::set &GeneratedDecl, std::vector &TargetOpcodes, - std::vector &TargetVTs) { + std::vector &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 > PatternOpcodes; std::vector > PatternVTs; std::vector > PatternDecls; + std::vector OutputIsVariadicFlags; + std::vector NumInputRootOpsCounts; for (unsigned i = 0, e = Patterns.size(); i != e; ++i) { CodeList GeneratedCode; std::set GeneratedDecl; std::vector TargetOpcodes; std::vector 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 &TargetOpcodes = PatternOpcodes[i]; std::vector &TargetVTs = PatternVTs[i]; std::set Decls = PatternDecls[i]; + bool OutputIsVariadic = OutputIsVariadicFlags[i]; + unsigned NumInputRootOps = NumInputRootOpsCounts[i]; std::vector 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 1b47bcc156e..2f626f6b866 100644 --- a/utils/TableGen/DAGISelEmitter.h +++ b/utils/TableGen/DAGISelEmitter.h @@ -41,7 +41,9 @@ private: std::vector > &GeneratedCode, std::set &GeneratedDecl, std::vector &TargetOpcodes, - std::vector &TargetVTs); + std::vector &TargetVTs, + bool &OutputIsVariadic, + unsigned &NumInputRootOps); void EmitPatterns(std::vector > > > &Patterns, unsigned Indent, std::ostream &OS); diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index 8390c906604..fb8dd371efd 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)