16#include "llvm/Config/llvm-config.h"
26 cl::desc(
"Enable phi-translation of add instructions"));
29 if (isa<PHINode>(Inst) || isa<GetElementPtrInst>(Inst) || isa<CastInst>(Inst))
32 if (Inst->
getOpcode() == Instruction::Add &&
39#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
42 dbgs() <<
"PHITransAddr: null\n";
45 dbgs() <<
"PHITransAddr: " << *Addr <<
"\n";
46 for (
unsigned i = 0, e = InstInputs.size(); i != e; ++i)
47 dbgs() <<
" Input #" << i <<
" is " << *InstInputs[i] <<
"\n";
59 if (
auto Entry =
find(InstInputs,
I); Entry != InstInputs.
end()) {
60 InstInputs.
erase(Entry);
67 errs() <<
"Instruction in PHITransAddr is not phi-translatable:\n";
70 "canPHITrans is wrong.");
75 [&](
Value *Op) { return verifySubExpr(Op, InstInputs); });
82 if (!Addr)
return true;
90 errs() <<
"PHITransAddr contains extra instructions:\n";
91 for (
unsigned i = 0, e = InstInputs.size(); i != e; ++i)
92 errs() <<
" InstInput #" << i <<
" is " << *InstInputs[i] <<
"\n";
116 if (
auto Entry =
find(InstInputs,
I); Entry != InstInputs.
end()) {
117 InstInputs.
erase(Entry);
121 assert(!isa<PHINode>(
I) &&
"Error, removing something that isn't an input");
124 for (
Value *Op :
I->operands())
125 if (
Instruction *OpInst = dyn_cast<Instruction>(Op))
151 InstInputs.erase(
find(InstInputs, Inst));
154 if (
PHINode *PN = dyn_cast<PHINode>(Inst))
155 return addAsInput(PN->getIncomingValueForBlock(PredBB));
172 if (
CastInst *Cast = dyn_cast<CastInst>(Inst)) {
173 Value *PHIIn = translateSubExpr(Cast->getOperand(0), CurBB, PredBB, DT);
174 if (!PHIIn)
return nullptr;
175 if (PHIIn == Cast->getOperand(0))
182 {DL, TLI, DT, AC})) {
184 return addAsInput(V);
190 if (
CastInst *CastI = dyn_cast<CastInst>(U))
191 if (CastI->getOpcode() == Cast->getOpcode() &&
192 CastI->getType() == Cast->getType() &&
193 (!DT || DT->
dominates(CastI->getParent(), PredBB)))
202 bool AnyChanged =
false;
204 Value *GEPOp = translateSubExpr(Op, CurBB, PredBB, DT);
205 if (!GEPOp)
return nullptr;
207 AnyChanged |= GEPOp !=
Op;
217 GEP->isInBounds(), {DL, TLI, DT, AC})) {
218 for (
unsigned i = 0, e = GEPOps.
size(); i != e; ++i)
221 return addAsInput(V);
225 Value *APHIOp = GEPOps[0];
228 if (GEPI->getType() ==
GEP->getType() &&
229 GEPI->getSourceElementType() ==
GEP->getSourceElementType() &&
230 GEPI->getNumOperands() == GEPOps.
size() &&
231 GEPI->getParent()->getParent() == CurBB->
getParent() &&
232 (!DT || DT->
dominates(GEPI->getParent(), PredBB))) {
233 if (std::equal(GEPOps.
begin(), GEPOps.
end(), GEPI->op_begin()))
241 if (Inst->
getOpcode() == Instruction::Add &&
245 bool isNSW = cast<BinaryOperator>(Inst)->hasNoSignedWrap();
246 bool isNUW = cast<BinaryOperator>(Inst)->hasNoUnsignedWrap();
249 if (!LHS)
return nullptr;
253 if (BOp->getOpcode() == Instruction::Add)
254 if (
ConstantInt *CI = dyn_cast<ConstantInt>(BOp->getOperand(1))) {
255 LHS = BOp->getOperand(0);
257 isNSW = isNUW =
false;
271 return addAsInput(Res);
281 if (BO->getOpcode() == Instruction::Add &&
282 BO->getOperand(0) == LHS && BO->getOperand(1) == RHS &&
283 BO->getParent()->getParent() == CurBB->
getParent() &&
284 (!DT || DT->
dominates(BO->getParent(), PredBB)))
301 assert(DT || !MustDominate);
304 Addr = translateSubExpr(Addr, CurBB, PredBB, DT);
311 if (
Instruction *Inst = dyn_cast_or_null<Instruction>(Addr))
329 unsigned NISize = NewInsts.
size();
332 Addr = insertTranslatedSubExpr(Addr, CurBB, PredBB, DT, NewInsts);
335 if (Addr)
return Addr;
338 while (NewInsts.
size() != NISize)
348Value *PHITransAddr::insertTranslatedSubExpr(
355 Tmp.translateValue(CurBB, PredBB, &DT,
true))
359 auto *Inst = dyn_cast<Instruction>(InVal);
364 if (
CastInst *Cast = dyn_cast<CastInst>(Inst)) {
365 Value *OpVal = insertTranslatedSubExpr(Cast->getOperand(0), CurBB, PredBB,
367 if (!OpVal)
return nullptr;
371 InVal->
getName() +
".phi.trans.insert",
383 Value *OpVal = insertTranslatedSubExpr(Op, CurBB, PredBB, DT, NewInsts);
384 if (!OpVal)
return nullptr;
389 GEP->getSourceElementType(), GEPOps[0],
ArrayRef(GEPOps).slice(1),
392 Result->setIsInBounds(
GEP->isInBounds());
406 Value *OpVal = insertTranslatedSubExpr(Inst->
getOperand(0), CurBB, PredBB,
408 if (OpVal ==
nullptr)
412 InVal->
getName()+
".phi.trans.insert",
#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< StringLiteral > &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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
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 if the block is well formed or null if the block is not well forme...
This is the base class for all instructions that perform data casts.
static CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", Instruction *InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
static Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
This is the shared class of boolean and integer constants.
This is an important base class in LLVM.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
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="", Instruction *InsertBefore=nullptr)
void setHasNoUnsignedWrap(bool b=true)
Set or clear the nuw flag on this instruction, which must be an operator which supports this flag.
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.
const BasicBlock * getParent() const
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
PHITransAddr - An address value which tracks and handles phi translation.
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 ...
bool isPotentiallyPHITranslatable() const
isPotentiallyPHITranslatable - If this needs PHI translation, return true if we have some hope of doi...
bool verify() const
verify - Check internal consistency of this data structure.
Value * translateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree &DT, SmallVectorImpl< Instruction * > &NewInsts)
translateWithInsertion - PHI translate this value into the specified predecessor block,...
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()
StringRef getName() const
Return a constant reference to the value's name.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
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.
Value * simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const SimplifyQuery &Q)
Given operands for a CastInst, fold the result or return null.
Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for an Add, fold the result or return null.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Value * simplifyGEPInst(Type *SrcTy, Value *Ptr, ArrayRef< Value * > Indices, bool InBounds, const SimplifyQuery &Q)
Given operands for a GetElementPtrInst, fold the result or return null.