Skip to content

Commit

Permalink
IPO: Const correctness for summaries passed into passes.
Browse files Browse the repository at this point in the history
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298534 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
pcc committed Mar 22, 2017
1 parent 49df148 commit e53e585
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 78 deletions.
2 changes: 1 addition & 1 deletion include/llvm/LTO/LTOBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
28 changes: 21 additions & 7 deletions include/llvm/Transforms/IPO.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
13 changes: 9 additions & 4 deletions include/llvm/Transforms/IPO/PassManagerBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,15 @@ class PassManagerBuilder {
/// 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;
Expand Down
19 changes: 12 additions & 7 deletions lib/LTO/LTOBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand All @@ -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);
}

Expand Down Expand Up @@ -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();
}
Expand All @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down
64 changes: 36 additions & 28 deletions lib/Transforms/IPO/LowerTypeTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,8 @@ class GlobalTypeMember final : TrailingObjects<GlobalTypeMember, MDNode *> {
class LowerTypeTestsModule {
Module &M;

PassSummaryAction Action;
ModuleSummaryIndex *Summary;
ModuleSummaryIndex *ExportSummary;
const ModuleSummaryIndex *ImportSummary;

bool LinkerSubsectionsViaSymbols;
Triple::ArchType Arch;
Expand Down Expand Up @@ -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
Expand All @@ -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());
}

Expand All @@ -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();
}
};

Expand All @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand All @@ -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 +
Expand All @@ -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());
Expand Down Expand Up @@ -1423,15 +1431,15 @@ 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))
MetadataByGUID[GlobalValue::getGUID(TypeId->getString())].push_back(
TypeId);
}

for (auto &P : *Summary) {
for (auto &P : *ExportSummary) {
for (auto &S : P.second) {
auto *FS = dyn_cast<FunctionSummary>(S.get());
if (!FS)
Expand Down Expand Up @@ -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();
Expand Down
12 changes: 5 additions & 7 deletions lib/Transforms/IPO/PassManagerBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand All @@ -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);
Expand All @@ -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);
Expand Down
Loading

0 comments on commit e53e585

Please sign in to comment.