Skip to content

Commit 97a32f2

Browse files
committed
MC: Add MCSpecifierExpr to unify target MCExprs
Many targets define MCTargetExpr subclasses just to encode an expression with a relocation specifier. Create a generic MCSpecifierExpr to be inherited instead. Migrate M68k and SPARC as examples.
1 parent b4b86a7 commit 97a32f2

File tree

14 files changed

+75
-56
lines changed

14 files changed

+75
-56
lines changed

llvm/include/llvm/MC/MCExpr.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class MCExpr {
3838
Constant, ///< Constant expressions.
3939
SymbolRef, ///< References to labels and assigned expressions.
4040
Unary, ///< Unary expressions.
41+
Specifier, ///< Expression with a relocation specifier.
4142
Target ///< Target specific expression.
4243
};
4344

@@ -502,6 +503,33 @@ class LLVM_ABI MCTargetExpr : public MCExpr {
502503
}
503504
};
504505

506+
/// Extension point for target-specific MCExpr subclasses with a relocation
507+
/// specifier, serving as a replacement for MCSymbolRefExpr::VariantKind.
508+
/// Limit this to top-level use, avoiding its inclusion as a subexpression.
509+
class LLVM_ABI MCSpecifierExpr : public MCExpr {
510+
protected:
511+
using Spec = uint16_t;
512+
const MCExpr *Expr;
513+
// Target-specific relocation specifier code
514+
const Spec specifier;
515+
516+
protected:
517+
explicit MCSpecifierExpr(const MCExpr *Expr, Spec S)
518+
: MCExpr(Specifier, SMLoc()), Expr(Expr), specifier(S) {}
519+
virtual ~MCSpecifierExpr();
520+
521+
public:
522+
Spec getSpecifier() const { return specifier; }
523+
const MCExpr *getSubExpr() const { return Expr; }
524+
525+
virtual void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const = 0;
526+
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm) const;
527+
528+
static bool classof(const MCExpr *E) {
529+
return E->getKind() == MCExpr::Specifier;
530+
}
531+
};
532+
505533
} // end namespace llvm
506534

507535
#endif // LLVM_MC_MCEXPR_H

llvm/lib/MC/MCExpr.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "llvm/MC/MCAssembler.h"
1616
#include "llvm/MC/MCContext.h"
1717
#include "llvm/MC/MCObjectWriter.h"
18+
#include "llvm/MC/MCStreamer.h"
1819
#include "llvm/MC/MCSymbol.h"
1920
#include "llvm/MC/MCValue.h"
2021
#include "llvm/Support/Casting.h"
@@ -171,6 +172,9 @@ void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI,
171172
OS << ')';
172173
return;
173174
}
175+
176+
case MCExpr::Specifier:
177+
return cast<MCSpecifierExpr>(this)->printImpl(OS, MAI);
174178
}
175179

176180
llvm_unreachable("Invalid expression kind!");
@@ -207,6 +211,9 @@ bool MCExpr::isSymbolUsedInExpression(const MCSymbol *Sym) const {
207211
static_cast<const MCUnaryExpr *>(this)->getSubExpr();
208212
return SubExpr->isSymbolUsedInExpression(Sym);
209213
}
214+
case MCExpr::Specifier:
215+
return static_cast<const MCSpecifierExpr *>(this)->isSymbolUsedInExpression(
216+
Sym);
210217
}
211218

212219
llvm_unreachable("Unknown expr kind!");
@@ -702,6 +709,8 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
702709

703710
return true;
704711
}
712+
case Specifier:
713+
return cast<MCSpecifierExpr>(this)->evaluateAsRelocatableImpl(Res, Asm);
705714
}
706715

707716
llvm_unreachable("Invalid assembly expression kind!");
@@ -750,7 +759,21 @@ MCFragment *MCExpr::findAssociatedFragment() const {
750759
// Otherwise, return the first non-null fragment.
751760
return LHS_F ? LHS_F : RHS_F;
752761
}
762+
763+
case Specifier:
764+
return cast<MCSpecifierExpr>(this)->getSubExpr()->findAssociatedFragment();
753765
}
754766

755767
llvm_unreachable("Invalid assembly expression kind!");
756768
}
769+
770+
MCSpecifierExpr::~MCSpecifierExpr() {}
771+
772+
bool MCSpecifierExpr::evaluateAsRelocatableImpl(MCValue &Res,
773+
const MCAssembler *Asm) const {
774+
if (!getSubExpr()->evaluateAsRelocatable(Res, Asm))
775+
return false;
776+
777+
Res.setSpecifier(specifier);
778+
return !Res.getSubSym();
779+
}

llvm/lib/MC/MCParser/AsmParser.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,6 +1344,8 @@ const MCExpr *MCAsmParser::applySpecifier(const MCExpr *E, uint32_t Spec) {
13441344
// Recurse over the given expression, rebuilding it to apply the given variant
13451345
// if there is exactly one symbol.
13461346
switch (E->getKind()) {
1347+
case MCExpr::Specifier:
1348+
llvm_unreachable("cannot apply another specifier to MCSpecifierExpr");
13471349
case MCExpr::Target:
13481350
case MCExpr::Constant:
13491351
return nullptr;

llvm/lib/MC/MCStreamer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,10 @@ void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
11861186
case MCExpr::Unary:
11871187
visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
11881188
break;
1189+
1190+
case MCExpr::Specifier:
1191+
visitUsedExpr(*cast<MCSpecifierExpr>(Expr).getSubExpr());
1192+
break;
11891193
}
11901194
}
11911195

llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,7 @@ static bool needsPCRel(const MCExpr *Expr) {
547547
}
548548
case MCExpr::Unary:
549549
return needsPCRel(cast<MCUnaryExpr>(Expr)->getSubExpr());
550+
case MCExpr::Specifier:
550551
case MCExpr::Target:
551552
case MCExpr::Constant:
552553
return false;

llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,8 @@ static void knownBitsMapHelper(const MCExpr *Expr, KnownBitsMap &KBM,
557557
case MCExpr::ExprKind::Target: {
558558
targetOpKnownBitsMapHelper(Expr, KBM, Depth);
559559
return;
560+
case MCExpr::Specifier:
561+
llvm_unreachable("unused by this backend");
560562
}
561563
}
562564
}

llvm/lib/Target/M68k/MCTargetDesc/M68kMCExpr.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,3 @@ const M68kMCExpr *M68kMCExpr::create(const MCExpr *Expr, Specifier S,
1919
}
2020

2121
void M68kMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {}
22-
23-
bool M68kMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
24-
const MCAssembler *Asm) const {
25-
if (!getSubExpr()->evaluateAsRelocatable(Res, Asm))
26-
return false;
27-
28-
Res.setSpecifier(specifier);
29-
return !Res.getSubSym();
30-
}
31-
32-
void M68kMCExpr::visitUsedExpr(MCStreamer &S) const { S.visitUsedExpr(*Expr); }

llvm/lib/Target/M68k/MCTargetDesc/M68kMCExpr.h

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
namespace llvm {
2020

21-
class M68kMCExpr : public MCTargetExpr {
21+
class M68kMCExpr : public MCSpecifierExpr {
2222
public:
2323
enum Specifier {
2424
VK_None,
@@ -34,27 +34,14 @@ class M68kMCExpr : public MCTargetExpr {
3434
VK_TPOFF,
3535
};
3636

37-
private:
38-
const MCExpr *Expr;
39-
const Specifier specifier;
40-
4137
protected:
4238
explicit M68kMCExpr(const MCExpr *Expr, Specifier S)
43-
: Expr(Expr), specifier(S) {}
39+
: MCSpecifierExpr(Expr, S) {}
4440

4541
public:
4642
static const M68kMCExpr *create(const MCExpr *, Specifier, MCContext &);
4743

48-
Specifier getSpecifier() const { return specifier; }
49-
const MCExpr *getSubExpr() const { return Expr; }
50-
5144
void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
52-
bool evaluateAsRelocatableImpl(MCValue &Res,
53-
const MCAssembler *Asm) const override;
54-
void visitUsedExpr(MCStreamer &Streamer) const override;
55-
MCFragment *findAssociatedFragment() const override {
56-
return getSubExpr()->findAssociatedFragment();
57-
}
5845
};
5946
} // namespace llvm
6047

llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,6 +1783,8 @@ static bool isEvaluated(const MCExpr *Expr) {
17831783
}
17841784
case MCExpr::Unary:
17851785
return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1786+
case MCExpr::Specifier:
1787+
llvm_unreachable("unused by this backend");
17861788
case MCExpr::Target:
17871789
return true;
17881790
}

llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ EvaluateCRExpr(const MCExpr *E) {
8787

8888
return Res < 0 ? -1 : Res;
8989
}
90+
case MCExpr::Specifier:
91+
llvm_unreachable("unused by this backend");
9092
}
9193

9294
llvm_unreachable("Invalid expression kind!");
@@ -1420,6 +1422,8 @@ const MCExpr *PPCAsmParser::extractSpecifier(const MCExpr *E,
14201422
return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);
14211423
break;
14221424
}
1425+
case MCExpr::Specifier:
1426+
llvm_unreachable("unused by this backend");
14231427
}
14241428

14251429
return E;

llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1661,6 +1661,9 @@ static bool hasGOTReference(const MCExpr *Expr) {
16611661

16621662
case MCExpr::Unary:
16631663
return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr());
1664+
1665+
case MCExpr::Specifier:
1666+
llvm_unreachable("unused by this backend");
16641667
}
16651668
return false;
16661669
}

llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -133,16 +133,3 @@ uint16_t SparcMCExpr::getFixupKind() const {
133133
assert(uint16_t(specifier) < FirstTargetFixupKind);
134134
return specifier;
135135
}
136-
137-
bool SparcMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
138-
const MCAssembler *Asm) const {
139-
if (!getSubExpr()->evaluateAsRelocatable(Res, Asm))
140-
return false;
141-
142-
Res.setSpecifier(specifier);
143-
return true;
144-
}
145-
146-
void SparcMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
147-
Streamer.visitUsedExpr(*getSubExpr());
148-
}

llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,32 +20,17 @@
2020
namespace llvm {
2121

2222
class StringRef;
23-
class SparcMCExpr : public MCTargetExpr {
23+
class SparcMCExpr : public MCSpecifierExpr {
2424
private:
25-
const uint16_t specifier;
26-
const MCExpr *Expr;
27-
2825
explicit SparcMCExpr(uint16_t S, const MCExpr *Expr)
29-
: specifier(S), Expr(Expr) {}
26+
: MCSpecifierExpr(Expr, S) {}
3027

3128
public:
3229
static const SparcMCExpr *create(uint16_t S, const MCExpr *Expr,
3330
MCContext &Ctx);
34-
uint16_t getSpecifier() const { return specifier; }
35-
const MCExpr *getSubExpr() const { return Expr; }
3631
uint16_t getFixupKind() const;
3732

3833
void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
39-
bool evaluateAsRelocatableImpl(MCValue &Res,
40-
const MCAssembler *Asm) const override;
41-
void visitUsedExpr(MCStreamer &Streamer) const override;
42-
MCFragment *findAssociatedFragment() const override {
43-
return getSubExpr()->findAssociatedFragment();
44-
}
45-
46-
static bool classof(const MCExpr *E) {
47-
return E->getKind() == MCExpr::Target;
48-
}
4934

5035
static uint16_t parseSpecifier(StringRef name);
5136
static StringRef getSpecifierName(uint16_t S);

llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,8 @@ const MCExpr *VEAsmParser::extractSpecifier(const MCExpr *E,
10481048
case MCExpr::Target:
10491049
case MCExpr::Constant:
10501050
return nullptr;
1051+
case MCExpr::Specifier:
1052+
llvm_unreachable("unused by this backend");
10511053

10521054
case MCExpr::SymbolRef: {
10531055
const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);

0 commit comments

Comments
 (0)