diff options
| author | Philip Reames <listmail@philipreames.com> | 2019-11-19 14:43:13 -0800 |
|---|---|---|
| committer | Philip Reames <listmail@philipreames.com> | 2019-11-19 14:43:13 -0800 |
| commit | 70c68a6b0e515967dba5b30f6a60e220a8cd8d2c (patch) | |
| tree | 23ec3ddaefb2ed5edc15e23376ecfb5d284ddd8a /llvm/lib/Transforms | |
| parent | f3eb5dee5756876be0524c59c21478659eba8c4d (diff) | |
| download | bcm5719-llvm-70c68a6b0e515967dba5b30f6a60e220a8cd8d2c.tar.gz bcm5719-llvm-70c68a6b0e515967dba5b30f6a60e220a8cd8d2c.zip | |
[NFC] Factor out utilities for manipulating widenable branches
With the widenable condition construct, we have the ability to reason about branches which can be 'widened' (i.e. made to fail more often). We've got a couple o transforms which leverage this. This patch just cleans up the API a bit.
This is prep work for generalizing our definition of a widenable branch slightly. At the moment "br i1 (and A, wc()), ..." is considered widenable, but oddly, neither "br i1 (and wc(), B), ..." or "br i1 wc(), ..." is. That clearly needs addressed, so first, let's centralize the code in one place.
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/GuardWidening.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LoopPredication.cpp | 10 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Utils/GuardUtils.cpp | 26 |
3 files changed, 30 insertions, 13 deletions
diff --git a/llvm/lib/Transforms/Scalar/GuardWidening.cpp b/llvm/lib/Transforms/Scalar/GuardWidening.cpp index 27439a206d1..943cc9ac593 100644 --- a/llvm/lib/Transforms/Scalar/GuardWidening.cpp +++ b/llvm/lib/Transforms/Scalar/GuardWidening.cpp @@ -58,6 +58,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/KnownBits.h" #include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/GuardUtils.h" #include "llvm/Transforms/Utils/LoopUtils.h" #include <functional> @@ -277,11 +278,7 @@ class GuardWideningImpl { widenCondCommon(getCondition(ToWiden), NewCondition, ToWiden, Result, InvertCondition); if (isGuardAsWidenableBranch(ToWiden)) { - auto *BI = cast<BranchInst>(ToWiden); - auto *And = cast<Instruction>(BI->getCondition()); - And->setOperand(0, Result); - And->moveBefore(ToWiden); - assert(isGuardAsWidenableBranch(ToWiden) && "still widenable?"); + setWidenableBranchCond(cast<BranchInst>(ToWiden), Result); return; } setCondition(ToWiden, Result); diff --git a/llvm/lib/Transforms/Scalar/LoopPredication.cpp b/llvm/lib/Transforms/Scalar/LoopPredication.cpp index 9d67046d743..1962c8ba39f 100644 --- a/llvm/lib/Transforms/Scalar/LoopPredication.cpp +++ b/llvm/lib/Transforms/Scalar/LoopPredication.cpp @@ -196,6 +196,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/GuardUtils.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/LoopUtils.h" @@ -1144,14 +1145,7 @@ bool LoopPredication::predicateLoopExits(Loop *L, SCEVExpander &Rewriter) { // context. NewCond = B.CreateFreeze(NewCond); - Value *Cond, *WC; - BasicBlock *IfTrueBB, *IfFalseBB; - bool Success = - parseWidenableBranch(WidenableBR, Cond, WC, IfTrueBB, IfFalseBB); - assert(Success && "implied from above"); - (void)Success; - Instruction *WCAnd = cast<Instruction>(WidenableBR->getCondition()); - WCAnd->setOperand(0, B.CreateAnd(NewCond, Cond)); + widenWidenableBranch(WidenableBR, NewCond); Value *OldCond = BI->getCondition(); BI->setCondition(ConstantInt::get(OldCond->getType(), !ExitIfTrue)); diff --git a/llvm/lib/Transforms/Utils/GuardUtils.cpp b/llvm/lib/Transforms/Utils/GuardUtils.cpp index 8069aba1fd1..37fca0d129b 100644 --- a/llvm/lib/Transforms/Utils/GuardUtils.cpp +++ b/llvm/lib/Transforms/Utils/GuardUtils.cpp @@ -10,6 +10,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Utils/GuardUtils.h" +#include "llvm/Analysis/GuardUtils.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instructions.h" @@ -62,3 +63,28 @@ void llvm::makeGuardControlFlowExplicit(Function *DeoptIntrinsic, DeoptCall->setCallingConv(Guard->getCallingConv()); DeoptBlockTerm->eraseFromParent(); } + + +void llvm::widenWidenableBranch(BranchInst *WidenableBR, Value *NewCond) { + assert(isWidenableBranch(WidenableBR) && "precondition"); + + Instruction *WCAnd = cast<Instruction>(WidenableBR->getCondition()); + // Condition is only guaranteed to dominate branch + WCAnd->moveBefore(WidenableBR); + Value *OldCond = WCAnd->getOperand(0); + IRBuilder<> B(WCAnd); + WCAnd->setOperand(0, B.CreateAnd(NewCond, OldCond)); + + assert(isWidenableBranch(WidenableBR) && "preserve widenabiliy"); +} + +void llvm::setWidenableBranchCond(BranchInst *WidenableBR, Value *NewCond) { + assert(isWidenableBranch(WidenableBR) && "precondition"); + + Instruction *WCAnd = cast<Instruction>(WidenableBR->getCondition()); + // Condition is only guaranteed to dominate branch + WCAnd->moveBefore(WidenableBR); + WCAnd->setOperand(0, NewCond); + + assert(isWidenableBranch(WidenableBR) && "preserve widenabiliy"); +} |

