Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/Utils/Instrumentation.cpp
213799 views
//===-- Instrumentation.cpp - TransformUtils Infrastructure ---------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file defines the common initialization infrastructure for the9// Instrumentation library.10//11//===----------------------------------------------------------------------===//1213#include "llvm/Transforms/Utils/Instrumentation.h"14#include "llvm/IR/DiagnosticInfo.h"15#include "llvm/IR/DiagnosticPrinter.h"16#include "llvm/IR/IntrinsicInst.h"17#include "llvm/IR/Module.h"18#include "llvm/TargetParser/Triple.h"1920using namespace llvm;2122static cl::opt<bool> ClIgnoreRedundantInstrumentation(23"ignore-redundant-instrumentation",24cl::desc("Ignore redundant instrumentation"), cl::Hidden, cl::init(false));2526/// Check if module has flag attached, if not add the flag.27bool llvm::checkIfAlreadyInstrumented(Module &M, StringRef Flag) {28if (!M.getModuleFlag(Flag)) {29M.addModuleFlag(Module::ModFlagBehavior::Override, Flag, 1);30return false;31}32if (ClIgnoreRedundantInstrumentation)33return true;34std::string diagInfo =35"Redundant instrumentation detected, with module flag: " +36std::string(Flag);37M.getContext().diagnose(38DiagnosticInfoInstrumentation(diagInfo, DiagnosticSeverity::DS_Warning));39return true;40}4142/// Moves I before IP. Returns new insert point.43static BasicBlock::iterator moveBeforeInsertPoint(BasicBlock::iterator I,44BasicBlock::iterator IP) {45// If I is IP, move the insert point down.46if (I == IP) {47++IP;48} else {49// Otherwise, move I before IP and return IP.50I->moveBefore(IP);51}52return IP;53}5455/// Instrumentation passes often insert conditional checks into entry blocks.56/// Call this function before splitting the entry block to move instructions57/// that must remain in the entry block up before the split point. Static58/// allocas and llvm.localescape calls, for example, must remain in the entry59/// block.60BasicBlock::iterator llvm::PrepareToSplitEntryBlock(BasicBlock &BB,61BasicBlock::iterator IP) {62assert(&BB.getParent()->getEntryBlock() == &BB);63for (auto I = IP, E = BB.end(); I != E; ++I) {64bool KeepInEntry = false;65if (auto *AI = dyn_cast<AllocaInst>(I)) {66if (AI->isStaticAlloca())67KeepInEntry = true;68} else if (auto *II = dyn_cast<IntrinsicInst>(I)) {69if (II->getIntrinsicID() == llvm::Intrinsic::localescape)70KeepInEntry = true;71}72if (KeepInEntry)73IP = moveBeforeInsertPoint(I, IP);74}75return IP;76}7778// Create a constant for Str so that we can pass it to the run-time lib.79GlobalVariable *llvm::createPrivateGlobalForString(Module &M, StringRef Str,80bool AllowMerging,81Twine NamePrefix) {82Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str);83// We use private linkage for module-local strings. If they can be merged84// with another one, we set the unnamed_addr attribute.85GlobalVariable *GV =86new GlobalVariable(M, StrConst->getType(), true,87GlobalValue::PrivateLinkage, StrConst, NamePrefix);88if (AllowMerging)89GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);90GV->setAlignment(Align(1)); // Strings may not be merged w/o setting91// alignment explicitly.92return GV;93}9495Comdat *llvm::getOrCreateFunctionComdat(Function &F, Triple &T) {96if (auto Comdat = F.getComdat())97return Comdat;98assert(F.hasName());99Module *M = F.getParent();100101// Make a new comdat for the function. Use the "no duplicates" selection kind102// if the object file format supports it. For COFF we restrict it to non-weak103// symbols.104Comdat *C = M->getOrInsertComdat(F.getName());105if (T.isOSBinFormatELF() || (T.isOSBinFormatCOFF() && !F.isWeakForLinker()))106C->setSelectionKind(Comdat::NoDeduplicate);107F.setComdat(C);108return C;109}110111void llvm::setGlobalVariableLargeSection(const Triple &TargetTriple,112GlobalVariable &GV) {113// Limit to x86-64 ELF.114if (TargetTriple.getArch() != Triple::x86_64 ||115TargetTriple.getObjectFormat() != Triple::ELF)116return;117// Limit to medium/large code models.118std::optional<CodeModel::Model> CM = GV.getParent()->getCodeModel();119if (!CM || (*CM != CodeModel::Medium && *CM != CodeModel::Large))120return;121GV.setCodeModel(CodeModel::Large);122}123124125