diff options
-rw-r--r-- | lib/Target/Target.td | 6 | ||||
-rw-r--r-- | lib/Target/TargetSelectionDAG.td | 3 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.td | 4 | ||||
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.cpp | 2 | ||||
-rw-r--r-- | utils/TableGen/CodeGenInstruction.cpp | 3 | ||||
-rw-r--r-- | utils/TableGen/DAGISelEmitter.cpp | 81 | ||||
-rw-r--r-- | utils/TableGen/DAGISelEmitter.h | 4 | ||||
-rw-r--r-- | utils/TableGen/InstrInfoEmitter.cpp | 12 |
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) |