Example #1
0
void InstrProfiling::emitInitialization() {
  StringRef InstrProfileOutput = Options.InstrProfileOutput;

  if (!InstrProfileOutput.empty()) {
    // Create variable for profile name.
    Constant *ProfileNameConst =
        ConstantDataArray::getString(M->getContext(), InstrProfileOutput, true);
    GlobalVariable *ProfileNameVar = new GlobalVariable(
        *M, ProfileNameConst->getType(), true, GlobalValue::WeakAnyLinkage,
        ProfileNameConst, INSTR_PROF_QUOTE(INSTR_PROF_PROFILE_NAME_VAR));
    Triple TT(M->getTargetTriple());
    if (TT.supportsCOMDAT()) {
      ProfileNameVar->setLinkage(GlobalValue::ExternalLinkage);
      ProfileNameVar->setComdat(M->getOrInsertComdat(
          StringRef(INSTR_PROF_QUOTE(INSTR_PROF_PROFILE_NAME_VAR))));
    }
  }

  Constant *RegisterF = M->getFunction(getInstrProfRegFuncsName());
  if (!RegisterF)
    return;

  // Create the initialization function.
  auto *VoidTy = Type::getVoidTy(M->getContext());
  auto *F = Function::Create(FunctionType::get(VoidTy, false),
                             GlobalValue::InternalLinkage,
                             getInstrProfInitFuncName(), M);
  F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
  F->addFnAttr(Attribute::NoInline);
  if (Options.NoRedZone)
    F->addFnAttr(Attribute::NoRedZone);

  // Add the basic block and the necessary calls.
  IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", F));
  if (RegisterF)
    IRB.CreateCall(RegisterF, {});
  IRB.CreateRetVoid();

  appendToGlobalCtors(*M, F, 0);
}
Example #2
0
GlobalVariable *
InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
  GlobalVariable *Name = Inc->getName();
  auto It = RegionCounters.find(Name);
  if (It != RegionCounters.end())
    return It->second;

  // Move the name variable to the right section. Place them in a COMDAT group
  // if the associated function is a COMDAT. This will make sure that
  // only one copy of counters of the COMDAT function will be emitted after
  // linking.
  Function *Fn = Inc->getParent()->getParent();
  Comdat *ProfileVarsComdat = nullptr;
  if (Fn->hasComdat())
    ProfileVarsComdat = M->getOrInsertComdat(StringRef(getVarName(Inc, "vars")));
  Name->setSection(getNameSection());
  Name->setAlignment(1);
  Name->setComdat(ProfileVarsComdat);

  uint64_t NumCounters = Inc->getNumCounters()->getZExtValue();
  LLVMContext &Ctx = M->getContext();
  ArrayType *CounterTy = ArrayType::get(Type::getInt64Ty(Ctx), NumCounters);

  // Create the counters variable.
  auto *Counters = new GlobalVariable(*M, CounterTy, false, Name->getLinkage(),
                                      Constant::getNullValue(CounterTy),
                                      getVarName(Inc, "counters"));
  Counters->setVisibility(Name->getVisibility());
  Counters->setSection(getCountersSection());
  Counters->setAlignment(8);
  Counters->setComdat(ProfileVarsComdat);

  RegionCounters[Inc->getName()] = Counters;

  // Create data variable.
  auto *NameArrayTy = Name->getType()->getPointerElementType();
  auto *Int32Ty = Type::getInt32Ty(Ctx);
  auto *Int64Ty = Type::getInt64Ty(Ctx);
  auto *Int8PtrTy = Type::getInt8PtrTy(Ctx);
  auto *Int64PtrTy = Type::getInt64PtrTy(Ctx);

  Type *DataTypes[] = {Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int64PtrTy};
  auto *DataTy = StructType::get(Ctx, makeArrayRef(DataTypes));
  Constant *DataVals[] = {
      ConstantInt::get(Int32Ty, NameArrayTy->getArrayNumElements()),
      ConstantInt::get(Int32Ty, NumCounters),
      ConstantInt::get(Int64Ty, Inc->getHash()->getZExtValue()),
      ConstantExpr::getBitCast(Name, Int8PtrTy),
      ConstantExpr::getBitCast(Counters, Int64PtrTy)};
  auto *Data = new GlobalVariable(*M, DataTy, true, Name->getLinkage(),
                                  ConstantStruct::get(DataTy, DataVals),
                                  getVarName(Inc, "data"));
  Data->setVisibility(Name->getVisibility());
  Data->setSection(getDataSection());
  Data->setAlignment(8);
  Data->setComdat(ProfileVarsComdat);

  // Mark the data variable as used so that it isn't stripped out.
  UsedVars.push_back(Data);

  return Counters;
}
Example #3
0
GlobalVariable *
InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
  GlobalVariable *NamePtr = Inc->getName();
  auto It = ProfileDataMap.find(NamePtr);
  PerFunctionProfileData PD;
  if (It != ProfileDataMap.end()) {
    if (It->second.RegionCounters)
      return It->second.RegionCounters;
    PD = It->second;
  }

  // Move the name variable to the right section. Place them in a COMDAT group
  // if the associated function is a COMDAT. This will make sure that
  // only one copy of counters of the COMDAT function will be emitted after
  // linking.
  Function *Fn = Inc->getParent()->getParent();
  Comdat *ProfileVarsComdat = nullptr;
  if (Fn->hasComdat())
    ProfileVarsComdat = getOrCreateProfileComdat(*M, Inc);
  NamePtr->setSection(getNameSection());
  NamePtr->setAlignment(1);
  NamePtr->setComdat(ProfileVarsComdat);

  uint64_t NumCounters = Inc->getNumCounters()->getZExtValue();
  LLVMContext &Ctx = M->getContext();
  ArrayType *CounterTy = ArrayType::get(Type::getInt64Ty(Ctx), NumCounters);

  // Create the counters variable.
  auto *CounterPtr =
      new GlobalVariable(*M, CounterTy, false, NamePtr->getLinkage(),
                         Constant::getNullValue(CounterTy),
                         getVarName(Inc, getInstrProfCountersVarPrefix()));
  CounterPtr->setVisibility(NamePtr->getVisibility());
  CounterPtr->setSection(getCountersSection());
  CounterPtr->setAlignment(8);
  CounterPtr->setComdat(ProfileVarsComdat);

  // Create data variable.
  auto *Int8PtrTy = Type::getInt8PtrTy(Ctx);
  auto *Int16Ty = Type::getInt16Ty(Ctx);
  auto *Int16ArrayTy = ArrayType::get(Int16Ty, IPVK_Last+1);
  Type *DataTypes[] = {
    #define INSTR_PROF_DATA(Type, LLVMType, Name, Init) LLVMType,
    #include "llvm/ProfileData/InstrProfData.inc"
  };
  auto *DataTy = StructType::get(Ctx, makeArrayRef(DataTypes));

  Constant *FunctionAddr = shouldRecordFunctionAddr(Fn) ?
                           ConstantExpr::getBitCast(Fn, Int8PtrTy) :
                           ConstantPointerNull::get(Int8PtrTy);

  Constant *Int16ArrayVals[IPVK_Last+1];
  for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
    Int16ArrayVals[Kind] = ConstantInt::get(Int16Ty, PD.NumValueSites[Kind]);

  Constant *DataVals[] = {
    #define INSTR_PROF_DATA(Type, LLVMType, Name, Init) Init,
    #include "llvm/ProfileData/InstrProfData.inc"
  };
  auto *Data = new GlobalVariable(*M, DataTy, false, NamePtr->getLinkage(),
                                  ConstantStruct::get(DataTy, DataVals),
                                  getVarName(Inc, getInstrProfDataVarPrefix()));
  Data->setVisibility(NamePtr->getVisibility());
  Data->setSection(getDataSection());
  Data->setAlignment(INSTR_PROF_DATA_ALIGNMENT);
  Data->setComdat(ProfileVarsComdat);

  PD.RegionCounters = CounterPtr;
  PD.DataVar = Data;
  ProfileDataMap[NamePtr] = PD;

  // Mark the data variable as used so that it isn't stripped out.
  UsedVars.push_back(Data);

  return CounterPtr;
}