summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-08-10 22:38:36 +0000
committerChris Lattner <sabre@nondot.org>2003-08-10 22:38:36 +0000
commit990db46e9ae7faa742a152ca4126d0bee9f1df9c (patch)
treefe6de6e535fb4c8acfe51afc28f14f33e8487844 /utils
parent91290d7e9a743de363049e705a8303ae1f3a6e68 (diff)
downloadllvm-990db46e9ae7faa742a152ca4126d0bee9f1df9c.tar.gz
llvm-990db46e9ae7faa742a152ca4126d0bee9f1df9c.tar.bz2
llvm-990db46e9ae7faa742a152ca4126d0bee9f1df9c.tar.xz
Implement autopromotion of leaf trees from arguments to nodes of their own,
making it easier to write patterns without lots of extraneous parens git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7714 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/InstrSelectorEmitter.cpp42
-rw-r--r--utils/TableGen/Record.h5
2 files changed, 34 insertions, 13 deletions
diff --git a/utils/TableGen/InstrSelectorEmitter.cpp b/utils/TableGen/InstrSelectorEmitter.cpp
index 9eb3be7f3f..99f22f07b9 100644
--- a/utils/TableGen/InstrSelectorEmitter.cpp
+++ b/utils/TableGen/InstrSelectorEmitter.cpp
@@ -167,19 +167,20 @@ MVT::ValueType Pattern::getIntrinsicType(Record *R) const {
return MVT::Other;
}
- throw "Error: Unknown value used: " + R->getName();
+ error("Unknown value used: " + R->getName());
+ return MVT::Other;
}
-TreePatternNode *Pattern::ParseTreePattern(DagInit *DI) {
- Record *Operator = DI->getNodeType();
+TreePatternNode *Pattern::ParseTreePattern(DagInit *Dag) {
+ Record *Operator = Dag->getNodeType();
if (Operator->isSubClassOf("ValueType")) {
// If the operator is a ValueType, then this must be "type cast" of a leaf
// node.
- if (DI->getNumArgs() != 1)
+ if (Dag->getNumArgs() != 1)
error("Type cast only valid for a leaf node!");
- Init *Arg = DI->getArg(0);
+ Init *Arg = Dag->getArg(0);
TreePatternNode *New;
if (DefInit *DI = dynamic_cast<DefInit*>(Arg)) {
New = new TreePatternNode(DI);
@@ -200,14 +201,22 @@ TreePatternNode *Pattern::ParseTreePattern(DagInit *DI) {
std::vector<TreePatternNode*> Children;
- for (unsigned i = 0, e = DI->getNumArgs(); i != e; ++i) {
- Init *Arg = DI->getArg(i);
+ for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) {
+ Init *Arg = Dag->getArg(i);
if (DagInit *DI = dynamic_cast<DagInit*>(Arg)) {
Children.push_back(ParseTreePattern(DI));
- } else if (DefInit *DI = dynamic_cast<DefInit*>(Arg)) {
- Children.push_back(new TreePatternNode(DI));
- // If it's a regclass or something else known, set the type.
- Children.back()->setType(getIntrinsicType(DI->getDef()));
+ } else if (DefInit *DefI = dynamic_cast<DefInit*>(Arg)) {
+ Record *R = DefI->getDef();
+ // Direct reference to a leaf DagNode? Turn it into a DagNode if its own.
+ if (R->isSubClassOf("DagNode")) {
+ Dag->setArg(i, new DagInit(R,
+ std::vector<std::pair<Init*, std::string> >()));
+ --i; // Revisit this node...
+ } else {
+ Children.push_back(new TreePatternNode(DefI));
+ // If it's a regclass or something else known, set the type.
+ Children.back()->setType(getIntrinsicType(R));
+ }
} else {
Arg->dump();
error("Unknown leaf value for tree pattern!");
@@ -524,8 +533,15 @@ void InstrSelectorEmitter::CalculateComputableValues() {
// Loop over all of the patterns, adding them to the ComputableValues map
for (std::map<Record*, Pattern*>::iterator I = Patterns.begin(),
E = Patterns.end(); I != E; ++I)
- if (I->second->isResolved())
- ComputableValues.addPattern(I->second);
+ if (I->second->isResolved()) {
+ // We don't want to add patterns like R32 = R32. This is a hack working
+ // around a special case of a general problem, but for now we explicitly
+ // forbid these patterns. They can never match anyway.
+ Pattern *P = I->second;
+ if (!P->getResult() || !P->getTree()->isLeaf() ||
+ P->getResult() != P->getTree()->getValueRecord())
+ ComputableValues.addPattern(P);
+ }
}
#if 0
diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h
index 88312509ef..4a2fa057cf 100644
--- a/utils/TableGen/Record.h
+++ b/utils/TableGen/Record.h
@@ -619,6 +619,11 @@ public:
return ArgNames[Num];
}
+ void setArg(unsigned Num, Init *I) {
+ assert(Num < Args.size() && "Arg number out of range!");
+ Args[Num] = I;
+ }
+
virtual void print(std::ostream &OS) const;
};