Refactor code to add initial support for OptionalDefOperand.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37933 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2007-07-06 01:05:26 +00:00
parent dfb2ebac29
commit a955939ca2
2 changed files with 68 additions and 58 deletions

View File

@ -775,11 +775,12 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i) {
Record *OperandNode = Inst.getOperand(i);
// If the instruction expects a predicate operand, we codegen this by
// setting the predicate to it's "execute always" value if it has a
// non-empty ExecuteAlways field.
if (OperandNode->isSubClassOf("PredicateOperand") &&
!ISE.getPredicateOperand(OperandNode).AlwaysOps.empty())
// If the instruction expects a predicate or optional def operand, we
// codegen this by setting the operand to it's default value if it has a
// non-empty DefaultOps field.
if ((OperandNode->isSubClassOf("PredicateOperand") ||
OperandNode->isSubClassOf("OptionalDefOperand")) &&
!ISE.getDefaultOperand(OperandNode).DefaultOps.empty())
continue;
// Verify that we didn't run out of provided operands.
@ -1246,47 +1247,54 @@ void DAGISelEmitter::ParsePatternFragments(std::ostream &OS) {
}
}
void DAGISelEmitter::ParsePredicateOperands() {
std::vector<Record*> PredOps =
Records.getAllDerivedDefinitions("PredicateOperand");
void DAGISelEmitter::ParseDefaultOperands() {
std::vector<Record*> DefaultOps[2];
DefaultOps[0] = Records.getAllDerivedDefinitions("PredicateOperand");
DefaultOps[1] = Records.getAllDerivedDefinitions("OptionalDefOperand");
// Find some SDNode.
assert(!SDNodes.empty() && "No SDNodes parsed?");
Init *SomeSDNode = new DefInit(SDNodes.begin()->first);
for (unsigned i = 0, e = PredOps.size(); i != e; ++i) {
DagInit *AlwaysInfo = PredOps[i]->getValueAsDag("ExecuteAlways");
for (unsigned iter = 0; iter != 2; ++iter) {
for (unsigned i = 0, e = DefaultOps[iter].size(); i != e; ++i) {
DagInit *DefaultInfo = DefaultOps[iter][i]->getValueAsDag("DefaultOps");
// Clone the AlwaysInfo dag node, changing the operator from 'ops' to
// SomeSDnode so that we can parse this.
std::vector<std::pair<Init*, std::string> > Ops;
for (unsigned op = 0, e = AlwaysInfo->getNumArgs(); op != e; ++op)
Ops.push_back(std::make_pair(AlwaysInfo->getArg(op),
AlwaysInfo->getArgName(op)));
DagInit *DI = new DagInit(SomeSDNode, Ops);
// Clone the DefaultInfo dag node, changing the operator from 'ops' to
// SomeSDnode so that we can parse this.
std::vector<std::pair<Init*, std::string> > Ops;
for (unsigned op = 0, e = DefaultInfo->getNumArgs(); op != e; ++op)
Ops.push_back(std::make_pair(DefaultInfo->getArg(op),
DefaultInfo->getArgName(op)));
DagInit *DI = new DagInit(SomeSDNode, Ops);
// Create a TreePattern to parse this.
TreePattern P(PredOps[i], DI, false, *this);
assert(P.getNumTrees() == 1 && "This ctor can only produce one tree!");
// Create a TreePattern to parse this.
TreePattern P(DefaultOps[iter][i], DI, false, *this);
assert(P.getNumTrees() == 1 && "This ctor can only produce one tree!");
// Copy the operands over into a DAGPredicateOperand.
DAGPredicateOperand PredOpInfo;
// Copy the operands over into a DAGDefaultOperand.
DAGDefaultOperand DefaultOpInfo;
TreePatternNode *T = P.getTree(0);
for (unsigned op = 0, e = T->getNumChildren(); op != e; ++op) {
TreePatternNode *TPN = T->getChild(op);
while (TPN->ApplyTypeConstraints(P, false))
/* Resolve all types */;
TreePatternNode *T = P.getTree(0);
for (unsigned op = 0, e = T->getNumChildren(); op != e; ++op) {
TreePatternNode *TPN = T->getChild(op);
while (TPN->ApplyTypeConstraints(P, false))
/* Resolve all types */;
if (TPN->ContainsUnresolvedType())
throw "Value #" + utostr(i) + " of PredicateOperand '" +
PredOps[i]->getName() + "' doesn't have a concrete type!";
if (TPN->ContainsUnresolvedType())
if (iter == 0)
throw "Value #" + utostr(i) + " of PredicateOperand '" +
DefaultOps[iter][i]->getName() + "' doesn't have a concrete type!";
else
throw "Value #" + utostr(i) + " of OptionalDefOperand '" +
DefaultOps[iter][i]->getName() + "' doesn't have a concrete type!";
PredOpInfo.AlwaysOps.push_back(TPN);
DefaultOpInfo.DefaultOps.push_back(TPN);
}
// Insert it into the DefaultOperands map so we can find it later.
DefaultOperands[DefaultOps[iter][i]] = DefaultOpInfo;
}
// Insert it into the PredicateOperands map so we can find it later.
PredicateOperands[PredOps[i]] = PredOpInfo;
}
}
@ -1550,13 +1558,14 @@ void DAGISelEmitter::ParseInstructions() {
I->error("Operand #" + utostr(i) + " in operands list has no name!");
if (!InstInputsCheck.count(OpName)) {
// If this is an predicate operand with an ExecuteAlways set filled in,
// we can ignore this. When we codegen it, we will do so as always
// executed.
if (Op.Rec->isSubClassOf("PredicateOperand")) {
// Does it have a non-empty ExecuteAlways field? If so, ignore this
// If this is an predicate operand or optional def operand with an
// DefaultOps set filled in, we can ignore this. When we codegen it,
// we will do so as always executed.
if (Op.Rec->isSubClassOf("PredicateOperand") ||
Op.Rec->isSubClassOf("OptionalDefOperand")) {
// Does it have a non-empty DefaultOps field? If so, ignore this
// operand.
if (!getPredicateOperand(Op.Rec).AlwaysOps.empty())
if (!getDefaultOperand(Op.Rec).DefaultOps.empty())
continue;
}
I->error("Operand $" + OpName +
@ -2813,19 +2822,20 @@ public:
// If this is a normal operand or a predicate operand without
// 'execute always', emit it.
Record *OperandNode = II.OperandList[InstOpNo].Rec;
if (!OperandNode->isSubClassOf("PredicateOperand") ||
ISE.getPredicateOperand(OperandNode).AlwaysOps.empty()) {
if ((!OperandNode->isSubClassOf("PredicateOperand") &&
!OperandNode->isSubClassOf("OptionalDefOperand")) ||
ISE.getDefaultOperand(OperandNode).DefaultOps.empty()) {
Ops = EmitResultCode(N->getChild(ChildNo), RetSelected,
InFlagDecled, ResNodeDecled);
AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
++ChildNo;
} else {
// Otherwise, this is a predicate operand, emit the 'execute always'
// operands.
const DAGPredicateOperand &Pred =
ISE.getPredicateOperand(II.OperandList[InstOpNo].Rec);
for (unsigned i = 0, e = Pred.AlwaysOps.size(); i != e; ++i) {
Ops = EmitResultCode(Pred.AlwaysOps[i], RetSelected,
// Otherwise, this is a predicate or optional def operand, emit the
// 'default ops' operands.
const DAGDefaultOperand &DefaultOp =
ISE.getDefaultOperand(II.OperandList[InstOpNo].Rec);
for (unsigned i = 0, e = DefaultOp.DefaultOps.size(); i != e; ++i) {
Ops = EmitResultCode(DefaultOp.DefaultOps[i], RetSelected,
InFlagDecled, ResNodeDecled);
AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
NumEAInputs += Ops.size();
@ -3962,7 +3972,7 @@ OS << " unsigned NumKilled = ISelKilled.size();\n";
ParseNodeTransforms(OS);
ParseComplexPatterns();
ParsePatternFragments(OS);
ParsePredicateOperands();
ParseDefaultOperands();
ParseInstructions();
ParsePatterns();

View File

@ -343,10 +343,10 @@ namespace llvm {
TreePatternNode *ParseTreePattern(DagInit *DI);
};
/// DAGPredicateOperand - One of these is created for each PredicateOperand
/// that has a set ExecuteAlways field.
struct DAGPredicateOperand {
std::vector<TreePatternNode*> AlwaysOps;
/// DAGDefaultOperand - One of these is created for each PredicateOperand
/// or OptionalDefOperand that has a set ExecuteAlways / DefaultOps field.
struct DAGDefaultOperand {
std::vector<TreePatternNode*> DefaultOps;
};
class DAGInstruction {
@ -430,7 +430,7 @@ private:
std::map<Record*, std::pair<Record*, std::string> > SDNodeXForms;
std::map<Record*, ComplexPattern> ComplexPatterns;
std::map<Record*, TreePattern*> PatternFragments;
std::map<Record*, DAGPredicateOperand> PredicateOperands;
std::map<Record*, DAGDefaultOperand> DefaultOperands;
std::map<Record*, DAGInstruction> Instructions;
// Specific SDNode definitions:
@ -485,9 +485,9 @@ public:
abort();
}
const DAGPredicateOperand &getPredicateOperand(Record *R) {
assert(PredicateOperands.count(R) &&"Isn't an analyzed predicate operand!");
return PredicateOperands.find(R)->second;
const DAGDefaultOperand &getDefaultOperand(Record *R) {
assert(DefaultOperands.count(R) &&"Isn't an analyzed default operand!");
return DefaultOperands.find(R)->second;
}
TreePattern *getPatternFragment(Record *R) const {
@ -516,7 +516,7 @@ private:
void ParseNodeTransforms(std::ostream &OS);
void ParseComplexPatterns();
void ParsePatternFragments(std::ostream &OS);
void ParsePredicateOperands();
void ParseDefaultOperands();
void ParseInstructions();
void ParsePatterns();
void GenerateVariants();