92 #define DEBUG_TYPE "mldst-motion" 105 const int MagicCompileTimeControl = 250;
116 bool isStoreSinkBarrierInRange(
const Instruction &Start,
127 assert(isDiamondHead(BB) &&
"Basic block is not head of a diamond");
134 bool MergedLoadStoreMotion::isDiamondHead(
BasicBlock *BB) {
138 if (!BI || !BI->isConditional())
152 if (!Succ0Succ || !Succ1Succ || Succ0Succ != Succ1Succ)
166 bool MergedLoadStoreMotion::isStoreSinkBarrierInRange(
const Instruction &Start,
193 !isStoreSinkBarrierInRange(*Store1->getNextNode(), BB1->
back(), Loc1) &&
194 !isStoreSinkBarrierInRange(*Store0->
getNextNode(), BB0->back(), Loc0)) {
215 NewPN->addIncoming(Opd1, S0->
getParent());
216 NewPN->addIncoming(Opd2, S1->
getParent());
230 if (A0 && A1 && A0->isIdenticalTo(A1) && A0->hasOneUse() &&
231 (A0->getParent() == S0->
getParent()) && A1->hasOneUse() &&
232 (A1->getParent() == S1->
getParent()) && isa<GetElementPtrInst>(A0)) {
234 dbgs() <<
"Instruction Left\n"; S0->
dump();
dbgs() <<
"\n";
235 dbgs() <<
"Instruction Right\n"; S1->
dump();
dbgs() <<
"\n");
246 ANew->insertBefore(SNew);
252 if (
PHINode *NewPN = getPHIOperand(BB, S0, S1))
256 A0->replaceAllUsesWith(ANew);
257 A0->eraseFromParent();
258 A1->replaceAllUsesWith(ANew);
259 A1->eraseFromParent();
271 bool MergedLoadStoreMotion::mergeStores(
BasicBlock *
T) {
273 bool MergedStores =
false;
274 assert(T &&
"Footer of a diamond cannot be empty");
290 int Size1 = std::distance(InstsNoDbg.begin(), InstsNoDbg.end());
305 if (NStores * Size1 >= MagicCompileTimeControl)
307 if (
StoreInst *S1 = canSinkFromBlock(Pred1, S0)) {
308 bool Res = sinkStore(T, S0, S1);
327 bool Changed =
false;
337 if (isDiamondHead(BB)) {
338 Changed |= mergeStores(getDiamondTail(BB));
345 class MergedLoadStoreMotionLegacyPass :
public FunctionPass {
360 return Impl.run(F, getAnalysis<AAResultsWrapperPass>().getAAResults());
378 return new MergedLoadStoreMotionLegacyPass();
382 "MergedLoadStoreMotion",
false,
false)
391 if (!Impl.run(F, AA))
Legacy wrapper pass to provide the GlobalsAAResult object.
The access may reference and may modify the value stored in memory.
Value * getValueOperand()
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
bool isSameOperationAs(const Instruction *I, unsigned flags=0) const
This function determines if the specified instruction executes the same operation as the current one...
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
This class represents lattice values for constants.
This is the interface for a simple mod/ref and alias analysis over globals.
void dropUnknownNonDebugMetadata(ArrayRef< unsigned > KnownIDs)
Drop all unknown metadata except for debug locations.
BasicBlock * getSuccessor(unsigned Idx) const
Return the specified successor. This instruction must be a terminator.
INITIALIZE_PASS_BEGIN(MergedLoadStoreMotionLegacyPass, "mldst-motion", "MergedLoadStoreMotion", false, false) INITIALIZE_PASS_END(MergedLoadStoreMotionLegacyPass
reverse_iterator rbegin()
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...
void dump() const
Support for debugging, callable in GDB: V->dump()
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
mldst MergedLoadStoreMotion
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following: ...
Type * getType() const
All values are typed, get the type of this value.
void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction...
const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
An instruction for storing to memory.
static bool runOnFunction(Function &F, bool PostInlining)
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
A set of analyses that are preserved following a run of a transformation pass.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction...
LLVM Basic Block Representation.
Conditional or Unconditional Branch instruction.
iterator_range< filter_iterator< BasicBlock::const_iterator, std::function< bool(const Instruction &)> > > instructionsWithoutDebug() const
Return a const iterator range over the instructions in the block, skipping any debug instructions...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const Instruction & front() const
A manager for alias analyses.
Interval::pred_iterator pred_begin(Interval *I)
pred_begin/pred_end - define methods so that Intervals may be used just like BasicBlocks can with the...
Represent the analysis usage information of a pass.
const Instruction & back() const
Analysis pass providing a never-invalidated alias analysis result.
FunctionPass class - This class is used to implement most global optimizations.
Interval::pred_iterator pred_end(Interval *I)
self_iterator getIterator()
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
Representation for a specific memory location.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Iterator for intrusive lists based on ilist_node.
void applyMergedLocation(const DILocation *LocA, const DILocation *LocB)
Merge 2 debug locations and apply it to the Instruction.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
void setPreservesCFG()
This function should be called by the pass, iff they do not:
void setOperand(unsigned i, Value *Val)
FunctionPass * createMergedLoadStoreMotionPass()
createMergedLoadStoreMotionPass - The public interface to this file.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Represents analyses that only rely on functions' control flow.
This pass performs merges of loads and stores on both sides of a.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
void preserveSet()
Mark an analysis set as preserved.
StringRef getName() const
Return a constant reference to the value's name.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void preserve()
Mark an analysis as preserved.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
A container for analyses that lazily runs them and caches their results.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
void initializeMergedLoadStoreMotionLegacyPassPass(PassRegistry &)
Value * getPointerOperand()
const BasicBlock * getParent() const