xref: /llvm-project/llvm/lib/Transforms/Utils/Instrumentation.cpp (revision 8e702735090388a3231a863e343f880d0f96fecb)
12ae968a0SAntonio Frighetto //===-- Instrumentation.cpp - TransformUtils Infrastructure ---------------===//
22ae968a0SAntonio Frighetto //
32ae968a0SAntonio Frighetto // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42ae968a0SAntonio Frighetto // See https://llvm.org/LICENSE.txt for license information.
52ae968a0SAntonio Frighetto // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62ae968a0SAntonio Frighetto //
72ae968a0SAntonio Frighetto //===----------------------------------------------------------------------===//
82ae968a0SAntonio Frighetto //
92ae968a0SAntonio Frighetto // This file defines the common initialization infrastructure for the
102ae968a0SAntonio Frighetto // Instrumentation library.
112ae968a0SAntonio Frighetto //
122ae968a0SAntonio Frighetto //===----------------------------------------------------------------------===//
132ae968a0SAntonio Frighetto 
142ae968a0SAntonio Frighetto #include "llvm/Transforms/Utils/Instrumentation.h"
152ae968a0SAntonio Frighetto #include "llvm/IR/DiagnosticInfo.h"
162ae968a0SAntonio Frighetto #include "llvm/IR/DiagnosticPrinter.h"
172ae968a0SAntonio Frighetto #include "llvm/IR/IntrinsicInst.h"
182ae968a0SAntonio Frighetto #include "llvm/IR/Module.h"
192ae968a0SAntonio Frighetto #include "llvm/TargetParser/Triple.h"
202ae968a0SAntonio Frighetto 
212ae968a0SAntonio Frighetto using namespace llvm;
222ae968a0SAntonio Frighetto 
232ae968a0SAntonio Frighetto static cl::opt<bool> ClIgnoreRedundantInstrumentation(
242ae968a0SAntonio Frighetto     "ignore-redundant-instrumentation",
252ae968a0SAntonio Frighetto     cl::desc("Ignore redundant instrumentation"), cl::Hidden, cl::init(false));
262ae968a0SAntonio Frighetto 
272ae968a0SAntonio Frighetto /// Check if module has flag attached, if not add the flag.
282ae968a0SAntonio Frighetto bool llvm::checkIfAlreadyInstrumented(Module &M, StringRef Flag) {
292ae968a0SAntonio Frighetto   if (!M.getModuleFlag(Flag)) {
302ae968a0SAntonio Frighetto     M.addModuleFlag(Module::ModFlagBehavior::Override, Flag, 1);
312ae968a0SAntonio Frighetto     return false;
322ae968a0SAntonio Frighetto   }
332ae968a0SAntonio Frighetto   if (ClIgnoreRedundantInstrumentation)
342ae968a0SAntonio Frighetto     return true;
352ae968a0SAntonio Frighetto   std::string diagInfo =
362ae968a0SAntonio Frighetto       "Redundant instrumentation detected, with module flag: " +
372ae968a0SAntonio Frighetto       std::string(Flag);
382ae968a0SAntonio Frighetto   M.getContext().diagnose(
392ae968a0SAntonio Frighetto       DiagnosticInfoInstrumentation(diagInfo, DiagnosticSeverity::DS_Warning));
402ae968a0SAntonio Frighetto   return true;
412ae968a0SAntonio Frighetto }
422ae968a0SAntonio Frighetto 
432ae968a0SAntonio Frighetto /// Moves I before IP. Returns new insert point.
442ae968a0SAntonio Frighetto static BasicBlock::iterator moveBeforeInsertPoint(BasicBlock::iterator I,
452ae968a0SAntonio Frighetto                                                   BasicBlock::iterator IP) {
462ae968a0SAntonio Frighetto   // If I is IP, move the insert point down.
472ae968a0SAntonio Frighetto   if (I == IP) {
482ae968a0SAntonio Frighetto     ++IP;
492ae968a0SAntonio Frighetto   } else {
502ae968a0SAntonio Frighetto     // Otherwise, move I before IP and return IP.
51*8e702735SJeremy Morse     I->moveBefore(IP);
522ae968a0SAntonio Frighetto   }
532ae968a0SAntonio Frighetto   return IP;
542ae968a0SAntonio Frighetto }
552ae968a0SAntonio Frighetto 
562ae968a0SAntonio Frighetto /// Instrumentation passes often insert conditional checks into entry blocks.
572ae968a0SAntonio Frighetto /// Call this function before splitting the entry block to move instructions
582ae968a0SAntonio Frighetto /// that must remain in the entry block up before the split point. Static
592ae968a0SAntonio Frighetto /// allocas and llvm.localescape calls, for example, must remain in the entry
602ae968a0SAntonio Frighetto /// block.
612ae968a0SAntonio Frighetto BasicBlock::iterator llvm::PrepareToSplitEntryBlock(BasicBlock &BB,
622ae968a0SAntonio Frighetto                                                     BasicBlock::iterator IP) {
632ae968a0SAntonio Frighetto   assert(&BB.getParent()->getEntryBlock() == &BB);
642ae968a0SAntonio Frighetto   for (auto I = IP, E = BB.end(); I != E; ++I) {
652ae968a0SAntonio Frighetto     bool KeepInEntry = false;
662ae968a0SAntonio Frighetto     if (auto *AI = dyn_cast<AllocaInst>(I)) {
672ae968a0SAntonio Frighetto       if (AI->isStaticAlloca())
682ae968a0SAntonio Frighetto         KeepInEntry = true;
692ae968a0SAntonio Frighetto     } else if (auto *II = dyn_cast<IntrinsicInst>(I)) {
702ae968a0SAntonio Frighetto       if (II->getIntrinsicID() == llvm::Intrinsic::localescape)
712ae968a0SAntonio Frighetto         KeepInEntry = true;
722ae968a0SAntonio Frighetto     }
732ae968a0SAntonio Frighetto     if (KeepInEntry)
742ae968a0SAntonio Frighetto       IP = moveBeforeInsertPoint(I, IP);
752ae968a0SAntonio Frighetto   }
762ae968a0SAntonio Frighetto   return IP;
772ae968a0SAntonio Frighetto }
782ae968a0SAntonio Frighetto 
792ae968a0SAntonio Frighetto // Create a constant for Str so that we can pass it to the run-time lib.
802ae968a0SAntonio Frighetto GlobalVariable *llvm::createPrivateGlobalForString(Module &M, StringRef Str,
812ae968a0SAntonio Frighetto                                                    bool AllowMerging,
822ae968a0SAntonio Frighetto                                                    Twine NamePrefix) {
832ae968a0SAntonio Frighetto   Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str);
842ae968a0SAntonio Frighetto   // We use private linkage for module-local strings. If they can be merged
852ae968a0SAntonio Frighetto   // with another one, we set the unnamed_addr attribute.
862ae968a0SAntonio Frighetto   GlobalVariable *GV =
872ae968a0SAntonio Frighetto       new GlobalVariable(M, StrConst->getType(), true,
882ae968a0SAntonio Frighetto                          GlobalValue::PrivateLinkage, StrConst, NamePrefix);
892ae968a0SAntonio Frighetto   if (AllowMerging)
902ae968a0SAntonio Frighetto     GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
912ae968a0SAntonio Frighetto   GV->setAlignment(Align(1)); // Strings may not be merged w/o setting
922ae968a0SAntonio Frighetto                               // alignment explicitly.
932ae968a0SAntonio Frighetto   return GV;
942ae968a0SAntonio Frighetto }
952ae968a0SAntonio Frighetto 
962ae968a0SAntonio Frighetto Comdat *llvm::getOrCreateFunctionComdat(Function &F, Triple &T) {
972ae968a0SAntonio Frighetto   if (auto Comdat = F.getComdat())
982ae968a0SAntonio Frighetto     return Comdat;
992ae968a0SAntonio Frighetto   assert(F.hasName());
1002ae968a0SAntonio Frighetto   Module *M = F.getParent();
1012ae968a0SAntonio Frighetto 
1022ae968a0SAntonio Frighetto   // Make a new comdat for the function. Use the "no duplicates" selection kind
1032ae968a0SAntonio Frighetto   // if the object file format supports it. For COFF we restrict it to non-weak
1042ae968a0SAntonio Frighetto   // symbols.
1052ae968a0SAntonio Frighetto   Comdat *C = M->getOrInsertComdat(F.getName());
1062ae968a0SAntonio Frighetto   if (T.isOSBinFormatELF() || (T.isOSBinFormatCOFF() && !F.isWeakForLinker()))
1072ae968a0SAntonio Frighetto     C->setSelectionKind(Comdat::NoDeduplicate);
1082ae968a0SAntonio Frighetto   F.setComdat(C);
1092ae968a0SAntonio Frighetto   return C;
1102ae968a0SAntonio Frighetto }
1112ae968a0SAntonio Frighetto 
1122ae968a0SAntonio Frighetto void llvm::setGlobalVariableLargeSection(const Triple &TargetTriple,
1132ae968a0SAntonio Frighetto                                          GlobalVariable &GV) {
1142ae968a0SAntonio Frighetto   // Limit to x86-64 ELF.
1152ae968a0SAntonio Frighetto   if (TargetTriple.getArch() != Triple::x86_64 ||
1162ae968a0SAntonio Frighetto       TargetTriple.getObjectFormat() != Triple::ELF)
1172ae968a0SAntonio Frighetto     return;
1182ae968a0SAntonio Frighetto   // Limit to medium/large code models.
1192ae968a0SAntonio Frighetto   std::optional<CodeModel::Model> CM = GV.getParent()->getCodeModel();
1202ae968a0SAntonio Frighetto   if (!CM || (*CM != CodeModel::Medium && *CM != CodeModel::Large))
1212ae968a0SAntonio Frighetto     return;
1222ae968a0SAntonio Frighetto   GV.setCodeModel(CodeModel::Large);
1232ae968a0SAntonio Frighetto }
124