[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