[llvm] r271298 - [esan|cfrag] Create the skeleton of cfrag variable for the runtime

Qin Zhao via llvm-commits llvm-commits at lists.llvm.org
Tue May 31 10:14:03 PDT 2016


Author: zhaoqin
Date: Tue May 31 12:14:02 2016
New Revision: 271298

URL: http://llvm.org/viewvc/llvm-project?rev=271298&view=rev
Log:
[esan|cfrag] Create the skeleton of cfrag variable for the runtime

Summary:
Creates a global variable containing preliminary information
for the cache-fragmentation tool runtime.

Passes a pointer to the variable (null if no variable is created) to the
compilation unit init and exit routines in the runtime.

Reviewers: aizatsky, bruening

Subscribers: filcab, kubabrecka, bruening, kcc, vitalybuka, eugenis, llvm-commits, zhaoqin

Differential Revision: http://reviews.llvm.org/D20541

Modified:
    llvm/trunk/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp
    llvm/trunk/test/Instrumentation/EfficiencySanitizer/cache_frag_basic.ll
    llvm/trunk/test/Instrumentation/EfficiencySanitizer/working_set_basic.ll

Modified: llvm/trunk/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp?rev=271298&r1=271297&r2=271298&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp Tue May 31 12:14:02 2016
@@ -102,6 +102,21 @@ OverrideOptionsFromCL(EfficiencySanitize
   return Options;
 }
 
+// Create a constant for Str so that we can pass it to the run-time lib.
+static GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str,
+                                                    bool AllowMerging) {
+  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, "");
+  if (AllowMerging)
+    GV->setUnnamedAddr(true);
+  GV->setAlignment(1);  // Strings may not be merged w/o setting align 1.
+  return GV;
+}
+
 /// EfficiencySanitizer: instrument each module to find performance issues.
 class EfficiencySanitizer : public ModulePass {
 public:
@@ -115,8 +130,9 @@ public:
 private:
   bool initOnModule(Module &M);
   void initializeCallbacks(Module &M);
-  GlobalVariable *createEsanInitToolGV(Module &M);
-  void createDestructor(Module &M, GlobalVariable *GV);
+  GlobalVariable *createCacheFragInfoGV(Module &M, Constant *UnitName);
+  Constant *createEsanInitToolInfoArg(Module &M);
+  void createDestructor(Module &M, Constant *ToolInfoArg);
   bool runOnFunction(Function &F, Module &M);
   bool instrumentLoadOrStore(Instruction *I, const DataLayout &DL);
   bool instrumentMemIntrinsic(MemIntrinsic *MI);
@@ -204,18 +220,73 @@ void EfficiencySanitizer::initializeCall
                             IRB.getInt32Ty(), IntptrTy, nullptr));
 }
 
-// Create the tool-specific global variable passed to EsanInit and EsanExit.
-GlobalVariable *EfficiencySanitizer::createEsanInitToolGV(Module &M) {
-  GlobalVariable *GV = nullptr;
-  // FIXME: create the tool specific global variable.
-  if (GV == nullptr) {
-    GV = new GlobalVariable(M, IntptrTy, true, GlobalVariable::InternalLinkage,
-                            Constant::getNullValue(IntptrTy));
-  }
-  return GV;
+// Create the global variable for the cache-fragmentation tool.
+GlobalVariable *EfficiencySanitizer::createCacheFragInfoGV(
+    Module &M, Constant *UnitName) {
+  assert(Options.ToolType == EfficiencySanitizerOptions::ESAN_CacheFrag);
+
+  auto *Int8PtrTy = Type::getInt8PtrTy(*Ctx);
+  auto *Int8PtrPtrTy = Int8PtrTy->getPointerTo();
+  auto *Int32Ty = Type::getInt32Ty(*Ctx);
+  auto *Int64PtrTy = Type::getInt64PtrTy(*Ctx);
+  // This structure should be kept consistent with the StructInfo struct
+  // in the runtime library.
+  // struct StructInfo {
+  //   const char *StructName;
+  //   u32 NumOfFields;
+  //   u64 *FieldCounters;
+  //   const char **FieldTypeNames;
+  // };
+  auto *StructInfoTy =
+    StructType::get(Int8PtrTy, Int32Ty, Int64PtrTy, Int8PtrPtrTy, nullptr);
+  auto *StructInfoPtrTy = StructInfoTy->getPointerTo();
+  // This structure should be kept consistent with the CacheFragInfo struct
+  // in the runtime library.
+  // struct CacheFragInfo {
+  //   const char *UnitName;
+  //   u32 NumOfStructs;
+  //   StructInfo *Structs;
+  // };
+  auto *CacheFragInfoTy =
+    StructType::get(Int8PtrTy, Int32Ty, StructInfoPtrTy, nullptr);
+
+  std::vector<StructType *> Vec = M.getIdentifiedStructTypes();
+  // FIXME: iterate over Vec and create the StructInfo array.
+  auto *CacheFragInfoGV = new GlobalVariable(
+      M, CacheFragInfoTy, true, GlobalVariable::InternalLinkage,
+      ConstantStruct::get(CacheFragInfoTy,
+                          UnitName,
+                          ConstantInt::get(Int32Ty, Vec.size()),
+                          ConstantPointerNull::get(StructInfoPtrTy),
+                          nullptr));
+  return CacheFragInfoGV;
+}
+
+// Create the tool-specific argument passed to EsanInit and EsanExit.
+Constant *EfficiencySanitizer::createEsanInitToolInfoArg(Module &M) {
+  // This structure contains tool-specific information about each compilation
+  // unit (module) and is passed to the runtime library.
+  GlobalVariable *ToolInfoGV = nullptr;
+
+  auto *Int8PtrTy = Type::getInt8PtrTy(*Ctx);
+  // Compilation unit name.
+  auto *UnitName = ConstantExpr::getPointerCast(
+      createPrivateGlobalForString(M, M.getModuleIdentifier(), true),
+      Int8PtrTy);
+
+  // Create the tool-specific variable.
+  if (Options.ToolType == EfficiencySanitizerOptions::ESAN_CacheFrag)
+    ToolInfoGV = createCacheFragInfoGV(M, UnitName);
+
+  if (ToolInfoGV != nullptr)
+    return ConstantExpr::getPointerCast(ToolInfoGV, Int8PtrTy);
+
+  // Create the null pointer if no tool-specific variable created.
+  return ConstantPointerNull::get(Int8PtrTy);
 }
 
-void EfficiencySanitizer::createDestructor(Module &M, GlobalVariable *GV) {
+void EfficiencySanitizer::createDestructor(Module &M, Constant *ToolInfoArg) {
+  PointerType *Int8PtrTy = Type::getInt8PtrTy(*Ctx);
   EsanDtorFunction = Function::Create(FunctionType::get(Type::getVoidTy(*Ctx),
                                                         false),
                                       GlobalValue::InternalLinkage,
@@ -224,10 +295,9 @@ void EfficiencySanitizer::createDestruct
   IRBuilder<> IRB_Dtor(EsanDtorFunction->getEntryBlock().getTerminator());
   Function *EsanExit = checkSanitizerInterfaceFunction(
       M.getOrInsertFunction(EsanExitName, IRB_Dtor.getVoidTy(),
-                            IntptrTy, nullptr));
+                            Int8PtrTy, nullptr));
   EsanExit->setLinkage(Function::ExternalLinkage);
-  IRB_Dtor.CreateCall(EsanExit,
-                      {IRB_Dtor.CreatePointerCast(GV, IntptrTy)});
+  IRB_Dtor.CreateCall(EsanExit, {ToolInfoArg});
   appendToGlobalDtors(M, EsanDtorFunction, EsanCtorAndDtorPriority);
 }
 
@@ -236,18 +306,19 @@ bool EfficiencySanitizer::initOnModule(M
   const DataLayout &DL = M.getDataLayout();
   IRBuilder<> IRB(M.getContext());
   IntegerType *OrdTy = IRB.getInt32Ty();
+  PointerType *Int8PtrTy = Type::getInt8PtrTy(*Ctx);
   IntptrTy = DL.getIntPtrType(M.getContext());
   // Create the variable passed to EsanInit and EsanExit.
-  GlobalVariable *GV = createEsanInitToolGV(M);
+  Constant *ToolInfoArg = createEsanInitToolInfoArg(M);
   // Constructor
   std::tie(EsanCtorFunction, std::ignore) = createSanitizerCtorAndInitFunctions(
-      M, EsanModuleCtorName, EsanInitName, /*InitArgTypes=*/{OrdTy, IntptrTy},
+      M, EsanModuleCtorName, EsanInitName, /*InitArgTypes=*/{OrdTy, Int8PtrTy},
       /*InitArgs=*/{
         ConstantInt::get(OrdTy, static_cast<int>(Options.ToolType)),
-        ConstantExpr::getPointerCast(GV, IntptrTy)});
+        ToolInfoArg});
   appendToGlobalCtors(M, EsanCtorFunction, EsanCtorAndDtorPriority);
 
-  createDestructor(M, GV);
+  createDestructor(M, ToolInfoArg);
   return true;
 }
 

Modified: llvm/trunk/test/Instrumentation/EfficiencySanitizer/cache_frag_basic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/EfficiencySanitizer/cache_frag_basic.ll?rev=271298&r1=271297&r2=271298&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/EfficiencySanitizer/cache_frag_basic.ll (original)
+++ llvm/trunk/test/Instrumentation/EfficiencySanitizer/cache_frag_basic.ll Tue May 31 12:14:02 2016
@@ -254,6 +254,6 @@ entry:
 ; Top-level:
 
 ; CHECK: define internal void @esan.module_ctor()
-; CHECK: call void @__esan_init(i32 1, i64 ptrtoint (i64* @0 to i64))
+; CHECK: call void @__esan_init(i32 1, i8* bitcast ({ i8*, i32, { i8*, i32, i64*, i8** }* }* @1 to i8*))
 ; CHECK: define internal void @esan.module_dtor()
-; CHECK: call void @__esan_exit(i64 ptrtoint (i64* @0 to i64))
+; CHECK: call void @__esan_exit(i8* bitcast ({ i8*, i32, { i8*, i32, i64*, i8** }* }* @1 to i8*))

Modified: llvm/trunk/test/Instrumentation/EfficiencySanitizer/working_set_basic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/EfficiencySanitizer/working_set_basic.ll?rev=271298&r1=271297&r2=271298&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/EfficiencySanitizer/working_set_basic.ll (original)
+++ llvm/trunk/test/Instrumentation/EfficiencySanitizer/working_set_basic.ll Tue May 31 12:14:02 2016
@@ -161,4 +161,6 @@ entry:
 ; Top-level:
 
 ; CHECK: define internal void @esan.module_ctor()
-; CHECK: call void @__esan_init(i32 2, i64 ptrtoint (i64* @0 to i64))
+; CHECK: call void @__esan_init(i32 2, i8* null)
+; CHECK: define internal void @esan.module_dtor()
+; CHECK: call void @__esan_exit(i8* null)




More information about the llvm-commits mailing list