16#include "llvm/Config/llvm-config.h"
27 cl::desc(
"Enable phi-translation of add instructions"));
33 if (Inst->
getOpcode() == Instruction::Add &&
40#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
43 dbgs() <<
"PHITransAddr: null\n";
46 dbgs() <<
"PHITransAddr: " << *Addr <<
"\n";
47 for (
unsigned i = 0, e = InstInputs.size(); i != e; ++i)
48 dbgs() <<
" Input #" << i <<
" is " << *InstInputs[i] <<
"\n";
60 if (
auto Entry =
find(InstInputs,
I); Entry != InstInputs.
end()) {
61 InstInputs.
erase(Entry);
68 errs() <<
"Instruction in PHITransAddr is not phi-translatable:\n";
71 "canPHITrans is wrong.");
76 [&](
Value *
Op) { return verifySubExpr(Op, InstInputs); });
83 if (!Addr)
return true;
91 errs() <<
"PHITransAddr contains extra instructions:\n";
92 for (
unsigned i = 0, e = InstInputs.size(); i != e; ++i)
93 errs() <<
" InstInput #" << i <<
" is " << *InstInputs[i] <<
"\n";
117 if (
auto Entry =
find(InstInputs,
I); Entry != InstInputs.
end()) {
118 InstInputs.
erase(Entry);
153 InstInputs.erase(
find(InstInputs, Inst));
157 Value *Incoming = PN->getIncomingValueForBlock(PredBB);
164 if (
SI->getCondition() ==
Cond)
165 return addAsInput(CondVal ?
SI->getTrueValue()
166 :
SI->getFalseValue());
167 return addAsInput(Incoming);
187 translateSubExpr(Cast->getOperand(0), CurBB, PredBB, DT,
Cond, CondVal);
188 if (!PHIIn)
return nullptr;
189 if (PHIIn == Cast->getOperand(0))
196 {DL, TLI, DT, AC})) {
198 return addAsInput(V);
207 for (User *U : PHIIn->
users()) {
209 if (CastI->getOpcode() == Cast->getOpcode() &&
210 CastI->getType() == Cast->getType() &&
211 (!DT || DT->
dominates(CastI->getParent(), PredBB)))
220 SmallVector<Value*, 8> GEPOps;
221 bool AnyChanged =
false;
223 Value *GEPOp = translateSubExpr(
Op, CurBB, PredBB, DT,
Cond, CondVal);
224 if (!GEPOp)
return nullptr;
226 AnyChanged |= GEPOp !=
Op;
236 GEP->getNoWrapFlags(), {DL, TLI, DT, AC})) {
240 return addAsInput(V);
244 Value *APHIOp = GEPOps[0];
248 for (User *U : APHIOp->
users()) {
250 if (GEPI->getType() ==
GEP->getType() &&
251 GEPI->getSourceElementType() ==
GEP->getSourceElementType() &&
252 GEPI->getNumOperands() == GEPOps.
size() &&
253 GEPI->getParent()->getParent() == CurBB->
getParent() &&
254 (!DT || DT->
dominates(GEPI->getParent(), PredBB))) {
255 if (std::equal(GEPOps.
begin(), GEPOps.
end(), GEPI->op_begin()))
263 if (Inst->
getOpcode() == Instruction::Add &&
271 translateSubExpr(Inst->
getOperand(0), CurBB, PredBB, DT,
Cond, CondVal);
272 if (!
LHS)
return nullptr;
276 if (BOp->getOpcode() == Instruction::Add)
278 LHS = BOp->getOperand(0);
280 isNSW = isNUW =
false;
294 return addAsInput(Res);
304 if (BO->getOpcode() == Instruction::Add &&
305 BO->getOperand(0) ==
LHS && BO->getOperand(1) ==
RHS &&
306 BO->getParent()->getParent() == CurBB->
getParent() &&
307 (!DT || DT->
dominates(BO->getParent(), PredBB)))
324 assert(DT || !MustDominate);
327 Addr = translateSubExpr(Addr, CurBB, PredBB, DT);
345 assert(
Cond &&
"expected a non-null select condition");
349 return {
nullptr,
nullptr};
351 auto TranslateSide = [&](
bool CondVal) ->
Value * {
355 return Tmp.translateSubExpr(Tmp.Addr, CurBB, PredBB, DT,
Cond, CondVal);
358 return {TranslateSide(
true), TranslateSide(
false)};
364 return SI->getCondition();
379 unsigned NISize = NewInsts.
size();
382 Addr = insertTranslatedSubExpr(Addr, CurBB, PredBB, DT, NewInsts);
385 if (Addr)
return Addr;
388 while (NewInsts.
size() != NISize)
398Value *PHITransAddr::insertTranslatedSubExpr(
405 Tmp.translateValue(CurBB, PredBB, &DT,
true))
415 Value *OpVal = insertTranslatedSubExpr(Cast->getOperand(0), CurBB, PredBB,
417 if (!OpVal)
return nullptr;
421 InVal->
getName() +
".phi.trans.insert",
433 Value *OpVal = insertTranslatedSubExpr(
Op, CurBB, PredBB, DT, NewInsts);
434 if (!OpVal)
return nullptr;
439 GEP->getSourceElementType(), GEPOps[0],
ArrayRef(GEPOps).slice(1),
440 InVal->
getName() +
".phi.trans.insert",
443 Result->setNoWrapFlags(
GEP->getNoWrapFlags());
457 Value *OpVal = insertTranslatedSubExpr(Inst->
getOperand(0), CurBB, PredBB,
459 if (OpVal ==
nullptr)
462 BinaryOperator *Res = BinaryOperator::CreateAdd(
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool hasNoSignedWrap(BinaryOperator &I)
static bool hasNoUnsignedWrap(BinaryOperator &I)
static bool isInput(const ArrayRef< StringRef > &Prefixes, StringRef Arg)
static void RemoveInstInputs(Value *V, SmallVectorImpl< Instruction * > &InstInputs)
static bool canPHITrans(Instruction *Inst)
static cl::opt< bool > EnableAddPhiTranslation("gvn-add-phi-translation", cl::init(false), cl::Hidden, cl::desc("Enable phi-translation of add instructions"))
static bool verifySubExpr(Value *Expr, SmallVectorImpl< Instruction * > &InstInputs)
const SmallVectorImpl< MachineOperand > & Cond
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
This is the base class for all instructions that perform data casts.
static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
static LLVM_ABI Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
LLVM_ABI void setHasNoUnsignedWrap(bool b=true)
Set or clear the nuw flag on this instruction, which must be an operator which supports this flag.
LLVM_ABI void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
PHITransAddr - An address value which tracks and handles phi translation.
LLVM_ABI Value * translateValue(BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree *DT, bool MustDominate)
translateValue - PHI translate the current address up the CFG from CurBB to Pred, updating our state ...
LLVM_ABI void dump() const
PHITransAddr(Value *Addr, const DataLayout &DL, AssumptionCache *AC)
LLVM_ABI bool isPotentiallyPHITranslatable() const
isPotentiallyPHITranslatable - If this needs PHI translation, return true if we have some hope of doi...
LLVM_ABI Value * getSelectCondition() const
If the address expression depends on a select instruction (possibly through casts or GEPs),...
LLVM_ABI bool verify() const
verify - Check internal consistency of this data structure.
LLVM_ABI Value * translateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree &DT, SmallVectorImpl< Instruction * > &NewInsts)
translateWithInsertion - PHI translate this value into the specified predecessor block,...
std::pair< Value *, Value * > SelectAddrs
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
iterator_range< user_iterator > users()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Value * simplifyGEPInst(Type *SrcTy, Value *Ptr, ArrayRef< Value * > Indices, GEPNoWrapFlags NW, const SimplifyQuery &Q)
Given operands for a GetElementPtrInst, fold the result or return null.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI Value * simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const SimplifyQuery &Q)
Given operands for a CastInst, fold the result or return null.
LLVM_ABI Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for an Add, fold the result or return null.
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.