diff options
author | Sean Silva <chisophugis@gmail.com> | 2016-06-15 06:18:01 +0000 |
---|---|---|
committer | Sean Silva <chisophugis@gmail.com> | 2016-06-15 06:18:01 +0000 |
commit | a4c2d150d0129364b546ead5785da0ea9e77acae (patch) | |
tree | e82e3b4b6f348c7dcaa8bdd5b436d81a50a5be99 | |
parent | 0272be206a0d1369736dfee456bfa7430ccd5e02 (diff) | |
download | bcm5719-llvm-a4c2d150d0129364b546ead5785da0ea9e77acae.tar.gz bcm5719-llvm-a4c2d150d0129364b546ead5785da0ea9e77acae.zip |
[PM] Port AlignmentFromAssumptions to the new PM.
This uses the "runImpl" pattern to share code between the old and new PM.
llvm-svn: 272757
7 files changed, 92 insertions, 21 deletions
diff --git a/llvm/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h b/llvm/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h new file mode 100644 index 00000000000..f75dc4dc331 --- /dev/null +++ b/llvm/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h @@ -0,0 +1,51 @@ +//===---- AlignmentFromAssumptions.h ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements a ScalarEvolution-based transformation to set +// the alignments of load, stores and memory intrinsics based on the truth +// expressions of assume intrinsics. The primary motivation is to handle +// complex alignment assumptions that apply to vector loads and stores that +// appear after vectorization and unrolling. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_SCALAR_ALIGNMENTFROMASSUMPTIONS_H +#define LLVM_TRANSFORMS_SCALAR_ALIGNMENTFROMASSUMPTIONS_H + +#include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/PassManager.h" + +namespace llvm { + +struct AlignmentFromAssumptionsPass + : public PassInfoMixin<AlignmentFromAssumptionsPass> { + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); + + // Glue for old PM. + bool runImpl(Function &F, AssumptionCache &AC, ScalarEvolution *SE_, + DominatorTree *DT_); + + // For memory transfers, we need a common alignment for both the source and + // destination. If we have a new alignment for only one operand of a transfer + // instruction, save it in these maps. If we reach the other operand through + // another assumption later, then we may change the alignment at that point. + DenseMap<MemTransferInst *, unsigned> NewDestAlignments, NewSrcAlignments; + + ScalarEvolution *SE = nullptr; + DominatorTree *DT = nullptr; + + bool extractAlignmentInfo(CallInst *I, Value *&AAPtr, const SCEV *&AlignSCEV, + const SCEV *&OffSCEV); + bool processAssumption(CallInst *I); +}; +} + +#endif // LLVM_TRANSFORMS_SCALAR_ALIGNMENTFROMASSUMPTIONS_H diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index b629ac7e61c..cc0ae02eb26 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -69,6 +69,7 @@ #include "llvm/Transforms/PGOInstrumentation.h" #include "llvm/Transforms/SampleProfile.h" #include "llvm/Transforms/Scalar/ADCE.h" +#include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h" #include "llvm/Transforms/Scalar/BDCE.h" #include "llvm/Transforms/Scalar/DCE.h" #include "llvm/Transforms/Scalar/DeadStoreElimination.h" diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 06892cb52b8..844bb843a7a 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -119,6 +119,7 @@ FUNCTION_ALIAS_ANALYSIS("type-based-aa", TypeBasedAA()) #endif FUNCTION_PASS("aa-eval", AAEvaluator()) FUNCTION_PASS("adce", ADCEPass()) +FUNCTION_PASS("alignment-from-assumptions", AlignmentFromAssumptionsPass()) FUNCTION_PASS("bdce", BDCEPass()) FUNCTION_PASS("dce", DCEPass()) FUNCTION_PASS("dse", DSEPass()) diff --git a/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp b/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp index 8332c8edb9f..7f8b8ce91e7 100644 --- a/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp +++ b/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp @@ -18,6 +18,7 @@ #define AA_NAME "alignment-from-assumptions" #define DEBUG_TYPE AA_NAME +#include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h" #include "llvm/Transforms/Scalar.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" @@ -25,13 +26,11 @@ #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/LoopInfo.h" -#include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/Constant.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Instruction.h" -#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" @@ -67,18 +66,7 @@ struct AlignmentFromAssumptions : public FunctionPass { AU.addPreserved<ScalarEvolutionWrapperPass>(); } - // For memory transfers, we need a common alignment for both the source and - // destination. If we have a new alignment for only one operand of a transfer - // instruction, save it in these maps. If we reach the other operand through - // another assumption later, then we may change the alignment at that point. - DenseMap<MemTransferInst *, unsigned> NewDestAlignments, NewSrcAlignments; - - ScalarEvolution *SE; - DominatorTree *DT; - - bool extractAlignmentInfo(CallInst *I, Value *&AAPtr, const SCEV *&AlignSCEV, - const SCEV *&OffSCEV); - bool processAssumption(CallInst *I); + AlignmentFromAssumptionsPass Impl; }; } @@ -209,9 +197,10 @@ static unsigned getNewAlignment(const SCEV *AASCEV, const SCEV *AlignSCEV, return 0; } -bool AlignmentFromAssumptions::extractAlignmentInfo(CallInst *I, - Value *&AAPtr, const SCEV *&AlignSCEV, - const SCEV *&OffSCEV) { +bool AlignmentFromAssumptionsPass::extractAlignmentInfo(CallInst *I, + Value *&AAPtr, + const SCEV *&AlignSCEV, + const SCEV *&OffSCEV) { // An alignment assume must be a statement about the least-significant // bits of the pointer being zero, possibly with some offset. ICmpInst *ICI = dyn_cast<ICmpInst>(I->getArgOperand(0)); @@ -302,7 +291,7 @@ bool AlignmentFromAssumptions::extractAlignmentInfo(CallInst *I, return true; } -bool AlignmentFromAssumptions::processAssumption(CallInst *ACall) { +bool AlignmentFromAssumptionsPass::processAssumption(CallInst *ACall) { Value *AAPtr; const SCEV *AlignSCEV, *OffSCEV; if (!extractAlignmentInfo(ACall, AAPtr, AlignSCEV, OffSCEV)) @@ -414,14 +403,23 @@ bool AlignmentFromAssumptions::runOnFunction(Function &F) { if (skipFunction(F)) return false; - bool Changed = false; auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F); - SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE(); - DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); + ScalarEvolution *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE(); + DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); + + return Impl.runImpl(F, AC, SE, DT); +} + +bool AlignmentFromAssumptionsPass::runImpl(Function &F, AssumptionCache &AC, + ScalarEvolution *SE_, + DominatorTree *DT_) { + SE = SE_; + DT = DT_; NewDestAlignments.clear(); NewSrcAlignments.clear(); + bool Changed = false; for (auto &AssumeVH : AC.assumptions()) if (AssumeVH) Changed |= processAssumption(cast<CallInst>(AssumeVH)); @@ -429,3 +427,20 @@ bool AlignmentFromAssumptions::runOnFunction(Function &F) { return Changed; } +PreservedAnalyses +AlignmentFromAssumptionsPass::run(Function &F, FunctionAnalysisManager &AM) { + + AssumptionCache &AC = AM.getResult<AssumptionAnalysis>(F); + ScalarEvolution &SE = AM.getResult<ScalarEvolutionAnalysis>(F); + DominatorTree &DT = AM.getResult<DominatorTreeAnalysis>(F); + bool Changed = runImpl(F, AC, &SE, &DT); + if (!Changed) + return PreservedAnalyses::all(); + PreservedAnalyses PA; + PA.preserve<AAManager>(); + PA.preserve<ScalarEvolutionAnalysis>(); + PA.preserve<GlobalsAA>(); + PA.preserve<LoopAnalysis>(); + PA.preserve<DominatorTreeAnalysis>(); + return PA; +} diff --git a/llvm/test/Transforms/AlignmentFromAssumptions/simple.ll b/llvm/test/Transforms/AlignmentFromAssumptions/simple.ll index 851e6dc3ccc..b91722839c6 100644 --- a/llvm/test/Transforms/AlignmentFromAssumptions/simple.ll +++ b/llvm/test/Transforms/AlignmentFromAssumptions/simple.ll @@ -1,5 +1,6 @@ target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128" ; RUN: opt < %s -alignment-from-assumptions -S | FileCheck %s +; RUN: opt < %s -passes=alignment-from-assumptions -S | FileCheck %s define i32 @foo(i32* nocapture %a) nounwind uwtable readonly { entry: diff --git a/llvm/test/Transforms/AlignmentFromAssumptions/simple32.ll b/llvm/test/Transforms/AlignmentFromAssumptions/simple32.ll index 2edc2e95f41..e474bd33c31 100644 --- a/llvm/test/Transforms/AlignmentFromAssumptions/simple32.ll +++ b/llvm/test/Transforms/AlignmentFromAssumptions/simple32.ll @@ -1,5 +1,6 @@ target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64" ; RUN: opt < %s -alignment-from-assumptions -S | FileCheck %s +; RUN: opt < %s -passes=alignment-from-assumptions -S | FileCheck %s define i32 @foo(i32* nocapture %a) nounwind uwtable readonly { entry: diff --git a/llvm/test/Transforms/AlignmentFromAssumptions/start-unk.ll b/llvm/test/Transforms/AlignmentFromAssumptions/start-unk.ll index 99533cf6ccb..9357734a350 100644 --- a/llvm/test/Transforms/AlignmentFromAssumptions/start-unk.ll +++ b/llvm/test/Transforms/AlignmentFromAssumptions/start-unk.ll @@ -1,4 +1,5 @@ ; RUN: opt -alignment-from-assumptions -S < %s | FileCheck %s +; RUN: opt -passes=alignment-from-assumptions -S < %s | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" |