[llvm-commits] [llvm] r78526 - /llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
Daniel Dunbar
daniel at zuster.org
Sat Aug 8 23:05:33 PDT 2009
Author: ddunbar
Date: Sun Aug 9 01:05:33 2009
New Revision: 78526
URL: http://llvm.org/viewvc/llvm-project?rev=78526&view=rev
Log:
llvm-mc/AsmParser: Separate instruction ordering for ambiguity detection.
- We want the ordering operation to be simple, since we run it on every
match. The old ordering is also not a strict weak ordering when there are
ambiguities, which makes MSVC unhappy.
- While we are at it, detect all ambiguities instead of just the adjacent
ones. There are actually 655, for X86.
Modified:
llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=78526&r1=78525&r2=78526&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Sun Aug 9 01:05:33 2009
@@ -263,7 +263,7 @@
DEBUG({
errs() << "warning: '" << Name << "': "
<< "ignoring instruction; tied operand '"
- << Tokens[i] << "', \n";
+ << Tokens[i] << "'\n";
});
return false;
}
@@ -368,34 +368,45 @@
/// operator< - Compare two instructions.
bool operator<(const InstructionInfo &RHS) const {
- // Order first by the number of operands (which is unambiguous).
if (Operands.size() != RHS.Operands.size())
return Operands.size() < RHS.Operands.size();
-
- // Otherwise, order by lexicographic comparison of tokens and operand kinds
- // (these can never be ambiguous).
+
for (unsigned i = 0, e = Operands.size(); i != e; ++i)
- if (Operands[i].Class->Kind != RHS.Operands[i].Class->Kind ||
- Operands[i].Class->Kind == ClassInfo::Token)
- if (*Operands[i].Class < *RHS.Operands[i].Class)
- return true;
+ if (*Operands[i].Class < *RHS.Operands[i].Class)
+ return true;
- // Finally, order by the component wise comparison of operand classes. We
- // don't want to rely on the lexigraphic ordering of elements, so we define
- // only define the ordering when it is unambiguous. That is, when some pair
- // compares less than and no pair compares greater than.
+ return false;
+ }
- // Check that no pair compares greater than.
- for (unsigned i = 0, e = Operands.size(); i != e; ++i)
- if (*RHS.Operands[i].Class < *Operands[i].Class)
- return false;
+ /// CouldMatchAmiguouslyWith - Check whether this instruction could
+ /// ambiguously match the same set of operands as \arg RHS (without being a
+ /// strictly superior match).
+ bool CouldMatchAmiguouslyWith(const InstructionInfo &RHS) {
+ // The number of operands is unambiguous.
+ if (Operands.size() != RHS.Operands.size())
+ return false;
- // Otherwise, return true if some pair compares less than.
+ // Tokens and operand kinds are unambiguous (assuming a correct target
+ // specific parser).
for (unsigned i = 0, e = Operands.size(); i != e; ++i)
+ if (Operands[i].Class->Kind != RHS.Operands[i].Class->Kind ||
+ Operands[i].Class->Kind == ClassInfo::Token)
+ if (*Operands[i].Class < *RHS.Operands[i].Class ||
+ *RHS.Operands[i].Class < *Operands[i].Class)
+ return false;
+
+ // Otherwise, this operand could commute if all operands are equivalent, or
+ // there is a pair of operands that compare less than and a pair that
+ // compare greater than.
+ bool HasLT = false, HasGT = false;
+ for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
if (*Operands[i].Class < *RHS.Operands[i].Class)
- return true;
+ HasLT = true;
+ if (*RHS.Operands[i].Class < *Operands[i].Class)
+ HasGT = true;
+ }
- return false;
+ return !(HasLT ^ HasGT);
}
public:
@@ -991,23 +1002,21 @@
// Check for ambiguous instructions.
unsigned NumAmbiguous = 0;
- for (std::vector<InstructionInfo*>::const_iterator it =
- Info.Instructions.begin(), ie = Info.Instructions.end() - 1;
- it != ie;) {
- InstructionInfo &II = **it;
- ++it;
-
- InstructionInfo &Next = **it;
+ for (unsigned i = 0, e = Info.Instructions.size(); i != e; ++i) {
+ for (unsigned j = i + 1; j != e; ++j) {
+ InstructionInfo &A = *Info.Instructions[i];
+ InstructionInfo &B = *Info.Instructions[j];
- if (!(II < Next)){
- DEBUG_WITH_TYPE("ambiguous_instrs", {
- errs() << "warning: ambiguous instruction match:\n";
- II.dump();
- errs() << "\nis incomparable with:\n";
- Next.dump();
- errs() << "\n\n";
- });
- ++NumAmbiguous;
+ if (A.CouldMatchAmiguouslyWith(B)) {
+ DEBUG_WITH_TYPE("ambiguous_instrs", {
+ errs() << "warning: ambiguous instruction match:\n";
+ A.dump();
+ errs() << "\nis incomparable with:\n";
+ B.dump();
+ errs() << "\n\n";
+ });
+ ++NumAmbiguous;
+ }
}
}
if (NumAmbiguous)
More information about the llvm-commits
mailing list