96 lines · cpp
1//===- bolt/Passes/FixRISCVCallsPass.cpp ------------------------*- C++ -*-===//2//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "bolt/Passes/FixRISCVCallsPass.h"10#include "bolt/Core/ParallelUtilities.h"11 12#include <iterator>13 14using namespace llvm;15 16namespace llvm {17namespace bolt {18 19void FixRISCVCallsPass::runOnFunction(BinaryFunction &BF) {20 auto &BC = BF.getBinaryContext();21 auto &MIB = BC.MIB;22 auto *Ctx = BC.Ctx.get();23 24 for (auto &BB : BF) {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");29 30 MCInst OldCall = *II;31 auto L = BC.scopeLock();32 33 if (MIB->isTailCall(*II))34 MIB->createTailCall(*II, Target, Ctx);35 else36 MIB->createCall(*II, Target, Ctx);37 38 MIB->moveAnnotations(std::move(OldCall), *II);39 ++II;40 continue;41 }42 43 auto NextII = std::next(II);44 45 if (NextII == BB.end())46 break;47 48 if (MIB->isRISCVCall(*II, *NextII)) {49 auto *Target = MIB->getTargetSymbol(*II);50 assert(Target && "Cannot find call target");51 52 MCInst OldCall = *NextII;53 auto L = BC.scopeLock();54 55 if (MIB->isTailCall(*NextII))56 MIB->createTailCall(*II, Target, Ctx);57 else58 MIB->createCall(*II, Target, Ctx);59 60 MIB->moveAnnotations(std::move(OldCall), *II);61 62 // The original offset was set on the jalr of the auipc+jalr pair. Since63 // the whole pair is replaced by a call, adjust the offset by -4 (the64 // size of a auipc).65 if (std::optional<uint32_t> Offset = MIB->getOffset(*II)) {66 assert(*Offset >= 4 && "Illegal jalr offset");67 MIB->setOffset(*II, *Offset - 4);68 }69 70 II = BB.eraseInstruction(NextII);71 continue;72 }73 74 ++II;75 }76 }77}78 79Error FixRISCVCallsPass::runOnFunctions(BinaryContext &BC) {80 if (!BC.isRISCV() || !BC.HasRelocations)81 return Error::success();82 83 ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {84 runOnFunction(BF);85 };86 87 ParallelUtilities::runOnEachFunction(88 BC, ParallelUtilities::SchedulingPolicy::SP_INST_LINEAR, WorkFun, nullptr,89 "FixRISCVCalls");90 91 return Error::success();92}93 94} // namespace bolt95} // namespace llvm96