diff options
Diffstat (limited to 'llvm/lib/Transforms/Instrumentation/Instrumentation.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Instrumentation/Instrumentation.cpp | 128 | 
1 files changed, 128 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp b/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp new file mode 100644 index 000000000000..a6c2c9b464b6 --- /dev/null +++ b/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp @@ -0,0 +1,128 @@ +//===-- 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-c/Initialization.h" +#include "llvm/ADT/Triple.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/InitializePasses.h" +#include "llvm/PassRegistry.h" + +using namespace llvm; + +/// 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::None()); // Strings may not be merged w/o setting +                                   // alignment explicitly. +  return GV; +} + +Comdat *llvm::GetOrCreateFunctionComdat(Function &F, Triple &T, +                                        const std::string &ModuleId) { +  if (auto Comdat = F.getComdat()) return Comdat; +  assert(F.hasName()); +  Module *M = F.getParent(); +  std::string Name = F.getName(); + +  // Make a unique comdat name for internal linkage things on ELF. On COFF, the +  // name of the comdat group identifies the leader symbol of the comdat group. +  // The linkage of the leader symbol is considered during comdat resolution, +  // and internal symbols with the same name from different objects will not be +  // merged. +  if (T.isOSBinFormatELF() && F.hasLocalLinkage()) { +    if (ModuleId.empty()) +      return nullptr; +    Name += ModuleId; +  } + +  // Make a new comdat for the function. Use the "no duplicates" selection kind +  // for non-weak symbols if the object file format supports it. +  Comdat *C = M->getOrInsertComdat(Name); +  if (T.isOSBinFormatCOFF() && !F.isWeakForLinker()) +    C->setSelectionKind(Comdat::NoDuplicates); +  F.setComdat(C); +  return C; +} + +/// initializeInstrumentation - Initialize all passes in the TransformUtils +/// library. +void llvm::initializeInstrumentation(PassRegistry &Registry) { +  initializeAddressSanitizerLegacyPassPass(Registry); +  initializeModuleAddressSanitizerLegacyPassPass(Registry); +  initializeBoundsCheckingLegacyPassPass(Registry); +  initializeControlHeightReductionLegacyPassPass(Registry); +  initializeGCOVProfilerLegacyPassPass(Registry); +  initializePGOInstrumentationGenLegacyPassPass(Registry); +  initializePGOInstrumentationUseLegacyPassPass(Registry); +  initializePGOIndirectCallPromotionLegacyPassPass(Registry); +  initializePGOMemOPSizeOptLegacyPassPass(Registry); +  initializeInstrOrderFileLegacyPassPass(Registry); +  initializeInstrProfilingLegacyPassPass(Registry); +  initializeMemorySanitizerLegacyPassPass(Registry); +  initializeHWAddressSanitizerLegacyPassPass(Registry); +  initializeThreadSanitizerLegacyPassPass(Registry); +  initializeModuleSanitizerCoverageLegacyPassPass(Registry); +  initializeDataFlowSanitizerPass(Registry); +} + +/// LLVMInitializeInstrumentation - C binding for +/// initializeInstrumentation. +void LLVMInitializeInstrumentation(LLVMPassRegistryRef R) { +  initializeInstrumentation(*unwrap(R)); +}  | 
