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. 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. 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. 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 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 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