1 #include "bolt/Passes/FixRISCVCallsPass.h"
2 #include "bolt/Core/ParallelUtilities.h"
11 void FixRISCVCallsPass::runOnFunction(BinaryFunction
&BF
) {
12 auto &BC
= BF
.getBinaryContext();
14 auto *Ctx
= BC
.Ctx
.get();
17 for (auto II
= BB
.begin(); II
!= BB
.end();) {
18 if (MIB
->isCall(*II
) && !MIB
->isIndirectCall(*II
)) {
19 auto *Target
= MIB
->getTargetSymbol(*II
);
20 assert(Target
&& "Cannot find call target");
23 auto L
= BC
.scopeLock();
25 if (MIB
->isTailCall(*II
))
26 MIB
->createTailCall(*II
, Target
, Ctx
);
28 MIB
->createCall(*II
, Target
, Ctx
);
30 MIB
->moveAnnotations(std::move(OldCall
), *II
);
35 auto NextII
= std::next(II
);
37 if (NextII
== BB
.end())
40 if (MIB
->isRISCVCall(*II
, *NextII
)) {
41 auto *Target
= MIB
->getTargetSymbol(*II
);
42 assert(Target
&& "Cannot find call target");
44 MCInst OldCall
= *NextII
;
45 auto L
= BC
.scopeLock();
47 if (MIB
->isTailCall(*NextII
))
48 MIB
->createTailCall(*II
, Target
, Ctx
);
50 MIB
->createCall(*II
, Target
, Ctx
);
52 MIB
->moveAnnotations(std::move(OldCall
), *II
);
54 // The original offset was set on the jalr of the auipc+jalr pair. Since
55 // the whole pair is replaced by a call, adjust the offset by -4 (the
57 if (std::optional
<uint32_t> Offset
= MIB
->getOffset(*II
)) {
58 assert(*Offset
>= 4 && "Illegal jalr offset");
59 MIB
->setOffset(*II
, *Offset
- 4);
62 II
= BB
.eraseInstruction(NextII
);
71 void FixRISCVCallsPass::runOnFunctions(BinaryContext
&BC
) {
72 if (!BC
.isRISCV() || !BC
.HasRelocations
)
75 ParallelUtilities::WorkFuncTy WorkFun
= [&](BinaryFunction
&BF
) {
79 ParallelUtilities::runOnEachFunction(
80 BC
, ParallelUtilities::SchedulingPolicy::SP_INST_LINEAR
, WorkFun
, nullptr,