[PATCH] D33074: InstCombine: Allow sinking instructions with more uses in the same block.
Kyle Butt via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed May 10 14:56:54 PDT 2017
iteratee created this revision.
Currently InstCombine will sink instructions that may be trivially sunk if they
have a single use. This patch relaxes this requirement to 4 or fewer uses, and
requires that they all be in the same basic block. The motivating case was an
instruction that was used by 2 extractvalue instructions, both in the same
block.
Repository:
rL LLVM
https://reviews.llvm.org/D33074
Files:
lib/Transforms/InstCombine/InstructionCombining.cpp
Index: lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- lib/Transforms/InstCombine/InstructionCombining.cpp
+++ lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2789,7 +2789,25 @@
/// instruction past all of the instructions between it and the end of its
/// block.
static bool TryToSinkInstruction(Instruction *I, BasicBlock *DestBlock) {
- assert(I->hasOneUse() && "Invariants didn't hold!");
+ // verify that all uses are in the same block.
+ DEBUG(
+ BasicBlock *UsersParent = nullptr;
+ int UseCount = 0;
+ for (const Use &U : I->uses()) {
+ if (++UseCount > 4)
+ llvm_unreachable("Instruction has too many uses to be sunk.");
+ Instruction *UserInst = cast<Instruction>(U.getUser());
+ BasicBlock *CurrentUserParent;
+ // Get the block the use occurs in.
+ if (PHINode *PN = dyn_cast<PHINode>(UserInst))
+ CurrentUserParent = PN->getIncomingBlock(U);
+ else
+ CurrentUserParent = UserInst->getParent();
+ if (UsersParent == nullptr)
+ UsersParent = CurrentUserParent;
+ else if (CurrentUserParent != UsersParent)
+ llvm_unreachable("Instruction has uses in different blocks.");
+ });
// Cannot move control-flow-involving, volatile loads, vaarg, etc.
if (isa<PHINode>(I) || I->isEHPad() || I->mayHaveSideEffects() ||
@@ -2879,32 +2897,51 @@
}
// See if we can trivially sink this instruction to a successor basic block.
- if (I->hasOneUse()) {
- BasicBlock *BB = I->getParent();
- Instruction *UserInst = cast<Instruction>(*I->user_begin());
- BasicBlock *UserParent;
-
+ // First see if we have a small number of uses, all in the same block.
+ bool UsesInOneBlock = false;
+ BasicBlock *UsersParent = nullptr;
+ int MaxUseCount = 4;
+
+ for (const Use &U : I->uses()) {
+ if (MaxUseCount <= 0) {
+ UsesInOneBlock = false;
+ break;
+ }
+ Instruction *UserInst = cast<Instruction>(U.getUser());
+ BasicBlock *CurrentUserParent;
// Get the block the use occurs in.
if (PHINode *PN = dyn_cast<PHINode>(UserInst))
- UserParent = PN->getIncomingBlock(*I->use_begin());
+ CurrentUserParent = PN->getIncomingBlock(U);
else
- UserParent = UserInst->getParent();
+ CurrentUserParent = UserInst->getParent();
+ if (UsersParent == nullptr) {
+ UsersParent = CurrentUserParent;
+ UsesInOneBlock = true;
+ } else if (CurrentUserParent != UsersParent) {
+ UsesInOneBlock = false;
+ break;
+ }
+ --MaxUseCount;
+ }
+
+ if (UsesInOneBlock) {
+ BasicBlock *BB = I->getParent();
- if (UserParent != BB) {
+ if (UsersParent != BB) {
bool UserIsSuccessor = false;
// See if the user is one of our successors.
for (succ_iterator SI = succ_begin(BB), E = succ_end(BB); SI != E; ++SI)
- if (*SI == UserParent) {
+ if (*SI == UsersParent) {
UserIsSuccessor = true;
break;
}
// If the user is one of our immediate successors, and if that successor
// only has us as a predecessors (we'd have to split the critical edge
// otherwise), we can keep going.
- if (UserIsSuccessor && UserParent->getUniquePredecessor()) {
+ if (UserIsSuccessor && UsersParent->getUniquePredecessor()) {
// Okay, the CFG is simple enough, try to sink this instruction.
- if (TryToSinkInstruction(I, UserParent)) {
+ if (TryToSinkInstruction(I, UsersParent)) {
DEBUG(dbgs() << "IC: Sink: " << *I << '\n');
MadeIRChange = true;
// We'll add uses of the sunk instruction below, but since sinking
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D33074.98537.patch
Type: text/x-patch
Size: 3859 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170510/312056a8/attachment.bin>
More information about the llvm-commits
mailing list