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