mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-04 05:31:51 +00:00
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:
parent
dfb2ebac29
commit
a955939ca2
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user