Emit an error if instructions or patterns are defined but can never match.

Currently we check that immediate values live on the RHS of commutative
operators.  Defining ORI like this, for example:

def ORI   : DForm_4<24, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2),
                    "ori $dst, $src1, $src2",
                    [(set GPRC:$dst, (or immZExt16:$src2, GPRC:$src1))]>;

results in:

tblgen: In ORI: Instruction can never match: Immediate values must be on the RHS of commutative operators!
llvm-svn: 23501
This commit is contained in:
Chris Lattner 2005-09-28 19:27:25 +00:00
parent b97b054ba7
commit 8bb25cd68a
2 changed files with 52 additions and 3 deletions

View File

@ -372,6 +372,34 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP) {
}
}
/// canPatternMatch - If it is impossible for this pattern to match on this
/// target, fill in Reason and return false. Otherwise, return true. This is
/// used as a santity check for .td files (to prevent people from writing stuff
/// that can never possibly work), and to prevent the pattern permuter from
/// generating stuff that is useless.
bool TreePatternNode::canPatternMatch(std::string &Reason, DAGISelEmitter &ISE) {
if (isLeaf()) return true;
for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
if (!getChild(i)->canPatternMatch(Reason, ISE))
return false;
// If this node is a commutative operator, check that the LHS isn't an
// immediate.
const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(getOperator());
if (NodeInfo.hasProperty(SDNodeInfo::SDNPCommutative)) {
// Scan all of the operands of the node and make sure that only the last one
// is a constant node.
for (unsigned i = 0, e = getNumChildren()-1; i != e; ++i)
if (!getChild(i)->isLeaf() &&
getChild(i)->getOperator()->getName() == "imm") {
Reason = "Immediate value must be on the RHS of commutative operators!";
return false;
}
}
return true;
}
//===----------------------------------------------------------------------===//
// TreePattern implementation
@ -962,6 +990,11 @@ void DAGISelEmitter::ParseInstructions() {
continue; // Not a set of a single value (not handled so far)
TreePatternNode *SrcPattern = Pattern->getChild(1)->clone();
std::string Reason;
if (!SrcPattern->canPatternMatch(Reason, *this))
I->error("Instruction can never match: " + Reason);
TreePatternNode *DstPattern = II->second.getResultPattern();
PatternsToMatch.push_back(std::make_pair(SrcPattern, DstPattern));
}
@ -999,6 +1032,11 @@ void DAGISelEmitter::ParsePatterns() {
if (Result->getNumTrees() != 1)
Result->error("Cannot handle instructions producing instructions "
"with temporaries yet!");
std::string Reason;
if (!Pattern->getOnlyTree()->canPatternMatch(Reason, *this))
Pattern->error("Pattern can never match: " + Reason);
PatternsToMatch.push_back(std::make_pair(Pattern->getOnlyTree(),
Result->getOnlyTree()));
}
@ -1011,6 +1049,12 @@ void DAGISelEmitter::ParsePatterns() {
});
}
// GenerateVariants - Generate variants. For example, commutative patterns can
// match multiple ways. Add them to PatternsToMatch as well.
void DAGISelEmitter::GenerateVariants() {
}
/// getPatternSize - Return the 'size' of this pattern. We want to match large
/// patterns before small ones. This is used to determine the size of a
/// pattern.
@ -1331,13 +1375,13 @@ void DAGISelEmitter::run(std::ostream &OS) {
ParseInstructions();
ParsePatterns();
// FIXME: Generate variants. For example, commutative patterns can match
// Generate variants. For example, commutative patterns can match
// multiple ways. Add them to PatternsToMatch as well.
GenerateVariants();
// At this point, we have full information about the 'Patterns' we need to
// parse, both implicitly from instructions as well as from explicit pattern
// definitions.
// definitions. Emit the resultant instruction selector.
EmitInstructionSelector(OS);
for (std::map<Record*, TreePattern*>::iterator I = PatternFragments.begin(),

View File

@ -204,6 +204,10 @@ namespace llvm {
if (getChild(i)->ContainsUnresolvedType()) return true;
return false;
}
/// canPatternMatch - Return false if it is impossible for this pattern to
/// match on this target.
bool canPatternMatch(std::string &Reason, DAGISelEmitter &ISE);
};
@ -369,6 +373,7 @@ private:
void ParsePatternFragments(std::ostream &OS);
void ParseInstructions();
void ParsePatterns();
void GenerateVariants();
void FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
std::map<std::string,
TreePatternNode*> &InstInputs,