From: Sean Silva Date: Wed, 15 Jun 2016 06:18:01 +0000 (+0000) Subject: [PM] Port AlignmentFromAssumptions to the new PM. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=570b29d91dceee1a01b3804aaf3689515136a857;p=llvm [PM] Port AlignmentFromAssumptions to the new PM. This uses the "runImpl" pattern to share code between the old and new PM. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@272757 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h b/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h new file mode 100644 index 00000000000..f75dc4dc331 --- /dev/null +++ b/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 { + 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 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/lib/Passes/PassBuilder.cpp b/lib/Passes/PassBuilder.cpp index b629ac7e61c..cc0ae02eb26 100644 --- a/lib/Passes/PassBuilder.cpp +++ b/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/lib/Passes/PassRegistry.def b/lib/Passes/PassRegistry.def index 06892cb52b8..844bb843a7a 100644 --- a/lib/Passes/PassRegistry.def +++ b/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/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp b/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp index 8332c8edb9f..7f8b8ce91e7 100644 --- a/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp +++ b/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(); } - // 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 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(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().getAssumptionCache(F); - SE = &getAnalysis().getSE(); - DT = &getAnalysis().getDomTree(); + ScalarEvolution *SE = &getAnalysis().getSE(); + DominatorTree *DT = &getAnalysis().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(AssumeVH)); @@ -429,3 +427,20 @@ bool AlignmentFromAssumptions::runOnFunction(Function &F) { return Changed; } +PreservedAnalyses +AlignmentFromAssumptionsPass::run(Function &F, FunctionAnalysisManager &AM) { + + AssumptionCache &AC = AM.getResult(F); + ScalarEvolution &SE = AM.getResult(F); + DominatorTree &DT = AM.getResult(F); + bool Changed = runImpl(F, AC, &SE, &DT); + if (!Changed) + return PreservedAnalyses::all(); + PreservedAnalyses PA; + PA.preserve(); + PA.preserve(); + PA.preserve(); + PA.preserve(); + PA.preserve(); + return PA; +} diff --git a/test/Transforms/AlignmentFromAssumptions/simple.ll b/test/Transforms/AlignmentFromAssumptions/simple.ll index 851e6dc3ccc..b91722839c6 100644 --- a/test/Transforms/AlignmentFromAssumptions/simple.ll +++ b/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/test/Transforms/AlignmentFromAssumptions/simple32.ll b/test/Transforms/AlignmentFromAssumptions/simple32.ll index 2edc2e95f41..e474bd33c31 100644 --- a/test/Transforms/AlignmentFromAssumptions/simple32.ll +++ b/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/test/Transforms/AlignmentFromAssumptions/start-unk.ll b/test/Transforms/AlignmentFromAssumptions/start-unk.ll index 99533cf6ccb..9357734a350 100644 --- a/test/Transforms/AlignmentFromAssumptions/start-unk.ll +++ b/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"