forked from OSchip/llvm-project
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:
parent
b97b054ba7
commit
8bb25cd68a
|
@ -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(),
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue