aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorPhilip Reames <listmail@philipreames.com>2019-11-19 14:43:13 -0800
committerPhilip Reames <listmail@philipreames.com>2019-11-19 14:43:13 -0800
commit70c68a6b0e515967dba5b30f6a60e220a8cd8d2c (patch)
tree23ec3ddaefb2ed5edc15e23376ecfb5d284ddd8a /llvm/lib/Transforms
parentf3eb5dee5756876be0524c59c21478659eba8c4d (diff)
downloadllvm-70c68a6b0e515967dba5b30f6a60e220a8cd8d2c.zip
llvm-70c68a6b0e515967dba5b30f6a60e220a8cd8d2c.tar.gz
llvm-70c68a6b0e515967dba5b30f6a60e220a8cd8d2c.tar.bz2
[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.cpp7
-rw-r--r--llvm/lib/Transforms/Scalar/LoopPredication.cpp10
-rw-r--r--llvm/lib/Transforms/Utils/GuardUtils.cpp26
3 files changed, 30 insertions, 13 deletions
diff --git a/llvm/lib/Transforms/Scalar/GuardWidening.cpp b/llvm/lib/Transforms/Scalar/GuardWidening.cpp
index 27439a2..943cc9a 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 9d67046..1962c8b 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 8069aba..37fca0d 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");
+}