forked from OSchip/llvm-project
[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:
parent
89a2e16037
commit
60b10a8ead
|
@ -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.
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue