25 #define DEBUG_TYPE "spec-phis"
27 STATISTIC(NumPHIsSpeculated,
"Number of PHI nodes we speculated around");
29 "Number of critical edges which were split for speculation");
31 "Number of instructions we speculated around the PHI nodes");
33 "Number of new, redundant instructions inserted");
58 auto *UI = cast<Instruction>(U.getUser());
65 if (UI->getParent() != PhiBB) {
66 LLVM_DEBUG(
dbgs() <<
" Unsafe: use in a different BB: " << *UI <<
"\n");
70 if (
const auto *CS = dyn_cast<CallBase>(UI)) {
71 if (CS->isConvergent() || CS->cannotDuplicate()) {
73 "callsite cannot de duplicated: " << *UI <<
'\n');
85 LLVM_DEBUG(
dbgs() <<
" Unsafe: can't speculate use: " << *UI <<
"\n");
93 DFSStack.push_back({UI, UI->value_op_begin()});
98 while (OpIt != UI->value_op_end()) {
99 auto *OpI = dyn_cast<Instruction>(*OpIt);
116 auto *ParentBB = OpI->getParent();
117 if (ParentBB == PhiBB) {
118 if (isa<PHINode>(OpI)) {
122 }
else if (DT.
dominates(ParentBB, PhiBB)) {
129 if (PotentialSpecSet.
count(OpI))
134 if (UnsafeSet.
count(OpI) || ParentBB != PhiBB ||
141 for (
auto &StackPair : DFSStack) {
149 if (!Visited.
insert(OpI).second)
154 DFSStack.push_back({UI, OpIt});
156 OpIt = OpI->value_op_begin();
161 PotentialSpecSet.
insert(UI);
164 }
while (!DFSStack.empty());
170 for (
auto *
I : Visited)
172 "Failed to mark a visited instruction as safe!");
210 bool NonFreeMat =
false;
211 struct CostsAndCount {
227 auto InsertResult = CostsAndCounts.
insert({IncomingC, {}});
229 ++InsertResult.first->second.Count;
231 if (!InsertResult.second)
255 auto *UserI = cast<Instruction>(U.getUser());
258 unsigned Idx = U.getOperandNo();
273 if (UserI->isBinaryOp() && UserI->isCommutative() && Idx != 1)
279 if (
auto *UserII = dyn_cast<IntrinsicInst>(UserI))
280 IID = UserII->getIntrinsicID();
282 for (
auto &IncomingConstantAndCostsAndCount : CostsAndCounts) {
283 ConstantInt *IncomingC = IncomingConstantAndCostsAndCount.first;
284 InstructionCost MatCost = IncomingConstantAndCostsAndCount.second.MatCost;
286 IncomingConstantAndCostsAndCount.second.FoldedCost;
302 if (FoldedCost > MatCost) {
303 LLVM_DEBUG(
dbgs() <<
" Not profitable to fold imm: " << *IncomingC
305 " Materializing cost: "
308 " Accumulated folded cost: "
309 << FoldedCost <<
"\n");
317 for (
auto IncomingConstantAndCostsAndCount : CostsAndCounts) {
318 InstructionCost MatCost = IncomingConstantAndCostsAndCount.second.MatCost;
320 IncomingConstantAndCostsAndCount.second.FoldedCost;
321 int Count = IncomingConstantAndCostsAndCount.second.Count;
323 TotalMatCost += MatCost * Count;
324 TotalFoldedCost += FoldedCost * Count;
326 assert(TotalMatCost.
isValid() &&
"Constants must be materializable");
327 assert(TotalFoldedCost <= TotalMatCost &&
"If each constant's folded cost is "
328 "less that its materialized cost, "
329 "the sum must be as well.");
330 LLVM_DEBUG(
dbgs() <<
" Cost savings " << (TotalMatCost - TotalFoldedCost)
331 <<
": " << PN <<
"\n");
332 CostSavingsMap[&PN] = TotalMatCost - TotalFoldedCost;
348 template <
typename IsVisitedT,
typename VisitT>
350 IsVisitedT IsVisited,
355 auto *UI = cast<Instruction>(U.getUser());
362 DFSStack.push_back({UI, UI->value_op_begin()});
366 while (OpIt != UI->value_op_end()) {
367 auto *OpI = dyn_cast<Instruction>(*OpIt);
374 if (!OpI || IsVisited(OpI))
379 DFSStack.push_back({UI, OpIt});
381 OpIt = OpI->value_op_begin();
385 assert(!IsVisited(UI) &&
"Should not have already visited a node!");
387 }
while (!DFSStack.empty());
439 for (
auto *PN : PNs) {
440 assert(UserSet.
empty() &&
"Must start with an empty user set!");
442 UserSet.
insert(cast<Instruction>(U.getUser()));
443 PNUserCountMap[PN] = UserSet.
size();
444 for (
auto *UI : UserSet)
445 UserToPNMap.
insert({UI, {}}).first->second.push_back(PN);
461 return !PotentialSpecSet.
count(
I) || SpecCostMap.
count(
I);
468 for (
Value *OpV :
I->operand_values())
469 if (
auto *OpI = dyn_cast<Instruction>(OpV)) {
470 auto CostMapIt = SpecCostMap.
find(OpI);
471 if (CostMapIt != SpecCostMap.
end())
472 Cost += CostMapIt->second;
475 bool Inserted = SpecCostMap.
insert({
I, Cost}).second;
477 assert(Inserted &&
"Must not re-insert a cost during the DFS!");
481 auto UserPNsIt = UserToPNMap.
find(
I);
482 if (UserPNsIt == UserToPNMap.
end())
484 auto &UserPNs = UserPNsIt->second;
485 auto UserPNsSplitIt = std::stable_partition(
486 UserPNs.begin(), UserPNs.end(), [&](
PHINode *UserPN) {
487 int &PNUserCount = PNUserCountMap.find(UserPN)->second;
490 "Should never re-visit a PN after its user count hits zero!");
492 return PNUserCount != 0;
502 SpecCostMap.
find(cast<Instruction>(U.getUser()))->second;
503 SpecCost *= (NumPreds - 1);
508 if (SpecCost > CostSavings) {
514 " Speculation cost: "
515 << SpecCost <<
"\n");
521 SpecPNs.push_back(PN);
523 auto *UI = cast<Instruction>(U.getUser());
524 auto CostMapIt = SpecCostMap.
find(UI);
525 if (CostMapIt->second == 0)
528 CostMapIt->second = 0;
529 SpecWorklist.push_back(UI);
535 while (!SpecWorklist.empty()) {
537 assert(SpecCostMap.
find(SpecI)->second == 0 &&
538 "Didn't zero out a cost!");
542 auto *OpI = dyn_cast<Instruction>(OpV);
545 auto CostMapIt = SpecCostMap.
find(OpI);
546 if (CostMapIt == SpecCostMap.
end() || CostMapIt->second == 0)
548 CostMapIt->second = 0;
549 SpecWorklist.push_back(OpI);
570 NumPHIsSpeculated += SpecPNs.
size();
573 auto *ParentBB = SpecPNs[0]->getParent();
576 for (
auto *PredBB : PredSet) {
582 LLVM_DEBUG(
dbgs() <<
" Split critical edge from: " << PredBB->getName()
584 SpecPreds.push_back(NewPredBB);
586 assert(PredBB->getSingleSuccessor() == ParentBB &&
587 "We need a non-critical predecessor to speculate into.");
588 assert(!isa<InvokeInst>(PredBB->getTerminator()) &&
589 "Cannot have a non-critical invoke!");
592 SpecPreds.push_back(PredBB);
604 return !PotentialSpecSet.
count(
I) ||
612 SpecList.push_back(
I);
615 int NumSpecInsts = SpecList.size() * SpecPreds.size();
616 int NumRedundantInsts = NumSpecInsts - SpecList.size();
618 <<
" speculated instructions, " << NumRedundantInsts
619 <<
" redundancies\n");
620 NumSpeculatedInstructions += NumSpecInsts;
621 NumNewRedundantInstructions += NumRedundantInsts;
632 for (
auto *OrigI : SpecList)
633 for (
auto *OpV : OrigI->operand_values()) {
634 auto *OpPN = dyn_cast<PHINode>(OpV);
635 if (!OpPN || OpPN->getParent() != ParentBB)
638 auto InsertResult = SpeculatedValueMap.
insert({OpPN, {}});
639 if (!InsertResult.second)
642 auto &SpeculatedVals = InsertResult.first->second;
650 for (
int i : llvm::seq<int>(0, OpPN->getNumIncomingValues()))
653 for (
auto *PredBB : SpecPreds)
658 for (
int PredIdx : llvm::seq<int>(0, SpecPreds.size())) {
659 auto *PredBB = SpecPreds[PredIdx];
660 assert(PredBB->getSingleSuccessor() == ParentBB &&
661 "We need a non-critical predecessor to speculate into.");
663 for (
auto *OrigI : SpecList) {
664 auto *NewI = OrigI->clone();
665 NewI->setName(
Twine(OrigI->getName()) +
"." +
Twine(PredIdx));
666 NewI->insertBefore(PredBB->getTerminator());
671 for (
Use &U : NewI->operands()) {
672 auto *OpI = dyn_cast<Instruction>(U.get());
675 auto MapIt = SpeculatedValueMap.
find(OpI);
676 if (MapIt == SpeculatedValueMap.
end())
678 const auto &SpeculatedVals = MapIt->second;
679 assert(SpeculatedVals[PredIdx] &&
680 "Must have a speculated value for this predecessor!");
681 assert(SpeculatedVals[PredIdx]->
getType() == OpI->getType() &&
682 "Speculated value has the wrong type!");
685 U.set(SpeculatedVals[PredIdx]);
690 if (NewI->isBinaryOp() && NewI->isCommutative() &&
691 isa<Constant>(NewI->getOperand(0)) &&
692 !isa<Constant>(NewI->getOperand(1)))
693 NewI->getOperandUse(0).swap(NewI->getOperandUse(1));
695 SpeculatedValueMap[OrigI].push_back(NewI);
696 assert(SpeculatedValueMap[OrigI][PredIdx] == NewI &&
697 "Mismatched speculated instruction index!");
709 if (!OrigI->use_empty()) {
710 auto *SpecIPN = IRB.
CreatePHI(OrigI->getType(), SpecPreds.size(),
711 Twine(OrigI->getName()) +
".phi");
713 auto &SpeculatedVals = SpeculatedValueMap.
find(OrigI)->second;
714 for (
int PredIdx : llvm::seq<int>(0, SpecPreds.size()))
715 SpecIPN->addIncoming(SpeculatedVals[PredIdx], SpecPreds[PredIdx]);
718 OrigI->replaceAllUsesWith(SpecIPN);
723 OrigI->eraseFromParent();
728 for (
auto *SpecPN : SpecPNs) {
729 assert(SpecPN->use_empty() &&
"All users should have been speculated!");
730 SpecPN->eraseFromParent();
763 *PN, CostSavingsMap, PotentialSpecSet, UnsafeSet, DT,
TTI);
774 for (
auto *PredBB : PNs[0]->blocks()) {
775 if (!PredSet.
insert(PredBB))
783 const auto *TermInst = PredBB->getTerminator();
784 if (isa<IndirectBrInst>(TermInst) ||
785 isa<InvokeInst>(TermInst) ||
786 isa<CallBrInst>(TermInst)) {
788 << PredBB->getName() <<
"\n");
792 if (PredSet.
size() < 2) {
793 LLVM_DEBUG(
dbgs() <<
" Unimportant: phi with only one predecessor\n");
798 PNs, CostSavingsMap, PotentialSpecSet, PredSet.
size(), DT,
TTI);
812 bool Changed =
false;
815 auto BBI =
BB->begin();
816 while (
auto *PN = dyn_cast<PHINode>(&*BBI)) {