diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2017-02-13 19:26:18 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2017-02-13 19:26:18 +0000 |
commit | 2b33f65317aa8f4145432f902c12d5a127bcbffe (patch) | |
tree | 53d2475025592b2340fa71a68213b4e20ab15546 /llvm/lib/Transforms/IPO | |
parent | 7bed48e7a3fda0eb04875d1fc05a4db516f26b5c (diff) | |
download | bcm5719-llvm-2b33f65317aa8f4145432f902c12d5a127bcbffe.tar.gz bcm5719-llvm-2b33f65317aa8f4145432f902c12d5a127bcbffe.zip |
IR: Type ID summary extensions for WPD; thread summary into WPD pass.
Make the whole thing testable by adding YAML I/O support for the WPD
summary information and adding some negative tests that exercise the
YAML support.
Differential Revision: https://reviews.llvm.org/D29782
llvm-svn: 294981
Diffstat (limited to 'llvm/lib/Transforms/IPO')
-rw-r--r-- | llvm/lib/Transforms/IPO/PassManagerBuilder.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp | 92 |
2 files changed, 86 insertions, 9 deletions
diff --git a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp index 144504d4a3d..bfc6bbdb816 100644 --- a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp +++ b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -700,7 +700,8 @@ void PassManagerBuilder::addLTOOptimizationPasses(legacy::PassManagerBase &PM) { PM.add(createGlobalSplitPass()); // Apply whole-program devirtualization and virtual constant propagation. - PM.add(createWholeProgramDevirtPass()); + PM.add(createWholeProgramDevirtPass( + Summary ? PassSummaryAction::Export : PassSummaryAction::None, Summary)); // That's all we need at opt level 1. if (OptLevel == 1) diff --git a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp index 66c4f6eb86d..73ea5c19267 100644 --- a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp +++ b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp @@ -54,10 +54,13 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" +#include "llvm/IR/ModuleSummaryIndexYAML.h" #include "llvm/Pass.h" #include "llvm/PassRegistry.h" #include "llvm/PassSupport.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/MathExtras.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Utils/Evaluator.h" @@ -72,6 +75,26 @@ using namespace wholeprogramdevirt; #define DEBUG_TYPE "wholeprogramdevirt" +static cl::opt<PassSummaryAction> ClSummaryAction( + "wholeprogramdevirt-summary-action", + cl::desc("What to do with the summary when running this pass"), + cl::values(clEnumValN(PassSummaryAction::None, "none", "Do nothing"), + clEnumValN(PassSummaryAction::Import, "import", + "Import typeid resolutions from summary and globals"), + clEnumValN(PassSummaryAction::Export, "export", + "Export typeid resolutions to summary and globals")), + cl::Hidden); + +static cl::opt<std::string> ClReadSummary( + "wholeprogramdevirt-read-summary", + cl::desc("Read summary from given YAML file before running pass"), + cl::Hidden); + +static cl::opt<std::string> ClWriteSummary( + "wholeprogramdevirt-write-summary", + cl::desc("Write summary to given YAML file after running pass"), + cl::Hidden); + // Find the minimum offset that we may store a value of size Size bits at. If // IsAfter is set, look for an offset before the object, otherwise look for an // offset after the object. @@ -261,6 +284,10 @@ struct VirtualCallSite { struct DevirtModule { Module &M; + + PassSummaryAction Action; + ModuleSummaryIndex *Summary; + IntegerType *Int8Ty; PointerType *Int8PtrTy; IntegerType *Int32Ty; @@ -279,8 +306,9 @@ struct DevirtModule { // true. std::map<CallInst *, unsigned> NumUnsafeUsesForTypeTest; - DevirtModule(Module &M) - : M(M), Int8Ty(Type::getInt8Ty(M.getContext())), + DevirtModule(Module &M, PassSummaryAction Action, ModuleSummaryIndex *Summary) + : M(M), Action(Action), Summary(Summary), + Int8Ty(Type::getInt8Ty(M.getContext())), Int8PtrTy(Type::getInt8PtrTy(M.getContext())), Int32Ty(Type::getInt32Ty(M.getContext())), RemarksEnabled(areRemarksEnabled()) {} @@ -315,20 +343,35 @@ struct DevirtModule { void rebuildGlobal(VTableBits &B); bool run(); + + // Lower the module using the action and summary passed as command line + // arguments. For testing purposes only. + static bool runForTesting(Module &M); }; struct WholeProgramDevirt : public ModulePass { static char ID; - WholeProgramDevirt() : ModulePass(ID) { + bool UseCommandLine = false; + + PassSummaryAction Action; + ModuleSummaryIndex *Summary; + + WholeProgramDevirt() : ModulePass(ID), UseCommandLine(true) { + initializeWholeProgramDevirtPass(*PassRegistry::getPassRegistry()); + } + + WholeProgramDevirt(PassSummaryAction Action, ModuleSummaryIndex *Summary) + : ModulePass(ID), Action(Action), Summary(Summary) { initializeWholeProgramDevirtPass(*PassRegistry::getPassRegistry()); } bool runOnModule(Module &M) override { if (skipModule(M)) return false; - - return DevirtModule(M).run(); + if (UseCommandLine) + return DevirtModule::runForTesting(M); + return DevirtModule(M, Action, Summary).run(); } }; @@ -338,17 +381,50 @@ INITIALIZE_PASS(WholeProgramDevirt, "wholeprogramdevirt", "Whole program devirtualization", false, false) char WholeProgramDevirt::ID = 0; -ModulePass *llvm::createWholeProgramDevirtPass() { - return new WholeProgramDevirt; +ModulePass *llvm::createWholeProgramDevirtPass(PassSummaryAction Action, + ModuleSummaryIndex *Summary) { + return new WholeProgramDevirt(Action, Summary); } PreservedAnalyses WholeProgramDevirtPass::run(Module &M, ModuleAnalysisManager &) { - if (!DevirtModule(M).run()) + if (!DevirtModule(M, PassSummaryAction::None, nullptr).run()) return PreservedAnalyses::all(); return PreservedAnalyses::none(); } +bool DevirtModule::runForTesting(Module &M) { + ModuleSummaryIndex Summary; + + // Handle the command-line summary arguments. This code is for testing + // purposes only, so we handle errors directly. + if (!ClReadSummary.empty()) { + ExitOnError ExitOnErr("-wholeprogramdevirt-read-summary: " + ClReadSummary + + ": "); + auto ReadSummaryFile = + ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(ClReadSummary))); + + yaml::Input In(ReadSummaryFile->getBuffer()); + In >> Summary; + ExitOnErr(errorCodeToError(In.error())); + } + + bool Changed = DevirtModule(M, ClSummaryAction, &Summary).run(); + + if (!ClWriteSummary.empty()) { + ExitOnError ExitOnErr( + "-wholeprogramdevirt-write-summary: " + ClWriteSummary + ": "); + std::error_code EC; + raw_fd_ostream OS(ClWriteSummary, EC, sys::fs::F_Text); + ExitOnErr(errorCodeToError(EC)); + + yaml::Output Out(OS); + Out << Summary; + } + + return Changed; +} + void DevirtModule::buildTypeIdentifierMap( std::vector<VTableBits> &Bits, DenseMap<Metadata *, std::set<TypeMemberInfo>> &TypeIdMap) { |