LLVM: lib/Transforms/Scalar/MergedLoadStoreMotion.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
88
89using namespace llvm;
90
91#define DEBUG_TYPE "mldst-motion"
92
93namespace {
94
95
96
97class MergedLoadStoreMotion {
99
100
101
102
103
104 const int MagicCompileTimeControl = 250;
105
106 const bool SplitFooterBB;
107public:
108 MergedLoadStoreMotion(bool SplitFooterBB) : SplitFooterBB(SplitFooterBB) {}
110
111private:
114
117 bool isStoreSinkBarrierInRange(const Instruction &Start,
123};
124}
125
126
127
128
130 assert(isDiamondHead(BB) && "Basic block is not head of a diamond");
132}
133
134
135
136
137bool MergedLoadStoreMotion::isDiamondHead(BasicBlock *BB) {
138 if (!BB)
139 return false;
141 if (!BI || !BI->isConditional())
142 return false;
143
144 BasicBlock *Succ0 = BI->getSuccessor(0);
145 BasicBlock *Succ1 = BI->getSuccessor(1);
146
148 return false;
150 return false;
151
154
155 if (!Succ0Succ || !Succ1Succ || Succ0Succ != Succ1Succ)
156 return false;
157 return true;
158}
159
160
161
162
163
164
165
166
167
168
169bool MergedLoadStoreMotion::isStoreSinkBarrierInRange(const Instruction &Start,
170 const Instruction &End,
171 MemoryLocation Loc) {
172 for (const Instruction &Inst :
174 if (Inst.mayThrow())
175 return true;
177}
178
179
180
181
182
183
184StoreInst *MergedLoadStoreMotion::canSinkFromBlock(BasicBlock *BB1,
185 StoreInst *Store0) {
188 for (Instruction &Inst : reverse(*BB1)) {
190 if (!Store1)
191 continue;
192
195
197 !isStoreSinkBarrierInRange(*Store1->getNextNode(), BB1->back(), Loc1) &&
198 !isStoreSinkBarrierInRange(*Store0->getNextNode(), BB0->back(), Loc0) &&
202 Store1->getValueOperand()->getType(),
204 return Store1;
205 }
206 return nullptr;
207}
208
209
210
211
212PHINode *MergedLoadStoreMotion::getPHIOperand(BasicBlock *BB, StoreInst *S0,
213 StoreInst *S1) {
214
216 Value *Opd2 = S1->getValueOperand();
217 if (Opd1 == Opd2)
218 return nullptr;
219
221 NewPN->insertBefore(BB->begin());
222 NewPN->applyMergedLocation(S0->getDebugLoc(), S1->getDebugLoc());
223 NewPN->addIncoming(Opd1, S0->getParent());
224 NewPN->addIncoming(Opd2, S1->getParent());
225 return NewPN;
226}
227
228
229
230
231bool MergedLoadStoreMotion::canSinkStoresAndGEPs(StoreInst *S0,
232 StoreInst *S1) const {
234 return true;
237 return GEP0 && GEP1 && GEP0->isIdenticalTo(GEP1) && GEP0->hasOneUse() &&
238 (GEP0->getParent() == S0->getParent()) && GEP1->hasOneUse() &&
239 (GEP1->getParent() == S1->getParent());
240}
241
242
243
244
245
246
247void MergedLoadStoreMotion::sinkStoresAndGEPs(BasicBlock *BB, StoreInst *S0,
248 StoreInst *S1) {
250 Value *Ptr1 = S1->getPointerOperand();
251
253 dbgs() << "Instruction Left\n"; S0->dump(); dbgs() << "\n";
254 dbgs() << "Instruction Right\n"; S1->dump(); dbgs() << "\n");
255
257
259
263
264
265
267 auto Cast = Builder.CreateBitOrPointerCast(S0->getValueOperand(),
268 S1->getValueOperand()->getType());
270
271
274
275 if (PHINode *NewPN = getPHIOperand(BB, S0, S1))
278 S1->eraseFromParent();
279
280 if (Ptr0 != Ptr1) {
287 GEP0->replaceAllUsesWith(GEPNew);
288 GEP0->eraseFromParent();
289 GEP1->replaceAllUsesWith(GEPNew);
290 GEP1->eraseFromParent();
291 }
292}
293
294
295
296
297
298
299
300bool MergedLoadStoreMotion::mergeStores(BasicBlock *HeadBB) {
301
302 bool MergedStores = false;
303 BasicBlock *TailBB = getDiamondTail(HeadBB);
305 assert(SinkBB && "Footer of a diamond cannot be empty");
306
308 assert(SI != succ_end(HeadBB) && "Diamond head cannot have zero successors");
310 ++SI;
311 assert(SI != succ_end(HeadBB) && "Diamond head cannot have single successor");
313
314 if (Pred0 == Pred1)
315 return false;
316
318 return false;
319
321 int Size1 = std::distance(InstsNoDbg.begin(), InstsNoDbg.end());
322 int NStores = 0;
323
325 RBI != RBE;) {
326
328 ++RBI;
329
330
333 continue;
334
335 ++NStores;
336 if (NStores * Size1 >= MagicCompileTimeControl)
337 break;
338 if (StoreInst *S1 = canSinkFromBlock(Pred1, S0)) {
339 if (!canSinkStoresAndGEPs(S0, S1))
340
341
342
343
344 break;
345
347
348
350 if (!SinkBB)
351 break;
352 }
353
354 MergedStores = true;
355 sinkStoresAndGEPs(SinkBB, S0, S1);
356 RBI = Pred0->rbegin();
357 RBE = Pred0->rend();
359 }
360 }
361 return MergedStores;
362}
363
364bool MergedLoadStoreMotion::run(Function &F, AliasAnalysis &AA) {
365 this->AA = &AA;
366
369
370
371
372
373
375
376
377 if (isDiamondHead(&BB))
378 Changed |= mergeStores(&BB);
380}
381
382PreservedAnalyses
384 MergedLoadStoreMotion Impl(Options.SplitFooterBB);
388
390 if (!Options.SplitFooterBB)
392 return PA;
393}
394
398 OS, MapClassName2PassName);
399 OS << '<';
400 OS << (Options.SplitFooterBB ? "" : "no-") << "split-footer-bb";
401 OS << '>';
402}
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()
LLVM_ABI iterator_range< filter_iterator< BasicBlock::const_iterator, std::function< bool(const Instruction &)> > > instructionsWithoutDebug(bool SkipPseudoOp=true) const
Return a const iterator range over the instructions in the block, skipping any debug instructions.
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 if the block is well formed or null if the block is not well forme...
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)
Definition MergedLoadStoreMotion.cpp:395
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition MergedLoadStoreMotion.cpp:383
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 - 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)
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
SuccIterator< Instruction, BasicBlock > succ_iterator
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.