Skip to content

Commit f03c485

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 f03c485

File tree

4 files changed

+41
-10
lines changed

4 files changed

+41
-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: 27 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,17 @@ 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, const CodeGenTarget &Target) const {
613618
// The primary comparator is the instruction mnemonic.
614619
if (int Cmp = Mnemonic.compare_insensitive(RHS.Mnemonic))
615620
return Cmp == -1;
616621

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

@@ -652,7 +662,8 @@ struct MatchableInfo {
652662
/// couldMatchAmbiguouslyWith - Check whether this matchable could
653663
/// ambiguously match the same set of operands as \p RHS (without being a
654664
/// strictly superior match).
655-
bool couldMatchAmbiguouslyWith(const MatchableInfo &RHS) const {
665+
bool couldMatchAmbiguouslyWith(const MatchableInfo &RHS,
666+
const CodeGenTarget &Target) const {
656667
// The primary comparator is the instruction mnemonic.
657668
if (Mnemonic != RHS.Mnemonic)
658669
return false;
@@ -661,6 +672,11 @@ struct MatchableInfo {
661672
if (AsmVariantID != RHS.AsmVariantID)
662673
return false;
663674

675+
// Sort by the resultant instuctions size, eg. for ARM instructions
676+
// we must choose the smallest matching instruction.
677+
if (Target.getPreferSmallerInstructions() && ResInstSize != RHS.ResInstSize)
678+
return false;
679+
664680
// The number of operands is unambiguous.
665681
if (AsmOperands.size() != RHS.AsmOperands.size())
666682
return false;
@@ -3224,17 +3240,18 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
32243240
// Sort the instruction table using the partial order on classes. We use
32253241
// stable_sort to ensure that ambiguous instructions are still
32263242
// 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; });
3243+
llvm::stable_sort(Info.Matchables,
3244+
[&Target](const std::unique_ptr<MatchableInfo> &a,
3245+
const std::unique_ptr<MatchableInfo> &b) {
3246+
return a->shouldBeMatchedBefore(*b, Target);
3247+
});
32313248

32323249
#ifdef EXPENSIVE_CHECKS
32333250
// Verify that the table is sorted and operator < works transitively.
32343251
for (auto I = Info.Matchables.begin(), E = Info.Matchables.end(); I != E;
32353252
++I) {
32363253
for (auto J = I; J != E; ++J) {
3237-
assert(!(**J < **I));
3254+
assert(!((*J)->shouldBeMatchedBefore(**I, Target)));
32383255
}
32393256
}
32403257
#endif
@@ -3253,7 +3270,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
32533270
const MatchableInfo &A = **I;
32543271
const MatchableInfo &B = **J;
32553272

3256-
if (A.couldMatchAmbiguouslyWith(B)) {
3273+
if (A.couldMatchAmbiguouslyWith(B, Target)) {
32573274
errs() << "warning: ambiguous matchables:\n";
32583275
A.dump();
32593276
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)