10b57cec5SDimitry Andric //===-- Instrumentation.cpp - TransformUtils Infrastructure ---------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines the common initialization infrastructure for the
100b57cec5SDimitry Andric // Instrumentation library.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric #include "llvm/Transforms/Instrumentation.h"
150b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
160b57cec5SDimitry Andric #include "llvm/IR/Module.h"
1706c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h"
180b57cec5SDimitry Andric
190b57cec5SDimitry Andric using namespace llvm;
200b57cec5SDimitry Andric
210b57cec5SDimitry Andric /// Moves I before IP. Returns new insert point.
moveBeforeInsertPoint(BasicBlock::iterator I,BasicBlock::iterator IP)220b57cec5SDimitry Andric static BasicBlock::iterator moveBeforeInsertPoint(BasicBlock::iterator I, BasicBlock::iterator IP) {
230b57cec5SDimitry Andric // If I is IP, move the insert point down.
240b57cec5SDimitry Andric if (I == IP) {
250b57cec5SDimitry Andric ++IP;
260b57cec5SDimitry Andric } else {
270b57cec5SDimitry Andric // Otherwise, move I before IP and return IP.
280b57cec5SDimitry Andric I->moveBefore(&*IP);
290b57cec5SDimitry Andric }
300b57cec5SDimitry Andric return IP;
310b57cec5SDimitry Andric }
320b57cec5SDimitry Andric
330b57cec5SDimitry Andric /// Instrumentation passes often insert conditional checks into entry blocks.
340b57cec5SDimitry Andric /// Call this function before splitting the entry block to move instructions
350b57cec5SDimitry Andric /// that must remain in the entry block up before the split point. Static
360b57cec5SDimitry Andric /// allocas and llvm.localescape calls, for example, must remain in the entry
370b57cec5SDimitry Andric /// block.
PrepareToSplitEntryBlock(BasicBlock & BB,BasicBlock::iterator IP)380b57cec5SDimitry Andric BasicBlock::iterator llvm::PrepareToSplitEntryBlock(BasicBlock &BB,
390b57cec5SDimitry Andric BasicBlock::iterator IP) {
400b57cec5SDimitry Andric assert(&BB.getParent()->getEntryBlock() == &BB);
410b57cec5SDimitry Andric for (auto I = IP, E = BB.end(); I != E; ++I) {
420b57cec5SDimitry Andric bool KeepInEntry = false;
430b57cec5SDimitry Andric if (auto *AI = dyn_cast<AllocaInst>(I)) {
440b57cec5SDimitry Andric if (AI->isStaticAlloca())
450b57cec5SDimitry Andric KeepInEntry = true;
460b57cec5SDimitry Andric } else if (auto *II = dyn_cast<IntrinsicInst>(I)) {
470b57cec5SDimitry Andric if (II->getIntrinsicID() == llvm::Intrinsic::localescape)
480b57cec5SDimitry Andric KeepInEntry = true;
490b57cec5SDimitry Andric }
500b57cec5SDimitry Andric if (KeepInEntry)
510b57cec5SDimitry Andric IP = moveBeforeInsertPoint(I, IP);
520b57cec5SDimitry Andric }
530b57cec5SDimitry Andric return IP;
540b57cec5SDimitry Andric }
550b57cec5SDimitry Andric
560b57cec5SDimitry Andric // 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)570b57cec5SDimitry Andric GlobalVariable *llvm::createPrivateGlobalForString(Module &M, StringRef Str,
580b57cec5SDimitry Andric bool AllowMerging,
590b57cec5SDimitry Andric const char *NamePrefix) {
600b57cec5SDimitry Andric Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str);
610b57cec5SDimitry Andric // We use private linkage for module-local strings. If they can be merged
620b57cec5SDimitry Andric // with another one, we set the unnamed_addr attribute.
630b57cec5SDimitry Andric GlobalVariable *GV =
640b57cec5SDimitry Andric new GlobalVariable(M, StrConst->getType(), true,
650b57cec5SDimitry Andric GlobalValue::PrivateLinkage, StrConst, NamePrefix);
660b57cec5SDimitry Andric if (AllowMerging)
670b57cec5SDimitry Andric GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
685ffd83dbSDimitry Andric GV->setAlignment(Align(1)); // Strings may not be merged w/o setting
698bcb0991SDimitry Andric // alignment explicitly.
700b57cec5SDimitry Andric return GV;
710b57cec5SDimitry Andric }
720b57cec5SDimitry Andric
getOrCreateFunctionComdat(Function & F,Triple & T)73fe6060f1SDimitry Andric Comdat *llvm::getOrCreateFunctionComdat(Function &F, Triple &T) {
740b57cec5SDimitry Andric if (auto Comdat = F.getComdat()) return Comdat;
750b57cec5SDimitry Andric assert(F.hasName());
760b57cec5SDimitry Andric Module *M = F.getParent();
770b57cec5SDimitry Andric
780b57cec5SDimitry Andric // Make a new comdat for the function. Use the "no duplicates" selection kind
79fe6060f1SDimitry Andric // if the object file format supports it. For COFF we restrict it to non-weak
80fe6060f1SDimitry Andric // symbols.
81fe6060f1SDimitry Andric Comdat *C = M->getOrInsertComdat(F.getName());
82fe6060f1SDimitry Andric if (T.isOSBinFormatELF() || (T.isOSBinFormatCOFF() && !F.isWeakForLinker()))
83fe6060f1SDimitry Andric C->setSelectionKind(Comdat::NoDeduplicate);
840b57cec5SDimitry Andric F.setComdat(C);
850b57cec5SDimitry Andric return C;
860b57cec5SDimitry Andric }
870b57cec5SDimitry Andric
setGlobalVariableLargeSection(const Triple & TargetTriple,GlobalVariable & GV)88*5f757f3fSDimitry Andric void llvm::setGlobalVariableLargeSection(const Triple &TargetTriple,
89*5f757f3fSDimitry Andric GlobalVariable &GV) {
90*5f757f3fSDimitry Andric // Limit to x86-64 ELF.
91*5f757f3fSDimitry Andric if (TargetTriple.getArch() != Triple::x86_64 ||
92*5f757f3fSDimitry Andric TargetTriple.getObjectFormat() != Triple::ELF)
93*5f757f3fSDimitry Andric return;
94*5f757f3fSDimitry Andric // Limit to medium/large code models.
95*5f757f3fSDimitry Andric std::optional<CodeModel::Model> CM = GV.getParent()->getCodeModel();
96*5f757f3fSDimitry Andric if (!CM || (*CM != CodeModel::Medium && *CM != CodeModel::Large))
97*5f757f3fSDimitry Andric return;
98*5f757f3fSDimitry Andric GV.setCodeModel(CodeModel::Large);
99*5f757f3fSDimitry Andric }
100