summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp40
1 files changed, 29 insertions, 11 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp
index 63391b373c5..83ae3d516f8 100644
--- a/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp
@@ -158,8 +158,9 @@ private:
bool shouldIgnoreStructType(StructType *StructTy);
void createStructCounterName(
StructType *StructTy, SmallString<MaxStructCounterNameSize> &NameStr);
- GlobalVariable *createCacheFragInfoGV(Module &M, Constant *UnitName);
- Constant *createEsanInitToolInfoArg(Module &M);
+ GlobalVariable *createCacheFragInfoGV(Module &M, const DataLayout &DL,
+ Constant *UnitName);
+ Constant *createEsanInitToolInfoArg(Module &M, const DataLayout &DL);
void createDestructor(Module &M, Constant *ToolInfoArg);
bool runOnFunction(Function &F, Module &M);
bool instrumentLoadOrStore(Instruction *I, const DataLayout &DL);
@@ -287,24 +288,28 @@ void EfficiencySanitizer::createStructCounterName(
// Create the global variable for the cache-fragmentation tool.
GlobalVariable *EfficiencySanitizer::createCacheFragInfoGV(
- Module &M, Constant *UnitName) {
+ Module &M, const DataLayout &DL, Constant *UnitName) {
assert(Options.ToolType == EfficiencySanitizerOptions::ESAN_CacheFrag);
auto *Int8PtrTy = Type::getInt8PtrTy(*Ctx);
auto *Int8PtrPtrTy = Int8PtrTy->getPointerTo();
auto *Int32Ty = Type::getInt32Ty(*Ctx);
+ auto *Int32PtrTy = Type::getInt32PtrTy(*Ctx);
auto *Int64Ty = Type::getInt64Ty(*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 Size;
// u32 NumFields;
+ // u32 *FieldOffsets;
// u64 *FieldCounters;
// const char **FieldTypeNames;
// };
auto *StructInfoTy =
- StructType::get(Int8PtrTy, Int32Ty, Int64PtrTy, Int8PtrPtrTy, nullptr);
+ StructType::get(Int8PtrTy, Int32Ty, Int32Ty, Int32PtrTy, Int64PtrTy,
+ Int8PtrPtrTy, nullptr);
auto *StructInfoPtrTy = StructInfoTy->getPointerTo();
// This structure should be kept consistent with the CacheFragInfo struct
// in the runtime library.
@@ -347,13 +352,21 @@ GlobalVariable *EfficiencySanitizer::createCacheFragInfoGV(
// Remember the counter variable for each struct type.
StructTyMap.insert(std::pair<Type *, GlobalVariable *>(StructTy, Counters));
+ // We pass the field type name array and offset array to the runtime for
+ // better reporting.
// FieldTypeNames.
- // We pass the field type name array to the runtime for better reporting.
auto *TypeNameArrayTy = ArrayType::get(Int8PtrTy, StructTy->getNumElements());
- GlobalVariable *TypeName =
+ GlobalVariable *TypeNames =
new GlobalVariable(M, TypeNameArrayTy, true,
GlobalVariable::InternalLinkage, nullptr);
SmallVector<Constant *, 16> TypeNameVec;
+ // FieldOffsets.
+ const StructLayout *SL = DL.getStructLayout(StructTy);
+ auto *OffsetArrayTy = ArrayType::get(Int32Ty, StructTy->getNumElements());
+ GlobalVariable *Offsets =
+ new GlobalVariable(M, OffsetArrayTy, true,
+ GlobalVariable::InternalLinkage, nullptr);
+ SmallVector<Constant *, 16> OffsetVec;
for (unsigned i = 0; i < StructTy->getNumElements(); ++i) {
Type *Ty = StructTy->getElementType(i);
std::string Str;
@@ -363,16 +376,20 @@ GlobalVariable *EfficiencySanitizer::createCacheFragInfoGV(
ConstantExpr::getPointerCast(
createPrivateGlobalForString(M, StrOS.str(), true),
Int8PtrTy));
+ OffsetVec.push_back(ConstantInt::get(Int32Ty, SL->getElementOffset(i)));
}
- TypeName->setInitializer(ConstantArray::get(TypeNameArrayTy, TypeNameVec));
+ TypeNames->setInitializer(ConstantArray::get(TypeNameArrayTy, TypeNameVec));
+ Offsets->setInitializer(ConstantArray::get(OffsetArrayTy, OffsetVec));
Initializers.push_back(
ConstantStruct::get(
StructInfoTy,
ConstantExpr::getPointerCast(StructCounterName, Int8PtrTy),
+ ConstantInt::get(Int32Ty, SL->getSizeInBytes()),
ConstantInt::get(Int32Ty, StructTy->getNumElements()),
+ ConstantExpr::getPointerCast(Offsets, Int32PtrTy),
ConstantExpr::getPointerCast(Counters, Int64PtrTy),
- ConstantExpr::getPointerCast(TypeName, Int8PtrPtrTy),
+ ConstantExpr::getPointerCast(TypeNames, Int8PtrPtrTy),
nullptr));
}
// Structs.
@@ -399,7 +416,8 @@ GlobalVariable *EfficiencySanitizer::createCacheFragInfoGV(
}
// Create the tool-specific argument passed to EsanInit and EsanExit.
-Constant *EfficiencySanitizer::createEsanInitToolInfoArg(Module &M) {
+Constant *EfficiencySanitizer::createEsanInitToolInfoArg(Module &M,
+ const DataLayout &DL) {
// This structure contains tool-specific information about each compilation
// unit (module) and is passed to the runtime library.
GlobalVariable *ToolInfoGV = nullptr;
@@ -412,7 +430,7 @@ Constant *EfficiencySanitizer::createEsanInitToolInfoArg(Module &M) {
// Create the tool-specific variable.
if (Options.ToolType == EfficiencySanitizerOptions::ESAN_CacheFrag)
- ToolInfoGV = createCacheFragInfoGV(M, UnitName);
+ ToolInfoGV = createCacheFragInfoGV(M, DL, UnitName);
if (ToolInfoGV != nullptr)
return ConstantExpr::getPointerCast(ToolInfoGV, Int8PtrTy);
@@ -445,7 +463,7 @@ bool EfficiencySanitizer::initOnModule(Module &M) {
PointerType *Int8PtrTy = Type::getInt8PtrTy(*Ctx);
IntptrTy = DL.getIntPtrType(M.getContext());
// Create the variable passed to EsanInit and EsanExit.
- Constant *ToolInfoArg = createEsanInitToolInfoArg(M);
+ Constant *ToolInfoArg = createEsanInitToolInfoArg(M, DL);
// Constructor
// We specify the tool type both in the EsanWhichToolName global
// and as an arg to the init routine as a sanity check.
OpenPOWER on IntegriCloud