197868689SOwen Anderson //===-- Instrumentation.cpp - TransformUtils Infrastructure ---------------===//
297868689SOwen Anderson //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
697868689SOwen Anderson //
797868689SOwen Anderson //===----------------------------------------------------------------------===//
897868689SOwen Anderson //
997868689SOwen Anderson // This file defines the common initialization infrastructure for the
1097868689SOwen Anderson // Instrumentation library.
1197868689SOwen Anderson //
1297868689SOwen Anderson //===----------------------------------------------------------------------===//
1397868689SOwen Anderson
14a57d0151SReid Kleckner #include "llvm/Transforms/Instrumentation.h"
1597868689SOwen Anderson #include "llvm-c/Initialization.h"
16b41b3721SReid Kleckner #include "llvm/ADT/Triple.h"
17a57d0151SReid Kleckner #include "llvm/IR/IntrinsicInst.h"
18d891ac97SKostya Serebryany #include "llvm/IR/Module.h"
19a57d0151SReid Kleckner #include "llvm/InitializePasses.h"
208a8cd2baSChandler Carruth #include "llvm/PassRegistry.h"
2197868689SOwen Anderson
2297868689SOwen Anderson using namespace llvm;
2397868689SOwen Anderson
24a57d0151SReid Kleckner /// Moves I before IP. Returns new insert point.
moveBeforeInsertPoint(BasicBlock::iterator I,BasicBlock::iterator IP)25a57d0151SReid Kleckner static BasicBlock::iterator moveBeforeInsertPoint(BasicBlock::iterator I, BasicBlock::iterator IP) {
26a57d0151SReid Kleckner // If I is IP, move the insert point down.
270c4dbf9eSDavid Blaikie if (I == IP) {
280c4dbf9eSDavid Blaikie ++IP;
290c4dbf9eSDavid Blaikie } else {
30a57d0151SReid Kleckner // Otherwise, move I before IP and return IP.
31e82c286fSDuncan P. N. Exon Smith I->moveBefore(&*IP);
320c4dbf9eSDavid Blaikie }
33a57d0151SReid Kleckner return IP;
34a57d0151SReid Kleckner }
35a57d0151SReid Kleckner
36a57d0151SReid Kleckner /// Instrumentation passes often insert conditional checks into entry blocks.
37a57d0151SReid Kleckner /// Call this function before splitting the entry block to move instructions
38a57d0151SReid Kleckner /// that must remain in the entry block up before the split point. Static
39a57d0151SReid Kleckner /// allocas and llvm.localescape calls, for example, must remain in the entry
40a57d0151SReid Kleckner /// block.
PrepareToSplitEntryBlock(BasicBlock & BB,BasicBlock::iterator IP)41a57d0151SReid Kleckner BasicBlock::iterator llvm::PrepareToSplitEntryBlock(BasicBlock &BB,
42a57d0151SReid Kleckner BasicBlock::iterator IP) {
43a57d0151SReid Kleckner assert(&BB.getParent()->getEntryBlock() == &BB);
44a57d0151SReid Kleckner for (auto I = IP, E = BB.end(); I != E; ++I) {
45a57d0151SReid Kleckner bool KeepInEntry = false;
46a57d0151SReid Kleckner if (auto *AI = dyn_cast<AllocaInst>(I)) {
47a57d0151SReid Kleckner if (AI->isStaticAlloca())
48a57d0151SReid Kleckner KeepInEntry = true;
49a57d0151SReid Kleckner } else if (auto *II = dyn_cast<IntrinsicInst>(I)) {
50a57d0151SReid Kleckner if (II->getIntrinsicID() == llvm::Intrinsic::localescape)
51a57d0151SReid Kleckner KeepInEntry = true;
52a57d0151SReid Kleckner }
53a57d0151SReid Kleckner if (KeepInEntry)
54a57d0151SReid Kleckner IP = moveBeforeInsertPoint(I, IP);
55a57d0151SReid Kleckner }
56a57d0151SReid Kleckner return IP;
57a57d0151SReid Kleckner }
58a57d0151SReid Kleckner
59d891ac97SKostya Serebryany // Create a constant for Str so that we can pass it to the run-time lib.
createPrivateGlobalForString(Module & M,StringRef Str,bool AllowMerging,const char * NamePrefix)60d891ac97SKostya Serebryany GlobalVariable *llvm::createPrivateGlobalForString(Module &M, StringRef Str,
61d891ac97SKostya Serebryany bool AllowMerging,
62d891ac97SKostya Serebryany const char *NamePrefix) {
63d891ac97SKostya Serebryany Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str);
64d891ac97SKostya Serebryany // We use private linkage for module-local strings. If they can be merged
65d891ac97SKostya Serebryany // with another one, we set the unnamed_addr attribute.
66d891ac97SKostya Serebryany GlobalVariable *GV =
67d891ac97SKostya Serebryany new GlobalVariable(M, StrConst->getType(), true,
68d891ac97SKostya Serebryany GlobalValue::PrivateLinkage, StrConst, NamePrefix);
69d891ac97SKostya Serebryany if (AllowMerging)
70d891ac97SKostya Serebryany GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
71805c157eSGuillaume Chatelet GV->setAlignment(Align(1)); // Strings may not be merged w/o setting
720e62011dSGuillaume Chatelet // alignment explicitly.
73d891ac97SKostya Serebryany return GV;
74d891ac97SKostya Serebryany }
75d891ac97SKostya Serebryany
getOrCreateFunctionComdat(Function & F,Triple & T)764d63892aSFangrui Song Comdat *llvm::getOrCreateFunctionComdat(Function &F, Triple &T) {
77bc504559SKostya Serebryany if (auto Comdat = F.getComdat()) return Comdat;
78bc504559SKostya Serebryany assert(F.hasName());
79bc504559SKostya Serebryany Module *M = F.getParent();
80b41b3721SReid Kleckner
81b41b3721SReid Kleckner // Make a new comdat for the function. Use the "no duplicates" selection kind
824d63892aSFangrui Song // if the object file format supports it. For COFF we restrict it to non-weak
834d63892aSFangrui Song // symbols.
844d63892aSFangrui Song Comdat *C = M->getOrInsertComdat(F.getName());
854d63892aSFangrui Song if (T.isOSBinFormatELF() || (T.isOSBinFormatCOFF() && !F.isWeakForLinker()))
86*39248779SFangrui Song C->setSelectionKind(Comdat::NoDeduplicate);
87b41b3721SReid Kleckner F.setComdat(C);
88b41b3721SReid Kleckner return C;
89bc504559SKostya Serebryany }
90bc504559SKostya Serebryany
9197868689SOwen Anderson /// initializeInstrumentation - Initialize all passes in the TransformUtils
9297868689SOwen Anderson /// library.
initializeInstrumentation(PassRegistry & Registry)9397868689SOwen Anderson void llvm::initializeInstrumentation(PassRegistry &Registry) {
94226d80ebSTeresa Johnson initializeMemProfilerLegacyPassPass(Registry);
95226d80ebSTeresa Johnson initializeModuleMemProfilerLegacyPassPass(Registry);
9600a301d5SChandler Carruth initializeBoundsCheckingLegacyPassPass(Registry);
9771d0a2b8SArthur Eubanks initializeDataFlowSanitizerLegacyPassPass(Registry);
9897868689SOwen Anderson }
9997868689SOwen Anderson
10097868689SOwen Anderson /// LLVMInitializeInstrumentation - C binding for
10197868689SOwen Anderson /// initializeInstrumentation.
LLVMInitializeInstrumentation(LLVMPassRegistryRef R)10297868689SOwen Anderson void LLVMInitializeInstrumentation(LLVMPassRegistryRef R) {
10397868689SOwen Anderson initializeInstrumentation(*unwrap(R));
10497868689SOwen Anderson }
105