1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

IPO: Const correctness for summaries passed into passes.

Pass const qualified summaries into importers and unqualified summaries into
exporters. This lets us const-qualify the summary argument to thinBackend.

Differential Revision: https://reviews.llvm.org/D31230

llvm-svn: 298534
This commit is contained in:
Peter Collingbourne 2017-03-22 18:22:59 +00:00
parent 10376af4e8
commit c6d4553768
7 changed files with 120 additions and 78 deletions

View File

@ -42,7 +42,7 @@ Error backend(Config &C, AddStreamFn AddStream,
/// Runs a ThinLTO backend.
Error thinBackend(Config &C, unsigned Task, AddStreamFn AddStream, Module &M,
ModuleSummaryIndex &CombinedIndex,
const ModuleSummaryIndex &CombinedIndex,
const FunctionImporter::ImportMapTy &ImportList,
const GVSummaryMapTy &DefinedGlobals,
MapVector<StringRef, BitcodeModule> &ModuleMap);

View File

@ -225,19 +225,33 @@ enum class PassSummaryAction {
/// \brief This pass lowers type metadata and the llvm.type.test intrinsic to
/// bitsets.
/// \param Action What to do with the summary passed as Index.
/// \param Index The summary to use for importing or exporting, this can be null
/// when Action is None.
ModulePass *createLowerTypeTestsPass(PassSummaryAction Action,
ModuleSummaryIndex *Index);
///
/// The behavior depends on the summary arguments:
/// - If ExportSummary is non-null, this pass will export type identifiers to
/// the given summary.
/// - Otherwise, if ImportSummary is non-null, this pass will import type
/// identifiers from the given summary.
/// - Otherwise it does neither.
/// It is invalid for both ExportSummary and ImportSummary to be non-null.
ModulePass *createLowerTypeTestsPass(ModuleSummaryIndex *ExportSummary,
const ModuleSummaryIndex *ImportSummary);
/// \brief This pass export CFI checks for use by external modules.
ModulePass *createCrossDSOCFIPass();
/// \brief This pass implements whole-program devirtualization using type
/// metadata.
ModulePass *createWholeProgramDevirtPass(PassSummaryAction Action,
ModuleSummaryIndex *Index);
///
/// The behavior depends on the summary arguments:
/// - If ExportSummary is non-null, this pass will export type identifiers to
/// the given summary.
/// - Otherwise, if ImportSummary is non-null, this pass will import type
/// identifiers from the given summary.
/// - Otherwise it does neither.
/// It is invalid for both ExportSummary and ImportSummary to be non-null.
ModulePass *
createWholeProgramDevirtPass(ModuleSummaryIndex *ExportSummary,
const ModuleSummaryIndex *ImportSummary);
/// This pass splits globals into pieces for the benefit of whole-program
/// devirtualization and control-flow integrity.

View File

@ -132,10 +132,15 @@ public:
/// added to the per-module passes.
Pass *Inliner;
/// The module summary index to use for passing information between the
/// regular LTO phase and the thin LTO backends, for example the CFI and
/// devirtualization type tests.
ModuleSummaryIndex *Summary = nullptr;
/// The module summary index to use for exporting information from the
/// regular LTO phase, for example for the CFI and devirtualization type
/// tests.
ModuleSummaryIndex *ExportSummary = nullptr;
/// The module summary index to use for importing information to the
/// thin LTO backends, for example for the CFI and devirtualization type
/// tests.
const ModuleSummaryIndex *ImportSummary = nullptr;
bool DisableTailCalls;
bool DisableUnitAtATime;

View File

@ -223,14 +223,16 @@ static void runNewPMCustomPasses(Module &Mod, TargetMachine *TM,
}
static void runOldPMPasses(Config &Conf, Module &Mod, TargetMachine *TM,
bool IsThinLTO, ModuleSummaryIndex &CombinedIndex) {
bool IsThinLTO, ModuleSummaryIndex *ExportSummary,
const ModuleSummaryIndex *ImportSummary) {
legacy::PassManager passes;
passes.add(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis()));
PassManagerBuilder PMB;
PMB.LibraryInfo = new TargetLibraryInfoImpl(Triple(TM->getTargetTriple()));
PMB.Inliner = createFunctionInliningPass();
PMB.Summary = &CombinedIndex;
PMB.ExportSummary = ExportSummary;
PMB.ImportSummary = ImportSummary;
// Unconditionally verify input since it is not verified before this
// point and has unknown origin.
PMB.VerifyInput = true;
@ -247,7 +249,8 @@ static void runOldPMPasses(Config &Conf, Module &Mod, TargetMachine *TM,
}
bool opt(Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod,
bool IsThinLTO, ModuleSummaryIndex &CombinedIndex) {
bool IsThinLTO, ModuleSummaryIndex *ExportSummary,
const ModuleSummaryIndex *ImportSummary) {
// There's still no ThinLTO pipeline hooked up in the new pass manager,
// once there is one, we can just remove this.
if (LTOUseNewPM && IsThinLTO)
@ -260,7 +263,7 @@ bool opt(Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod,
else if (LTOUseNewPM)
runNewPMPasses(Mod, TM, Conf.OptLevel);
else
runOldPMPasses(Conf, Mod, TM, IsThinLTO, CombinedIndex);
runOldPMPasses(Conf, Mod, TM, IsThinLTO, ExportSummary, ImportSummary);
return !Conf.PostOptModuleHook || Conf.PostOptModuleHook(Task, Mod);
}
@ -383,7 +386,8 @@ Error lto::backend(Config &C, AddStreamFn AddStream,
auto DiagnosticOutputFile = std::move(*DiagFileOrErr);
if (!C.CodeGenOnly) {
if (!opt(C, TM.get(), 0, *Mod, /*IsThinLTO=*/false, CombinedIndex)) {
if (!opt(C, TM.get(), 0, *Mod, /*IsThinLTO=*/false,
/*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr)) {
finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
return Error::success();
}
@ -400,7 +404,7 @@ Error lto::backend(Config &C, AddStreamFn AddStream,
}
Error lto::thinBackend(Config &Conf, unsigned Task, AddStreamFn AddStream,
Module &Mod, ModuleSummaryIndex &CombinedIndex,
Module &Mod, const ModuleSummaryIndex &CombinedIndex,
const FunctionImporter::ImportMapTy &ImportList,
const GVSummaryMapTy &DefinedGlobals,
MapVector<StringRef, BitcodeModule> &ModuleMap) {
@ -452,7 +456,8 @@ Error lto::thinBackend(Config &Conf, unsigned Task, AddStreamFn AddStream,
if (Conf.PostImportModuleHook && !Conf.PostImportModuleHook(Task, Mod))
return Error::success();
if (!opt(Conf, TM.get(), Task, Mod, /*IsThinLTO=*/true, CombinedIndex))
if (!opt(Conf, TM.get(), Task, Mod, /*IsThinLTO=*/true,
/*ExportSummary=*/nullptr, /*ImportSummary=*/&CombinedIndex))
return Error::success();
codegen(Conf, TM.get(), AddStream, Task, Mod);

View File

@ -232,8 +232,8 @@ public:
class LowerTypeTestsModule {
Module &M;
PassSummaryAction Action;
ModuleSummaryIndex *Summary;
ModuleSummaryIndex *ExportSummary;
const ModuleSummaryIndex *ImportSummary;
bool LinkerSubsectionsViaSymbols;
Triple::ArchType Arch;
@ -332,8 +332,8 @@ class LowerTypeTestsModule {
void createJumpTable(Function *F, ArrayRef<GlobalTypeMember *> Functions);
public:
LowerTypeTestsModule(Module &M, PassSummaryAction Action,
ModuleSummaryIndex *Summary);
LowerTypeTestsModule(Module &M, ModuleSummaryIndex *ExportSummary,
const ModuleSummaryIndex *ImportSummary);
bool lower();
// Lower the module using the action and summary passed as command line
@ -346,15 +346,17 @@ struct LowerTypeTests : public ModulePass {
bool UseCommandLine = false;
PassSummaryAction Action;
ModuleSummaryIndex *Summary;
ModuleSummaryIndex *ExportSummary;
const ModuleSummaryIndex *ImportSummary;
LowerTypeTests() : ModulePass(ID), UseCommandLine(true) {
initializeLowerTypeTestsPass(*PassRegistry::getPassRegistry());
}
LowerTypeTests(PassSummaryAction Action, ModuleSummaryIndex *Summary)
: ModulePass(ID), Action(Action), Summary(Summary) {
LowerTypeTests(ModuleSummaryIndex *ExportSummary,
const ModuleSummaryIndex *ImportSummary)
: ModulePass(ID), ExportSummary(ExportSummary),
ImportSummary(ImportSummary) {
initializeLowerTypeTestsPass(*PassRegistry::getPassRegistry());
}
@ -363,7 +365,7 @@ struct LowerTypeTests : public ModulePass {
return false;
if (UseCommandLine)
return LowerTypeTestsModule::runForTesting(M);
return LowerTypeTestsModule(M, Action, Summary).lower();
return LowerTypeTestsModule(M, ExportSummary, ImportSummary).lower();
}
};
@ -373,9 +375,10 @@ INITIALIZE_PASS(LowerTypeTests, "lowertypetests", "Lower type metadata", false,
false)
char LowerTypeTests::ID = 0;
ModulePass *llvm::createLowerTypeTestsPass(PassSummaryAction Action,
ModuleSummaryIndex *Summary) {
return new LowerTypeTests(Action, Summary);
ModulePass *
llvm::createLowerTypeTestsPass(ModuleSummaryIndex *ExportSummary,
const ModuleSummaryIndex *ImportSummary) {
return new LowerTypeTests(ExportSummary, ImportSummary);
}
/// Build a bit set for TypeId using the object layouts in
@ -499,8 +502,7 @@ Value *LowerTypeTestsModule::createBitSetTest(IRBuilder<> &B,
return createMaskedBitTest(B, TIL.InlineBits, BitOffset);
} else {
Constant *ByteArray = TIL.TheByteArray;
if (!LinkerSubsectionsViaSymbols && AvoidReuse &&
Action != PassSummaryAction::Import) {
if (!LinkerSubsectionsViaSymbols && AvoidReuse && !ImportSummary) {
// Each use of the byte array uses a different alias. This makes the
// backend less likely to reuse previously computed byte array addresses,
// improving the security of the CFI mechanism based on this pass.
@ -700,7 +702,8 @@ void LowerTypeTestsModule::buildBitSetsFromGlobalVariables(
/// information about the type identifier.
void LowerTypeTestsModule::exportTypeId(StringRef TypeId,
const TypeIdLowering &TIL) {
TypeTestResolution &TTRes = Summary->getOrInsertTypeIdSummary(TypeId).TTRes;
TypeTestResolution &TTRes =
ExportSummary->getOrInsertTypeIdSummary(TypeId).TTRes;
TTRes.TheKind = TIL.TheKind;
auto ExportGlobal = [&](StringRef Name, Constant *C) {
@ -738,7 +741,7 @@ void LowerTypeTestsModule::exportTypeId(StringRef TypeId,
LowerTypeTestsModule::TypeIdLowering
LowerTypeTestsModule::importTypeId(StringRef TypeId) {
const TypeIdSummary *TidSummary = Summary->getTypeIdSummary(TypeId);
const TypeIdSummary *TidSummary = ImportSummary->getTypeIdSummary(TypeId);
if (!TidSummary)
return {}; // Unsat: no globals match this type id.
const TypeTestResolution &TTRes = TidSummary->TTRes;
@ -1293,9 +1296,11 @@ void LowerTypeTestsModule::buildBitSetsFromDisjointSet(
}
/// Lower all type tests in this module.
LowerTypeTestsModule::LowerTypeTestsModule(Module &M, PassSummaryAction Action,
ModuleSummaryIndex *Summary)
: M(M), Action(Action), Summary(Summary) {
LowerTypeTestsModule::LowerTypeTestsModule(
Module &M, ModuleSummaryIndex *ExportSummary,
const ModuleSummaryIndex *ImportSummary)
: M(M), ExportSummary(ExportSummary), ImportSummary(ImportSummary) {
assert(!(ExportSummary && ImportSummary));
Triple TargetTriple(M.getTargetTriple());
LinkerSubsectionsViaSymbols = TargetTriple.isMacOSX();
Arch = TargetTriple.getArch();
@ -1319,7 +1324,11 @@ bool LowerTypeTestsModule::runForTesting(Module &M) {
ExitOnErr(errorCodeToError(In.error()));
}
bool Changed = LowerTypeTestsModule(M, ClSummaryAction, &Summary).lower();
bool Changed =
LowerTypeTestsModule(
M, ClSummaryAction == PassSummaryAction::Export ? &Summary : nullptr,
ClSummaryAction == PassSummaryAction::Import ? &Summary : nullptr)
.lower();
if (!ClWriteSummary.empty()) {
ExitOnError ExitOnErr("-lowertypetests-write-summary: " + ClWriteSummary +
@ -1338,11 +1347,10 @@ bool LowerTypeTestsModule::runForTesting(Module &M) {
bool LowerTypeTestsModule::lower() {
Function *TypeTestFunc =
M.getFunction(Intrinsic::getName(Intrinsic::type_test));
if ((!TypeTestFunc || TypeTestFunc->use_empty()) &&
Action != PassSummaryAction::Export)
if ((!TypeTestFunc || TypeTestFunc->use_empty()) && !ExportSummary)
return false;
if (Action == PassSummaryAction::Import) {
if (ImportSummary) {
for (auto UI = TypeTestFunc->use_begin(), UE = TypeTestFunc->use_end();
UI != UE;) {
auto *CI = cast<CallInst>((*UI++).getUser());
@ -1423,7 +1431,7 @@ bool LowerTypeTestsModule::lower() {
}
}
if (Action == PassSummaryAction::Export) {
if (ExportSummary) {
DenseMap<GlobalValue::GUID, TinyPtrVector<Metadata *>> MetadataByGUID;
for (auto &P : TypeIdInfo) {
if (auto *TypeId = dyn_cast<MDString>(P.first))
@ -1431,7 +1439,7 @@ bool LowerTypeTestsModule::lower() {
TypeId);
}
for (auto &P : *Summary) {
for (auto &P : *ExportSummary) {
for (auto &S : P.second) {
auto *FS = dyn_cast<FunctionSummary>(S.get());
if (!FS)
@ -1502,8 +1510,8 @@ bool LowerTypeTestsModule::lower() {
PreservedAnalyses LowerTypeTestsPass::run(Module &M,
ModuleAnalysisManager &AM) {
bool Changed =
LowerTypeTestsModule(M, PassSummaryAction::None, /*Summary=*/nullptr)
bool Changed = LowerTypeTestsModule(M, /*ExportSummary=*/nullptr,
/*ImportSummary=*/nullptr)
.lower();
if (!Changed)
return PreservedAnalyses::all();

View File

@ -704,8 +704,7 @@ void PassManagerBuilder::addLTOOptimizationPasses(legacy::PassManagerBase &PM) {
PM.add(createGlobalSplitPass());
// Apply whole-program devirtualization and virtual constant propagation.
PM.add(createWholeProgramDevirtPass(
Summary ? PassSummaryAction::Export : PassSummaryAction::None, Summary));
PM.add(createWholeProgramDevirtPass(ExportSummary, nullptr));
// That's all we need at opt level 1.
if (OptLevel == 1)
@ -834,7 +833,7 @@ void PassManagerBuilder::populateThinLTOPassManager(
if (VerifyInput)
PM.add(createVerifierPass());
if (Summary) {
if (ImportSummary) {
// These passes import type identifier resolutions for whole-program
// devirtualization and CFI. They must run early because other passes may
// disturb the specific instruction patterns that these passes look for,
@ -847,8 +846,8 @@ void PassManagerBuilder::populateThinLTOPassManager(
//
// Also, WPD has access to more precise information than ICP and can
// devirtualize more effectively, so it should operate on the IR first.
PM.add(createWholeProgramDevirtPass(PassSummaryAction::Import, Summary));
PM.add(createLowerTypeTestsPass(PassSummaryAction::Import, Summary));
PM.add(createWholeProgramDevirtPass(nullptr, ImportSummary));
PM.add(createLowerTypeTestsPass(nullptr, ImportSummary));
}
populateModulePassManager(PM);
@ -875,8 +874,7 @@ void PassManagerBuilder::populateLTOPassManager(legacy::PassManagerBase &PM) {
// Lower type metadata and the type.test intrinsic. This pass supports Clang's
// control flow integrity mechanisms (-fsanitize=cfi*) and needs to run at
// link time if CFI is enabled. The pass does nothing if CFI is disabled.
PM.add(createLowerTypeTestsPass(
Summary ? PassSummaryAction::Export : PassSummaryAction::None, Summary));
PM.add(createLowerTypeTestsPass(ExportSummary, nullptr));
if (OptLevel != 0)
addLateLTOOptimizationPasses(PM);

View File

@ -373,8 +373,8 @@ struct DevirtModule {
Module &M;
function_ref<AAResults &(Function &)> AARGetter;
PassSummaryAction Action;
ModuleSummaryIndex *Summary;
ModuleSummaryIndex *ExportSummary;
const ModuleSummaryIndex *ImportSummary;
IntegerType *Int8Ty;
PointerType *Int8PtrTy;
@ -397,14 +397,17 @@ struct DevirtModule {
std::map<CallInst *, unsigned> NumUnsafeUsesForTypeTest;
DevirtModule(Module &M, function_ref<AAResults &(Function &)> AARGetter,
PassSummaryAction Action, ModuleSummaryIndex *Summary)
: M(M), AARGetter(AARGetter), Action(Action), Summary(Summary),
Int8Ty(Type::getInt8Ty(M.getContext())),
ModuleSummaryIndex *ExportSummary,
const ModuleSummaryIndex *ImportSummary)
: M(M), AARGetter(AARGetter), ExportSummary(ExportSummary),
ImportSummary(ImportSummary), Int8Ty(Type::getInt8Ty(M.getContext())),
Int8PtrTy(Type::getInt8PtrTy(M.getContext())),
Int32Ty(Type::getInt32Ty(M.getContext())),
Int64Ty(Type::getInt64Ty(M.getContext())),
IntPtrTy(M.getDataLayout().getIntPtrType(M.getContext(), 0)),
RemarksEnabled(areRemarksEnabled()) {}
RemarksEnabled(areRemarksEnabled()) {
assert(!(ExportSummary && ImportSummary));
}
bool areRemarksEnabled();
@ -488,15 +491,17 @@ struct WholeProgramDevirt : public ModulePass {
bool UseCommandLine = false;
PassSummaryAction Action;
ModuleSummaryIndex *Summary;
ModuleSummaryIndex *ExportSummary;
const ModuleSummaryIndex *ImportSummary;
WholeProgramDevirt() : ModulePass(ID), UseCommandLine(true) {
initializeWholeProgramDevirtPass(*PassRegistry::getPassRegistry());
}
WholeProgramDevirt(PassSummaryAction Action, ModuleSummaryIndex *Summary)
: ModulePass(ID), Action(Action), Summary(Summary) {
WholeProgramDevirt(ModuleSummaryIndex *ExportSummary,
const ModuleSummaryIndex *ImportSummary)
: ModulePass(ID), ExportSummary(ExportSummary),
ImportSummary(ImportSummary) {
initializeWholeProgramDevirtPass(*PassRegistry::getPassRegistry());
}
@ -505,7 +510,8 @@ struct WholeProgramDevirt : public ModulePass {
return false;
if (UseCommandLine)
return DevirtModule::runForTesting(M, LegacyAARGetter(*this));
return DevirtModule(M, LegacyAARGetter(*this), Action, Summary).run();
return DevirtModule(M, LegacyAARGetter(*this), ExportSummary, ImportSummary)
.run();
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
@ -524,9 +530,10 @@ INITIALIZE_PASS_END(WholeProgramDevirt, "wholeprogramdevirt",
"Whole program devirtualization", false, false)
char WholeProgramDevirt::ID = 0;
ModulePass *llvm::createWholeProgramDevirtPass(PassSummaryAction Action,
ModuleSummaryIndex *Summary) {
return new WholeProgramDevirt(Action, Summary);
ModulePass *
llvm::createWholeProgramDevirtPass(ModuleSummaryIndex *ExportSummary,
const ModuleSummaryIndex *ImportSummary) {
return new WholeProgramDevirt(ExportSummary, ImportSummary);
}
PreservedAnalyses WholeProgramDevirtPass::run(Module &M,
@ -535,7 +542,7 @@ PreservedAnalyses WholeProgramDevirtPass::run(Module &M,
auto AARGetter = [&](Function &F) -> AAResults & {
return FAM.getResult<AAManager>(F);
};
if (!DevirtModule(M, AARGetter, PassSummaryAction::None, nullptr).run())
if (!DevirtModule(M, AARGetter, nullptr, nullptr).run())
return PreservedAnalyses::all();
return PreservedAnalyses::none();
}
@ -557,7 +564,12 @@ bool DevirtModule::runForTesting(
ExitOnErr(errorCodeToError(In.error()));
}
bool Changed = DevirtModule(M, AARGetter, ClSummaryAction, &Summary).run();
bool Changed =
DevirtModule(
M, AARGetter,
ClSummaryAction == PassSummaryAction::Export ? &Summary : nullptr,
ClSummaryAction == PassSummaryAction::Import ? &Summary : nullptr)
.run();
if (!ClWriteSummary.empty()) {
ExitOnError ExitOnErr(
@ -1197,7 +1209,7 @@ void DevirtModule::scanTypeCheckedLoadUsers(Function *TypeCheckedLoadFunc) {
void DevirtModule::importResolution(VTableSlot Slot, VTableSlotInfo &SlotInfo) {
const TypeIdSummary *TidSummary =
Summary->getTypeIdSummary(cast<MDString>(Slot.TypeID)->getString());
ImportSummary->getTypeIdSummary(cast<MDString>(Slot.TypeID)->getString());
if (!TidSummary)
return;
auto ResI = TidSummary->WPDRes.find(Slot.ByteOffset);
@ -1270,7 +1282,7 @@ bool DevirtModule::run() {
// Normally if there are no users of the devirtualization intrinsics in the
// module, this pass has nothing to do. But if we are exporting, we also need
// to handle any users that appear only in the function summaries.
if (Action != PassSummaryAction::Export &&
if (!ExportSummary &&
(!TypeTestFunc || TypeTestFunc->use_empty() || !AssumeFunc ||
AssumeFunc->use_empty()) &&
(!TypeCheckedLoadFunc || TypeCheckedLoadFunc->use_empty()))
@ -1282,7 +1294,7 @@ bool DevirtModule::run() {
if (TypeCheckedLoadFunc)
scanTypeCheckedLoadUsers(TypeCheckedLoadFunc);
if (Action == PassSummaryAction::Import) {
if (ImportSummary) {
for (auto &S : CallSlots)
importResolution(S.first, S.second);
@ -1301,7 +1313,7 @@ bool DevirtModule::run() {
return true;
// Collect information from summary about which calls to try to devirtualize.
if (Action == PassSummaryAction::Export) {
if (ExportSummary) {
DenseMap<GlobalValue::GUID, TinyPtrVector<Metadata *>> MetadataByGUID;
for (auto &P : TypeIdMap) {
if (auto *TypeId = dyn_cast<MDString>(P.first))
@ -1309,7 +1321,7 @@ bool DevirtModule::run() {
TypeId);
}
for (auto &P : *Summary) {
for (auto &P : *ExportSummary) {
for (auto &S : P.second) {
auto *FS = dyn_cast<FunctionSummary>(S.get());
if (!FS)
@ -1358,8 +1370,8 @@ bool DevirtModule::run() {
if (tryFindVirtualCallTargets(TargetsForSlot, TypeIdMap[S.first.TypeID],
S.first.ByteOffset)) {
WholeProgramDevirtResolution *Res = nullptr;
if (Action == PassSummaryAction::Export && isa<MDString>(S.first.TypeID))
Res = &Summary
if (ExportSummary && isa<MDString>(S.first.TypeID))
Res = &ExportSummary
->getOrInsertTypeIdSummary(
cast<MDString>(S.first.TypeID)->getString())
.WPDRes[S.first.ByteOffset];
@ -1379,7 +1391,7 @@ bool DevirtModule::run() {
// intrinsics were *not* devirtualized, we need to add the resulting
// llvm.type.test intrinsics to the function summaries so that the
// LowerTypeTests pass will export them.
if (Action == PassSummaryAction::Export && isa<MDString>(S.first.TypeID)) {
if (ExportSummary && isa<MDString>(S.first.TypeID)) {
auto GUID =
GlobalValue::getGUID(cast<MDString>(S.first.TypeID)->getString());
for (auto FS : S.second.CSInfo.SummaryTypeCheckedLoadUsers)