Skip to content

Commit 505a547

Browse files
[TabeGen] Add PreferSmallerInstructions for Targets.
This option means that in assembly matching instructions with smaller encodings will be preferred. This will be used for the ARM instruciton set where this is the correct behaviour after some other refactoring.
1 parent b92c3fe commit 505a547

File tree

4 files changed

+42
-10
lines changed

4 files changed

+42
-10
lines changed

llvm/include/llvm/Target/Target.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,6 +1724,11 @@ class Target {
17241724
// setting hasExtraDefRegAllocReq and hasExtraSrcRegAllocReq to 1
17251725
// for all opcodes if this flag is set to 0.
17261726
int AllowRegisterRenaming = 0;
1727+
1728+
// PreferSmallerInstructions - Should the assembly matcher prefer the smaller
1729+
// instructions. 1 if the instruction set should sort by size,
1730+
// 0 otherwise.
1731+
bit PreferSmallerInstructions = 0;
17271732
}
17281733

17291734
//===----------------------------------------------------------------------===//

llvm/utils/TableGen/AsmMatcherEmitter.cpp

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,9 @@ struct MatchableInfo {
502502
/// matchable came from.
503503
Record *const TheDef;
504504

505+
// ResInstSize - The size of the resulting instruction for this matchable.
506+
unsigned ResInstSize;
507+
505508
/// DefRec - This is the definition that it came from.
506509
PointerUnion<const CodeGenInstruction *, const CodeGenInstAlias *> DefRec;
507510

@@ -543,10 +546,12 @@ struct MatchableInfo {
543546

544547
MatchableInfo(const CodeGenInstruction &CGI)
545548
: AsmVariantID(0), AsmString(CGI.AsmString), TheDef(CGI.TheDef),
546-
DefRec(&CGI), UseInstAsmMatchConverter(true) {}
549+
ResInstSize(TheDef->getValueAsInt("Size")), DefRec(&CGI),
550+
UseInstAsmMatchConverter(true) {}
547551

548552
MatchableInfo(std::unique_ptr<const CodeGenInstAlias> Alias)
549553
: AsmVariantID(0), AsmString(Alias->AsmString), TheDef(Alias->TheDef),
554+
ResInstSize(Alias->ResultInst->TheDef->getValueAsInt("Size")),
550555
DefRec(Alias.release()), UseInstAsmMatchConverter(TheDef->getValueAsBit(
551556
"UseInstAsmMatchConverter")) {}
552557

@@ -608,12 +613,18 @@ struct MatchableInfo {
608613
void buildInstructionResultOperands();
609614
void buildAliasResultOperands(bool AliasConstraintsAreChecked);
610615

611-
/// operator< - Compare two matchables.
612-
bool operator<(const MatchableInfo &RHS) const {
616+
/// shouldBeMatchedBefore - Compare two matchables for ordering.
617+
bool shouldBeMatchedBefore(const MatchableInfo &RHS,
618+
const CodeGenTarget &Target) const {
613619
// The primary comparator is the instruction mnemonic.
614620
if (int Cmp = Mnemonic.compare_insensitive(RHS.Mnemonic))
615621
return Cmp == -1;
616622

623+
// Sort by the resultant instuctions size, eg. for ARM instructions
624+
// we must choose the smallest matching instruction.
625+
if (Target.getPreferSmallerInstructions() && ResInstSize != RHS.ResInstSize)
626+
return ResInstSize < RHS.ResInstSize;
627+
617628
if (AsmOperands.size() != RHS.AsmOperands.size())
618629
return AsmOperands.size() < RHS.AsmOperands.size();
619630

@@ -652,7 +663,8 @@ struct MatchableInfo {
652663
/// couldMatchAmbiguouslyWith - Check whether this matchable could
653664
/// ambiguously match the same set of operands as \p RHS (without being a
654665
/// strictly superior match).
655-
bool couldMatchAmbiguouslyWith(const MatchableInfo &RHS) const {
666+
bool couldMatchAmbiguouslyWith(const MatchableInfo &RHS,
667+
const CodeGenTarget &Target) const {
656668
// The primary comparator is the instruction mnemonic.
657669
if (Mnemonic != RHS.Mnemonic)
658670
return false;
@@ -661,6 +673,11 @@ struct MatchableInfo {
661673
if (AsmVariantID != RHS.AsmVariantID)
662674
return false;
663675

676+
// Sort by the resultant instuctions size, eg. for ARM instructions
677+
// we must choose the smallest matching instruction.
678+
if (Target.getPreferSmallerInstructions() && ResInstSize != RHS.ResInstSize)
679+
return false;
680+
664681
// The number of operands is unambiguous.
665682
if (AsmOperands.size() != RHS.AsmOperands.size())
666683
return false;
@@ -3224,17 +3241,18 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
32243241
// Sort the instruction table using the partial order on classes. We use
32253242
// stable_sort to ensure that ambiguous instructions are still
32263243
// deterministically ordered.
3227-
llvm::stable_sort(
3228-
Info.Matchables,
3229-
[](const std::unique_ptr<MatchableInfo> &a,
3230-
const std::unique_ptr<MatchableInfo> &b) { return *a < *b; });
3244+
llvm::stable_sort(Info.Matchables,
3245+
[&Target](const std::unique_ptr<MatchableInfo> &a,
3246+
const std::unique_ptr<MatchableInfo> &b) {
3247+
return a->shouldBeMatchedBefore(*b, Target);
3248+
});
32313249

32323250
#ifdef EXPENSIVE_CHECKS
32333251
// Verify that the table is sorted and operator < works transitively.
32343252
for (auto I = Info.Matchables.begin(), E = Info.Matchables.end(); I != E;
32353253
++I) {
32363254
for (auto J = I; J != E; ++J) {
3237-
assert(!(**J < **I));
3255+
assert(!((*J)->shouldBeMatchedBefore(**I, Target)));
32383256
}
32393257
}
32403258
#endif
@@ -3253,7 +3271,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
32533271
const MatchableInfo &A = **I;
32543272
const MatchableInfo &B = **J;
32553273

3256-
if (A.couldMatchAmbiguouslyWith(B)) {
3274+
if (A.couldMatchAmbiguouslyWith(B, Target)) {
32573275
errs() << "warning: ambiguous matchables:\n";
32583276
A.dump();
32593277
errs() << "\nis incomparable with:\n";

llvm/utils/TableGen/CodeGenTarget.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,10 @@ bool CodeGenTarget::getAllowRegisterRenaming() const {
332332
return TargetRec->getValueAsInt("AllowRegisterRenaming");
333333
}
334334

335+
bool CodeGenTarget::getPreferSmallerInstructions() const {
336+
return TargetRec->getValueAsBit("PreferSmallerInstructions");
337+
}
338+
335339
/// getAsmParser - Return the AssemblyParser definition for this target.
336340
///
337341
Record *CodeGenTarget::getAsmParser() const {

llvm/utils/TableGen/CodeGenTarget.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ class CodeGenTarget {
9999
///
100100
bool getAllowRegisterRenaming() const;
101101

102+
/// getPreferSmallerInstructions - Return the PreferSmallerInstructions
103+
/// flag value for this target.
104+
///
105+
bool getPreferSmallerInstructions() const;
106+
102107
/// getAsmParser - Return the AssemblyParser definition for this target.
103108
///
104109
Record *getAsmParser() const;

0 commit comments

Comments
 (0)