[llvm] ac7419b - [Hexagon][NewPM] Port -hexagon-loop-idiom and add to pipeline
Arthur Eubanks via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 20 09:39:05 PST 2020
Author: Arthur Eubanks
Date: 2020-11-20T09:34:37-08:00
New Revision: ac7419bb4f3a06caa4d239662edfba7886298d76
URL: https://github.com/llvm/llvm-project/commit/ac7419bb4f3a06caa4d239662edfba7886298d76
DIFF: https://github.com/llvm/llvm-project/commit/ac7419bb4f3a06caa4d239662edfba7886298d76.diff
LOG: [Hexagon][NewPM] Port -hexagon-loop-idiom and add to pipeline
Fixes pmpy-mod.ll under NPM
Reviewed By: kparzysz
Differential Revision: https://reviews.llvm.org/D91829
Added:
llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.h
Modified:
llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp
llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
llvm/test/CodeGen/Hexagon/loop-idiom/pmpy-mod.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp b/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp
index 2c1e0cadd9ee..65bbaa513a87 100644
--- a/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "HexagonLoopIdiomRecognition.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SetVector.h"
@@ -16,6 +17,7 @@
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/InstructionSimplify.h"
+#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/MemoryLocation.h"
@@ -40,6 +42,7 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsHexagon.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
@@ -108,136 +111,152 @@ static const char *HexagonVolatileMemcpyName
namespace llvm {
- void initializeHexagonLoopIdiomRecognizePass(PassRegistry&);
- Pass *createHexagonLoopIdiomPass();
+void initializeHexagonLoopIdiomRecognizeLegacyPassPass(PassRegistry &);
+Pass *createHexagonLoopIdiomPass();
} // end namespace llvm
namespace {
- class HexagonLoopIdiomRecognize : public LoopPass {
- public:
- static char ID;
-
- explicit HexagonLoopIdiomRecognize() : LoopPass(ID) {
- initializeHexagonLoopIdiomRecognizePass(*PassRegistry::getPassRegistry());
- }
+class HexagonLoopIdiomRecognize {
+public:
+ explicit HexagonLoopIdiomRecognize(AliasAnalysis *AA, DominatorTree *DT,
+ LoopInfo *LF, const TargetLibraryInfo *TLI,
+ ScalarEvolution *SE)
+ : AA(AA), DT(DT), LF(LF), TLI(TLI), SE(SE) {}
+
+ bool run(Loop *L);
+
+private:
+ int getSCEVStride(const SCEVAddRecExpr *StoreEv);
+ bool isLegalStore(Loop *CurLoop, StoreInst *SI);
+ void collectStores(Loop *CurLoop, BasicBlock *BB,
+ SmallVectorImpl<StoreInst *> &Stores);
+ bool processCopyingStore(Loop *CurLoop, StoreInst *SI, const SCEV *BECount);
+ bool coverLoop(Loop *L, SmallVectorImpl<Instruction *> &Insts) const;
+ bool runOnLoopBlock(Loop *CurLoop, BasicBlock *BB, const SCEV *BECount,
+ SmallVectorImpl<BasicBlock *> &ExitBlocks);
+ bool runOnCountableLoop(Loop *L);
+
+ AliasAnalysis *AA;
+ const DataLayout *DL;
+ DominatorTree *DT;
+ LoopInfo *LF;
+ const TargetLibraryInfo *TLI;
+ ScalarEvolution *SE;
+ bool HasMemcpy, HasMemmove;
+};
+
+class HexagonLoopIdiomRecognizeLegacyPass : public LoopPass {
+public:
+ static char ID;
+
+ explicit HexagonLoopIdiomRecognizeLegacyPass() : LoopPass(ID) {
+ initializeHexagonLoopIdiomRecognizeLegacyPassPass(
+ *PassRegistry::getPassRegistry());
+ }
- StringRef getPassName() const override {
- return "Recognize Hexagon-specific loop idioms";
- }
+ StringRef getPassName() const override {
+ return "Recognize Hexagon-specific loop idioms";
+ }
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<LoopInfoWrapperPass>();
- AU.addRequiredID(LoopSimplifyID);
- AU.addRequiredID(LCSSAID);
- AU.addRequired<AAResultsWrapperPass>();
- AU.addPreserved<AAResultsWrapperPass>();
- AU.addRequired<ScalarEvolutionWrapperPass>();
- AU.addRequired<DominatorTreeWrapperPass>();
- AU.addRequired<TargetLibraryInfoWrapperPass>();
- AU.addPreserved<TargetLibraryInfoWrapperPass>();
- }
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<LoopInfoWrapperPass>();
+ AU.addRequiredID(LoopSimplifyID);
+ AU.addRequiredID(LCSSAID);
+ AU.addRequired<AAResultsWrapperPass>();
+ AU.addPreserved<AAResultsWrapperPass>();
+ AU.addRequired<ScalarEvolutionWrapperPass>();
+ AU.addRequired<DominatorTreeWrapperPass>();
+ AU.addRequired<TargetLibraryInfoWrapperPass>();
+ AU.addPreserved<TargetLibraryInfoWrapperPass>();
+ }
- bool runOnLoop(Loop *L, LPPassManager &LPM) override;
+ bool runOnLoop(Loop *L, LPPassManager &LPM) override;
+};
- private:
- int getSCEVStride(const SCEVAddRecExpr *StoreEv);
- bool isLegalStore(Loop *CurLoop, StoreInst *SI);
- void collectStores(Loop *CurLoop, BasicBlock *BB,
- SmallVectorImpl<StoreInst*> &Stores);
- bool processCopyingStore(Loop *CurLoop, StoreInst *SI, const SCEV *BECount);
- bool coverLoop(Loop *L, SmallVectorImpl<Instruction*> &Insts) const;
- bool runOnLoopBlock(Loop *CurLoop, BasicBlock *BB, const SCEV *BECount,
- SmallVectorImpl<BasicBlock*> &ExitBlocks);
- bool runOnCountableLoop(Loop *L);
-
- AliasAnalysis *AA;
- const DataLayout *DL;
- DominatorTree *DT;
- LoopInfo *LF;
- const TargetLibraryInfo *TLI;
- ScalarEvolution *SE;
- bool HasMemcpy, HasMemmove;
+struct Simplifier {
+ struct Rule {
+ using FuncType = std::function<Value *(Instruction *, LLVMContext &)>;
+ Rule(StringRef N, FuncType F) : Name(N), Fn(F) {}
+ StringRef Name; // For debugging.
+ FuncType Fn;
};
- struct Simplifier {
- struct Rule {
- using FuncType = std::function<Value* (Instruction*, LLVMContext&)>;
- Rule(StringRef N, FuncType F) : Name(N), Fn(F) {}
- StringRef Name; // For debugging.
- FuncType Fn;
- };
-
- void addRule(StringRef N, const Rule::FuncType &F) {
- Rules.push_back(Rule(N, F));
- }
+ void addRule(StringRef N, const Rule::FuncType &F) {
+ Rules.push_back(Rule(N, F));
+ }
- private:
- struct WorkListType {
- WorkListType() = default;
+private:
+ struct WorkListType {
+ WorkListType() = default;
- void push_back(Value* V) {
- // Do not push back duplicates.
- if (!S.count(V)) { Q.push_back(V); S.insert(V); }
+ void push_back(Value *V) {
+ // Do not push back duplicates.
+ if (!S.count(V)) {
+ Q.push_back(V);
+ S.insert(V);
}
+ }
- Value *pop_front_val() {
- Value *V = Q.front(); Q.pop_front(); S.erase(V);
- return V;
- }
+ Value *pop_front_val() {
+ Value *V = Q.front();
+ Q.pop_front();
+ S.erase(V);
+ return V;
+ }
- bool empty() const { return Q.empty(); }
+ bool empty() const { return Q.empty(); }
- private:
- std::deque<Value*> Q;
- std::set<Value*> S;
- };
+ private:
+ std::deque<Value *> Q;
+ std::set<Value *> S;
+ };
- using ValueSetType = std::set<Value *>;
+ using ValueSetType = std::set<Value *>;
- std::vector<Rule> Rules;
+ std::vector<Rule> Rules;
- public:
- struct Context {
- using ValueMapType = DenseMap<Value *, Value *>;
+public:
+ struct Context {
+ using ValueMapType = DenseMap<Value *, Value *>;
- Value *Root;
- ValueSetType Used; // The set of all cloned values used by Root.
- ValueSetType Clones; // The set of all cloned values.
- LLVMContext &Ctx;
+ Value *Root;
+ ValueSetType Used; // The set of all cloned values used by Root.
+ ValueSetType Clones; // The set of all cloned values.
+ LLVMContext &Ctx;
- Context(Instruction *Exp)
+ Context(Instruction *Exp)
: Ctx(Exp->getParent()->getParent()->getContext()) {
- initialize(Exp);
- }
-
- ~Context() { cleanup(); }
+ initialize(Exp);
+ }
- void print(raw_ostream &OS, const Value *V) const;
- Value *materialize(BasicBlock *B, BasicBlock::iterator At);
+ ~Context() { cleanup(); }
- private:
- friend struct Simplifier;
+ void print(raw_ostream &OS, const Value *V) const;
+ Value *materialize(BasicBlock *B, BasicBlock::iterator At);
- void initialize(Instruction *Exp);
- void cleanup();
+ private:
+ friend struct Simplifier;
- template <typename FuncT> void traverse(Value *V, FuncT F);
- void record(Value *V);
- void use(Value *V);
- void unuse(Value *V);
+ void initialize(Instruction *Exp);
+ void cleanup();
- bool equal(const Instruction *I, const Instruction *J) const;
- Value *find(Value *Tree, Value *Sub) const;
- Value *subst(Value *Tree, Value *OldV, Value *NewV);
- void replace(Value *OldV, Value *NewV);
- void link(Instruction *I, BasicBlock *B, BasicBlock::iterator At);
- };
+ template <typename FuncT> void traverse(Value *V, FuncT F);
+ void record(Value *V);
+ void use(Value *V);
+ void unuse(Value *V);
- Value *simplify(Context &C);
+ bool equal(const Instruction *I, const Instruction *J) const;
+ Value *find(Value *Tree, Value *Sub) const;
+ Value *subst(Value *Tree, Value *OldV, Value *NewV);
+ void replace(Value *OldV, Value *NewV);
+ void link(Instruction *I, BasicBlock *B, BasicBlock::iterator At);
};
+ Value *simplify(Context &C);
+};
+
struct PE {
PE(const Simplifier::Context &c, Value *v = nullptr) : C(c), V(v) {}
@@ -253,10 +272,10 @@ namespace {
} // end anonymous namespace
-char HexagonLoopIdiomRecognize::ID = 0;
+char HexagonLoopIdiomRecognizeLegacyPass::ID = 0;
-INITIALIZE_PASS_BEGIN(HexagonLoopIdiomRecognize, "hexagon-loop-idiom",
- "Recognize Hexagon-specific loop idioms", false, false)
+INITIALIZE_PASS_BEGIN(HexagonLoopIdiomRecognizeLegacyPass, "hexagon-loop-idiom",
+ "Recognize Hexagon-specific loop idioms", false, false)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
INITIALIZE_PASS_DEPENDENCY(LCSSAWrapperPass)
@@ -264,8 +283,8 @@ INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
-INITIALIZE_PASS_END(HexagonLoopIdiomRecognize, "hexagon-loop-idiom",
- "Recognize Hexagon-specific loop idioms", false, false)
+INITIALIZE_PASS_END(HexagonLoopIdiomRecognizeLegacyPass, "hexagon-loop-idiom",
+ "Recognize Hexagon-specific loop idioms", false, false)
template <typename FuncT>
void Simplifier::Context::traverse(Value *V, FuncT F) {
@@ -2404,14 +2423,11 @@ bool HexagonLoopIdiomRecognize::runOnCountableLoop(Loop *L) {
return Changed;
}
-bool HexagonLoopIdiomRecognize::runOnLoop(Loop *L, LPPassManager &LPM) {
+bool HexagonLoopIdiomRecognize::run(Loop *L) {
const Module &M = *L->getHeader()->getParent()->getParent();
if (Triple(M.getTargetTriple()).getArch() != Triple::hexagon)
return false;
- if (skipLoop(L))
- return false;
-
// If the loop could not be converted to canonical form, it must have an
// indirectbr in it, just give up.
if (!L->getLoopPreheader())
@@ -2422,13 +2438,7 @@ bool HexagonLoopIdiomRecognize::runOnLoop(Loop *L, LPPassManager &LPM) {
if (Name == "memset" || Name == "memcpy" || Name == "memmove")
return false;
- AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
DL = &L->getHeader()->getModule()->getDataLayout();
- DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- LF = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
- *L->getHeader()->getParent());
- SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
HasMemcpy = TLI->has(LibFunc_memcpy);
HasMemmove = TLI->has(LibFunc_memmove);
@@ -2438,6 +2448,30 @@ bool HexagonLoopIdiomRecognize::runOnLoop(Loop *L, LPPassManager &LPM) {
return false;
}
+bool HexagonLoopIdiomRecognizeLegacyPass::runOnLoop(Loop *L,
+ LPPassManager &LPM) {
+ if (skipLoop(L))
+ return false;
+
+ auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
+ auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ auto *LF = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
+ auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
+ *L->getHeader()->getParent());
+ auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
+ return HexagonLoopIdiomRecognize(AA, DT, LF, TLI, SE).run(L);
+}
+
Pass *llvm::createHexagonLoopIdiomPass() {
- return new HexagonLoopIdiomRecognize();
+ return new HexagonLoopIdiomRecognizeLegacyPass();
+}
+
+PreservedAnalyses
+HexagonLoopIdiomRecognitionPass::run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR,
+ LPMUpdater &U) {
+ return HexagonLoopIdiomRecognize(&AR.AA, &AR.DT, &AR.LI, &AR.TLI, &AR.SE)
+ .run(&L)
+ ? getLoopPassPreservedAnalyses()
+ : PreservedAnalyses::all();
}
diff --git a/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.h b/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.h
new file mode 100644
index 000000000000..28ec83b05dac
--- /dev/null
+++ b/llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.h
@@ -0,0 +1,24 @@
+//===- HexagonLoopIdiomRecognition.h --------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONLOOPIDIOMRECOGNITION_H
+#define LLVM_LIB_TARGET_HEXAGON_HEXAGONLOOPIDIOMRECOGNITION_H
+
+#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
+
+namespace llvm {
+
+struct HexagonLoopIdiomRecognitionPass
+ : PassInfoMixin<HexagonLoopIdiomRecognitionPass> {
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
+};
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONLOOPIDIOMRECOGNITION_H
diff --git a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
index 0f15c46bc8bb..1e034ce515c1 100644
--- a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
@@ -13,6 +13,7 @@
#include "HexagonTargetMachine.h"
#include "Hexagon.h"
#include "HexagonISelLowering.h"
+#include "HexagonLoopIdiomRecognition.h"
#include "HexagonMachineScheduler.h"
#include "HexagonTargetObjectFile.h"
#include "HexagonTargetTransformInfo.h"
@@ -138,7 +139,7 @@ namespace llvm {
void initializeHexagonExpandCondsetsPass(PassRegistry&);
void initializeHexagonGenMuxPass(PassRegistry&);
void initializeHexagonHardwareLoopsPass(PassRegistry&);
- void initializeHexagonLoopIdiomRecognizePass(PassRegistry&);
+ void initializeHexagonLoopIdiomRecognizeLegacyPassPass(PassRegistry &);
void initializeHexagonVectorLoopCarriedReuseLegacyPassPass(PassRegistry &);
void initializeHexagonNewValueJumpPass(PassRegistry&);
void initializeHexagonOptAddrModePass(PassRegistry&);
@@ -197,7 +198,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonTarget() {
initializeHexagonEarlyIfConversionPass(PR);
initializeHexagonGenMuxPass(PR);
initializeHexagonHardwareLoopsPass(PR);
- initializeHexagonLoopIdiomRecognizePass(PR);
+ initializeHexagonLoopIdiomRecognizeLegacyPassPass(PR);
initializeHexagonVectorLoopCarriedReuseLegacyPassPass(PR);
initializeHexagonNewValueJumpPass(PR);
initializeHexagonOptAddrModePass(PR);
@@ -276,6 +277,10 @@ void HexagonTargetMachine::adjustPassManager(PassManagerBuilder &PMB) {
void HexagonTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB,
bool DebugPassManager) {
+ PB.registerLateLoopOptimizationsEPCallback(
+ [=](LoopPassManager &LPM, PassBuilder::OptimizationLevel Level) {
+ LPM.addPass(HexagonLoopIdiomRecognitionPass());
+ });
PB.registerOptimizerLastEPCallback(
[=](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
LoopPassManager LPM(DebugPassManager);
diff --git a/llvm/test/CodeGen/Hexagon/loop-idiom/pmpy-mod.ll b/llvm/test/CodeGen/Hexagon/loop-idiom/pmpy-mod.ll
index 3e1e39b9d094..06d4544be5cf 100644
--- a/llvm/test/CodeGen/Hexagon/loop-idiom/pmpy-mod.ll
+++ b/llvm/test/CodeGen/Hexagon/loop-idiom/pmpy-mod.ll
@@ -3,6 +3,7 @@
; get this opportunity regardless of what happens before.
; RUN: opt -O2 -march=hexagon -S < %s | FileCheck %s
+; RUN: opt -aa-pipeline=default -passes='default<O2>' -march=hexagon -S < %s | FileCheck %s
target triple = "hexagon"
target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
More information about the llvm-commits
mailing list