96 #define DEBUG_TYPE "mldst-motion"
114 bool runOnFunction(
Function &
F)
override;
135 bool isLoadHoistBarrierInRange(
const Instruction& Start,
147 bool isStoreSinkBarrierInRange(
const Instruction &Start,
155 const int MagicCompileTimeControl;
169 "MergedLoadStoreMotion",
false,
false)
174 "MergedLoadStoreMotion",
false, false)
179 void MergedLoadStoreMotion::removeInstruction(
Instruction *Inst) {
182 MD->removeInstruction(Inst);
183 if (
LoadInst *LI = dyn_cast<LoadInst>(Inst))
184 MD->invalidateCachedPointerInfo(LI->getPointerOperand());
185 if (Inst->getType()->getScalarType()->isPointerTy()) {
186 MD->invalidateCachedPointerInfo(Inst);
189 Inst->eraseFromParent();
196 assert(isDiamondHead(BB) &&
"Basic block is not head of a diamond");
206 bool MergedLoadStoreMotion::isDiamondHead(
BasicBlock *BB) {
240 bool MergedLoadStoreMotion::isLoadHoistBarrierInRange(
const Instruction& Start,
271 !isLoadHoistBarrierInRange(BB1->
front(), *Load1, Load1) &&
272 !isLoadHoistBarrierInRange(BB0->front(), *Load0, Load0)) {
285 void MergedLoadStoreMotion::hoistInstruction(
BasicBlock *BB,
289 dbgs() <<
"Instruction Left\n"; HoistCand->
dump();
dbgs() <<
"\n";
290 dbgs() <<
"Instruction Right\n"; ElseInst->
dump();
dbgs() <<
"\n");
308 removeInstruction(HoistCand);
311 removeInstruction(ElseInst);
317 bool MergedLoadStoreMotion::isSafeToHoist(
Instruction *
I)
const {
321 if (Instr && Instr->
getParent() == Parent)
335 if (A0 && A1 && A0->
isIdenticalTo(A1) && isSafeToHoist(A0) &&
337 A1->hasOneUse() && (A1->getParent() == L1->
getParent()) &&
338 isa<GetElementPtrInst>(A0)) {
340 dbgs() <<
"Instruction Left\n"; L0->
dump();
dbgs() <<
"\n";
341 dbgs() <<
"Instruction Right\n"; L1->
dump();
dbgs() <<
"\n");
342 hoistInstruction(BB, A0, A1);
343 hoistInstruction(BB, L0, L1);
355 bool MergedLoadStoreMotion::mergeLoads(
BasicBlock *BB) {
356 bool MergedLoads =
false;
357 assert(isDiamondHead(BB));
362 int Size1 = Succ1->
size();
376 if (NLoads * Size1 >= MagicCompileTimeControl)
378 if (
LoadInst *L1 = canHoistFromBlock(Succ1, L0)) {
379 bool Res = hoistLoad(BB, L0, L1);
398 bool MergedLoadStoreMotion::isStoreSinkBarrierInRange(
const Instruction &Start,
417 if (!isa<StoreInst>(Inst))
420 StoreInst *Store1 = cast<StoreInst>(Inst);
426 BB1->
back(), Loc1) &&
428 BB0->back(), Loc0)) {
456 MD->invalidateCachedPointerInfo(NewPN);
474 (A1->getParent() == S1->
getParent()) && isa<GetElementPtrInst>(A0)) {
476 dbgs() <<
"Instruction Left\n"; S0->
dump();
dbgs() <<
"\n";
477 dbgs() <<
"Instruction Right\n"; S1->
dump();
dbgs() <<
"\n");
493 PHINode *NewPN = getPHIOperand(BB, S0, S1);
497 removeInstruction(S0);
498 removeInstruction(S1);
500 removeInstruction(A0);
501 A1->replaceAllUsesWith(ANew);
502 removeInstruction(A1);
514 bool MergedLoadStoreMotion::mergeStores(
BasicBlock *
T) {
516 bool MergedStores =
false;
517 assert(T &&
"Footer of a diamond cannot be empty");
532 int Size1 = Pred1->
size();
542 if (!isa<StoreInst>(I))
549 if (NStores * Size1 >= MagicCompileTimeControl)
551 if (
StoreInst *S1 = canSinkFromBlock(Pred1, S0)) {
552 bool Res = sinkStore(T, S0, S1);
572 bool MergedLoadStoreMotion::runOnFunction(
Function &
F) {
573 MD = getAnalysisIfAvailable<MemoryDependenceAnalysis>();
574 AA = &getAnalysis<AliasAnalysis>();
576 bool Changed =
false;
586 if (isDiamondHead(BB)) {
587 Changed |= mergeLoads(BB);
588 Changed |= mergeStores(getDiamondTail(BB));
const Use & getOperandUse(unsigned i) const
Value * getValueOperand()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void addIncoming(Value *V, BasicBlock *BB)
addIncoming - Add an incoming value to the end of the PHI list
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
const Instruction & back() const
unsigned getNumOperands() const
bool isUsedOutsideOfBlock(const BasicBlock *BB) const
isUsedOutsideOfBlock - Return true if there are any uses of this instruction in blocks other than the...
const Function * getParent() const
Return the enclosing method, or null if none.
const Instruction & front() const
LoadInst - an instruction for reading from memory.
reverse_iterator rbegin()
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
StringRef getName() const
Return a constant reference to the value's name.
iterator begin()
Instruction iterator methods.
static unsigned getOperandNumForIncomingValue(unsigned i)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
bool isIdenticalTo(const Instruction *I) const
isIdenticalTo - Return true if the specified instruction is exactly identical to the current one...
void initializeMergedLoadStoreMotionPass(PassRegistry &)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
mldst MergedLoadStoreMotion
MemoryDependenceAnalysis - This is an analysis that determines, for a given memory operation...
Instruction * clone() const
clone() - Create a copy of 'this' instruction that is identical in all ways except the following: ...
BasicBlock * getSuccessor(unsigned i) const
StoreInst - an instruction for storing to memory.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
unsigned getNumIncomingValues() const
getNumIncomingValues - Return the number of incoming edges
InstListType::reverse_iterator reverse_iterator
unsigned getNumSuccessors() const
Return the number of successors that this terminator has.
void intersectOptionalDataWith(const Value *V)
Clear any optional flags not set in the given Value.
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction...
LLVM Basic Block Representation.
BasicBlock * getSuccessor(unsigned idx) const
Return the specified successor.
BranchInst - Conditional or Unconditional Branch instruction.
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.
FunctionPass class - This class is used to implement most global optimizations.
Value * getOperand(unsigned i) const
Interval::pred_iterator pred_end(Interval *I)
Value * getPointerOperand()
#define INITIALIZE_AG_DEPENDENCY(depName)
bool isPointerTy() const
isPointerTy - True if this is an instance of PointerType.
void dump() const
Support for debugging, callable in GDB: V->dump()
Representation for a specific memory location.
Type * getType() const
All values are typed, get the type of this value.
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 setOperand(unsigned i, Value *Val)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createMergedLoadStoreMotionPass()
createMergedLoadStoreMotionPass - The public interface to this file.
BasicBlock * getSinglePredecessor()
Return the predecessor of this block if it has a single predecessor block.
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
const Type * getScalarType() const LLVM_READONLY
getScalarType - If this is a vector type, return the element type, otherwise return 'this'...
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
bool hasOneUse() const
Return true if there is exactly one user of this value.
INITIALIZE_PASS_BEGIN(MergedLoadStoreMotion,"mldst-motion","MergedLoadStoreMotion", false, false) INITIALIZE_PASS_END(MergedLoadStoreMotion
void dropUnknownMetadata(ArrayRef< unsigned > KnownIDs)
Drop unknown metadata.
LLVM Value Representation.
bool isSameOperationAs(const Instruction *I, unsigned flags=0) const
This function determines if the specified instruction executes the same operation as the current one...
iterator getFirstInsertionPt()
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
Value * getPointerOperand()
const BasicBlock * getParent() const