xref: /freebsd-src/contrib/llvm-project/llvm/lib/Analysis/PHITransAddr.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- PHITransAddr.cpp - PHI Translation for Addresses -------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the PHITransAddr class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm/Analysis/PHITransAddr.h"
140b57cec5SDimitry Andric #include "llvm/Analysis/InstructionSimplify.h"
150b57cec5SDimitry Andric #include "llvm/Analysis/ValueTracking.h"
160b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
170b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
180b57cec5SDimitry Andric #include "llvm/IR/Dominators.h"
190b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
20*0fca6ea1SDimitry Andric #include "llvm/Support/CommandLine.h"
210b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
220b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
230b57cec5SDimitry Andric using namespace llvm;
240b57cec5SDimitry Andric 
25972a253aSDimitry Andric static cl::opt<bool> EnableAddPhiTranslation(
26972a253aSDimitry Andric     "gvn-add-phi-translation", cl::init(false), cl::Hidden,
27972a253aSDimitry Andric     cl::desc("Enable phi-translation of add instructions"));
28972a253aSDimitry Andric 
2906c3fb27SDimitry Andric static bool canPHITrans(Instruction *Inst) {
3006c3fb27SDimitry Andric   if (isa<PHINode>(Inst) || isa<GetElementPtrInst>(Inst) || isa<CastInst>(Inst))
310b57cec5SDimitry Andric     return true;
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric   if (Inst->getOpcode() == Instruction::Add &&
340b57cec5SDimitry Andric       isa<ConstantInt>(Inst->getOperand(1)))
350b57cec5SDimitry Andric     return true;
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric   return false;
380b57cec5SDimitry Andric }
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
410b57cec5SDimitry Andric LLVM_DUMP_METHOD void PHITransAddr::dump() const {
420b57cec5SDimitry Andric   if (!Addr) {
430b57cec5SDimitry Andric     dbgs() << "PHITransAddr: null\n";
440b57cec5SDimitry Andric     return;
450b57cec5SDimitry Andric   }
460b57cec5SDimitry Andric   dbgs() << "PHITransAddr: " << *Addr << "\n";
470b57cec5SDimitry Andric   for (unsigned i = 0, e = InstInputs.size(); i != e; ++i)
480b57cec5SDimitry Andric     dbgs() << "  Input #" << i << " is " << *InstInputs[i] << "\n";
490b57cec5SDimitry Andric }
500b57cec5SDimitry Andric #endif
510b57cec5SDimitry Andric 
5206c3fb27SDimitry Andric static bool verifySubExpr(Value *Expr,
530b57cec5SDimitry Andric                           SmallVectorImpl<Instruction *> &InstInputs) {
540b57cec5SDimitry Andric   // If this is a non-instruction value, there is nothing to do.
550b57cec5SDimitry Andric   Instruction *I = dyn_cast<Instruction>(Expr);
560b57cec5SDimitry Andric   if (!I) return true;
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric   // If it's an instruction, it is either in Tmp or its operands recursively
590b57cec5SDimitry Andric   // are.
6006c3fb27SDimitry Andric   if (auto Entry = find(InstInputs, I); Entry != InstInputs.end()) {
610b57cec5SDimitry Andric     InstInputs.erase(Entry);
620b57cec5SDimitry Andric     return true;
630b57cec5SDimitry Andric   }
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric   // If it isn't in the InstInputs list it is a subexpr incorporated into the
664824e7fdSDimitry Andric   // address.  Validate that it is phi translatable.
6706c3fb27SDimitry Andric   if (!canPHITrans(I)) {
680b57cec5SDimitry Andric     errs() << "Instruction in PHITransAddr is not phi-translatable:\n";
690b57cec5SDimitry Andric     errs() << *I << '\n';
700b57cec5SDimitry Andric     llvm_unreachable("Either something is missing from InstInputs or "
7106c3fb27SDimitry Andric                      "canPHITrans is wrong.");
720b57cec5SDimitry Andric   }
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric   // Validate the operands of the instruction.
7506c3fb27SDimitry Andric   return all_of(I->operands(),
7606c3fb27SDimitry Andric                 [&](Value *Op) { return verifySubExpr(Op, InstInputs); });
770b57cec5SDimitry Andric }
780b57cec5SDimitry Andric 
7906c3fb27SDimitry Andric /// verify - Check internal consistency of this data structure.  If the
800b57cec5SDimitry Andric /// structure is valid, it returns true.  If invalid, it prints errors and
810b57cec5SDimitry Andric /// returns false.
8206c3fb27SDimitry Andric bool PHITransAddr::verify() const {
830b57cec5SDimitry Andric   if (!Addr) return true;
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   SmallVector<Instruction*, 8> Tmp(InstInputs.begin(), InstInputs.end());
860b57cec5SDimitry Andric 
8706c3fb27SDimitry Andric   if (!verifySubExpr(Addr, Tmp))
880b57cec5SDimitry Andric     return false;
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric   if (!Tmp.empty()) {
910b57cec5SDimitry Andric     errs() << "PHITransAddr contains extra instructions:\n";
920b57cec5SDimitry Andric     for (unsigned i = 0, e = InstInputs.size(); i != e; ++i)
930b57cec5SDimitry Andric       errs() << "  InstInput #" << i << " is " << *InstInputs[i] << "\n";
940b57cec5SDimitry Andric     llvm_unreachable("This is unexpected.");
950b57cec5SDimitry Andric   }
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric   // a-ok.
980b57cec5SDimitry Andric   return true;
990b57cec5SDimitry Andric }
1000b57cec5SDimitry Andric 
10106c3fb27SDimitry Andric /// isPotentiallyPHITranslatable - If this needs PHI translation, return true
1020b57cec5SDimitry Andric /// if we have some hope of doing it.  This should be used as a filter to
1030b57cec5SDimitry Andric /// avoid calling PHITranslateValue in hopeless situations.
10406c3fb27SDimitry Andric bool PHITransAddr::isPotentiallyPHITranslatable() const {
1050b57cec5SDimitry Andric   // If the input value is not an instruction, or if it is not defined in CurBB,
1060b57cec5SDimitry Andric   // then we don't need to phi translate it.
1070b57cec5SDimitry Andric   Instruction *Inst = dyn_cast<Instruction>(Addr);
10806c3fb27SDimitry Andric   return !Inst || canPHITrans(Inst);
1090b57cec5SDimitry Andric }
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric static void RemoveInstInputs(Value *V,
1120b57cec5SDimitry Andric                              SmallVectorImpl<Instruction*> &InstInputs) {
1130b57cec5SDimitry Andric   Instruction *I = dyn_cast<Instruction>(V);
1140b57cec5SDimitry Andric   if (!I) return;
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric   // If the instruction is in the InstInputs list, remove it.
11706c3fb27SDimitry Andric   if (auto Entry = find(InstInputs, I); Entry != InstInputs.end()) {
1180b57cec5SDimitry Andric     InstInputs.erase(Entry);
1190b57cec5SDimitry Andric     return;
1200b57cec5SDimitry Andric   }
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   assert(!isa<PHINode>(I) && "Error, removing something that isn't an input");
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric   // Otherwise, it must have instruction inputs itself.  Zap them recursively.
12506c3fb27SDimitry Andric   for (Value *Op : I->operands())
12606c3fb27SDimitry Andric     if (Instruction *OpInst = dyn_cast<Instruction>(Op))
12706c3fb27SDimitry Andric       RemoveInstInputs(OpInst, InstInputs);
1280b57cec5SDimitry Andric }
1290b57cec5SDimitry Andric 
13006c3fb27SDimitry Andric Value *PHITransAddr::translateSubExpr(Value *V, BasicBlock *CurBB,
1310b57cec5SDimitry Andric                                       BasicBlock *PredBB,
1320b57cec5SDimitry Andric                                       const DominatorTree *DT) {
1330b57cec5SDimitry Andric   // If this is a non-instruction value, it can't require PHI translation.
1340b57cec5SDimitry Andric   Instruction *Inst = dyn_cast<Instruction>(V);
1350b57cec5SDimitry Andric   if (!Inst) return V;
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   // Determine whether 'Inst' is an input to our PHI translatable expression.
1380b57cec5SDimitry Andric   bool isInput = is_contained(InstInputs, Inst);
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric   // Handle inputs instructions if needed.
1410b57cec5SDimitry Andric   if (isInput) {
1420b57cec5SDimitry Andric     if (Inst->getParent() != CurBB) {
1430b57cec5SDimitry Andric       // If it is an input defined in a different block, then it remains an
1440b57cec5SDimitry Andric       // input.
1450b57cec5SDimitry Andric       return Inst;
1460b57cec5SDimitry Andric     }
1470b57cec5SDimitry Andric 
1480b57cec5SDimitry Andric     // If 'Inst' is defined in this block and is an input that needs to be phi
1490b57cec5SDimitry Andric     // translated, we need to incorporate the value into the expression or fail.
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric     // In either case, the instruction itself isn't an input any longer.
1520b57cec5SDimitry Andric     InstInputs.erase(find(InstInputs, Inst));
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric     // If this is a PHI, go ahead and translate it.
1550b57cec5SDimitry Andric     if (PHINode *PN = dyn_cast<PHINode>(Inst))
15606c3fb27SDimitry Andric       return addAsInput(PN->getIncomingValueForBlock(PredBB));
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric     // If this is a non-phi value, and it is analyzable, we can incorporate it
1590b57cec5SDimitry Andric     // into the expression by making all instruction operands be inputs.
16006c3fb27SDimitry Andric     if (!canPHITrans(Inst))
1610b57cec5SDimitry Andric       return nullptr;
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric     // All instruction operands are now inputs (and of course, they may also be
1640b57cec5SDimitry Andric     // defined in this block, so they may need to be phi translated themselves.
16506c3fb27SDimitry Andric     for (Value *Op : Inst->operands())
16606c3fb27SDimitry Andric       addAsInput(Op);
1670b57cec5SDimitry Andric   }
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric   // Ok, it must be an intermediate result (either because it started that way
1700b57cec5SDimitry Andric   // or because we just incorporated it into the expression).  See if its
1710b57cec5SDimitry Andric   // operands need to be phi translated, and if so, reconstruct it.
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric   if (CastInst *Cast = dyn_cast<CastInst>(Inst)) {
17406c3fb27SDimitry Andric     Value *PHIIn = translateSubExpr(Cast->getOperand(0), CurBB, PredBB, DT);
1750b57cec5SDimitry Andric     if (!PHIIn) return nullptr;
1760b57cec5SDimitry Andric     if (PHIIn == Cast->getOperand(0))
1770b57cec5SDimitry Andric       return Cast;
1780b57cec5SDimitry Andric 
1790b57cec5SDimitry Andric     // Find an available version of this cast.
1800b57cec5SDimitry Andric 
18106c3fb27SDimitry Andric     // Try to simplify cast first.
18206c3fb27SDimitry Andric     if (Value *V = simplifyCastInst(Cast->getOpcode(), PHIIn, Cast->getType(),
18306c3fb27SDimitry Andric                                     {DL, TLI, DT, AC})) {
18406c3fb27SDimitry Andric       RemoveInstInputs(PHIIn, InstInputs);
18506c3fb27SDimitry Andric       return addAsInput(V);
18606c3fb27SDimitry Andric     }
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric     // Otherwise we have to see if a casted version of the incoming pointer
1890b57cec5SDimitry Andric     // is available.  If so, we can use it, otherwise we have to fail.
1900b57cec5SDimitry Andric     for (User *U : PHIIn->users()) {
1910b57cec5SDimitry Andric       if (CastInst *CastI = dyn_cast<CastInst>(U))
1920b57cec5SDimitry Andric         if (CastI->getOpcode() == Cast->getOpcode() &&
1930b57cec5SDimitry Andric             CastI->getType() == Cast->getType() &&
1940b57cec5SDimitry Andric             (!DT || DT->dominates(CastI->getParent(), PredBB)))
1950b57cec5SDimitry Andric           return CastI;
1960b57cec5SDimitry Andric     }
1970b57cec5SDimitry Andric     return nullptr;
1980b57cec5SDimitry Andric   }
1990b57cec5SDimitry Andric 
2000b57cec5SDimitry Andric   // Handle getelementptr with at least one PHI translatable operand.
2010b57cec5SDimitry Andric   if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
2020b57cec5SDimitry Andric     SmallVector<Value*, 8> GEPOps;
2030b57cec5SDimitry Andric     bool AnyChanged = false;
20406c3fb27SDimitry Andric     for (Value *Op : GEP->operands()) {
20506c3fb27SDimitry Andric       Value *GEPOp = translateSubExpr(Op, CurBB, PredBB, DT);
2060b57cec5SDimitry Andric       if (!GEPOp) return nullptr;
2070b57cec5SDimitry Andric 
20806c3fb27SDimitry Andric       AnyChanged |= GEPOp != Op;
2090b57cec5SDimitry Andric       GEPOps.push_back(GEPOp);
2100b57cec5SDimitry Andric     }
2110b57cec5SDimitry Andric 
2120b57cec5SDimitry Andric     if (!AnyChanged)
2130b57cec5SDimitry Andric       return GEP;
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric     // Simplify the GEP to handle 'gep x, 0' -> x etc.
21681ad6265SDimitry Andric     if (Value *V = simplifyGEPInst(GEP->getSourceElementType(), GEPOps[0],
21704eeddc0SDimitry Andric                                    ArrayRef<Value *>(GEPOps).slice(1),
218*0fca6ea1SDimitry Andric                                    GEP->getNoWrapFlags(), {DL, TLI, DT, AC})) {
219*0fca6ea1SDimitry Andric       for (Value *Op : GEPOps)
220*0fca6ea1SDimitry Andric         RemoveInstInputs(Op, InstInputs);
2210b57cec5SDimitry Andric 
22206c3fb27SDimitry Andric       return addAsInput(V);
2230b57cec5SDimitry Andric     }
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric     // Scan to see if we have this GEP available.
2260b57cec5SDimitry Andric     Value *APHIOp = GEPOps[0];
2270b57cec5SDimitry Andric     for (User *U : APHIOp->users()) {
2280b57cec5SDimitry Andric       if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(U))
2290b57cec5SDimitry Andric         if (GEPI->getType() == GEP->getType() &&
23081ad6265SDimitry Andric             GEPI->getSourceElementType() == GEP->getSourceElementType() &&
2310b57cec5SDimitry Andric             GEPI->getNumOperands() == GEPOps.size() &&
2320b57cec5SDimitry Andric             GEPI->getParent()->getParent() == CurBB->getParent() &&
2330b57cec5SDimitry Andric             (!DT || DT->dominates(GEPI->getParent(), PredBB))) {
2340b57cec5SDimitry Andric           if (std::equal(GEPOps.begin(), GEPOps.end(), GEPI->op_begin()))
2350b57cec5SDimitry Andric             return GEPI;
2360b57cec5SDimitry Andric         }
2370b57cec5SDimitry Andric     }
2380b57cec5SDimitry Andric     return nullptr;
2390b57cec5SDimitry Andric   }
2400b57cec5SDimitry Andric 
2410b57cec5SDimitry Andric   // Handle add with a constant RHS.
2420b57cec5SDimitry Andric   if (Inst->getOpcode() == Instruction::Add &&
2430b57cec5SDimitry Andric       isa<ConstantInt>(Inst->getOperand(1))) {
2440b57cec5SDimitry Andric     // PHI translate the LHS.
2450b57cec5SDimitry Andric     Constant *RHS = cast<ConstantInt>(Inst->getOperand(1));
2460b57cec5SDimitry Andric     bool isNSW = cast<BinaryOperator>(Inst)->hasNoSignedWrap();
2470b57cec5SDimitry Andric     bool isNUW = cast<BinaryOperator>(Inst)->hasNoUnsignedWrap();
2480b57cec5SDimitry Andric 
24906c3fb27SDimitry Andric     Value *LHS = translateSubExpr(Inst->getOperand(0), CurBB, PredBB, DT);
2500b57cec5SDimitry Andric     if (!LHS) return nullptr;
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric     // If the PHI translated LHS is an add of a constant, fold the immediates.
2530b57cec5SDimitry Andric     if (BinaryOperator *BOp = dyn_cast<BinaryOperator>(LHS))
2540b57cec5SDimitry Andric       if (BOp->getOpcode() == Instruction::Add)
2550b57cec5SDimitry Andric         if (ConstantInt *CI = dyn_cast<ConstantInt>(BOp->getOperand(1))) {
2560b57cec5SDimitry Andric           LHS = BOp->getOperand(0);
2570b57cec5SDimitry Andric           RHS = ConstantExpr::getAdd(RHS, CI);
2580b57cec5SDimitry Andric           isNSW = isNUW = false;
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric           // If the old 'LHS' was an input, add the new 'LHS' as an input.
2610b57cec5SDimitry Andric           if (is_contained(InstInputs, BOp)) {
2620b57cec5SDimitry Andric             RemoveInstInputs(BOp, InstInputs);
26306c3fb27SDimitry Andric             addAsInput(LHS);
2640b57cec5SDimitry Andric           }
2650b57cec5SDimitry Andric         }
2660b57cec5SDimitry Andric 
2670b57cec5SDimitry Andric     // See if the add simplifies away.
26881ad6265SDimitry Andric     if (Value *Res = simplifyAddInst(LHS, RHS, isNSW, isNUW, {DL, TLI, DT, AC})) {
2690b57cec5SDimitry Andric       // If we simplified the operands, the LHS is no longer an input, but Res
2700b57cec5SDimitry Andric       // is.
2710b57cec5SDimitry Andric       RemoveInstInputs(LHS, InstInputs);
27206c3fb27SDimitry Andric       return addAsInput(Res);
2730b57cec5SDimitry Andric     }
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric     // If we didn't modify the add, just return it.
2760b57cec5SDimitry Andric     if (LHS == Inst->getOperand(0) && RHS == Inst->getOperand(1))
2770b57cec5SDimitry Andric       return Inst;
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric     // Otherwise, see if we have this add available somewhere.
2800b57cec5SDimitry Andric     for (User *U : LHS->users()) {
2810b57cec5SDimitry Andric       if (BinaryOperator *BO = dyn_cast<BinaryOperator>(U))
2820b57cec5SDimitry Andric         if (BO->getOpcode() == Instruction::Add &&
2830b57cec5SDimitry Andric             BO->getOperand(0) == LHS && BO->getOperand(1) == RHS &&
2840b57cec5SDimitry Andric             BO->getParent()->getParent() == CurBB->getParent() &&
2850b57cec5SDimitry Andric             (!DT || DT->dominates(BO->getParent(), PredBB)))
2860b57cec5SDimitry Andric           return BO;
2870b57cec5SDimitry Andric     }
2880b57cec5SDimitry Andric 
2890b57cec5SDimitry Andric     return nullptr;
2900b57cec5SDimitry Andric   }
2910b57cec5SDimitry Andric 
2920b57cec5SDimitry Andric   // Otherwise, we failed.
2930b57cec5SDimitry Andric   return nullptr;
2940b57cec5SDimitry Andric }
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric /// PHITranslateValue - PHI translate the current address up the CFG from
2970b57cec5SDimitry Andric /// CurBB to Pred, updating our state to reflect any needed changes.  If
29806c3fb27SDimitry Andric /// 'MustDominate' is true, the translated value must dominate PredBB.
29906c3fb27SDimitry Andric Value *PHITransAddr::translateValue(BasicBlock *CurBB, BasicBlock *PredBB,
3000b57cec5SDimitry Andric                                     const DominatorTree *DT,
3010b57cec5SDimitry Andric                                     bool MustDominate) {
3020b57cec5SDimitry Andric   assert(DT || !MustDominate);
30306c3fb27SDimitry Andric   assert(verify() && "Invalid PHITransAddr!");
3040b57cec5SDimitry Andric   if (DT && DT->isReachableFromEntry(PredBB))
30506c3fb27SDimitry Andric     Addr = translateSubExpr(Addr, CurBB, PredBB, DT);
3060b57cec5SDimitry Andric   else
3070b57cec5SDimitry Andric     Addr = nullptr;
30806c3fb27SDimitry Andric   assert(verify() && "Invalid PHITransAddr!");
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric   if (MustDominate)
3110b57cec5SDimitry Andric     // Make sure the value is live in the predecessor.
3120b57cec5SDimitry Andric     if (Instruction *Inst = dyn_cast_or_null<Instruction>(Addr))
3130b57cec5SDimitry Andric       if (!DT->dominates(Inst->getParent(), PredBB))
3140b57cec5SDimitry Andric         Addr = nullptr;
3150b57cec5SDimitry Andric 
31606c3fb27SDimitry Andric   return Addr;
3170b57cec5SDimitry Andric }
3180b57cec5SDimitry Andric 
3190b57cec5SDimitry Andric /// PHITranslateWithInsertion - PHI translate this value into the specified
3200b57cec5SDimitry Andric /// predecessor block, inserting a computation of the value if it is
3210b57cec5SDimitry Andric /// unavailable.
3220b57cec5SDimitry Andric ///
3230b57cec5SDimitry Andric /// All newly created instructions are added to the NewInsts list.  This
3240b57cec5SDimitry Andric /// returns null on failure.
3250b57cec5SDimitry Andric ///
32606c3fb27SDimitry Andric Value *
32706c3fb27SDimitry Andric PHITransAddr::translateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB,
3280b57cec5SDimitry Andric                                      const DominatorTree &DT,
3290b57cec5SDimitry Andric                                      SmallVectorImpl<Instruction *> &NewInsts) {
3300b57cec5SDimitry Andric   unsigned NISize = NewInsts.size();
3310b57cec5SDimitry Andric 
3320b57cec5SDimitry Andric   // Attempt to PHI translate with insertion.
33306c3fb27SDimitry Andric   Addr = insertTranslatedSubExpr(Addr, CurBB, PredBB, DT, NewInsts);
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric   // If successful, return the new value.
3360b57cec5SDimitry Andric   if (Addr) return Addr;
3370b57cec5SDimitry Andric 
3380b57cec5SDimitry Andric   // If not, destroy any intermediate instructions inserted.
3390b57cec5SDimitry Andric   while (NewInsts.size() != NISize)
3400b57cec5SDimitry Andric     NewInsts.pop_back_val()->eraseFromParent();
3410b57cec5SDimitry Andric   return nullptr;
3420b57cec5SDimitry Andric }
3430b57cec5SDimitry Andric 
34406c3fb27SDimitry Andric /// insertTranslatedSubExpr - Insert a computation of the PHI translated
3450b57cec5SDimitry Andric /// version of 'V' for the edge PredBB->CurBB into the end of the PredBB
3460b57cec5SDimitry Andric /// block.  All newly created instructions are added to the NewInsts list.
3470b57cec5SDimitry Andric /// This returns null on failure.
3480b57cec5SDimitry Andric ///
34906c3fb27SDimitry Andric Value *PHITransAddr::insertTranslatedSubExpr(
35006c3fb27SDimitry Andric     Value *InVal, BasicBlock *CurBB, BasicBlock *PredBB,
35106c3fb27SDimitry Andric     const DominatorTree &DT, SmallVectorImpl<Instruction *> &NewInsts) {
3520b57cec5SDimitry Andric   // See if we have a version of this value already available and dominating
3530b57cec5SDimitry Andric   // PredBB.  If so, there is no need to insert a new instance of it.
3540b57cec5SDimitry Andric   PHITransAddr Tmp(InVal, DL, AC);
35506c3fb27SDimitry Andric   if (Value *Addr =
35606c3fb27SDimitry Andric           Tmp.translateValue(CurBB, PredBB, &DT, /*MustDominate=*/true))
35706c3fb27SDimitry Andric     return Addr;
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric   // We don't need to PHI translate values which aren't instructions.
3600b57cec5SDimitry Andric   auto *Inst = dyn_cast<Instruction>(InVal);
3610b57cec5SDimitry Andric   if (!Inst)
3620b57cec5SDimitry Andric     return nullptr;
3630b57cec5SDimitry Andric 
3640b57cec5SDimitry Andric   // Handle cast of PHI translatable value.
3650b57cec5SDimitry Andric   if (CastInst *Cast = dyn_cast<CastInst>(Inst)) {
36606c3fb27SDimitry Andric     Value *OpVal = insertTranslatedSubExpr(Cast->getOperand(0), CurBB, PredBB,
36706c3fb27SDimitry Andric                                            DT, NewInsts);
3680b57cec5SDimitry Andric     if (!OpVal) return nullptr;
3690b57cec5SDimitry Andric 
3700b57cec5SDimitry Andric     // Otherwise insert a cast at the end of PredBB.
3710b57cec5SDimitry Andric     CastInst *New = CastInst::Create(Cast->getOpcode(), OpVal, InVal->getType(),
3720b57cec5SDimitry Andric                                      InVal->getName() + ".phi.trans.insert",
373*0fca6ea1SDimitry Andric                                      PredBB->getTerminator()->getIterator());
3740b57cec5SDimitry Andric     New->setDebugLoc(Inst->getDebugLoc());
3750b57cec5SDimitry Andric     NewInsts.push_back(New);
3760b57cec5SDimitry Andric     return New;
3770b57cec5SDimitry Andric   }
3780b57cec5SDimitry Andric 
3790b57cec5SDimitry Andric   // Handle getelementptr with at least one PHI operand.
3800b57cec5SDimitry Andric   if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
3810b57cec5SDimitry Andric     SmallVector<Value*, 8> GEPOps;
3820b57cec5SDimitry Andric     BasicBlock *CurBB = GEP->getParent();
38306c3fb27SDimitry Andric     for (Value *Op : GEP->operands()) {
38406c3fb27SDimitry Andric       Value *OpVal = insertTranslatedSubExpr(Op, CurBB, PredBB, DT, NewInsts);
3850b57cec5SDimitry Andric       if (!OpVal) return nullptr;
3860b57cec5SDimitry Andric       GEPOps.push_back(OpVal);
3870b57cec5SDimitry Andric     }
3880b57cec5SDimitry Andric 
3890b57cec5SDimitry Andric     GetElementPtrInst *Result = GetElementPtrInst::Create(
390bdd1243dSDimitry Andric         GEP->getSourceElementType(), GEPOps[0], ArrayRef(GEPOps).slice(1),
391*0fca6ea1SDimitry Andric         InVal->getName() + ".phi.trans.insert",
392*0fca6ea1SDimitry Andric         PredBB->getTerminator()->getIterator());
3930b57cec5SDimitry Andric     Result->setDebugLoc(Inst->getDebugLoc());
394*0fca6ea1SDimitry Andric     Result->setNoWrapFlags(GEP->getNoWrapFlags());
3950b57cec5SDimitry Andric     NewInsts.push_back(Result);
3960b57cec5SDimitry Andric     return Result;
3970b57cec5SDimitry Andric   }
3980b57cec5SDimitry Andric 
399972a253aSDimitry Andric   // Handle add with a constant RHS.
400972a253aSDimitry Andric   if (EnableAddPhiTranslation && Inst->getOpcode() == Instruction::Add &&
401972a253aSDimitry Andric       isa<ConstantInt>(Inst->getOperand(1))) {
402972a253aSDimitry Andric 
4030b57cec5SDimitry Andric     // FIXME: This code works, but it is unclear that we actually want to insert
4040b57cec5SDimitry Andric     // a big chain of computation in order to make a value available in a block.
4050b57cec5SDimitry Andric     // This needs to be evaluated carefully to consider its cost trade offs.
4060b57cec5SDimitry Andric 
4070b57cec5SDimitry Andric     // PHI translate the LHS.
40806c3fb27SDimitry Andric     Value *OpVal = insertTranslatedSubExpr(Inst->getOperand(0), CurBB, PredBB,
40906c3fb27SDimitry Andric                                            DT, NewInsts);
410bdd1243dSDimitry Andric     if (OpVal == nullptr)
411bdd1243dSDimitry Andric       return nullptr;
4120b57cec5SDimitry Andric 
413*0fca6ea1SDimitry Andric     BinaryOperator *Res = BinaryOperator::CreateAdd(
414*0fca6ea1SDimitry Andric         OpVal, Inst->getOperand(1), InVal->getName() + ".phi.trans.insert",
415*0fca6ea1SDimitry Andric         PredBB->getTerminator()->getIterator());
4160b57cec5SDimitry Andric     Res->setHasNoSignedWrap(cast<BinaryOperator>(Inst)->hasNoSignedWrap());
4170b57cec5SDimitry Andric     Res->setHasNoUnsignedWrap(cast<BinaryOperator>(Inst)->hasNoUnsignedWrap());
4180b57cec5SDimitry Andric     NewInsts.push_back(Res);
4190b57cec5SDimitry Andric     return Res;
4200b57cec5SDimitry Andric   }
4210b57cec5SDimitry Andric 
4220b57cec5SDimitry Andric   return nullptr;
4230b57cec5SDimitry Andric }
424