[BOLT][NFC] Unify isTailCall interface across X86 and AArch64

Summary:
Move the common code into MCPlusBuilder.h.
Use group 1 `kTailCall` MCAnnotation instead of dynamically allocated
annotation.
This diff reduces the processing time overhead to 1.5% vs using
TAILJMP opcode.

(cherry picked from FBD30055585)
This commit is contained in:
Amir Ayupov 2021-07-29 17:28:51 -07:00 committed by Maksim Panchenko
parent 89a2e16037
commit 60b10a8ead
5 changed files with 34 additions and 39 deletions

View File

@ -56,6 +56,7 @@ public:
kEHAction, /// Action for exception handler.
kGnuArgsSize, /// GNU args size.
kJumpTable, /// Jump Table.
kTailCall, /// Tail call.
kConditionalTailCall, /// CTC.
kGeneric /// First generic annotation.
};

View File

@ -120,6 +120,19 @@ bool MCPlusBuilder::equals(const MCTargetExpr &A, const MCTargetExpr &B,
llvm_unreachable("target-specific expressions are unsupported");
}
void MCPlusBuilder::setTailCall(MCInst &Inst) {
assert(!hasAnnotation(Inst, MCAnnotation::kTailCall));
setAnnotationOpValue(Inst, MCAnnotation::kTailCall, true);
}
bool MCPlusBuilder::isTailCall(const MCInst &Inst) const {
if (hasAnnotation(Inst, MCAnnotation::kTailCall))
return true;
if (getConditionalTailCall(Inst))
return true;
return false;
}
Optional<MCLandingPad> MCPlusBuilder::getEHInfo(const MCInst &Inst) const {
if (!isCall(Inst))
return NoneType();
@ -245,11 +258,11 @@ void MCPlusBuilder::stripAnnotations(MCInst &Inst, bool KeepTC) {
if (!AnnotationInst)
return;
// Preserve TailCall annotation.
auto IsTCOrErr = tryGetAnnotationAs<bool>(Inst, "TC");
auto IsTC = hasAnnotation(Inst, MCAnnotation::kTailCall);
Inst.erase(std::prev(Inst.end()));
if (KeepTC && IsTCOrErr)
addAnnotation(Inst, "TC", *IsTCOrErr);
if (KeepTC && IsTC)
setTailCall(Inst);
}
void

View File

@ -157,6 +157,10 @@ protected:
/// Names of non-standard annotations.
SmallVector<std::string, 8> AnnotationNames;
/// Allocate the TailCall annotation value. Clients of the target-specific
/// MCPlusBuilder classes must use convert/lower/create* interfaces instead.
void setTailCall(MCInst &Inst);
public:
class InstructionIterator
: public std::iterator<std::bidirectional_iterator_tag, MCInst> {
@ -1000,10 +1004,7 @@ public:
}
/// Return true if the instruction is a tail call.
virtual bool isTailCall(const MCInst &Inst) const {
llvm_unreachable("not implemented");
return false;
}
bool isTailCall(const MCInst &Inst) const;
/// Return true if the instruction is a call with an exception handling info.
virtual bool isInvoke(const MCInst &Inst) const {

View File

@ -741,32 +741,23 @@ public:
return 28;
}
bool isTailCall(const MCInst &Inst) const override {
auto IsTCOrErr = tryGetAnnotationAs<bool>(Inst, "TC");
if (IsTCOrErr)
return *IsTCOrErr;
if (getConditionalTailCall(Inst))
return true;
return false;
}
bool createTailCall(MCInst &Inst, const MCSymbol *Target,
MCContext *Ctx) override {
Inst.setOpcode(AArch64::B);
Inst.addOperand(MCOperand::createExpr(getTargetExprFor(
Inst, MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx),
*Ctx, 0)));
addAnnotation(Inst, "TC", true);
setTailCall(Inst);
return true;
}
bool convertJmpToTailCall(MCInst &Inst) override {
addAnnotation(Inst, "TC", true);
setTailCall(Inst);
return true;
}
bool convertTailCallToJmp(MCInst &Inst) override {
removeAnnotation(Inst, "TC");
removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);
removeAnnotation(Inst, "Offset");
if (getConditionalTailCall(Inst))
unsetConditionalTailCall(Inst);
@ -774,7 +765,7 @@ public:
}
bool lowerTailCall(MCInst &Inst) override {
removeAnnotation(Inst, "TC");
removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);
if (getConditionalTailCall(Inst))
unsetConditionalTailCall(Inst);
return true;

View File

@ -1977,17 +1977,6 @@ public:
return Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg();
}
bool isTailCall(const MCInst &Inst) const override {
auto IsTCOrErr = tryGetAnnotationAs<bool>(Inst, "TC");
if (IsTCOrErr)
return *IsTCOrErr;
if (getConditionalTailCall(Inst))
return true;
return false;
}
bool requiresAlignedAddress(const MCInst &Inst) const override {
const MCInstrDesc &Desc = Info->get(Inst.getOpcode());
for (unsigned int I = 0; I < Desc.getNumOperands(); ++I) {
@ -2026,7 +2015,7 @@ public:
}
Inst.setOpcode(NewOpcode);
addAnnotation(Inst, "TC", true);
setTailCall(Inst);
return true;
}
@ -2047,7 +2036,7 @@ public:
}
Inst.setOpcode(NewOpcode);
removeAnnotation(Inst, "TC");
removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);
removeAnnotation(Inst, "Offset");
return true;
}
@ -2069,7 +2058,7 @@ public:
}
Inst.setOpcode(NewOpcode);
removeAnnotation(Inst, "TC");
removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);
return true;
}
@ -2108,7 +2097,7 @@ public:
void convertIndirectCallToLoad(MCInst &Inst, MCPhysReg Reg) override {
bool IsTailCall = isTailCall(Inst);
if (IsTailCall)
removeAnnotation(Inst, "TC");
removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);
if (Inst.getOpcode() == X86::CALL64m ||
(Inst.getOpcode() == X86::JMP32m && IsTailCall)) {
Inst.setOpcode(X86::MOV64rm);
@ -2175,7 +2164,7 @@ public:
bool lowerTailCall(MCInst &Inst) override {
if (Inst.getOpcode() == X86::JMP_4 && isTailCall(Inst)) {
Inst.setOpcode(X86::JMP_1);
removeAnnotation(Inst, "TC");
removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);
return true;
}
return false;
@ -2976,7 +2965,7 @@ public:
*Ctx)));
Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg
if (IsTailCall)
addAnnotation(Inst, "TC", true);
setTailCall(Inst);
return true;
}
@ -2985,7 +2974,7 @@ public:
Inst.setOpcode(X86::JMP_4);
Inst.addOperand(MCOperand::createExpr(
MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx)));
addAnnotation(Inst, "TC", true);
setTailCall(Inst);
return true;
}
@ -3517,7 +3506,7 @@ public:
}
}
if (IsTailCall)
addAnnotation(CallOrJmp, "TC", true);
setTailCall(CallOrJmp);
if (CallOrJmp.getOpcode() == X86::CALL64r ||
CallOrJmp.getOpcode() == X86::CALL64pcrel32) {