[llvm] r318195 - Rename CountingFunctionInserter and use for both mcount and cygprofile calls, before and after inlining

Hans Wennborg via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 14 13:09:45 PST 2017


Author: hans
Date: Tue Nov 14 13:09:45 2017
New Revision: 318195

URL: http://llvm.org/viewvc/llvm-project?rev=318195&view=rev
Log:
Rename CountingFunctionInserter and use for both mcount and cygprofile calls, before and after inlining

Clang implements the -finstrument-functions flag inherited from GCC, which
inserts calls to __cyg_profile_func_{enter,exit} on function entry and exit.

This is useful for getting a trace of how the functions in a program are
executed. Normally, the calls remain even if a function is inlined into another
function, but it is useful to be able to turn this off for users who are
interested in a lower-level trace, i.e. one that reflects what functions are
called post-inlining. (We use this to generate link order files for Chromium.)

LLVM already has a pass for inserting similar instrumentation calls to
mcount(), which it does after inlining. This patch renames and extends that
pass to handle calls both to mcount and the cygprofile functions, before and/or
after inlining as controlled by function attributes.

Differential Revision: https://reviews.llvm.org/D39287

Added:
    llvm/trunk/include/llvm/Transforms/Utils/EntryExitInstrumenter.h
    llvm/trunk/lib/Transforms/Utils/EntryExitInstrumenter.cpp
Removed:
    llvm/trunk/lib/CodeGen/CountingFunctionInserter.cpp
Modified:
    llvm/trunk/include/llvm/CodeGen/Passes.h
    llvm/trunk/include/llvm/InitializePasses.h
    llvm/trunk/include/llvm/LinkAllPasses.h
    llvm/trunk/include/llvm/Transforms/Scalar.h
    llvm/trunk/lib/CodeGen/CMakeLists.txt
    llvm/trunk/lib/CodeGen/CodeGen.cpp
    llvm/trunk/lib/CodeGen/TargetPassConfig.cpp
    llvm/trunk/lib/Passes/PassBuilder.cpp
    llvm/trunk/lib/Passes/PassRegistry.def
    llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp
    llvm/trunk/lib/Transforms/Scalar/Scalar.cpp
    llvm/trunk/lib/Transforms/Utils/CMakeLists.txt
    llvm/trunk/test/CodeGen/PowerPC/mcount-insertion.ll
    llvm/trunk/test/CodeGen/X86/O0-pipeline.ll
    llvm/trunk/test/Transforms/CountingFunctionInserter/mcount.ll
    llvm/trunk/tools/llc/llc.cpp
    llvm/trunk/tools/opt/opt.cpp

Modified: llvm/trunk/include/llvm/CodeGen/Passes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=318195&r1=318194&r2=318195&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/Passes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/Passes.h Tue Nov 14 13:09:45 2017
@@ -43,9 +43,6 @@ namespace llvm {
   /// the entry block.
   FunctionPass *createUnreachableBlockEliminationPass();
 
-  /// Insert mcount-like function calls.
-  FunctionPass *createCountingFunctionInserterPass();
-
   /// MachineFunctionPrinter pass - This pass prints out the machine function to
   /// the given stream as a debugging tool.
   MachineFunctionPass *

Modified: llvm/trunk/include/llvm/InitializePasses.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=318195&r1=318194&r2=318195&view=diff
==============================================================================
--- llvm/trunk/include/llvm/InitializePasses.h (original)
+++ llvm/trunk/include/llvm/InitializePasses.h Tue Nov 14 13:09:45 2017
@@ -99,7 +99,8 @@ void initializeConstantMergeLegacyPassPa
 void initializeConstantPropagationPass(PassRegistry&);
 void initializeCorrelatedValuePropagationPass(PassRegistry&);
 void initializeCostModelAnalysisPass(PassRegistry&);
-void initializeCountingFunctionInserterPass(PassRegistry&);
+void initializeEntryExitInstrumenterPass(PassRegistry&);
+void initializePostInlineEntryExitInstrumenterPass(PassRegistry&);
 void initializeCrossDSOCFIPass(PassRegistry&);
 void initializeDAEPass(PassRegistry&);
 void initializeDAHPass(PassRegistry&);

Modified: llvm/trunk/include/llvm/LinkAllPasses.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=318195&r1=318194&r2=318195&view=diff
==============================================================================
--- llvm/trunk/include/llvm/LinkAllPasses.h (original)
+++ llvm/trunk/include/llvm/LinkAllPasses.h Tue Nov 14 13:09:45 2017
@@ -166,7 +166,8 @@ namespace {
       (void) llvm::createInstCountPass();
       (void) llvm::createConstantHoistingPass();
       (void) llvm::createCodeGenPreparePass();
-      (void) llvm::createCountingFunctionInserterPass();
+      (void) llvm::createEntryExitInstrumenterPass();
+      (void) llvm::createPostInlineEntryExitInstrumenterPass();
       (void) llvm::createEarlyCSEPass();
       (void) llvm::createGVNHoistPass();
       (void) llvm::createMergedLoadStoreMotionPass();

Modified: llvm/trunk/include/llvm/Transforms/Scalar.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=318195&r1=318194&r2=318195&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Scalar.h (original)
+++ llvm/trunk/include/llvm/Transforms/Scalar.h Tue Nov 14 13:09:45 2017
@@ -582,6 +582,16 @@ ModulePass *createNameAnonGlobalPass();
 // used.
 //
 FunctionPass *createLibCallsShrinkWrapPass();
+
+//===----------------------------------------------------------------------===//
+//
+// EntryExitInstrumenter pass - Instrument function entry/exit with calls to
+// mcount(), @__cyg_profile_func_{enter,exit} and the like. There are two
+// variants, intended to run pre- and post-inlining, respectively.
+//
+FunctionPass *createEntryExitInstrumenterPass();
+FunctionPass *createPostInlineEntryExitInstrumenterPass();
+
 } // End llvm namespace
 
 #endif

Added: llvm/trunk/include/llvm/Transforms/Utils/EntryExitInstrumenter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/EntryExitInstrumenter.h?rev=318195&view=auto
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/EntryExitInstrumenter.h (added)
+++ llvm/trunk/include/llvm/Transforms/Utils/EntryExitInstrumenter.h Tue Nov 14 13:09:45 2017
@@ -0,0 +1,36 @@
+//===- EntryExitInstrumenter.h - Function Entry/Exit Instrumentation ------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// EntryExitInstrumenter pass - Instrument function entry/exit with calls to
+// mcount(), @__cyg_profile_func_{enter,exit} and the like. There are two
+// variants, intended to run pre- and post-inlining, respectively.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_ENTRYEXITINSTRUMENTER_H
+#define LLVM_TRANSFORMS_UTILS_ENTRYEXITINSTRUMENTER_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Function;
+
+struct EntryExitInstrumenterPass
+    : public PassInfoMixin<EntryExitInstrumenterPass> {
+  EntryExitInstrumenterPass(bool PostInlining) : PostInlining(PostInlining) {}
+
+  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+
+  bool PostInlining;
+};
+
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_ENTRYEXITINSTRUMENTER_H

Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=318195&r1=318194&r2=318195&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/CMakeLists.txt (original)
+++ llvm/trunk/lib/CodeGen/CMakeLists.txt Tue Nov 14 13:09:45 2017
@@ -11,7 +11,6 @@ add_llvm_library(LLVMCodeGen
   CallingConvLower.cpp
   CodeGen.cpp
   CodeGenPrepare.cpp
-  CountingFunctionInserter.cpp
   CriticalAntiDepBreaker.cpp
   DeadMachineInstructionElim.cpp
   DetectDeadLanes.cpp

Modified: llvm/trunk/lib/CodeGen/CodeGen.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGen.cpp?rev=318195&r1=318194&r2=318195&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/CodeGen.cpp (original)
+++ llvm/trunk/lib/CodeGen/CodeGen.cpp Tue Nov 14 13:09:45 2017
@@ -24,7 +24,6 @@ void llvm::initializeCodeGen(PassRegistr
   initializeBranchFolderPassPass(Registry);
   initializeBranchRelaxationPass(Registry);
   initializeCodeGenPreparePass(Registry);
-  initializeCountingFunctionInserterPass(Registry);
   initializeDeadMachineInstructionElimPass(Registry);
   initializeDetectDeadLanesPass(Registry);
   initializeDwarfEHPreparePass(Registry);

Removed: llvm/trunk/lib/CodeGen/CountingFunctionInserter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CountingFunctionInserter.cpp?rev=318194&view=auto
==============================================================================
--- llvm/trunk/lib/CodeGen/CountingFunctionInserter.cpp (original)
+++ llvm/trunk/lib/CodeGen/CountingFunctionInserter.cpp (removed)
@@ -1,58 +0,0 @@
-//===- CountingFunctionInserter.cpp - Insert mcount-like function calls ---===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Insert calls to counter functions, such as mcount, intended to be called
-// once per function, at the beginning of each function.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/GlobalsModRef.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/Type.h"
-#include "llvm/Pass.h"
-using namespace llvm;
-
-namespace {
-  struct CountingFunctionInserter : public FunctionPass {
-    static char ID; // Pass identification, replacement for typeid
-    CountingFunctionInserter() : FunctionPass(ID) {
-      initializeCountingFunctionInserterPass(*PassRegistry::getPassRegistry());
-    }
-
-    void getAnalysisUsage(AnalysisUsage &AU) const override {
-      AU.addPreserved<GlobalsAAWrapperPass>();
-    }
-
-    bool runOnFunction(Function &F) override {
-      StringRef CountingFunctionName =
-        F.getFnAttribute("counting-function").getValueAsString();
-      if (CountingFunctionName.empty())
-        return false;
-
-      Type *VoidTy = Type::getVoidTy(F.getContext());
-      Constant *CountingFn =
-        F.getParent()->getOrInsertFunction(CountingFunctionName,
-                                           VoidTy);
-      CallInst::Create(CountingFn, "", &*F.begin()->getFirstInsertionPt());
-      return true;
-    }
-  };
-
-  char CountingFunctionInserter::ID = 0;
-}
-
-INITIALIZE_PASS(CountingFunctionInserter, "cfinserter",
-                "Inserts calls to mcount-like functions", false, false)
-
-FunctionPass *llvm::createCountingFunctionInserterPass() {
-  return new CountingFunctionInserter();
-}

Modified: llvm/trunk/lib/CodeGen/TargetPassConfig.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetPassConfig.cpp?rev=318195&r1=318194&r2=318195&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetPassConfig.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetPassConfig.cpp Tue Nov 14 13:09:45 2017
@@ -625,8 +625,8 @@ void TargetPassConfig::addIRPasses() {
   if (getOptLevel() != CodeGenOpt::None && !DisablePartialLibcallInlining)
     addPass(createPartiallyInlineLibCallsPass());
 
-  // Insert calls to mcount-like functions.
-  addPass(createCountingFunctionInserterPass());
+  // Instrument function entry and exit, e.g. with calls to mcount().
+  addPass(createPostInlineEntryExitInstrumenterPass());
 
   // Add scalarization of target's unsupported masked memory intrinsics pass.
   // the unsupported intrinsic will be replaced with a chain of basic blocks,

Modified: llvm/trunk/lib/Passes/PassBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassBuilder.cpp?rev=318195&r1=318194&r2=318195&view=diff
==============================================================================
--- llvm/trunk/lib/Passes/PassBuilder.cpp (original)
+++ llvm/trunk/lib/Passes/PassBuilder.cpp Tue Nov 14 13:09:45 2017
@@ -136,6 +136,7 @@
 #include "llvm/Transforms/Scalar/TailRecursionElimination.h"
 #include "llvm/Transforms/Utils/AddDiscriminators.h"
 #include "llvm/Transforms/Utils/BreakCriticalEdges.h"
+#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
 #include "llvm/Transforms/Utils/LCSSA.h"
 #include "llvm/Transforms/Utils/LibCallsShrinkWrap.h"
 #include "llvm/Transforms/Utils/LoopSimplify.h"

Modified: llvm/trunk/lib/Passes/PassRegistry.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassRegistry.def?rev=318195&r1=318194&r2=318195&view=diff
==============================================================================
--- llvm/trunk/lib/Passes/PassRegistry.def (original)
+++ llvm/trunk/lib/Passes/PassRegistry.def Tue Nov 14 13:09:45 2017
@@ -151,6 +151,8 @@ FUNCTION_PASS("dot-cfg", CFGPrinterPass(
 FUNCTION_PASS("dot-cfg-only", CFGOnlyPrinterPass())
 FUNCTION_PASS("early-cse", EarlyCSEPass(/*UseMemorySSA=*/false))
 FUNCTION_PASS("early-cse-memssa", EarlyCSEPass(/*UseMemorySSA=*/true))
+FUNCTION_PASS("ee-instrument", EntryExitInstrumenterPass(/*PostInlining=*/false))
+FUNCTION_PASS("post-inline-ee-instrument", EntryExitInstrumenterPass(/*PostInlining=*/true))
 FUNCTION_PASS("gvn-hoist", GVNHoistPass())
 FUNCTION_PASS("instcombine", InstCombinePass())
 FUNCTION_PASS("instsimplify", InstSimplifierPass())

Modified: llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp?rev=318195&r1=318194&r2=318195&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp Tue Nov 14 13:09:45 2017
@@ -241,6 +241,7 @@ void PassManagerBuilder::addInstructionC
 void PassManagerBuilder::populateFunctionPassManager(
     legacy::FunctionPassManager &FPM) {
   addExtensionsToPM(EP_EarlyAsPossible, FPM);
+  FPM.add(createEntryExitInstrumenterPass());
 
   // Add LibraryInfo if we have some.
   if (LibraryInfo)

Modified: llvm/trunk/lib/Transforms/Scalar/Scalar.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/Scalar.cpp?rev=318195&r1=318194&r2=318195&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/Scalar.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/Scalar.cpp Tue Nov 14 13:09:45 2017
@@ -100,6 +100,8 @@ void llvm::initializeScalarOpts(PassRegi
   initializeLoopLoadEliminationPass(Registry);
   initializeLoopSimplifyCFGLegacyPassPass(Registry);
   initializeLoopVersioningPassPass(Registry);
+  initializeEntryExitInstrumenterPass(Registry);
+  initializePostInlineEntryExitInstrumenterPass(Registry);
 }
 
 void LLVMInitializeScalarOpts(LLVMPassRegistryRef R) {

Modified: llvm/trunk/lib/Transforms/Utils/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CMakeLists.txt?rev=318195&r1=318194&r2=318195&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/CMakeLists.txt (original)
+++ llvm/trunk/lib/Transforms/Utils/CMakeLists.txt Tue Nov 14 13:09:45 2017
@@ -10,6 +10,7 @@ add_llvm_library(LLVMTransformUtils
   CodeExtractor.cpp
   CtorUtils.cpp
   DemoteRegToStack.cpp
+  EntryExitInstrumenter.cpp
   EscapeEnumerator.cpp
   Evaluator.cpp
   FlattenCFG.cpp

Added: llvm/trunk/lib/Transforms/Utils/EntryExitInstrumenter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/EntryExitInstrumenter.cpp?rev=318195&view=auto
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/EntryExitInstrumenter.cpp (added)
+++ llvm/trunk/lib/Transforms/Utils/EntryExitInstrumenter.cpp Tue Nov 14 13:09:45 2017
@@ -0,0 +1,148 @@
+//===- EntryExitInstrumenter.cpp - Function Entry/Exit Instrumentation ----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
+#include "llvm/Analysis/GlobalsModRef.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Pass.h"
+#include "llvm/Transforms/Scalar.h"
+using namespace llvm;
+
+static void insertCall(Function &CurFn, StringRef Func,
+                       Instruction *InsertionPt) {
+  Module &M = *InsertionPt->getParent()->getParent()->getParent();
+  LLVMContext &C = InsertionPt->getParent()->getContext();
+
+  if (Func == "mcount" ||
+      Func == ".mcount" ||
+      Func == "\01__gnu_mcount_nc" ||
+      Func == "\01_mcount" ||
+      Func == "\01mcount" ||
+      Func == "__mcount" ||
+      Func == "_mcount") {
+    Constant *Fn = M.getOrInsertFunction(Func, Type::getVoidTy(C));
+    CallInst::Create(Fn, "", InsertionPt);
+    return;
+  }
+
+  if (Func == "__cyg_profile_func_enter" || Func == "__cyg_profile_func_exit") {
+    Type *ArgTypes[] = {Type::getInt8PtrTy(C), Type::getInt8PtrTy(C)};
+
+    Constant *Fn = M.getOrInsertFunction(
+        Func, FunctionType::get(Type::getVoidTy(C), ArgTypes, false));
+
+    Instruction *RetAddr = CallInst::Create(
+        Intrinsic::getDeclaration(&M, Intrinsic::returnaddress),
+        ArrayRef<Value *>(ConstantInt::get(Type::getInt32Ty(C), 0)), "",
+        InsertionPt);
+
+    Value *Args[] = {ConstantExpr::getBitCast(&CurFn, Type::getInt8PtrTy(C)),
+                     RetAddr};
+
+    CallInst::Create(Fn, ArrayRef<Value *>(Args), "", InsertionPt);
+    return;
+  }
+
+  // We only know how to call a fixed set of instrumentation functions, because
+  // they all expect different arguments, etc.
+  report_fatal_error(Twine("Unknown instrumentation function: '") + Func + "'");
+}
+
+static bool runOnFunction(Function &F, bool PostInlining) {
+  StringRef EntryAttr = PostInlining ? "instrument-function-entry-inlined"
+                                     : "instrument-function-entry";
+
+  StringRef ExitAttr = PostInlining ? "instrument-function-exit-inlined"
+                                    : "instrument-function-exit";
+
+  StringRef EntryFunc = F.getFnAttribute(EntryAttr).getValueAsString();
+  StringRef ExitFunc = F.getFnAttribute(ExitAttr).getValueAsString();
+
+  bool Changed = false;
+
+  // If the attribute is specified, insert instrumentation and then "consume"
+  // the attribute so that it's not inserted again if the pass should happen to
+  // run later for some reason.
+
+  if (!EntryFunc.empty()) {
+    insertCall(F, EntryFunc, &*F.begin()->getFirstInsertionPt());
+    Changed = true;
+    F.removeAttribute(AttributeList::FunctionIndex, EntryAttr);
+  }
+
+  if (!ExitFunc.empty()) {
+    for (BasicBlock &BB : F) {
+      TerminatorInst *T = BB.getTerminator();
+      if (isa<ReturnInst>(T)) {
+        insertCall(F, ExitFunc, T);
+        Changed = true;
+      }
+    }
+    F.removeAttribute(AttributeList::FunctionIndex, ExitAttr);
+  }
+
+  return Changed;
+}
+
+namespace {
+struct EntryExitInstrumenter : public FunctionPass {
+  static char ID;
+  EntryExitInstrumenter() : FunctionPass(ID) {
+    initializeEntryExitInstrumenterPass(*PassRegistry::getPassRegistry());
+  }
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.addPreserved<GlobalsAAWrapperPass>();
+  }
+  bool runOnFunction(Function &F) override { return ::runOnFunction(F, false); }
+};
+char EntryExitInstrumenter::ID = 0;
+
+struct PostInlineEntryExitInstrumenter : public FunctionPass {
+  static char ID;
+  PostInlineEntryExitInstrumenter() : FunctionPass(ID) {
+    initializePostInlineEntryExitInstrumenterPass(
+        *PassRegistry::getPassRegistry());
+  }
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.addPreserved<GlobalsAAWrapperPass>();
+  }
+  bool runOnFunction(Function &F) override { return ::runOnFunction(F, true); }
+};
+char PostInlineEntryExitInstrumenter::ID = 0;
+}
+
+INITIALIZE_PASS(
+    EntryExitInstrumenter, "ee-instrument",
+    "Instrument function entry/exit with calls to e.g. mcount() (pre inlining)",
+    false, false);
+
+INITIALIZE_PASS(PostInlineEntryExitInstrumenter, "post-inline-ee-instrument",
+                "Instrument function entry/exit with calls to e.g. mcount() "
+                "(post inlining)",
+                false, false);
+
+FunctionPass *llvm::createEntryExitInstrumenterPass() {
+  return new EntryExitInstrumenter();
+}
+
+FunctionPass *llvm::createPostInlineEntryExitInstrumenterPass() {
+  return new PostInlineEntryExitInstrumenter();
+}
+
+PreservedAnalyses
+llvm::EntryExitInstrumenterPass::run(Function &F, FunctionAnalysisManager &AM) {
+  runOnFunction(F, PostInlining);
+  PreservedAnalyses PA;
+  PA.preserveSet<CFGAnalyses>();
+  return PA;
+}

Modified: llvm/trunk/test/CodeGen/PowerPC/mcount-insertion.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/mcount-insertion.ll?rev=318195&r1=318194&r2=318195&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/mcount-insertion.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/mcount-insertion.ll Tue Nov 14 13:09:45 2017
@@ -1,16 +1,46 @@
-; RUN: llc < %s | FileCheck %s
+; RUN: opt -ee-instrument < %s | opt -inline | llc | FileCheck %s
+
+; The run-line mimics how Clang might run the instrumentation passes.
+
 target datalayout = "E-m:e-i64:64-n32:64"
 target triple = "powerpc64-bgq-linux"
 
-define void @test1() #0 {
+
+define void @leaf_function() #0 {
 entry:
   ret void
 
-; CHECK-LABEL: @test1
+; CHECK-LABEL: leaf_function:
 ; CHECK: bl mcount
-; CHECK-NOT: mcount
+; CHECK-NOT: bl
+; CHECK: bl __cyg_profile_func_enter
+; CHECK-NOT: bl
+; CHECK: bl __cyg_profile_func_exit
+; CHECK-NOT: bl
 ; CHECK: blr
 }
 
-attributes #0 = { "counting-function"="mcount" }
 
+define void @root_function() #0 {
+entry:
+  call void @leaf_function()
+  ret void
+
+; CHECK-LABEL: root_function:
+; CHECK: bl mcount
+; CHECK-NOT: bl
+; CHECK: bl __cyg_profile_func_enter
+; CHECK-NOT: bl
+
+; Entry and exit calls, inlined from @leaf_function()
+; CHECK: bl __cyg_profile_func_enter
+; CHECK-NOT: bl
+; CHECK: bl __cyg_profile_func_exit
+; CHECK-NOT: bl
+
+; CHECK: bl __cyg_profile_func_exit
+; CHECK-NOT: bl
+; CHECK: blr
+}
+
+attributes #0 = { "instrument-function-entry-inlined"="mcount" "instrument-function-entry"="__cyg_profile_func_enter" "instrument-function-exit"="__cyg_profile_func_exit" }

Modified: llvm/trunk/test/CodeGen/X86/O0-pipeline.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/O0-pipeline.ll?rev=318195&r1=318194&r2=318195&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/O0-pipeline.ll (original)
+++ llvm/trunk/test/CodeGen/X86/O0-pipeline.ll Tue Nov 14 13:09:45 2017
@@ -22,7 +22,7 @@
 ; CHECK-NEXT:       Lower Garbage Collection Instructions
 ; CHECK-NEXT:       Shadow Stack GC Lowering
 ; CHECK-NEXT:       Remove unreachable blocks from the CFG
-; CHECK-NEXT:       Inserts calls to mcount-like functions
+; CHECK-NEXT:       Instrument function entry/exit with calls to e.g. mcount() (post inlining)
 ; CHECK-NEXT:       Scalarize Masked Memory Intrinsics
 ; CHECK-NEXT:       Expand reduction intrinsics
 ; CHECK-NEXT:     Rewrite Symbols

Modified: llvm/trunk/test/Transforms/CountingFunctionInserter/mcount.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CountingFunctionInserter/mcount.ll?rev=318195&r1=318194&r2=318195&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/CountingFunctionInserter/mcount.ll (original)
+++ llvm/trunk/test/Transforms/CountingFunctionInserter/mcount.ll Tue Nov 14 13:09:45 2017
@@ -1,27 +1,86 @@
-; RUN: opt -S -cfinserter < %s | FileCheck %s
+; RUN: opt -passes="function(ee-instrument),cgscc(inline),function(post-inline-ee-instrument)" -S < %s | FileCheck %s
+
+; Running the passes twice should not result in more instrumentation.
+; RUN: opt -passes="function(ee-instrument),function(ee-instrument),cgscc(inline),function(post-inline-ee-instrument),function(post-inline-ee-instrument)" -S < %s | FileCheck %s
+
 target datalayout = "E-m:e-i64:64-n32:64"
 target triple = "powerpc64-bgq-linux"
 
-define void @test1() #0 {
+define void @leaf_function() #0 {
 entry:
   ret void
 
-; CHECK-LABEL: define void @test1()
+; CHECK-LABEL: define void @leaf_function()
 ; CHECK: entry:
 ; CHECK-NEXT: call void @mcount()
-; CHECK: ret void
+; CHECK-NEXT: %0 = call i8* @llvm.returnaddress(i32 0)
+; CHECK-NEXT: call void @__cyg_profile_func_enter(i8* bitcast (void ()* @leaf_function to i8*), i8* %0)
+; CHECK-NEXT: %1 = call i8* @llvm.returnaddress(i32 0)
+; CHECK-NEXT: call void @__cyg_profile_func_exit(i8* bitcast (void ()* @leaf_function to i8*), i8* %1)
+; CHECK-NEXT: ret void
 }
 
-define void @test2() #1 {
+
+define void @root_function() #0 {
 entry:
+  call void @leaf_function()
   ret void
 
-; CHECK-LABEL: define void @test2()
+; CHECK-LABEL: define void @root_function()
 ; CHECK: entry:
-; CHECK-NEXT: call void @.mcount()
-; CHECK: ret void
+; CHECK-NEXT: call void @mcount()
+
+; CHECK-NEXT %0 = call i8* @llvm.returnaddress(i32 0)
+; CHECK-NEXT call void @__cyg_profile_func_enter(i8* bitcast (void ()* @root_function to i8*), i8* %0)
+
+; Entry and exit calls, inlined from @leaf_function()
+; CHECK-NEXT %1 = call i8* @llvm.returnaddress(i32 0)
+; CHECK-NEXT call void @__cyg_profile_func_enter(i8* bitcast (void ()* @leaf_function to i8*), i8* %1)
+; CHECK-NEXT %2 = call i8* @llvm.returnaddress(i32 0)
+; CHECK-NEXT call void @__cyg_profile_func_exit(i8* bitcast (void ()* @leaf_function to i8*), i8* %2)
+; CHECK-NEXT %3 = call i8* @llvm.returnaddress(i32 0)
+
+; CHECK-NEXT call void @__cyg_profile_func_exit(i8* bitcast (void ()* @root_function to i8*), i8* %3)
+; CHECK-NEXT ret void
 }
 
-attributes #0 = { "counting-function"="mcount" }
-attributes #1 = { "counting-function"=".mcount" }
+attributes #0 = { "instrument-function-entry-inlined"="mcount" "instrument-function-entry"="__cyg_profile_func_enter" "instrument-function-exit"="__cyg_profile_func_exit" }
+
+
+; The mcount function has many different names.
+
+define void @f1() #1 { entry: ret void }
+; CHECK-LABEL: define void @f1
+; CHECK: call void @.mcount
+
+define void @f2() #2 { entry: ret void }
+; CHECK-LABEL: define void @f2
+; CHECK: call void @"\01__gnu_mcount_nc"
+
+define void @f3() #3 { entry: ret void }
+; CHECK-LABEL: define void @f3
+; CHECK: call void @"\01_mcount"
+
+define void @f4() #4 { entry: ret void }
+; CHECK-LABEL: define void @f4
+; CHECK: call void @"\01mcount"
+
+define void @f5() #5 { entry: ret void }
+; CHECK-LABEL: define void @f5
+; CHECK: call void @__mcount
+
+define void @f6() #6 { entry: ret void }
+; CHECK-LABEL: define void @f6
+; CHECK: call void @_mcount
+
+
+; The attributes are "consumed" when the instrumentation is inserted.
+; CHECK: attributes
+; CHECK-NOT: instrument-function
 
+attributes #1 = { "instrument-function-entry-inlined"=".mcount" }
+attributes #2 = { "instrument-function-entry-inlined"="\01__gnu_mcount_nc" }
+attributes #3 = { "instrument-function-entry-inlined"="\01_mcount" }
+attributes #4 = { "instrument-function-entry-inlined"="\01mcount" }
+attributes #5 = { "instrument-function-entry-inlined"="__mcount" }
+attributes #6 = { "instrument-function-entry-inlined"="_mcount" }

Modified: llvm/trunk/tools/llc/llc.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llc/llc.cpp?rev=318195&r1=318194&r2=318195&view=diff
==============================================================================
--- llvm/trunk/tools/llc/llc.cpp (original)
+++ llvm/trunk/tools/llc/llc.cpp Tue Nov 14 13:09:45 2017
@@ -291,7 +291,8 @@ int main(int argc, char **argv) {
   initializeCodeGen(*Registry);
   initializeLoopStrengthReducePass(*Registry);
   initializeLowerIntrinsicsPass(*Registry);
-  initializeCountingFunctionInserterPass(*Registry);
+  initializeEntryExitInstrumenterPass(*Registry);
+  initializePostInlineEntryExitInstrumenterPass(*Registry);
   initializeUnreachableBlockElimLegacyPassPass(*Registry);
   initializeConstantHoistingLegacyPassPass(*Registry);
   initializeScalarOpts(*Registry);

Modified: llvm/trunk/tools/opt/opt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/opt.cpp?rev=318195&r1=318194&r2=318195&view=diff
==============================================================================
--- llvm/trunk/tools/opt/opt.cpp (original)
+++ llvm/trunk/tools/opt/opt.cpp Tue Nov 14 13:09:45 2017
@@ -403,7 +403,8 @@ int main(int argc, char **argv) {
   initializePreISelIntrinsicLoweringLegacyPassPass(Registry);
   initializeGlobalMergePass(Registry);
   initializeInterleavedAccessPass(Registry);
-  initializeCountingFunctionInserterPass(Registry);
+  initializeEntryExitInstrumenterPass(Registry);
+  initializePostInlineEntryExitInstrumenterPass(Registry);
   initializeUnreachableBlockElimLegacyPassPass(Registry);
   initializeExpandReductionsPass(Registry);
   initializeWriteBitcodePassPass(Registry);




More information about the llvm-commits mailing list