1 //===- bolt/Passes/FixRISCVCallsPass.cpp ------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "bolt/Passes/FixRISCVCallsPass.h"
10 #include "bolt/Core/ParallelUtilities.h"
19 void FixRISCVCallsPass::runOnFunction(BinaryFunction
&BF
) {
20 auto &BC
= BF
.getBinaryContext();
22 auto *Ctx
= BC
.Ctx
.get();
25 for (auto II
= BB
.begin(); II
!= BB
.end();) {
26 if (MIB
->isCall(*II
) && !MIB
->isIndirectCall(*II
)) {
27 auto *Target
= MIB
->getTargetSymbol(*II
);
28 assert(Target
&& "Cannot find call target");
31 auto L
= BC
.scopeLock();
33 if (MIB
->isTailCall(*II
))
34 MIB
->createTailCall(*II
, Target
, Ctx
);
36 MIB
->createCall(*II
, Target
, Ctx
);
38 MIB
->moveAnnotations(std::move(OldCall
), *II
);
43 auto NextII
= std::next(II
);
45 if (NextII
== BB
.end())
48 if (MIB
->isRISCVCall(*II
, *NextII
)) {
49 auto *Target
= MIB
->getTargetSymbol(*II
);
50 assert(Target
&& "Cannot find call target");
52 MCInst OldCall
= *NextII
;
53 auto L
= BC
.scopeLock();
55 if (MIB
->isTailCall(*NextII
))
56 MIB
->createTailCall(*II
, Target
, Ctx
);
58 MIB
->createCall(*II
, Target
, Ctx
);
60 MIB
->moveAnnotations(std::move(OldCall
), *II
);
62 // The original offset was set on the jalr of the auipc+jalr pair. Since
63 // the whole pair is replaced by a call, adjust the offset by -4 (the
65 if (std::optional
<uint32_t> Offset
= MIB
->getOffset(*II
)) {
66 assert(*Offset
>= 4 && "Illegal jalr offset");
67 MIB
->setOffset(*II
, *Offset
- 4);
70 II
= BB
.eraseInstruction(NextII
);
79 Error
FixRISCVCallsPass::runOnFunctions(BinaryContext
&BC
) {
80 if (!BC
.isRISCV() || !BC
.HasRelocations
)
81 return Error::success();
83 ParallelUtilities::WorkFuncTy WorkFun
= [&](BinaryFunction
&BF
) {
87 ParallelUtilities::runOnEachFunction(
88 BC
, ParallelUtilities::SchedulingPolicy::SP_INST_LINEAR
, WorkFun
, nullptr,
91 return Error::success();