[llvm] r358704 - [GuardWidening] Wire up a NPM version of the LoopGuardWidening pass
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 18 12:17:14 PDT 2019
Author: reames
Date: Thu Apr 18 12:17:14 2019
New Revision: 358704
URL: http://llvm.org/viewvc/llvm-project?rev=358704&view=rev
Log:
[GuardWidening] Wire up a NPM version of the LoopGuardWidening pass
Added:
llvm/trunk/test/Transforms/GuardWidening/basic-loop.ll
Modified:
llvm/trunk/include/llvm/Transforms/Scalar/GuardWidening.h
llvm/trunk/lib/Passes/PassRegistry.def
llvm/trunk/lib/Transforms/Scalar/GuardWidening.cpp
Modified: llvm/trunk/include/llvm/Transforms/Scalar/GuardWidening.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar/GuardWidening.h?rev=358704&r1=358703&r2=358704&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Scalar/GuardWidening.h (original)
+++ llvm/trunk/include/llvm/Transforms/Scalar/GuardWidening.h Thu Apr 18 12:17:14 2019
@@ -16,7 +16,9 @@
#ifndef LLVM_TRANSFORMS_SCALAR_GUARD_WIDENING_H
#define LLVM_TRANSFORMS_SCALAR_GUARD_WIDENING_H
+#include "llvm/Analysis/LoopInfo.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
namespace llvm {
@@ -24,6 +26,8 @@ class Function;
struct GuardWideningPass : public PassInfoMixin<GuardWideningPass> {
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
};
}
Modified: llvm/trunk/lib/Passes/PassRegistry.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassRegistry.def?rev=358704&r1=358703&r2=358704&view=diff
==============================================================================
--- llvm/trunk/lib/Passes/PassRegistry.def (original)
+++ llvm/trunk/lib/Passes/PassRegistry.def Thu Apr 18 12:17:14 2019
@@ -294,4 +294,5 @@ LOOP_PASS("unswitch", SimpleLoopUnswitch
LOOP_PASS("print-access-info", LoopAccessInfoPrinterPass(dbgs()))
LOOP_PASS("print<ivusers>", IVUsersPrinterPass(dbgs()))
LOOP_PASS("loop-predication", LoopPredicationPass())
+LOOP_PASS("guard-widening", GuardWideningPass())
#undef LOOP_PASS
Modified: llvm/trunk/lib/Transforms/Scalar/GuardWidening.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GuardWidening.cpp?rev=358704&r1=358703&r2=358704&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/GuardWidening.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/GuardWidening.cpp Thu Apr 18 12:17:14 2019
@@ -817,6 +817,31 @@ PreservedAnalyses GuardWideningPass::run
return PA;
}
+PreservedAnalyses GuardWideningPass::run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR,
+ LPMUpdater &U) {
+
+ const auto &FAM =
+ AM.getResult<FunctionAnalysisManagerLoopProxy>(L, AR).getManager();
+ Function &F = *L.getHeader()->getParent();
+ BranchProbabilityInfo *BPI = nullptr;
+ if (WidenFrequentBranches)
+ BPI = FAM.getCachedResult<BranchProbabilityAnalysis>(F);
+
+ BasicBlock *RootBB = L.getLoopPredecessor();
+ if (!RootBB)
+ RootBB = L.getHeader();
+ auto BlockFilter = [&](BasicBlock *BB) {
+ return BB == RootBB || L.contains(BB);
+ };
+ if (!GuardWideningImpl(AR.DT, nullptr, AR.LI, BPI,
+ AR.DT.getNode(RootBB),
+ BlockFilter).run())
+ return PreservedAnalyses::all();
+
+ return getLoopPassPreservedAnalyses();
+}
+
namespace {
struct GuardWideningLegacyPass : public FunctionPass {
static char ID;
Added: llvm/trunk/test/Transforms/GuardWidening/basic-loop.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GuardWidening/basic-loop.ll?rev=358704&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/GuardWidening/basic-loop.ll (added)
+++ llvm/trunk/test/Transforms/GuardWidening/basic-loop.ll Thu Apr 18 12:17:14 2019
@@ -0,0 +1,138 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -loop-guard-widening < %s | FileCheck %s
+; RUN: opt -S -passes="loop(guard-widening)" < %s | FileCheck %s
+
+declare void @llvm.experimental.guard(i1,...)
+
+ at G = external global i32
+
+; Show that we can widen into early checks within a loop, and in the process
+; expose optimization oppurtunities.
+define void @widen_within_loop(i1 %cond_0, i1 %cond_1, i1 %cond_2) {
+; CHECK-LABEL: @widen_within_loop(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: store i32 0, i32* @G
+; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
+; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[COND_2:%.*]]
+; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK1]]) [ "deopt"(i32 0) ]
+; CHECK-NEXT: store i32 1, i32* @G
+; CHECK-NEXT: store i32 2, i32* @G
+; CHECK-NEXT: store i32 3, i32* @G
+; CHECK-NEXT: br label [[LOOP]]
+;
+entry:
+ br label %loop
+
+loop:
+ store i32 0, i32* @G
+ call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ]
+ store i32 1, i32* @G
+ call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"(i32 1) ]
+ store i32 2, i32* @G
+ call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ]
+ store i32 3, i32* @G
+ br label %loop
+}
+
+define void @widen_into_preheader(i1 %cond_0, i1 %cond_1, i1 %cond_2) {
+; CHECK-LABEL: @widen_into_preheader(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: store i32 0, i32* @G
+; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
+; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[COND_2:%.*]]
+; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK1]]) [ "deopt"(i32 0) ]
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: store i32 1, i32* @G
+; CHECK-NEXT: store i32 2, i32* @G
+; CHECK-NEXT: store i32 3, i32* @G
+; CHECK-NEXT: br label [[LOOP]]
+;
+entry:
+ store i32 0, i32* @G
+ call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ]
+ br label %loop
+
+loop:
+ store i32 1, i32* @G
+ call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"(i32 1) ]
+ store i32 2, i32* @G
+ call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ]
+ store i32 3, i32* @G
+ br label %loop
+}
+
+define void @dont_widen_over_common_exit(i1 %cond_0, i1 %cond_1, i1 %cond_2) {
+; CHECK-LABEL: @dont_widen_over_common_exit(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: store i32 0, i32* @G
+; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND_0:%.*]]) [ "deopt"(i32 0) ]
+; CHECK-NEXT: store i32 1, i32* @G
+; CHECK-NEXT: br i1 [[COND_1:%.*]], label [[BACKEDGE:%.*]], label [[EXIT:%.*]]
+; CHECK: backedge:
+; CHECK-NEXT: store i32 2, i32* @G
+; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND_2:%.*]]) [ "deopt"(i32 2) ]
+; CHECK-NEXT: store i32 3, i32* @G
+; CHECK-NEXT: br label [[LOOP]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %loop
+
+loop:
+ store i32 0, i32* @G
+ call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ]
+ store i32 1, i32* @G
+ br i1 %cond_1, label %backedge, label %exit
+
+backedge:
+ store i32 2, i32* @G
+ call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ]
+ store i32 3, i32* @G
+ br label %loop
+
+exit:
+ ret void
+}
+
+define void @widen_over_common_exit_to_ph(i1 %cond_0, i1 %cond_1, i1 %cond_2) {
+; CHECK-LABEL: @widen_over_common_exit_to_ph(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: store i32 0, i32* @G
+; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_2:%.*]]
+; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"(i32 0) ]
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: store i32 1, i32* @G
+; CHECK-NEXT: br i1 [[COND_1:%.*]], label [[BACKEDGE:%.*]], label [[EXIT:%.*]]
+; CHECK: backedge:
+; CHECK-NEXT: store i32 2, i32* @G
+; CHECK-NEXT: store i32 3, i32* @G
+; CHECK-NEXT: br label [[LOOP]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ store i32 0, i32* @G
+ call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ]
+ br label %loop
+
+loop:
+ store i32 1, i32* @G
+ br i1 %cond_1, label %backedge, label %exit
+
+backedge:
+ store i32 2, i32* @G
+ call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ]
+ store i32 3, i32* @G
+ br label %loop
+
+exit:
+ ret void
+}
+
More information about the llvm-commits
mailing list