[llvm] r372885 - [PatternMatch] Make m_Br more flexible, add matchers for BB values.
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 25 08:05:09 PDT 2019
Author: fhahn
Date: Wed Sep 25 08:05:08 2019
New Revision: 372885
URL: http://llvm.org/viewvc/llvm-project?rev=372885&view=rev
Log:
[PatternMatch] Make m_Br more flexible, add matchers for BB values.
Currently m_Br only takes references to BasicBlock*, which limits its
flexibility. For example, you have to declare a variable, even if you
ignore the result or you have to have additional checks to make sure the
matched BB matches an expected one.
This patch adds m_BasicBlock and m_SpecificBB matchers, which can be
used like the existing matchers for constants or values.
I also had a look at the existing uses and updated a few. IMO it makes
the code a bit more explicit.
Reviewers: spatel, craig.topper, RKSimon, majnemer, lebedev.ri
Reviewed By: lebedev.ri
Differential Revision: https://reviews.llvm.org/D68013
Modified:
llvm/trunk/include/llvm/IR/PatternMatch.h
llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp
llvm/trunk/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/trunk/unittests/IR/PatternMatch.cpp
Modified: llvm/trunk/include/llvm/IR/PatternMatch.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PatternMatch.h?rev=372885&r1=372884&r2=372885&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/PatternMatch.h (original)
+++ llvm/trunk/include/llvm/IR/PatternMatch.h Wed Sep 25 08:05:08 2019
@@ -88,6 +88,11 @@ inline class_match<UndefValue> m_Undef()
/// Match an arbitrary Constant and ignore it.
inline class_match<Constant> m_Constant() { return class_match<Constant>(); }
+/// Match an arbitrary basic block value and ignore it.
+inline class_match<BasicBlock> m_BasicBlock() {
+ return class_match<BasicBlock>();
+}
+
/// Inverting matcher
template <typename Ty> struct match_unless {
Ty M;
@@ -563,6 +568,12 @@ inline bind_ty<Constant> m_Constant(Cons
/// Match a ConstantFP, capturing the value if we match.
inline bind_ty<ConstantFP> m_ConstantFP(ConstantFP *&C) { return C; }
+/// Match a basic block value, capturing it if we match.
+inline bind_ty<BasicBlock> m_BasicBlock(BasicBlock *&V) { return V; }
+inline bind_ty<const BasicBlock> m_BasicBlock(const BasicBlock *&V) {
+ return V;
+}
+
/// Match a specified Value*.
struct specificval_ty {
const Value *Val;
@@ -656,6 +667,32 @@ inline specific_intval m_SpecificInt(uin
/// ConstantInts wider than 64-bits.
inline bind_const_intval_ty m_ConstantInt(uint64_t &V) { return V; }
+/// Match a specified basic block value.
+struct specific_bbval {
+ BasicBlock *Val;
+
+ specific_bbval(BasicBlock *Val) : Val(Val) {}
+
+ template <typename ITy> bool match(ITy *V) {
+ const auto *BB = dyn_cast<BasicBlock>(V);
+ return BB && BB == Val;
+ }
+};
+
+/// Match a specific basic block value.
+inline specific_bbval m_SpecificBB(BasicBlock *BB) {
+ return specific_bbval(BB);
+}
+
+/// A commutative-friendly version of m_Specific().
+inline deferredval_ty<BasicBlock> m_Deferred(BasicBlock *const &BB) {
+ return BB;
+}
+inline deferredval_ty<const BasicBlock>
+m_Deferred(const BasicBlock *const &BB) {
+ return BB;
+}
+
//===----------------------------------------------------------------------===//
// Matcher for any binary operator.
//
@@ -1345,19 +1382,23 @@ struct brc_match {
template <typename OpTy> bool match(OpTy *V) {
if (auto *BI = dyn_cast<BranchInst>(V))
- if (BI->isConditional() && Cond.match(BI->getCondition())) {
- T = BI->getSuccessor(0);
- F = BI->getSuccessor(1);
- return true;
- }
+ if (BI->isConditional() && Cond.match(BI->getCondition()))
+ return T.match(BI->getSuccessor(0)) && F.match(BI->getSuccessor(1));
return false;
}
};
template <typename Cond_t>
-inline brc_match<Cond_t, BasicBlock *&, BasicBlock *&>
+inline brc_match<Cond_t, bind_ty<BasicBlock>, bind_ty<BasicBlock>>
m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F) {
- return brc_match<Cond_t, BasicBlock *&, BasicBlock *&>(C, T, F);
+ return brc_match<Cond_t, bind_ty<BasicBlock>, bind_ty<BasicBlock>>(
+ C, m_BasicBlock(T), m_BasicBlock(F));
+}
+
+template <typename Cond_t, typename TrueBlock_t, typename FalseBlock_t>
+inline brc_match<Cond_t, TrueBlock_t, FalseBlock_t>
+m_Br(const Cond_t &C, const TrueBlock_t &T, const FalseBlock_t &F) {
+ return brc_match<Cond_t, TrueBlock_t, FalseBlock_t>(C, T, F);
}
//===----------------------------------------------------------------------===//
Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=372885&r1=372884&r2=372885&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Wed Sep 25 08:05:08 2019
@@ -2105,11 +2105,10 @@ SCEVExpander::getRelatedExistingExpansio
for (BasicBlock *BB : ExitingBlocks) {
ICmpInst::Predicate Pred;
Instruction *LHS, *RHS;
- BasicBlock *TrueBB, *FalseBB;
if (!match(BB->getTerminator(),
m_Br(m_ICmp(Pred, m_Instruction(LHS), m_Instruction(RHS)),
- TrueBB, FalseBB)))
+ m_BasicBlock(), m_BasicBlock())))
continue;
if (SE.getSCEV(LHS) == S && SE.DT.dominates(LHS, At))
Modified: llvm/trunk/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp?rev=372885&r1=372884&r2=372885&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp (original)
+++ llvm/trunk/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp Wed Sep 25 08:05:08 2019
@@ -121,14 +121,13 @@ static bool foldGuardedRotateToFunnelShi
BasicBlock *GuardBB = Phi.getIncomingBlock(RotSrc == P1);
BasicBlock *RotBB = Phi.getIncomingBlock(RotSrc != P1);
Instruction *TermI = GuardBB->getTerminator();
- BasicBlock *TrueBB, *FalseBB;
ICmpInst::Predicate Pred;
- if (!match(TermI, m_Br(m_ICmp(Pred, m_Specific(RotAmt), m_ZeroInt()), TrueBB,
- FalseBB)))
+ BasicBlock *PhiBB = Phi.getParent();
+ if (!match(TermI, m_Br(m_ICmp(Pred, m_Specific(RotAmt), m_ZeroInt()),
+ m_SpecificBB(PhiBB), m_SpecificBB(RotBB))))
return false;
- BasicBlock *PhiBB = Phi.getParent();
- if (Pred != CmpInst::ICMP_EQ || TrueBB != PhiBB || FalseBB != RotBB)
+ if (Pred != CmpInst::ICMP_EQ)
return false;
// We matched a variation of this IR pattern:
Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=372885&r1=372884&r2=372885&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Wed Sep 25 08:05:08 2019
@@ -2557,9 +2557,7 @@ Instruction *InstCombiner::visitReturnIn
Instruction *InstCombiner::visitBranchInst(BranchInst &BI) {
// Change br (not X), label True, label False to: br X, label False, True
Value *X = nullptr;
- BasicBlock *TrueDest;
- BasicBlock *FalseDest;
- if (match(&BI, m_Br(m_Not(m_Value(X)), TrueDest, FalseDest)) &&
+ if (match(&BI, m_Br(m_Not(m_Value(X)), m_BasicBlock(), m_BasicBlock())) &&
!isa<Constant>(X)) {
// Swap Destinations and condition...
BI.setCondition(X);
@@ -2577,8 +2575,8 @@ Instruction *InstCombiner::visitBranchIn
// Canonicalize, for example, icmp_ne -> icmp_eq or fcmp_one -> fcmp_oeq.
CmpInst::Predicate Pred;
- if (match(&BI, m_Br(m_OneUse(m_Cmp(Pred, m_Value(), m_Value())), TrueDest,
- FalseDest)) &&
+ if (match(&BI, m_Br(m_OneUse(m_Cmp(Pred, m_Value(), m_Value())),
+ m_BasicBlock(), m_BasicBlock())) &&
!isCanonicalPredicate(Pred)) {
// Swap destinations and condition.
CmpInst *Cond = cast<CmpInst>(BI.getCondition());
Modified: llvm/trunk/unittests/IR/PatternMatch.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/PatternMatch.cpp?rev=372885&r1=372884&r2=372885&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/PatternMatch.cpp (original)
+++ llvm/trunk/unittests/IR/PatternMatch.cpp Wed Sep 25 08:05:08 2019
@@ -1045,6 +1045,34 @@ TEST_F(PatternMatchTest, FloatingPointFN
EXPECT_FALSE(match(V3, m_FNeg(m_Value(Match))));
}
+TEST_F(PatternMatchTest, CondBranchTest) {
+ BasicBlock *TrueBB = BasicBlock::Create(Ctx, "TrueBB", F);
+ BasicBlock *FalseBB = BasicBlock::Create(Ctx, "FalseBB", F);
+ Value *Br1 = IRB.CreateCondBr(IRB.getTrue(), TrueBB, FalseBB);
+
+ EXPECT_TRUE(match(Br1, m_Br(m_Value(), m_BasicBlock(), m_BasicBlock())));
+
+ BasicBlock *A, *B;
+ EXPECT_TRUE(match(Br1, m_Br(m_Value(), m_BasicBlock(A), m_BasicBlock(B))));
+ EXPECT_EQ(TrueBB, A);
+ EXPECT_EQ(FalseBB, B);
+
+ EXPECT_FALSE(
+ match(Br1, m_Br(m_Value(), m_SpecificBB(FalseBB), m_BasicBlock())));
+ EXPECT_FALSE(
+ match(Br1, m_Br(m_Value(), m_BasicBlock(), m_SpecificBB(TrueBB))));
+ EXPECT_FALSE(
+ match(Br1, m_Br(m_Value(), m_SpecificBB(FalseBB), m_BasicBlock(TrueBB))));
+ EXPECT_TRUE(
+ match(Br1, m_Br(m_Value(), m_SpecificBB(TrueBB), m_BasicBlock(FalseBB))));
+
+ // Check we can use m_Deferred with branches.
+ EXPECT_FALSE(match(Br1, m_Br(m_Value(), m_BasicBlock(A), m_Deferred(A))));
+ Value *Br2 = IRB.CreateCondBr(IRB.getTrue(), TrueBB, TrueBB);
+ A = nullptr;
+ EXPECT_TRUE(match(Br2, m_Br(m_Value(), m_BasicBlock(A), m_Deferred(A))));
+}
+
template <typename T> struct MutableConstTest : PatternMatchTest { };
typedef ::testing::Types<std::tuple<Value*, Instruction*>,
More information about the llvm-commits
mailing list