[llvm] r271547 - [esan|cfrag] Create the cfrag struct array for the runtime
Qin Zhao via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 2 10:30:47 PDT 2016
Author: zhaoqin
Date: Thu Jun 2 12:30:47 2016
New Revision: 271547
URL: http://llvm.org/viewvc/llvm-project?rev=271547&view=rev
Log:
[esan|cfrag] Create the cfrag struct array for the runtime
Summary:
Fills the cfrag struct variable with an array of struct information
variables.
Reviewers: aizatsky, bruening
Subscribers: bruening, kcc, vitalybuka, eugenis, llvm-commits, zhaoqin
Differential Revision: http://reviews.llvm.org/D20661
Modified:
llvm/trunk/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp
Modified: llvm/trunk/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp?rev=271547&r1=271546&r2=271547&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp Thu Jun 2 12:30:47 2016
@@ -30,6 +30,7 @@
#include "llvm/IR/Type.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
@@ -61,6 +62,7 @@ STATISTIC(NumInstrumentedStores, "Number
STATISTIC(NumFastpaths, "Number of instrumented fastpaths");
STATISTIC(NumAccessesWithIrregularSize,
"Number of accesses with a size outside our targeted callout sizes");
+STATISTIC(NumIgnoredStructs, "Number of ignored structs");
static const uint64_t EsanCtorAndDtorPriority = 0;
static const char *const EsanModuleCtorName = "esan.module_ctor";
@@ -85,6 +87,10 @@ static const int ShadowScale[] = {
6, // ESAN_WorkingSet: 64B:1B, so 64 to 1 == >>6.
};
+// MaxStructCounterNameSize is a soft size limit to avoid insanely long
+// names for those extremely large structs.
+static const unsigned MaxStructCounterNameSize = 512;
+
namespace {
static EfficiencySanitizerOptions
@@ -130,6 +136,9 @@ public:
private:
bool initOnModule(Module &M);
void initializeCallbacks(Module &M);
+ bool shouldIgnoreStructType(StructType *StructTy);
+ void createStructCounterName(
+ StructType *StructTy, SmallString<MaxStructCounterNameSize> &NameStr);
GlobalVariable *createCacheFragInfoGV(Module &M, Constant *UnitName);
Constant *createEsanInitToolInfoArg(Module &M);
void createDestructor(Module &M, Constant *ToolInfoArg);
@@ -220,6 +229,39 @@ void EfficiencySanitizer::initializeCall
IRB.getInt32Ty(), IntptrTy, nullptr));
}
+bool EfficiencySanitizer::shouldIgnoreStructType(StructType *StructTy) {
+ if (StructTy == nullptr || StructTy->isOpaque() /* no struct body */)
+ return true;
+ return false;
+}
+
+void EfficiencySanitizer::createStructCounterName(
+ StructType *StructTy, SmallString<MaxStructCounterNameSize> &NameStr) {
+ // Append NumFields and field type ids to avoid struct conflicts
+ // with the same name but different fields.
+ if (StructTy->hasName())
+ NameStr += StructTy->getName();
+ else
+ NameStr += "struct.anon";
+ // We allow the actual size of the StructCounterName to be larger than
+ // MaxStructCounterNameSize and append #NumFields and at least one
+ // field type id.
+ // Append #NumFields.
+ NameStr += "#";
+ Twine(StructTy->getNumElements()).toVector(NameStr);
+ // Append struct field type ids in the reverse order.
+ for (int i = StructTy->getNumElements() - 1; i >= 0; --i) {
+ NameStr += "#";
+ Twine(StructTy->getElementType(i)->getTypeID()).toVector(NameStr);
+ if (NameStr.size() >= MaxStructCounterNameSize)
+ break;
+ }
+ if (StructTy->isLiteral()) {
+ // End with # for literal struct.
+ NameStr += "#";
+ }
+}
+
// Create the global variable for the cache-fragmentation tool.
GlobalVariable *EfficiencySanitizer::createCacheFragInfoGV(
Module &M, Constant *UnitName) {
@@ -228,12 +270,13 @@ GlobalVariable *EfficiencySanitizer::cre
auto *Int8PtrTy = Type::getInt8PtrTy(*Ctx);
auto *Int8PtrPtrTy = Int8PtrTy->getPointerTo();
auto *Int32Ty = Type::getInt32Ty(*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 NumOfFields;
+ // u32 NumFields;
// u64 *FieldCounters;
// const char **FieldTypeNames;
// };
@@ -244,20 +287,87 @@ GlobalVariable *EfficiencySanitizer::cre
// in the runtime library.
// struct CacheFragInfo {
// const char *UnitName;
- // u32 NumOfStructs;
+ // u32 NumStructs;
// 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.
+ unsigned NumStructs = 0;
+ SmallVector<Constant *, 16> Initializers;
+
+ for (auto &StructTy : Vec) {
+ if (shouldIgnoreStructType(StructTy)) {
+ ++NumIgnoredStructs;
+ continue;
+ }
+ ++NumStructs;
+
+ // StructName.
+ SmallString<MaxStructCounterNameSize> CounterNameStr;
+ createStructCounterName(StructTy, CounterNameStr);
+ GlobalVariable *StructCounterName = createPrivateGlobalForString(
+ M, CounterNameStr, /*AllowMerging*/true);
+
+ // FieldCounters.
+ // We create the counter array with StructCounterName and weak linkage
+ // so that the structs with the same name and layout from different
+ // compilation units will be merged into one.
+ auto *CounterArrayTy = ArrayType::get(Int64Ty, StructTy->getNumElements());
+ GlobalVariable *Counters =
+ new GlobalVariable(M, CounterArrayTy, false,
+ GlobalVariable::WeakAnyLinkage,
+ ConstantAggregateZero::get(CounterArrayTy),
+ CounterNameStr);
+
+ // FieldTypeNames.
+ // We pass the field type name array to the runtime for better reporting.
+ auto *TypeNameArrayTy = ArrayType::get(Int8PtrTy, StructTy->getNumElements());
+ GlobalVariable *TypeName =
+ new GlobalVariable(M, TypeNameArrayTy, true,
+ GlobalVariable::InternalLinkage, nullptr);
+ SmallVector<Constant *, 16> TypeNameVec;
+ for (unsigned i = 0; i < StructTy->getNumElements(); ++i) {
+ Type *Ty = StructTy->getElementType(i);
+ std::string Str;
+ raw_string_ostream StrOS(Str);
+ Ty->print(StrOS);
+ TypeNameVec.push_back(
+ ConstantExpr::getPointerCast(
+ createPrivateGlobalForString(M, StrOS.str(), true),
+ Int8PtrTy));
+ }
+ TypeName->setInitializer(ConstantArray::get(TypeNameArrayTy, TypeNameVec));
+
+ Initializers.push_back(
+ ConstantStruct::get(
+ StructInfoTy,
+ ConstantExpr::getPointerCast(StructCounterName, Int8PtrTy),
+ ConstantInt::get(Int32Ty, StructTy->getNumElements()),
+ ConstantExpr::getPointerCast(Counters, Int64PtrTy),
+ ConstantExpr::getPointerCast(TypeName, Int8PtrPtrTy),
+ nullptr));
+ }
+ // Structs.
+ Constant *StructInfo;
+ if (NumStructs == 0) {
+ StructInfo = ConstantPointerNull::get(StructInfoPtrTy);
+ } else {
+ auto *StructInfoArrayTy = ArrayType::get(StructInfoTy, NumStructs);
+ StructInfo = ConstantExpr::getPointerCast(
+ new GlobalVariable(M, StructInfoArrayTy, false,
+ GlobalVariable::InternalLinkage,
+ ConstantArray::get(StructInfoArrayTy, Initializers)),
+ StructInfoPtrTy);
+ }
+
auto *CacheFragInfoGV = new GlobalVariable(
M, CacheFragInfoTy, true, GlobalVariable::InternalLinkage,
ConstantStruct::get(CacheFragInfoTy,
UnitName,
- ConstantInt::get(Int32Ty, Vec.size()),
- ConstantPointerNull::get(StructInfoPtrTy),
+ ConstantInt::get(Int32Ty, NumStructs),
+ StructInfo,
nullptr));
return CacheFragInfoGV;
}
More information about the llvm-commits
mailing list