91#define DEBUG_TYPE "mldst-motion"
97class MergedLoadStoreMotion {
104 const unsigned MagicCompileTimeControl = 250;
106 const bool SplitFooterBB;
108 MergedLoadStoreMotion(
bool SplitFooterBB) : SplitFooterBB(SplitFooterBB) {}
117 bool isStoreSinkBarrierInRange(
const Instruction &Start,
130 assert(isDiamondHead(BB) &&
"Basic block is not head of a diamond");
137bool MergedLoadStoreMotion::isDiamondHead(BasicBlock *BB) {
155 if (!Succ0Succ || !Succ1Succ || Succ0Succ != Succ1Succ)
169bool MergedLoadStoreMotion::isStoreSinkBarrierInRange(
const Instruction &Start,
170 const Instruction &End,
171 MemoryLocation Loc) {
172 for (
const Instruction &Inst :
184StoreInst *MergedLoadStoreMotion::canSinkFromBlock(BasicBlock *BB1,
188 for (Instruction &Inst :
reverse(*BB1)) {
197 !isStoreSinkBarrierInRange(*Store1->getNextNode(), BB1->
back(), Loc1) &&
198 !isStoreSinkBarrierInRange(*Store0->
getNextNode(), BB0->back(), Loc0) &&
202 Store1->getValueOperand()->getType(),
212PHINode *MergedLoadStoreMotion::getPHIOperand(BasicBlock *BB, StoreInst *S0,
216 Value *Opd2 =
S1->getValueOperand();
221 NewPN->insertBefore(BB->
begin());
222 NewPN->applyMergedLocation(S0->
getDebugLoc(),
S1->getDebugLoc());
223 NewPN->addIncoming(Opd1, S0->
getParent());
224 NewPN->addIncoming(Opd2,
S1->getParent());
231bool MergedLoadStoreMotion::canSinkStoresAndGEPs(StoreInst *S0,
232 StoreInst *
S1)
const {
237 return GEP0 && GEP1 && GEP0->isIdenticalTo(GEP1) && GEP0->hasOneUse() &&
238 (GEP0->getParent() == S0->
getParent()) && GEP1->hasOneUse() &&
239 (GEP1->getParent() ==
S1->getParent());
247void MergedLoadStoreMotion::sinkStoresAndGEPs(BasicBlock *BB, StoreInst *S0,
250 Value *Ptr1 =
S1->getPointerOperand();
253 dbgs() <<
"Instruction Left\n"; S0->
dump();
dbgs() <<
"\n";
268 S1->getValueOperand()->getType());
275 if (PHINode *NewPN = getPHIOperand(BB, S0,
S1))
278 S1->eraseFromParent();
287 GEP0->replaceAllUsesWith(GEPNew);
288 GEP0->eraseFromParent();
289 GEP1->replaceAllUsesWith(GEPNew);
290 GEP1->eraseFromParent();
300bool MergedLoadStoreMotion::mergeStores(BasicBlock *HeadBB) {
302 bool MergedStores =
false;
305 assert(SinkBB &&
"Footer of a diamond cannot be empty");
308 assert(SI !=
succ_end(HeadBB) &&
"Diamond head cannot have zero successors");
311 assert(SI !=
succ_end(HeadBB) &&
"Diamond head cannot have single successor");
320 unsigned Size1 = Pred1->
size();
321 unsigned NStores = 0;
335 if (NStores * Size1 >= MagicCompileTimeControl)
337 if (StoreInst *
S1 = canSinkFromBlock(Pred1, S0)) {
338 if (!canSinkStoresAndGEPs(S0,
S1))
354 sinkStoresAndGEPs(SinkBB, S0,
S1);
376 if (isDiamondHead(&BB))
383 MergedLoadStoreMotion Impl(Options.SplitFooterBB);
385 if (!Impl.run(
F,
AA))
389 if (!Options.SplitFooterBB)
397 OS, MapClassName2PassName);
399 OS << (Options.SplitFooterBB ?
"" :
"no-") <<
"split-footer-bb";
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This is the interface for a simple mod/ref and alias analysis over globals.
This pass performs merges of loads and stores on both sides of a.
A manager for alias analyses.
bool isMustAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
A trivial helper function to check to see if the specified pointers are must-alias.
LLVM_ABI bool canInstructionRangeModRef(const Instruction &I1, const Instruction &I2, const MemoryLocation &Loc, const ModRefInfo Mode)
Check if it is possible for the execution of the specified instructions to mod(according to the mode)...
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
reverse_iterator rbegin()
const Instruction & back() const
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
InstListType::reverse_iterator reverse_iterator
LLVM_ABI const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI bool hasNPredecessorsOrMore(unsigned N) const
Return true if this block has N predecessors or more.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Represents analyses that only rely on functions' control flow.
static LLVM_ABI bool isBitOrNoopPointerCastable(Type *SrcTy, Type *DestTy, const DataLayout &DL)
Check whether a bitcast, inttoptr, or ptrtoint cast between these types is valid and a no-op.
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI void mergeDIAssignID(ArrayRef< const Instruction * > SourceInstructions)
Merge the DIAssignID metadata from this instruction and those attached to instructions in SourceInstr...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction.
LLVM_ABI bool hasSameSpecialState(const Instruction *I2, bool IgnoreAlignment=false, bool IntersectAttrs=false) const LLVM_READONLY
This function determines if the speficied instruction has the same "special" characteristics as the c...
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
LLVM_ABI void applyMergedLocation(DebugLoc LocA, DebugLoc LocB)
Merge 2 debug locations and apply it to the Instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
LLVM_DUMP_METHOD void dump() const
Representation for a specific memory location.
static LLVM_ABI MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
An instruction for storing to memory.
Value * getValueOperand()
Value * getPointerOperand()
StringRef - Represent a constant reference to a string, i.e.
void setOperand(unsigned i, Value *Val)
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void dump() const
Support for debugging, callable in GDB: V->dump()
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
self_iterator getIterator()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
This class implements an extremely fast bulk output stream that can only output to a stream.
Abstract Attribute helper functions.
@ BasicBlock
Various leaf nodes.
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
LLVM_ABI void combineMetadataForCSE(Instruction *K, const Instruction *J, bool DoesKMove)
Combine the metadata of two instructions so that K can replace J.
LLVM_ABI BasicBlock * SplitBlockPredecessors(BasicBlock *BB, ArrayRef< BasicBlock * > Preds, const char *Suffix, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, bool PreserveLCSSA=false)
This method introduces at least one new basic block into the function and moves some of the predecess...
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)
Instruction::succ_iterator succ_iterator
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
A CRTP mix-in to automatically provide informational APIs needed for passes.