From 9a24f88a37b581e6424ead70bf6f2da848944936 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Tue, 20 May 2014 09:17:16 +0000 Subject: TableGen: convert InstAlias's Emit bit to an int. When multiple aliases overlap, the correct string to print can often be determined purely by considering the InstAlias declarations in some particular order. This allows the user to specify that order manually when desired, without resorting to hacking around with the default lexicographical order on Record instantiation, which is error-prone and ugly. I was also mistaken about "add w2, w3, w4" being the same as "add w2, w3, w4, uxtw". That's only true if Rn is the stack pointer. llvm-svn: 209199 --- llvm/utils/TableGen/AsmWriterEmitter.cpp | 44 ++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 13 deletions(-) (limited to 'llvm/utils') diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp index c31c120a2f7..2741d8f4ade 100644 --- a/llvm/utils/TableGen/AsmWriterEmitter.cpp +++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp @@ -750,6 +750,23 @@ static unsigned CountNumOperands(StringRef AsmString, unsigned Variant) { return AsmString.count(' ') + AsmString.count('\t'); } +namespace { +struct AliasPriorityComparator { + typedef std::pair ValueType; + bool operator()(const ValueType &LHS, const ValueType &RHS) { + if (LHS.second == RHS.second) { + // We don't actually care about the order, but for consistency it + // shouldn't depend on pointer comparisons. + return LHS.first->TheDef->getName() < RHS.first->TheDef->getName(); + } + + // Aliases with larger priorities should be considered first. + return LHS.second > RHS.second; + } +}; +} + + void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { Record *AsmWriter = Target.getAsmWriter(); @@ -762,35 +779,36 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { // Emit the method that prints the alias instruction. std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); + unsigned Variant = AsmWriter->getValueAsInt("Variant"); std::vector AllInstAliases = Records.getAllDerivedDefinitions("InstAlias"); // Create a map from the qualified name to a list of potential matches. - std::map > AliasMap; - unsigned Variant = AsmWriter->getValueAsInt("Variant"); + typedef std::set, AliasPriorityComparator> + AliasWithPriority; + std::map AliasMap; for (std::vector::iterator I = AllInstAliases.begin(), E = AllInstAliases.end(); I != E; ++I) { CodeGenInstAlias *Alias = new CodeGenInstAlias(*I, Variant, Target); const Record *R = *I; - if (!R->getValueAsBit("EmitAlias")) - continue; // We were told not to emit the alias, but to emit the aliasee. + int Priority = R->getValueAsInt("EmitPriority"); + if (Priority < 1) + continue; // Aliases with priority 0 are never emitted. + const DagInit *DI = R->getValueAsDag("ResultInst"); const DefInit *Op = cast(DI->getOperator()); - AliasMap[getQualifiedName(Op->getDef())].push_back(Alias); + AliasMap[getQualifiedName(Op->getDef())].insert(std::make_pair(Alias, + Priority)); } // A map of which conditions need to be met for each instruction operand // before it can be matched to the mnemonic. std::map > IAPrinterMap; - for (std::map >::iterator - I = AliasMap.begin(), E = AliasMap.end(); I != E; ++I) { - std::vector &Aliases = I->second; - - for (std::vector::iterator - II = Aliases.begin(), IE = Aliases.end(); II != IE; ++II) { - const CodeGenInstAlias *CGA = *II; + for (auto &Aliases : AliasMap) { + for (auto &Alias : Aliases.second) { + const CodeGenInstAlias *CGA = Alias.first; unsigned LastOpNo = CGA->ResultInstOperandIndex.size(); unsigned NumResultOps = CountNumOperands(CGA->ResultInst->AsmString, Variant); @@ -900,7 +918,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { } if (CantHandle) continue; - IAPrinterMap[I->first].push_back(IAP); + IAPrinterMap[Aliases.first].push_back(IAP); } } -- cgit v1.2.3