Changeset View
Changeset View
Standalone View
Standalone View
llvm/trunk/lib/Transforms/Instrumentation/InstrProfiling.cpp
Show First 20 Lines • Show All 190 Lines • ▼ Show 20 Lines | |||||
GlobalVariable * | GlobalVariable * | ||||
InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) { | InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) { | ||||
GlobalVariable *Name = Inc->getName(); | GlobalVariable *Name = Inc->getName(); | ||||
auto It = RegionCounters.find(Name); | auto It = RegionCounters.find(Name); | ||||
if (It != RegionCounters.end()) | if (It != RegionCounters.end()) | ||||
return It->second; | return It->second; | ||||
// Move the name variable to the right section. Make sure it is placed in the | // Move the name variable to the right section. Place them in a COMDAT group | ||||
// same comdat as its associated function. Otherwise, we may get multiple | // if the associated function is a COMDAT. This will make sure that | ||||
// counters for the same function in certain cases. | // only one copy of counters of the COMDAT function will be emitted after | ||||
// linking. | |||||
Function *Fn = Inc->getParent()->getParent(); | Function *Fn = Inc->getParent()->getParent(); | ||||
Comdat *ProfileVarsComdat = nullptr; | |||||
if (Fn->hasComdat()) | |||||
ProfileVarsComdat = M->getOrInsertComdat(StringRef(getVarName(Inc, "vars"))); | |||||
Name->setSection(getNameSection()); | Name->setSection(getNameSection()); | ||||
Name->setAlignment(1); | Name->setAlignment(1); | ||||
Name->setComdat(Fn->getComdat()); | Name->setComdat(ProfileVarsComdat); | ||||
uint64_t NumCounters = Inc->getNumCounters()->getZExtValue(); | uint64_t NumCounters = Inc->getNumCounters()->getZExtValue(); | ||||
LLVMContext &Ctx = M->getContext(); | LLVMContext &Ctx = M->getContext(); | ||||
ArrayType *CounterTy = ArrayType::get(Type::getInt64Ty(Ctx), NumCounters); | ArrayType *CounterTy = ArrayType::get(Type::getInt64Ty(Ctx), NumCounters); | ||||
// Create the counters variable. | // Create the counters variable. | ||||
auto *Counters = new GlobalVariable(*M, CounterTy, false, Name->getLinkage(), | auto *Counters = new GlobalVariable(*M, CounterTy, false, Name->getLinkage(), | ||||
Constant::getNullValue(CounterTy), | Constant::getNullValue(CounterTy), | ||||
getVarName(Inc, "counters")); | getVarName(Inc, "counters")); | ||||
Counters->setVisibility(Name->getVisibility()); | Counters->setVisibility(Name->getVisibility()); | ||||
Counters->setSection(getCountersSection()); | Counters->setSection(getCountersSection()); | ||||
Counters->setAlignment(8); | Counters->setAlignment(8); | ||||
Counters->setComdat(Fn->getComdat()); | Counters->setComdat(ProfileVarsComdat); | ||||
RegionCounters[Inc->getName()] = Counters; | RegionCounters[Inc->getName()] = Counters; | ||||
// Create data variable. | // Create data variable. | ||||
auto *NameArrayTy = Name->getType()->getPointerElementType(); | auto *NameArrayTy = Name->getType()->getPointerElementType(); | ||||
auto *Int32Ty = Type::getInt32Ty(Ctx); | auto *Int32Ty = Type::getInt32Ty(Ctx); | ||||
auto *Int64Ty = Type::getInt64Ty(Ctx); | auto *Int64Ty = Type::getInt64Ty(Ctx); | ||||
auto *Int8PtrTy = Type::getInt8PtrTy(Ctx); | auto *Int8PtrTy = Type::getInt8PtrTy(Ctx); | ||||
auto *Int64PtrTy = Type::getInt64PtrTy(Ctx); | auto *Int64PtrTy = Type::getInt64PtrTy(Ctx); | ||||
Type *DataTypes[] = {Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int64PtrTy}; | Type *DataTypes[] = {Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int64PtrTy}; | ||||
auto *DataTy = StructType::get(Ctx, makeArrayRef(DataTypes)); | auto *DataTy = StructType::get(Ctx, makeArrayRef(DataTypes)); | ||||
Constant *DataVals[] = { | Constant *DataVals[] = { | ||||
ConstantInt::get(Int32Ty, NameArrayTy->getArrayNumElements()), | ConstantInt::get(Int32Ty, NameArrayTy->getArrayNumElements()), | ||||
ConstantInt::get(Int32Ty, NumCounters), | ConstantInt::get(Int32Ty, NumCounters), | ||||
ConstantInt::get(Int64Ty, Inc->getHash()->getZExtValue()), | ConstantInt::get(Int64Ty, Inc->getHash()->getZExtValue()), | ||||
ConstantExpr::getBitCast(Name, Int8PtrTy), | ConstantExpr::getBitCast(Name, Int8PtrTy), | ||||
ConstantExpr::getBitCast(Counters, Int64PtrTy)}; | ConstantExpr::getBitCast(Counters, Int64PtrTy)}; | ||||
auto *Data = new GlobalVariable(*M, DataTy, true, Name->getLinkage(), | auto *Data = new GlobalVariable(*M, DataTy, true, Name->getLinkage(), | ||||
ConstantStruct::get(DataTy, DataVals), | ConstantStruct::get(DataTy, DataVals), | ||||
getVarName(Inc, "data")); | getVarName(Inc, "data")); | ||||
Data->setVisibility(Name->getVisibility()); | Data->setVisibility(Name->getVisibility()); | ||||
Data->setSection(getDataSection()); | Data->setSection(getDataSection()); | ||||
Data->setAlignment(8); | Data->setAlignment(8); | ||||
Data->setComdat(Fn->getComdat()); | Data->setComdat(ProfileVarsComdat); | ||||
// Mark the data variable as used so that it isn't stripped out. | // Mark the data variable as used so that it isn't stripped out. | ||||
UsedVars.push_back(Data); | UsedVars.push_back(Data); | ||||
return Counters; | return Counters; | ||||
} | } | ||||
void InstrProfiling::emitRegistration() { | void InstrProfiling::emitRegistration() { | ||||
▲ Show 20 Lines • Show All 126 Lines • Show Last 20 Lines |