bool runOnFunction(Function &F) override {
if (skipFunction(F) || !EnableKnowledgeRetention)
return false;
- DominatorTreeWrapperPass *DT =
- getAnalysisIfAvailable<DominatorTreeWrapperPass>();
AssumptionCache &AC =
getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
- return simplifyAssumes(F, &AC, DT ? &DT->getDomTree() : nullptr);
+ DominatorTreeWrapperPass *DTWP =
+ getAnalysisIfAvailable<DominatorTreeWrapperPass>();
+ return simplifyAssumes(F, &AC, DTWP ? &DTWP->getDomTree() : nullptr);
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<AssumptionCacheTracker>();
+
AU.setPreservesAll();
}
};
INITIALIZE_PASS_BEGIN(AssumeSimplifyPassLegacyPass, "assume-simplify",
"Assume Simplify", false, false)
-INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_END(AssumeSimplifyPassLegacyPass, "assume-simplify",
"Assume Simplify", false, false)
PreservedAnalyses AssumeBuilderPass::run(Function &F,
FunctionAnalysisManager &AM) {
- AssumptionCache* AC = AM.getCachedResult<AssumptionAnalysis>(F);
+ AssumptionCache *AC = &AM.getResult<AssumptionAnalysis>(F);
DominatorTree* DT = AM.getCachedResult<DominatorTreeAnalysis>(F);
for (Instruction &I : instructions(F))
salvageKnowledge(&I, AC, DT);
return PreservedAnalyses::all();
}
+
+namespace {
+class AssumeBuilderPassLegacyPass : public FunctionPass {
+public:
+ static char ID;
+
+ AssumeBuilderPassLegacyPass() : FunctionPass(ID) {
+ initializeAssumeBuilderPassLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+ bool runOnFunction(Function &F) override {
+ AssumptionCache &AC =
+ getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
+ DominatorTreeWrapperPass *DTWP =
+ getAnalysisIfAvailable<DominatorTreeWrapperPass>();
+ for (Instruction &I : instructions(F))
+ salvageKnowledge(&I, &AC, DTWP ? &DTWP->getDomTree() : nullptr);
+ return true;
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<AssumptionCacheTracker>();
+
+ AU.setPreservesAll();
+ }
+};
+} // namespace
+
+char AssumeBuilderPassLegacyPass::ID = 0;
+
+INITIALIZE_PASS_BEGIN(AssumeBuilderPassLegacyPass, "assume-builder",
+ "Assume Builder", false, false)
+INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
+INITIALIZE_PASS_END(AssumeBuilderPassLegacyPass, "assume-builder",
+ "Assume Builder", false, false)
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
+; RUN: opt -assume-builder -verify --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=BASIC
+; RUN: opt -assume-builder -verify --enable-knowledge-retention --assume-preserve-all -S %s | FileCheck %s --check-prefixes=ALL
+; RUN: opt -assumption-cache-tracker -assume-builder -verify --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=WITH-AC
+; RUN: opt -domtree -assumption-cache-tracker -assume-builder -verify --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=CROSS-BLOCK,CROSS-BLOCK-OLDPM
+; RUN: opt -assume-builder -domtree -assumption-cache-tracker -assume-simplify -verify --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=FULL-SIMPLIFY
+
; RUN: opt -passes='assume-builder,verify' --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=BASIC
; RUN: opt -passes='assume-builder,verify' --enable-knowledge-retention --assume-preserve-all -S %s | FileCheck %s --check-prefixes=ALL
; RUN: opt -passes='require<assumptions>,assume-builder,verify' --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=WITH-AC
-; RUN: opt -passes='require<domtree>,require<assumptions>,assume-builder,verify' --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=CROSS-BLOCK
+; RUN: opt -passes='require<domtree>,require<assumptions>,assume-builder,verify' --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=CROSS-BLOCK,CROSS-BLOCK-NEWMP
; RUN: opt -passes='assume-builder,require<domtree>,require<assumptions>,assume-simplify,verify' --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=FULL-SIMPLIFY
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
; WITH-AC-NEXT: store i32 0, i32* [[P1]], align 4
; WITH-AC-NEXT: ret i32 0
;
-; CROSS-BLOCK-LABEL: define {{[^@]+}}@_Z6squarePi
-; CROSS-BLOCK-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i1 [[COND:%.*]])
-; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]), "align"(i32* [[P]], i64 4) ]
-; CROSS-BLOCK-NEXT: store i32 0, i32* [[P]], align 4
-; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
-; CROSS-BLOCK-NEXT: store i32 0, i32* [[P1]], align 8
-; CROSS-BLOCK-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
-; CROSS-BLOCK: A:
-; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8) ]
-; CROSS-BLOCK-NEXT: store i32 0, i32* [[P]], align 8
-; CROSS-BLOCK-NEXT: store i32 0, i32* [[P1]], align 4
-; CROSS-BLOCK-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
-; CROSS-BLOCK: B:
-; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8) ]
-; CROSS-BLOCK-NEXT: store i32 0, i32* [[P]], align 8
-; CROSS-BLOCK-NEXT: store i32 0, i32* [[P1]], align 8
-; CROSS-BLOCK-NEXT: br label [[C]]
-; CROSS-BLOCK: C:
-; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 32) ]
-; CROSS-BLOCK-NEXT: store i32 0, i32* [[P]], align 32
-; CROSS-BLOCK-NEXT: store i32 0, i32* [[P1]], align 4
-; CROSS-BLOCK-NEXT: ret i32 0
+; CROSS-BLOCK-OLDPM-LABEL: define {{[^@]+}}@_Z6squarePi
+; CROSS-BLOCK-OLDPM-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i1 [[COND:%.*]])
+; CROSS-BLOCK-OLDPM-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]), "align"(i32* [[P]], i64 4) ]
+; CROSS-BLOCK-OLDPM-NEXT: store i32 0, i32* [[P]], align 4
+; CROSS-BLOCK-OLDPM-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
+; CROSS-BLOCK-OLDPM-NEXT: store i32 0, i32* [[P1]], align 8
+; CROSS-BLOCK-OLDPM-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
+; CROSS-BLOCK-OLDPM: A:
+; CROSS-BLOCK-OLDPM-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8) ]
+; CROSS-BLOCK-OLDPM-NEXT: store i32 0, i32* [[P]], align 8
+; CROSS-BLOCK-OLDPM-NEXT: store i32 0, i32* [[P1]], align 4
+; CROSS-BLOCK-OLDPM-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
+; CROSS-BLOCK-OLDPM: B:
+; CROSS-BLOCK-OLDPM-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]), "align"(i32* [[P]], i64 8) ]
+; CROSS-BLOCK-OLDPM-NEXT: store i32 0, i32* [[P]], align 8
+; CROSS-BLOCK-OLDPM-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
+; CROSS-BLOCK-OLDPM-NEXT: store i32 0, i32* [[P1]], align 8
+; CROSS-BLOCK-OLDPM-NEXT: br label [[C]]
+; CROSS-BLOCK-OLDPM: C:
+; CROSS-BLOCK-OLDPM-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]), "align"(i32* [[P]], i64 32) ]
+; CROSS-BLOCK-OLDPM-NEXT: store i32 0, i32* [[P]], align 32
+; CROSS-BLOCK-OLDPM-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]), "align"(i32* [[P1]], i64 4) ]
+; CROSS-BLOCK-OLDPM-NEXT: store i32 0, i32* [[P1]], align 4
+; CROSS-BLOCK-OLDPM-NEXT: ret i32 0
;
; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@_Z6squarePi
; FULL-SIMPLIFY-SAME: (i32* nonnull align 4 dereferenceable(4) [[P:%.*]], i32* nonnull align 8 dereferenceable(4) [[P1:%.*]], i1 [[COND:%.*]])
; FULL-SIMPLIFY-NEXT: store i32 0, i32* [[P1]], align 4
; FULL-SIMPLIFY-NEXT: ret i32 0
;
+; CROSS-BLOCK-NEWMP-LABEL: define {{[^@]+}}@_Z6squarePi
+; CROSS-BLOCK-NEWMP-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i1 [[COND:%.*]])
+; CROSS-BLOCK-NEWMP-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]), "align"(i32* [[P]], i64 4) ]
+; CROSS-BLOCK-NEWMP-NEXT: store i32 0, i32* [[P]], align 4
+; CROSS-BLOCK-NEWMP-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
+; CROSS-BLOCK-NEWMP-NEXT: store i32 0, i32* [[P1]], align 8
+; CROSS-BLOCK-NEWMP-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
+; CROSS-BLOCK-NEWMP: A:
+; CROSS-BLOCK-NEWMP-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8) ]
+; CROSS-BLOCK-NEWMP-NEXT: store i32 0, i32* [[P]], align 8
+; CROSS-BLOCK-NEWMP-NEXT: store i32 0, i32* [[P1]], align 4
+; CROSS-BLOCK-NEWMP-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
+; CROSS-BLOCK-NEWMP: B:
+; CROSS-BLOCK-NEWMP-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8) ]
+; CROSS-BLOCK-NEWMP-NEXT: store i32 0, i32* [[P]], align 8
+; CROSS-BLOCK-NEWMP-NEXT: store i32 0, i32* [[P1]], align 8
+; CROSS-BLOCK-NEWMP-NEXT: br label [[C]]
+; CROSS-BLOCK-NEWMP: C:
+; CROSS-BLOCK-NEWMP-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 32) ]
+; CROSS-BLOCK-NEWMP-NEXT: store i32 0, i32* [[P]], align 32
+; CROSS-BLOCK-NEWMP-NEXT: store i32 0, i32* [[P1]], align 4
+; CROSS-BLOCK-NEWMP-NEXT: ret i32 0
+;
store i32 0, i32* %P, align 4
store i32 0, i32* %P1, align 8
br i1 %cond, label %A, label %B