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