mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-20 14:29:27 +00:00
Teach the DAGISelEmitter to not compute the variable_ops operand
index for the input pattern in terms of the output pattern. Instead keep track of how many fixed operands the input pattern actually has, and have the input matching code pass the output-emitting function that index value. This simplifies the code, disentangles variables_ops from the support for predication operations, and makes variable_ops more robust. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51808 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2830741866
commit
e4c67cdab4
@ -259,12 +259,6 @@ def ins;
|
|||||||
/// of operands.
|
/// of operands.
|
||||||
def variable_ops;
|
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
|
/// ptr_rc definition - Mark this operand as being a pointer value whose
|
||||||
/// register class is resolved dynamically via a callback to TargetInstrInfo.
|
/// register class is resolved dynamically via a callback to TargetInstrInfo.
|
||||||
/// FIXME: We should probably change this to a class which contain a list of
|
/// FIXME: We should probably change this to a class which contain a list of
|
||||||
|
@ -62,7 +62,7 @@ class SDTCisIntVectorOfSameSize<int ThisOp, int OtherOp>
|
|||||||
|
|
||||||
/// SDTCisEltOfVec - This indicates that ThisOp is a scalar type of the same
|
/// SDTCisEltOfVec - This indicates that ThisOp is a scalar type of the same
|
||||||
/// type as the element type of OtherOp, which is a vector type.
|
/// 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> {
|
: SDTypeConstraint<ThisOp> {
|
||||||
int OtherOpNum = OtherOp;
|
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 vtInt : PatLeaf<(vt), [{ return MVT::isInteger(N->getVT()); }]>;
|
||||||
def vtFP : PatLeaf<(vt), [{ return MVT::isFloatingPoint(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 immAllOnes : PatLeaf<(imm), [{ return N->isAllOnesValue(); }]>;
|
||||||
def immAllOnesV: PatLeaf<(build_vector), [{
|
def immAllOnesV: PatLeaf<(build_vector), [{
|
||||||
return ISD::isBuildVectorAllOnes(N);
|
return ISD::isBuildVectorAllOnes(N);
|
||||||
|
@ -322,9 +322,9 @@ let neverHasSideEffects = 1, isNotDuplicable = 1 in
|
|||||||
// Return instructions.
|
// Return instructions.
|
||||||
let isTerminator = 1, isReturn = 1, isBarrier = 1,
|
let isTerminator = 1, isReturn = 1, isBarrier = 1,
|
||||||
hasCtrlDep = 1, FPForm = SpecialFP, FPFormBits = SpecialFP.Value in {
|
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",
|
"ret",
|
||||||
[(X86retflag immAllZeros:$amt)]>;
|
[(X86retflag 0)]>;
|
||||||
def RETI : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt, variable_ops),
|
def RETI : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt, variable_ops),
|
||||||
"ret\t$amt",
|
"ret\t$amt",
|
||||||
[(X86retflag imm:$amt)]>;
|
[(X86retflag imm:$amt)]>;
|
||||||
|
@ -916,8 +916,6 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
|
|||||||
MadeChange |= Child->UpdateNodeType(MVT::iPTR, TP);
|
MadeChange |= Child->UpdateNodeType(MVT::iPTR, TP);
|
||||||
} else if (OperandNode->getName() == "unknown") {
|
} else if (OperandNode->getName() == "unknown") {
|
||||||
MadeChange |= Child->UpdateNodeType(MVT::isUnknown, TP);
|
MadeChange |= Child->UpdateNodeType(MVT::isUnknown, TP);
|
||||||
} else if (OperandNode->getName() == "discard") {
|
|
||||||
MadeChange |= Child->UpdateNodeType(MVT::isUnknown, TP);
|
|
||||||
} else {
|
} else {
|
||||||
assert(0 && "Unknown operand type!");
|
assert(0 && "Unknown operand type!");
|
||||||
abort();
|
abort();
|
||||||
|
@ -163,8 +163,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
|
|||||||
isVariadic = true;
|
isVariadic = true;
|
||||||
continue;
|
continue;
|
||||||
} else if (!Rec->isSubClassOf("RegisterClass") &&
|
} else if (!Rec->isSubClassOf("RegisterClass") &&
|
||||||
Rec->getName() != "ptr_rc" && Rec->getName() != "unknown" &&
|
Rec->getName() != "ptr_rc" && Rec->getName() != "unknown")
|
||||||
Rec->getName() != "discard")
|
|
||||||
throw "Unknown operand class '" + Rec->getName() +
|
throw "Unknown operand class '" + Rec->getName() +
|
||||||
"' in instruction '" + R->getName() + "' instruction!";
|
"' in instruction '" + R->getName() + "' instruction!";
|
||||||
|
|
||||||
|
@ -331,6 +331,15 @@ private:
|
|||||||
/// instructions.
|
/// instructions.
|
||||||
std::vector<std::string> &TargetOpcodes;
|
std::vector<std::string> &TargetOpcodes;
|
||||||
std::vector<std::string> &TargetVTs;
|
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;
|
std::string ChainName;
|
||||||
unsigned TmpNo;
|
unsigned TmpNo;
|
||||||
@ -367,10 +376,13 @@ public:
|
|||||||
std::vector<std::pair<unsigned, std::string> > &gc,
|
std::vector<std::pair<unsigned, std::string> > &gc,
|
||||||
std::set<std::string> &gd,
|
std::set<std::string> &gd,
|
||||||
std::vector<std::string> &to,
|
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),
|
: CGP(cgp), Predicates(preds), Pattern(pattern), Instruction(instr),
|
||||||
GeneratedCode(gc), GeneratedDecl(gd),
|
GeneratedCode(gc), GeneratedDecl(gd),
|
||||||
TargetOpcodes(to), TargetVTs(tv),
|
TargetOpcodes(to), TargetVTs(tv),
|
||||||
|
OutputIsVariadic(oiv), NumInputRootOps(niro),
|
||||||
TmpNo(0), OpcNo(0), VTNo(0) {}
|
TmpNo(0), OpcNo(0), VTNo(0) {}
|
||||||
|
|
||||||
/// EmitMatchCode - Emit a matcher for N, going to the label for PatternNo
|
/// EmitMatchCode - Emit a matcher for N, going to the label for PatternNo
|
||||||
@ -392,6 +404,9 @@ public:
|
|||||||
bool isRoot = (P == NULL);
|
bool isRoot = (P == NULL);
|
||||||
// Emit instruction predicates. Each predicate is just a string for now.
|
// Emit instruction predicates. Each predicate is just a string for now.
|
||||||
if (isRoot) {
|
if (isRoot) {
|
||||||
|
// Record input varargs info.
|
||||||
|
NumInputRootOps = N->getNumChildren();
|
||||||
|
|
||||||
std::string PredicateCheck;
|
std::string PredicateCheck;
|
||||||
for (unsigned i = 0, e = Predicates->getSize(); i != e; ++i) {
|
for (unsigned i = 0, e = Predicates->getSize(); i != e; ++i) {
|
||||||
if (DefInit *Pred = dynamic_cast<DefInit*>(Predicates->getElement(i))) {
|
if (DefInit *Pred = dynamic_cast<DefInit*>(Predicates->getElement(i))) {
|
||||||
@ -887,7 +902,7 @@ public:
|
|||||||
if (InstPatNode && InstPatNode->getOperator()->getName() == "set") {
|
if (InstPatNode && InstPatNode->getOperator()->getName() == "set") {
|
||||||
InstPatNode = InstPatNode->getChild(InstPatNode->getNumChildren()-1);
|
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.
|
// FIXME: fix how we deal with physical register operands.
|
||||||
bool HasImpInputs = isRoot && Inst.getNumImpOperands() > 0;
|
bool HasImpInputs = isRoot && Inst.getNumImpOperands() > 0;
|
||||||
bool HasImpResults = isRoot && DstRegs.size() > 0;
|
bool HasImpResults = isRoot && DstRegs.size() > 0;
|
||||||
@ -904,11 +919,14 @@ public:
|
|||||||
unsigned NumResults = Inst.getNumResults();
|
unsigned NumResults = Inst.getNumResults();
|
||||||
unsigned NumDstRegs = HasImpResults ? DstRegs.size() : 0;
|
unsigned NumDstRegs = HasImpResults ? DstRegs.size() : 0;
|
||||||
|
|
||||||
|
// Record output varargs info.
|
||||||
|
OutputIsVariadic = IsVariadic;
|
||||||
|
|
||||||
if (NodeHasOptInFlag) {
|
if (NodeHasOptInFlag) {
|
||||||
emitCode("bool HasInFlag = "
|
emitCode("bool HasInFlag = "
|
||||||
"(N.getOperand(N.getNumOperands()-1).getValueType() == MVT::Flag);");
|
"(N.getOperand(N.getNumOperands()-1).getValueType() == MVT::Flag);");
|
||||||
}
|
}
|
||||||
if (HasVarOps)
|
if (IsVariadic)
|
||||||
emitCode("SmallVector<SDOperand, 8> Ops" + utostr(OpcNo) + ";");
|
emitCode("SmallVector<SDOperand, 8> Ops" + utostr(OpcNo) + ";");
|
||||||
|
|
||||||
// How many results is this pattern expected to produce?
|
// 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
|
// in the 'execute always' values. Match up the node operands to the
|
||||||
// instruction operands to do this.
|
// instruction operands to do this.
|
||||||
std::vector<std::string> AllOps;
|
std::vector<std::string> AllOps;
|
||||||
unsigned NumEAInputs = 0; // # of synthesized 'execute always' inputs.
|
|
||||||
unsigned InputIndex = 0;
|
|
||||||
for (unsigned ChildNo = 0, InstOpNo = NumResults;
|
for (unsigned ChildNo = 0, InstOpNo = NumResults;
|
||||||
InstOpNo != II.OperandList.size(); ++InstOpNo) {
|
InstOpNo != II.OperandList.size(); ++InstOpNo) {
|
||||||
std::vector<std::string> Ops;
|
std::vector<std::string> Ops;
|
||||||
|
|
||||||
// Determine what to emit for this operand.
|
// Determine what to emit for this operand.
|
||||||
Record *OperandNode = II.OperandList[InstOpNo].Rec;
|
Record *OperandNode = II.OperandList[InstOpNo].Rec;
|
||||||
if (OperandNode->getName() == "discard") {
|
if ((OperandNode->isSubClassOf("PredicateOperand") ||
|
||||||
// This is a "discard" operand; emit nothing. Just note it.
|
OperandNode->isSubClassOf("OptionalDefOperand")) &&
|
||||||
++InputIndex;
|
!CGP.getDefaultOperand(OperandNode).DefaultOps.empty()) {
|
||||||
} else if ((OperandNode->isSubClassOf("PredicateOperand") ||
|
|
||||||
OperandNode->isSubClassOf("OptionalDefOperand")) &&
|
|
||||||
!CGP.getDefaultOperand(OperandNode).DefaultOps.empty()) {
|
|
||||||
// This is a predicate or optional def operand; emit the
|
// This is a predicate or optional def operand; emit the
|
||||||
// 'default ops' operands.
|
// 'default ops' operands.
|
||||||
const DAGDefaultOperand &DefaultOp =
|
const DAGDefaultOperand &DefaultOp =
|
||||||
@ -968,9 +981,7 @@ public:
|
|||||||
Ops = EmitResultCode(DefaultOp.DefaultOps[i], DstRegs,
|
Ops = EmitResultCode(DefaultOp.DefaultOps[i], DstRegs,
|
||||||
InFlagDecled, ResNodeDecled);
|
InFlagDecled, ResNodeDecled);
|
||||||
AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
|
AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
|
||||||
NumEAInputs += Ops.size();
|
|
||||||
}
|
}
|
||||||
++InputIndex;
|
|
||||||
} else {
|
} else {
|
||||||
// Otherwise this is a normal operand or a predicate operand without
|
// Otherwise this is a normal operand or a predicate operand without
|
||||||
// 'execute always'; emit it.
|
// 'execute always'; emit it.
|
||||||
@ -978,7 +989,6 @@ public:
|
|||||||
InFlagDecled, ResNodeDecled);
|
InFlagDecled, ResNodeDecled);
|
||||||
AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
|
AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
|
||||||
++ChildNo;
|
++ChildNo;
|
||||||
++InputIndex;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1057,15 +1067,7 @@ public:
|
|||||||
Code += ", MVT::Flag";
|
Code += ", MVT::Flag";
|
||||||
|
|
||||||
// Inputs.
|
// Inputs.
|
||||||
if (HasVarOps) {
|
if (IsVariadic) {
|
||||||
// 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;
|
|
||||||
|
|
||||||
for (unsigned i = 0, e = AllOps.size(); i != e; ++i)
|
for (unsigned i = 0, e = AllOps.size(); i != e; ++i)
|
||||||
emitCode("Ops" + utostr(OpsNo) + ".push_back(" + AllOps[i] + ");");
|
emitCode("Ops" + utostr(OpsNo) + ".push_back(" + AllOps[i] + ");");
|
||||||
AllOps.clear();
|
AllOps.clear();
|
||||||
@ -1078,7 +1080,7 @@ public:
|
|||||||
else if (NodeHasOptInFlag)
|
else if (NodeHasOptInFlag)
|
||||||
EndAdjust = "-(HasInFlag?1:0)"; // May have a flag.
|
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) {");
|
", e = N.getNumOperands()" + EndAdjust + "; i != e; ++i) {");
|
||||||
|
|
||||||
emitCode(" AddToISelQueue(N.getOperand(i));");
|
emitCode(" AddToISelQueue(N.getOperand(i));");
|
||||||
@ -1087,13 +1089,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (NodeHasChain) {
|
if (NodeHasChain) {
|
||||||
if (HasVarOps)
|
if (IsVariadic)
|
||||||
emitCode("Ops" + utostr(OpsNo) + ".push_back(" + ChainName + ");");
|
emitCode("Ops" + utostr(OpsNo) + ".push_back(" + ChainName + ");");
|
||||||
else
|
else
|
||||||
AllOps.push_back(ChainName);
|
AllOps.push_back(ChainName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasVarOps) {
|
if (IsVariadic) {
|
||||||
if (NodeHasInFlag || HasImpInputs)
|
if (NodeHasInFlag || HasImpInputs)
|
||||||
emitCode("Ops" + utostr(OpsNo) + ".push_back(InFlag);");
|
emitCode("Ops" + utostr(OpsNo) + ".push_back(InFlag);");
|
||||||
else if (NodeHasOptInFlag) {
|
else if (NodeHasOptInFlag) {
|
||||||
@ -1358,11 +1360,17 @@ void DAGISelEmitter::GenerateCodeForPattern(const PatternToMatch &Pattern,
|
|||||||
std::vector<std::pair<unsigned, std::string> > &GeneratedCode,
|
std::vector<std::pair<unsigned, std::string> > &GeneratedCode,
|
||||||
std::set<std::string> &GeneratedDecl,
|
std::set<std::string> &GeneratedDecl,
|
||||||
std::vector<std::string> &TargetOpcodes,
|
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(),
|
PatternCodeEmitter Emitter(CGP, Pattern.getPredicates(),
|
||||||
Pattern.getSrcPattern(), Pattern.getDstPattern(),
|
Pattern.getSrcPattern(), Pattern.getDstPattern(),
|
||||||
GeneratedCode, GeneratedDecl,
|
GeneratedCode, GeneratedDecl,
|
||||||
TargetOpcodes, TargetVTs);
|
TargetOpcodes, TargetVTs,
|
||||||
|
OutputIsVariadic, NumInputRootOps);
|
||||||
|
|
||||||
// Emit the matcher, capturing named arguments in VariableMap.
|
// Emit the matcher, capturing named arguments in VariableMap.
|
||||||
bool FoundChain = false;
|
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> > PatternOpcodes;
|
||||||
std::vector<std::vector<std::string> > PatternVTs;
|
std::vector<std::vector<std::string> > PatternVTs;
|
||||||
std::vector<std::set<std::string> > PatternDecls;
|
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) {
|
for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
|
||||||
CodeList GeneratedCode;
|
CodeList GeneratedCode;
|
||||||
std::set<std::string> GeneratedDecl;
|
std::set<std::string> GeneratedDecl;
|
||||||
std::vector<std::string> TargetOpcodes;
|
std::vector<std::string> TargetOpcodes;
|
||||||
std::vector<std::string> TargetVTs;
|
std::vector<std::string> TargetVTs;
|
||||||
|
bool OutputIsVariadic;
|
||||||
|
unsigned NumInputRootOps;
|
||||||
GenerateCodeForPattern(*Patterns[i], GeneratedCode, GeneratedDecl,
|
GenerateCodeForPattern(*Patterns[i], GeneratedCode, GeneratedDecl,
|
||||||
TargetOpcodes, TargetVTs);
|
TargetOpcodes, TargetVTs,
|
||||||
|
OutputIsVariadic, NumInputRootOps);
|
||||||
CodeForPatterns.push_back(std::make_pair(Patterns[i], GeneratedCode));
|
CodeForPatterns.push_back(std::make_pair(Patterns[i], GeneratedCode));
|
||||||
PatternDecls.push_back(GeneratedDecl);
|
PatternDecls.push_back(GeneratedDecl);
|
||||||
PatternOpcodes.push_back(TargetOpcodes);
|
PatternOpcodes.push_back(TargetOpcodes);
|
||||||
PatternVTs.push_back(TargetVTs);
|
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
|
// 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> &TargetOpcodes = PatternOpcodes[i];
|
||||||
std::vector<std::string> &TargetVTs = PatternVTs[i];
|
std::vector<std::string> &TargetVTs = PatternVTs[i];
|
||||||
std::set<std::string> Decls = PatternDecls[i];
|
std::set<std::string> Decls = PatternDecls[i];
|
||||||
|
bool OutputIsVariadic = OutputIsVariadicFlags[i];
|
||||||
|
unsigned NumInputRootOps = NumInputRootOpsCounts[i];
|
||||||
std::vector<std::string> AddedInits;
|
std::vector<std::string> AddedInits;
|
||||||
int CodeSize = (int)GeneratedCode.size();
|
int CodeSize = (int)GeneratedCode.size();
|
||||||
int LastPred = -1;
|
int LastPred = -1;
|
||||||
@ -1723,6 +1740,12 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
CalleeCode += ", SDOperand &" + Name;
|
CalleeCode += ", SDOperand &" + Name;
|
||||||
CallerCode += ", " + Name;
|
CallerCode += ", " + Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (OutputIsVariadic) {
|
||||||
|
CalleeCode += ", unsigned NumInputRootOps";
|
||||||
|
CallerCode += ", " + utostr(NumInputRootOps);
|
||||||
|
}
|
||||||
|
|
||||||
CallerCode += ");";
|
CallerCode += ");";
|
||||||
CalleeCode += ") ";
|
CalleeCode += ") ";
|
||||||
// Prevent emission routines from being inlined to reduce selection
|
// Prevent emission routines from being inlined to reduce selection
|
||||||
|
@ -41,7 +41,9 @@ private:
|
|||||||
std::vector<std::pair<unsigned, std::string> > &GeneratedCode,
|
std::vector<std::pair<unsigned, std::string> > &GeneratedCode,
|
||||||
std::set<std::string> &GeneratedDecl,
|
std::set<std::string> &GeneratedDecl,
|
||||||
std::vector<std::string> &TargetOpcodes,
|
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*,
|
void EmitPatterns(std::vector<std::pair<const PatternToMatch*,
|
||||||
std::vector<std::pair<unsigned, std::string> > > > &Patterns,
|
std::vector<std::pair<unsigned, std::string> > > > &Patterns,
|
||||||
unsigned Indent, std::ostream &OS);
|
unsigned Indent, std::ostream &OS);
|
||||||
|
@ -85,10 +85,6 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
|
|||||||
Record *OpR = OperandList[j].Rec;
|
Record *OpR = OperandList[j].Rec;
|
||||||
std::string Res;
|
std::string Res;
|
||||||
|
|
||||||
// Discard "discard" operands.
|
|
||||||
if (OpR->getName() == "discard")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (OpR->isSubClassOf("RegisterClass"))
|
if (OpR->isSubClassOf("RegisterClass"))
|
||||||
Res += getQualifiedName(OpR) + "RegClassID, ";
|
Res += getQualifiedName(OpR) + "RegClassID, ";
|
||||||
else
|
else
|
||||||
@ -206,14 +202,6 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
|
|||||||
MinOperands = Inst.OperandList.back().MIOperandNo +
|
MinOperands = Inst.OperandList.back().MIOperandNo +
|
||||||
Inst.OperandList.back().MINumOperands;
|
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 << " { ";
|
||||||
OS << Num << ",\t" << MinOperands << ",\t"
|
OS << Num << ",\t" << MinOperands << ",\t"
|
||||||
<< Inst.NumDefs << ",\t" << getItinClassNumber(Inst.TheDef)
|
<< Inst.NumDefs << ",\t" << getItinClassNumber(Inst.TheDef)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user