diff options
author | Fangrui Song <i@maskray.me> | 2025-03-30 22:03:14 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-30 22:03:14 -0700 |
commit | 04a67528d303ac4be7943b2ae57222f9c9fd509a (patch) | |
tree | d19bad10d00a421c1794f313556e8c5368738df4 /llvm/lib/MC/MCExpr.cpp | |
parent | c9095aa3103460c967fd5ee5dcc695284793ef3c (diff) | |
download | llvm-04a67528d303ac4be7943b2ae57222f9c9fd509a.zip llvm-04a67528d303ac4be7943b2ae57222f9c9fd509a.tar.gz llvm-04a67528d303ac4be7943b2ae57222f9c9fd509a.tar.bz2 |
[MC] Simplify MCBinaryExpr/MCUnaryExpr printing by reducing parentheses (#133674)
The existing pretty printer generates excessive parentheses for
MCBinaryExpr expressions. This update removes unnecessary parentheses
of MCBinaryExpr with +/- operators and MCUnaryExpr.
Since relocatable expressions only use + and -, this change improves
readability in most cases.
Examples:
- (SymA - SymB) + C now prints as SymA - SymB + C.
This updates the output of -fexperimental-relative-c++-abi-vtables for
AArch64 and x86 to `.long _ZN1B3fooEv@PLT-_ZTV1B-8`
- expr + (MCTargetExpr) now prints as expr + MCTargetExpr, with this
change primarily affecting AMDGPUMCExpr.
Diffstat (limited to 'llvm/lib/MC/MCExpr.cpp')
-rw-r--r-- | llvm/lib/MC/MCExpr.cpp | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp index 2532475..fa5c3da 100644 --- a/llvm/lib/MC/MCExpr.cpp +++ b/llvm/lib/MC/MCExpr.cpp @@ -37,10 +37,22 @@ STATISTIC(MCExprEvaluate, "Number of MCExpr evaluations"); } // end namespace stats } // end anonymous namespace +static int getPrecedence(MCBinaryExpr::Opcode Op) { + switch (Op) { + case MCBinaryExpr::Add: + case MCBinaryExpr::Sub: + return 1; + default: + return 0; + } +} + // VariantKind printing and formatting utilize MAI. operator<< (dump and some // target code) specifies MAI as nullptr and should be avoided when MAI is // needed. -void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI) const { +void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI, + int SurroundingPrec) const { + constexpr int MaxPrec = 9; switch (getKind()) { case MCExpr::Target: return cast<MCTargetExpr>(this)->printImpl(OS, MAI); @@ -98,24 +110,26 @@ void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI) const { case MCUnaryExpr::Not: OS << '~'; break; case MCUnaryExpr::Plus: OS << '+'; break; } - bool Binary = UE.getSubExpr()->getKind() == MCExpr::Binary; - if (Binary) OS << "("; - UE.getSubExpr()->print(OS, MAI); - if (Binary) OS << ")"; + UE.getSubExpr()->print(OS, MAI, MaxPrec); return; } case MCExpr::Binary: { const MCBinaryExpr &BE = cast<MCBinaryExpr>(*this); - - // Only print parens around the LHS if it is non-trivial. - if (isa<MCConstantExpr>(BE.getLHS()) || isa<MCSymbolRefExpr>(BE.getLHS())) { - BE.getLHS()->print(OS, MAI); - } else { + // We want to avoid redundant parentheses for relocatable expressions like + // a-b+c. + // + // Print '(' if the current operator has lower precedence than the + // surrounding operator, or if the surrounding operator's precedence is + // unknown (set to HighPrecedence). + int Prec = getPrecedence(BE.getOpcode()); + bool Paren = Prec < SurroundingPrec; + if (Paren) OS << '('; - BE.getLHS()->print(OS, MAI); - OS << ')'; - } + // Many operators' precedence is different from C. Set the precedence to + // HighPrecedence for unknown operators. + int SubPrec = Prec ? Prec : MaxPrec; + BE.getLHS()->print(OS, MAI, SubPrec); switch (BE.getOpcode()) { case MCBinaryExpr::Add: @@ -123,6 +137,8 @@ void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI) const { if (const MCConstantExpr *RHSC = dyn_cast<MCConstantExpr>(BE.getRHS())) { if (RHSC->getValue() < 0) { OS << RHSC->getValue(); + if (Paren) + OS << ')'; return; } } @@ -150,14 +166,9 @@ void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI) const { case MCBinaryExpr::Xor: OS << '^'; break; } - // Only print parens around the LHS if it is non-trivial. - if (isa<MCConstantExpr>(BE.getRHS()) || isa<MCSymbolRefExpr>(BE.getRHS())) { - BE.getRHS()->print(OS, MAI); - } else { - OS << '('; - BE.getRHS()->print(OS, MAI); + BE.getRHS()->print(OS, MAI, SubPrec + 1); + if (Paren) OS << ')'; - } return; } } |