@@ -1932,7 +1932,7 @@ static bool replacingOperandWithVariableIsCheap(const Instruction *I,
1932
1932
// PHI node (because an operand varies in each input block), add to PHIOperands.
1933
1933
static bool canSinkInstructions (
1934
1934
ArrayRef<Instruction *> Insts,
1935
- DenseMap<Instruction *, SmallVector<Value *, 4 >> &PHIOperands) {
1935
+ DenseMap<const Use *, SmallVector<Value *, 4 >> &PHIOperands) {
1936
1936
// Prune out obviously bad instructions to move. Each instruction must have
1937
1937
// exactly zero or one use, and we check later that use is by a single, common
1938
1938
// PHI instruction in the successor.
@@ -1983,20 +1983,17 @@ static bool canSinkInstructions(
1983
1983
return false ;
1984
1984
}
1985
1985
1986
- // All instructions in Insts are known to be the same opcode. If they have a
1987
- // use, check that the only user is a PHI or in the same block as the
1988
- // instruction, because if a user is in the same block as an instruction we're
1989
- // contemplating sinking, it must already be determined to be sinkable .
1986
+ // Uses must be consistent: If I0 is used in a phi node in the sink target,
1987
+ // then the other phi operands must match the instructions from Insts. This
1988
+ // also has to hold true for any phi nodes that would be created as a result
1989
+ // of sinking. Both of these cases are represented by PhiOperands .
1990
1990
if (HasUse) {
1991
- auto *PNUse = dyn_cast<PHINode>(*I0->user_begin ());
1992
- auto *Succ = I0->getParent ()->getTerminator ()->getSuccessor (0 );
1993
- if (!all_of (Insts, [&PNUse,&Succ](const Instruction *I) -> bool {
1994
- auto *U = cast<Instruction>(*I->user_begin ());
1995
- return (PNUse &&
1996
- PNUse->getParent () == Succ &&
1997
- PNUse->getIncomingValueForBlock (I->getParent ()) == I) ||
1998
- U->getParent () == I->getParent ();
1999
- }))
1991
+ const Use &U = *I0->use_begin ();
1992
+ auto It = PHIOperands.find (&U);
1993
+ if (It == PHIOperands.end ())
1994
+ // There may be uses in other blocks when sinking into a loop header.
1995
+ return false ;
1996
+ if (!equal (Insts, It->second ))
2000
1997
return false ;
2001
1998
}
2002
1999
@@ -2063,8 +2060,9 @@ static bool canSinkInstructions(
2063
2060
!canReplaceOperandWithVariable (I0, OI))
2064
2061
// We can't create a PHI from this GEP.
2065
2062
return false ;
2063
+ auto &Ops = PHIOperands[&I0->getOperandUse (OI)];
2066
2064
for (auto *I : Insts)
2067
- PHIOperands[I] .push_back (I->getOperand (OI));
2065
+ Ops .push_back (I->getOperand (OI));
2068
2066
}
2069
2067
}
2070
2068
return true ;
@@ -2073,7 +2071,7 @@ static bool canSinkInstructions(
2073
2071
// Assuming canSinkInstructions(Blocks) has returned true, sink the last
2074
2072
// instruction of every block in Blocks to their common successor, commoning
2075
2073
// into one instruction.
2076
- static bool sinkLastInstruction (ArrayRef<BasicBlock*> Blocks) {
2074
+ static void sinkLastInstruction (ArrayRef<BasicBlock*> Blocks) {
2077
2075
auto *BBEnd = Blocks[0 ]->getTerminator ()->getSuccessor (0 );
2078
2076
2079
2077
// canSinkInstructions returning true guarantees that every block has at
@@ -2088,23 +2086,10 @@ static bool sinkLastInstruction(ArrayRef<BasicBlock*> Blocks) {
2088
2086
Insts.push_back (I);
2089
2087
}
2090
2088
2091
- // The only checking we need to do now is that all users of all instructions
2092
- // are the same PHI node. canSinkInstructions should have checked this but
2093
- // it is slightly over-aggressive - it gets confused by commutative
2094
- // instructions so double-check it here.
2095
- Instruction *I0 = Insts.front ();
2096
- if (!I0->user_empty ()) {
2097
- auto *PNUse = dyn_cast<PHINode>(*I0->user_begin ());
2098
- if (!all_of (Insts, [&PNUse](const Instruction *I) -> bool {
2099
- auto *U = cast<Instruction>(*I->user_begin ());
2100
- return U == PNUse;
2101
- }))
2102
- return false ;
2103
- }
2104
-
2105
2089
// We don't need to do any more checking here; canSinkInstructions should
2106
2090
// have done it all for us.
2107
2091
SmallVector<Value*, 4 > NewOperands;
2092
+ Instruction *I0 = Insts.front ();
2108
2093
for (unsigned O = 0 , E = I0->getNumOperands (); O != E; ++O) {
2109
2094
// This check is different to that in canSinkInstructions. There, we
2110
2095
// cared about the global view once simplifycfg (and instcombine) have
@@ -2172,8 +2157,6 @@ static bool sinkLastInstruction(ArrayRef<BasicBlock*> Blocks) {
2172
2157
I->replaceAllUsesWith (I0);
2173
2158
I->eraseFromParent ();
2174
2159
}
2175
-
2176
- return true ;
2177
2160
}
2178
2161
2179
2162
namespace {
@@ -2314,9 +2297,19 @@ static bool SinkCommonCodeFromPredecessors(BasicBlock *BB,
2314
2297
// carry on. If we can sink an instruction but need to PHI-merge some operands
2315
2298
// (because they're not identical in each instruction) we add these to
2316
2299
// PHIOperands.
2300
+ // We prepopulate PHIOperands with the phis that already exist in BB.
2301
+ DenseMap<const Use *, SmallVector<Value *, 4 >> PHIOperands;
2302
+ for (PHINode &PN : BB->phis ()) {
2303
+ SmallDenseMap<BasicBlock *, const Use *, 4 > IncomingVals;
2304
+ for (const Use &U : PN.incoming_values ())
2305
+ IncomingVals.insert ({PN.getIncomingBlock (U), &U});
2306
+ auto &Ops = PHIOperands[IncomingVals[UnconditionalPreds[0 ]]];
2307
+ for (BasicBlock *Pred : UnconditionalPreds)
2308
+ Ops.push_back (*IncomingVals[Pred]);
2309
+ }
2310
+
2317
2311
int ScanIdx = 0 ;
2318
2312
SmallPtrSet<Value*,4 > InstructionsToSink;
2319
- DenseMap<Instruction*, SmallVector<Value*,4 >> PHIOperands;
2320
2313
LockstepReverseIterator LRI (UnconditionalPreds);
2321
2314
while (LRI.isValid () &&
2322
2315
canSinkInstructions (*LRI, PHIOperands)) {
@@ -2338,20 +2331,19 @@ static bool SinkCommonCodeFromPredecessors(BasicBlock *BB,
2338
2331
// actually sink before encountering instruction that is unprofitable to
2339
2332
// sink?
2340
2333
auto ProfitableToSinkInstruction = [&](LockstepReverseIterator &LRI) {
2341
- unsigned NumPHIdValues = 0 ;
2342
- for (auto *I : *LRI)
2343
- for (auto *V : PHIOperands[I]) {
2344
- if (!InstructionsToSink.contains (V))
2345
- ++NumPHIdValues;
2334
+ unsigned NumPHIInsts = 0 ;
2335
+ for (Use &U : (*LRI)[0 ]->operands ()) {
2336
+ auto It = PHIOperands.find (&U);
2337
+ if (It != PHIOperands.end () && !all_of (It->second , [&](Value *V) {
2338
+ return InstructionsToSink.contains (V);
2339
+ })) {
2340
+ ++NumPHIInsts;
2346
2341
// FIXME: this check is overly optimistic. We may end up not sinking
2347
2342
// said instruction, due to the very same profitability check.
2348
2343
// See @creating_too_many_phis in sink-common-code.ll.
2349
2344
}
2350
- LLVM_DEBUG (dbgs () << " SINK: #phid values: " << NumPHIdValues << " \n " );
2351
- unsigned NumPHIInsts = NumPHIdValues / UnconditionalPreds.size ();
2352
- if ((NumPHIdValues % UnconditionalPreds.size ()) != 0 )
2353
- NumPHIInsts++;
2354
-
2345
+ }
2346
+ LLVM_DEBUG (dbgs () << " SINK: #phi insts: " << NumPHIInsts << " \n " );
2355
2347
return NumPHIInsts <= 1 ;
2356
2348
};
2357
2349
@@ -2476,13 +2468,7 @@ static bool SinkCommonCodeFromPredecessors(BasicBlock *BB,
2476
2468
// sink is always at index 0.
2477
2469
LRI.reset ();
2478
2470
2479
- if (!sinkLastInstruction (UnconditionalPreds)) {
2480
- LLVM_DEBUG (
2481
- dbgs ()
2482
- << " SINK: stopping here, failed to actually sink instruction!\n " );
2483
- break ;
2484
- }
2485
-
2471
+ sinkLastInstruction (UnconditionalPreds);
2486
2472
NumSinkCommonInstrs++;
2487
2473
Changed = true ;
2488
2474
}
0 commit comments