brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.9 KiB · 90b5f58 Raw
88 lines · cpp
1//===- bolt/Passes/PLTCall.h - PLT call optimization ----------------------===//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// This file implements the PLTCall class, which replaces calls to PLT entries10// with indirect calls against GOT.11//12//===----------------------------------------------------------------------===//13 14#include "bolt/Passes/PLTCall.h"15#include "llvm/Support/CommandLine.h"16 17#define DEBUG_TYPE "bolt-plt"18 19using namespace llvm;20 21namespace opts {22 23extern cl::OptionCategory BoltOptCategory;24 25static cl::opt<bolt::PLTCall::OptType>26    PLT("plt", cl::desc("optimize PLT calls (requires linking with -znow)"),27        cl::init(bolt::PLTCall::OT_NONE),28        cl::values(clEnumValN(bolt::PLTCall::OT_NONE, "none",29                              "do not optimize PLT calls"),30                   clEnumValN(bolt::PLTCall::OT_HOT, "hot",31                              "optimize executed (hot) PLT calls"),32                   clEnumValN(bolt::PLTCall::OT_ALL, "all",33                              "optimize all PLT calls")),34        cl::ZeroOrMore, cl::cat(BoltOptCategory));35}36 37namespace llvm {38namespace bolt {39 40Error PLTCall::runOnFunctions(BinaryContext &BC) {41  if (opts::PLT == OT_NONE)42    return Error::success();43 44  uint64_t NumCallsOptimized = 0;45  for (auto &BFI : BC.getBinaryFunctions()) {46    BinaryFunction &Function = BFI.second;47    if (!shouldOptimize(Function))48      continue;49 50    if (opts::PLT == OT_HOT &&51        Function.getExecutionCount() == BinaryFunction::COUNT_NO_PROFILE)52      continue;53 54    for (BinaryBasicBlock &BB : Function) {55      if (opts::PLT == OT_HOT && !BB.getKnownExecutionCount())56        continue;57 58      for (auto II = BB.begin(); II != BB.end(); II++) {59        if (!BC.MIB->isCall(*II))60          continue;61        const MCSymbol *CallSymbol = BC.MIB->getTargetSymbol(*II);62        if (!CallSymbol)63          continue;64        const BinaryFunction *CalleeBF = BC.getFunctionForSymbol(CallSymbol);65        if (!CalleeBF || !CalleeBF->isPLTFunction())66          continue;67        const InstructionListType NewCode = BC.MIB->createIndirectPLTCall(68            std::move(*II), CalleeBF->getPLTSymbol(), BC.Ctx.get());69        II = BB.replaceInstruction(II, NewCode);70        assert(!NewCode.empty() && "PLT Call replacement must be non-empty");71        std::advance(II, NewCode.size() - 1);72        BC.MIB->addAnnotation(*II, "PLTCall", true);73        ++NumCallsOptimized;74      }75    }76  }77 78  if (NumCallsOptimized) {79    BC.RequiresZNow = true;80    BC.outs() << "BOLT-INFO: " << NumCallsOptimized81              << " PLT calls in the binary were optimized.\n";82  }83  return Error::success();84}85 86} // namespace bolt87} // namespace llvm88