mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +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:
parent
10376af4e8
commit
c6d4553768
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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,9 +1510,9 @@ bool LowerTypeTestsModule::lower() {
|
||||
|
||||
PreservedAnalyses LowerTypeTestsPass::run(Module &M,
|
||||
ModuleAnalysisManager &AM) {
|
||||
bool Changed =
|
||||
LowerTypeTestsModule(M, PassSummaryAction::None, /*Summary=*/nullptr)
|
||||
.lower();
|
||||
bool Changed = LowerTypeTestsModule(M, /*ExportSummary=*/nullptr,
|
||||
/*ImportSummary=*/nullptr)
|
||||
.lower();
|
||||
if (!Changed)
|
||||
return PreservedAnalyses::all();
|
||||
return PreservedAnalyses::none();
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user