1 //===- HexagonCommonGEP.cpp -----------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #define DEBUG_TYPE "commgep"
11 #include "llvm/ADT/ArrayRef.h"
12 #include "llvm/ADT/FoldingSet.h"
13 #include "llvm/ADT/GraphTraits.h"
14 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/Analysis/LoopInfo.h"
17 #include "llvm/Analysis/PostDominators.h"
18 #include "llvm/Transforms/Utils/Local.h"
19 #include "llvm/IR/BasicBlock.h"
20 #include "llvm/IR/Constant.h"
21 #include "llvm/IR/Constants.h"
22 #include "llvm/IR/DerivedTypes.h"
23 #include "llvm/IR/Dominators.h"
24 #include "llvm/IR/Function.h"
25 #include "llvm/IR/Instruction.h"
26 #include "llvm/IR/Instructions.h"
27 #include "llvm/IR/Type.h"
28 #include "llvm/IR/Use.h"
29 #include "llvm/IR/User.h"
30 #include "llvm/IR/Value.h"
31 #include "llvm/IR/Verifier.h"
32 #include "llvm/Pass.h"
33 #include "llvm/Support/Allocator.h"
34 #include "llvm/Support/Casting.h"
35 #include "llvm/Support/CommandLine.h"
36 #include "llvm/Support/Compiler.h"
37 #include "llvm/Support/Debug.h"
38 #include "llvm/Support/raw_ostream.h"
51 static cl::opt
<bool> OptSpeculate("commgep-speculate", cl::init(true),
52 cl::Hidden
, cl::ZeroOrMore
);
54 static cl::opt
<bool> OptEnableInv("commgep-inv", cl::init(true), cl::Hidden
,
57 static cl::opt
<bool> OptEnableConst("commgep-const", cl::init(true),
58 cl::Hidden
, cl::ZeroOrMore
);
62 void initializeHexagonCommonGEPPass(PassRegistry
&);
64 } // end namespace llvm
69 using NodeSet
= std::set
<GepNode
*>;
70 using NodeToValueMap
= std::map
<GepNode
*, Value
*>;
71 using NodeVect
= std::vector
<GepNode
*>;
72 using NodeChildrenMap
= std::map
<GepNode
*, NodeVect
>;
73 using UseSet
= std::set
<Use
*>;
74 using NodeToUsesMap
= std::map
<GepNode
*, UseSet
>;
76 // Numbering map for gep nodes. Used to keep track of ordering for
79 NodeOrdering() = default;
81 void insert(const GepNode
*N
) { Map
.insert(std::make_pair(N
, ++LastNum
)); }
82 void clear() { Map
.clear(); }
84 bool operator()(const GepNode
*N1
, const GepNode
*N2
) const {
85 auto F1
= Map
.find(N1
), F2
= Map
.find(N2
);
86 assert(F1
!= Map
.end() && F2
!= Map
.end());
87 return F1
->second
< F2
->second
;
91 std::map
<const GepNode
*, unsigned> Map
;
95 class HexagonCommonGEP
: public FunctionPass
{
99 HexagonCommonGEP() : FunctionPass(ID
) {
100 initializeHexagonCommonGEPPass(*PassRegistry::getPassRegistry());
103 bool runOnFunction(Function
&F
) override
;
104 StringRef
getPassName() const override
{ return "Hexagon Common GEP"; }
106 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
107 AU
.addRequired
<DominatorTreeWrapperPass
>();
108 AU
.addPreserved
<DominatorTreeWrapperPass
>();
109 AU
.addRequired
<PostDominatorTreeWrapperPass
>();
110 AU
.addPreserved
<PostDominatorTreeWrapperPass
>();
111 AU
.addRequired
<LoopInfoWrapperPass
>();
112 AU
.addPreserved
<LoopInfoWrapperPass
>();
113 FunctionPass::getAnalysisUsage(AU
);
117 using ValueToNodeMap
= std::map
<Value
*, GepNode
*>;
118 using ValueVect
= std::vector
<Value
*>;
119 using NodeToValuesMap
= std::map
<GepNode
*, ValueVect
>;
121 void getBlockTraversalOrder(BasicBlock
*Root
, ValueVect
&Order
);
122 bool isHandledGepForm(GetElementPtrInst
*GepI
);
123 void processGepInst(GetElementPtrInst
*GepI
, ValueToNodeMap
&NM
);
127 BasicBlock
*recalculatePlacement(GepNode
*Node
, NodeChildrenMap
&NCM
,
128 NodeToValueMap
&Loc
);
129 BasicBlock
*recalculatePlacementRec(GepNode
*Node
, NodeChildrenMap
&NCM
,
130 NodeToValueMap
&Loc
);
131 bool isInvariantIn(Value
*Val
, Loop
*L
);
132 bool isInvariantIn(GepNode
*Node
, Loop
*L
);
133 bool isInMainPath(BasicBlock
*B
, Loop
*L
);
134 BasicBlock
*adjustForInvariance(GepNode
*Node
, NodeChildrenMap
&NCM
,
135 NodeToValueMap
&Loc
);
136 void separateChainForNode(GepNode
*Node
, Use
*U
, NodeToValueMap
&Loc
);
137 void separateConstantChains(GepNode
*Node
, NodeChildrenMap
&NCM
,
138 NodeToValueMap
&Loc
);
139 void computeNodePlacement(NodeToValueMap
&Loc
);
141 Value
*fabricateGEP(NodeVect
&NA
, BasicBlock::iterator At
,
143 void getAllUsersForNode(GepNode
*Node
, ValueVect
&Values
,
144 NodeChildrenMap
&NCM
);
145 void materialize(NodeToValueMap
&Loc
);
147 void removeDeadCode();
151 NodeOrdering NodeOrder
; // Node ordering, for deterministic behavior.
152 SpecificBumpPtrAllocator
<GepNode
> *Mem
;
156 PostDominatorTree
*PDT
;
160 } // end anonymous namespace
162 char HexagonCommonGEP::ID
= 0;
164 INITIALIZE_PASS_BEGIN(HexagonCommonGEP
, "hcommgep", "Hexagon Common GEP",
166 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass
)
167 INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass
)
168 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass
)
169 INITIALIZE_PASS_END(HexagonCommonGEP
, "hcommgep", "Hexagon Common GEP",
188 Value
*Idx
= nullptr;
189 Type
*PTy
= nullptr; // Type of the pointer operand.
191 GepNode() : Parent(nullptr) {}
192 GepNode(const GepNode
*N
) : Flags(N
->Flags
), Idx(N
->Idx
), PTy(N
->PTy
) {
194 BaseVal
= N
->BaseVal
;
199 friend raw_ostream
&operator<< (raw_ostream
&OS
, const GepNode
&GN
);
202 Type
*next_type(Type
*Ty
, Value
*Idx
) {
203 if (auto *PTy
= dyn_cast
<PointerType
>(Ty
))
204 return PTy
->getElementType();
206 if (!Ty
->isStructTy()) {
207 Type
*NexTy
= cast
<SequentialType
>(Ty
)->getElementType();
210 // Otherwise it is a struct type.
211 ConstantInt
*CI
= dyn_cast
<ConstantInt
>(Idx
);
212 assert(CI
&& "Struct type with non-constant index");
213 int64_t i
= CI
->getValue().getSExtValue();
214 Type
*NextTy
= cast
<StructType
>(Ty
)->getElementType(i
);
218 raw_ostream
&operator<< (raw_ostream
&OS
, const GepNode
&GN
) {
221 if (GN
.Flags
& GepNode::Root
) {
225 if (GN
.Flags
& GepNode::Internal
) {
231 if (GN
.Flags
& GepNode::Used
) {
236 if (GN
.Flags
& GepNode::InBounds
) {
242 if (GN
.Flags
& GepNode::Root
)
243 OS
<< "BaseVal:" << GN
.BaseVal
->getName() << '(' << GN
.BaseVal
<< ')';
245 OS
<< "Parent:" << GN
.Parent
;
248 if (ConstantInt
*CI
= dyn_cast
<ConstantInt
>(GN
.Idx
))
249 OS
<< CI
->getValue().getSExtValue();
250 else if (GN
.Idx
->hasName())
251 OS
<< GN
.Idx
->getName();
253 OS
<< "<anon> =" << *GN
.Idx
;
256 if (GN
.PTy
->isStructTy()) {
257 StructType
*STy
= cast
<StructType
>(GN
.PTy
);
258 if (!STy
->isLiteral())
259 OS
<< GN
.PTy
->getStructName();
261 OS
<< "<anon-struct>:" << *STy
;
269 template <typename NodeContainer
>
270 void dump_node_container(raw_ostream
&OS
, const NodeContainer
&S
) {
271 using const_iterator
= typename
NodeContainer::const_iterator
;
273 for (const_iterator I
= S
.begin(), E
= S
.end(); I
!= E
; ++I
)
274 OS
<< *I
<< ' ' << **I
<< '\n';
277 raw_ostream
&operator<< (raw_ostream
&OS
,
278 const NodeVect
&S
) LLVM_ATTRIBUTE_UNUSED
;
279 raw_ostream
&operator<< (raw_ostream
&OS
, const NodeVect
&S
) {
280 dump_node_container(OS
, S
);
284 raw_ostream
&operator<< (raw_ostream
&OS
,
285 const NodeToUsesMap
&M
) LLVM_ATTRIBUTE_UNUSED
;
286 raw_ostream
&operator<< (raw_ostream
&OS
, const NodeToUsesMap
&M
){
287 using const_iterator
= NodeToUsesMap::const_iterator
;
289 for (const_iterator I
= M
.begin(), E
= M
.end(); I
!= E
; ++I
) {
290 const UseSet
&Us
= I
->second
;
291 OS
<< I
->first
<< " -> #" << Us
.size() << '{';
292 for (UseSet::const_iterator J
= Us
.begin(), F
= Us
.end(); J
!= F
; ++J
) {
293 User
*R
= (*J
)->getUser();
295 OS
<< ' ' << R
->getName();
297 OS
<< " <?>(" << *R
<< ')';
305 in_set(const NodeSet
&S
) : NS(S
) {}
307 bool operator() (GepNode
*N
) const {
308 return NS
.find(N
) != NS
.end();
315 } // end anonymous namespace
317 inline void *operator new(size_t, SpecificBumpPtrAllocator
<GepNode
> &A
) {
321 void HexagonCommonGEP::getBlockTraversalOrder(BasicBlock
*Root
,
323 // Compute block ordering for a typical DT-based traversal of the flow
324 // graph: "before visiting a block, all of its dominators must have been
327 Order
.push_back(Root
);
328 for (auto *DTN
: children
<DomTreeNode
*>(DT
->getNode(Root
)))
329 getBlockTraversalOrder(DTN
->getBlock(), Order
);
332 bool HexagonCommonGEP::isHandledGepForm(GetElementPtrInst
*GepI
) {
334 if (!GepI
->getType()->isPointerTy())
336 // No GEPs without any indices. (Is this possible?)
337 if (GepI
->idx_begin() == GepI
->idx_end())
342 void HexagonCommonGEP::processGepInst(GetElementPtrInst
*GepI
,
343 ValueToNodeMap
&NM
) {
344 LLVM_DEBUG(dbgs() << "Visiting GEP: " << *GepI
<< '\n');
345 GepNode
*N
= new (*Mem
) GepNode
;
346 Value
*PtrOp
= GepI
->getPointerOperand();
347 uint32_t InBounds
= GepI
->isInBounds() ? GepNode::InBounds
: 0;
348 ValueToNodeMap::iterator F
= NM
.find(PtrOp
);
351 N
->Flags
|= GepNode::Root
| InBounds
;
353 // If PtrOp was a GEP instruction, it must have already been processed.
354 // The ValueToNodeMap entry for it is the last gep node in the generated
355 // chain. Link to it here.
356 N
->Parent
= F
->second
;
358 N
->PTy
= PtrOp
->getType();
359 N
->Idx
= *GepI
->idx_begin();
361 // Collect the list of users of this GEP instruction. Will add it to the
362 // last node created for it.
364 for (Value::user_iterator UI
= GepI
->user_begin(), UE
= GepI
->user_end();
366 // Check if this gep is used by anything other than other geps that
368 if (isa
<GetElementPtrInst
>(*UI
)) {
369 GetElementPtrInst
*UserG
= cast
<GetElementPtrInst
>(*UI
);
370 if (isHandledGepForm(UserG
))
373 Us
.insert(&UI
.getUse());
378 // Skip the first index operand, since we only handle 0. This dereferences
379 // the pointer operand.
381 Type
*PtrTy
= cast
<PointerType
>(PtrOp
->getType())->getElementType();
382 for (User::op_iterator OI
= GepI
->idx_begin()+1, OE
= GepI
->idx_end();
385 GepNode
*Nx
= new (*Mem
) GepNode
;
386 Nx
->Parent
= PN
; // Link Nx to the previous node.
387 Nx
->Flags
|= GepNode::Internal
| InBounds
;
391 NodeOrder
.insert(Nx
);
394 PtrTy
= next_type(PtrTy
, Op
);
397 // After last node has been created, update the use information.
399 PN
->Flags
|= GepNode::Used
;
400 Uses
[PN
].insert(Us
.begin(), Us
.end());
403 // Link the last node with the originating GEP instruction. This is to
404 // help with linking chained GEP instructions.
405 NM
.insert(std::make_pair(GepI
, PN
));
408 void HexagonCommonGEP::collect() {
409 // Establish depth-first traversal order of the dominator tree.
411 getBlockTraversalOrder(&Fn
->front(), BO
);
413 // The creation of gep nodes requires DT-traversal. When processing a GEP
414 // instruction that uses another GEP instruction as the base pointer, the
415 // gep node for the base pointer should already exist.
417 for (ValueVect::iterator I
= BO
.begin(), E
= BO
.end(); I
!= E
; ++I
) {
418 BasicBlock
*B
= cast
<BasicBlock
>(*I
);
419 for (BasicBlock::iterator J
= B
->begin(), F
= B
->end(); J
!= F
; ++J
) {
420 if (!isa
<GetElementPtrInst
>(J
))
422 GetElementPtrInst
*GepI
= cast
<GetElementPtrInst
>(J
);
423 if (isHandledGepForm(GepI
))
424 processGepInst(GepI
, NM
);
428 LLVM_DEBUG(dbgs() << "Gep nodes after initial collection:\n" << Nodes
);
431 static void invert_find_roots(const NodeVect
&Nodes
, NodeChildrenMap
&NCM
,
433 using const_iterator
= NodeVect::const_iterator
;
435 for (const_iterator I
= Nodes
.begin(), E
= Nodes
.end(); I
!= E
; ++I
) {
437 if (N
->Flags
& GepNode::Root
) {
441 GepNode
*PN
= N
->Parent
;
442 NCM
[PN
].push_back(N
);
446 static void nodes_for_root(GepNode
*Root
, NodeChildrenMap
&NCM
,
449 Work
.push_back(Root
);
452 while (!Work
.empty()) {
453 NodeVect::iterator First
= Work
.begin();
456 NodeChildrenMap::iterator CF
= NCM
.find(N
);
457 if (CF
!= NCM
.end()) {
458 Work
.insert(Work
.end(), CF
->second
.begin(), CF
->second
.end());
459 Nodes
.insert(CF
->second
.begin(), CF
->second
.end());
466 using NodeSymRel
= std::set
<NodeSet
>;
467 using NodePair
= std::pair
<GepNode
*, GepNode
*>;
468 using NodePairSet
= std::set
<NodePair
>;
470 } // end anonymous namespace
472 static const NodeSet
*node_class(GepNode
*N
, NodeSymRel
&Rel
) {
473 for (NodeSymRel::iterator I
= Rel
.begin(), E
= Rel
.end(); I
!= E
; ++I
)
479 // Create an ordered pair of GepNode pointers. The pair will be used in
480 // determining equality. The only purpose of the ordering is to eliminate
481 // duplication due to the commutativity of equality/non-equality.
482 static NodePair
node_pair(GepNode
*N1
, GepNode
*N2
) {
483 uintptr_t P1
= uintptr_t(N1
), P2
= uintptr_t(N2
);
485 return std::make_pair(N1
, N2
);
486 return std::make_pair(N2
, N1
);
489 static unsigned node_hash(GepNode
*N
) {
490 // Include everything except flags and parent.
492 ID
.AddPointer(N
->Idx
);
493 ID
.AddPointer(N
->PTy
);
494 return ID
.ComputeHash();
497 static bool node_eq(GepNode
*N1
, GepNode
*N2
, NodePairSet
&Eq
,
499 // Don't cache the result for nodes with different hashes. The hash
500 // comparison is fast enough.
501 if (node_hash(N1
) != node_hash(N2
))
504 NodePair NP
= node_pair(N1
, N2
);
505 NodePairSet::iterator FEq
= Eq
.find(NP
);
508 NodePairSet::iterator FNe
= Ne
.find(NP
);
511 // Not previously compared.
512 bool Root1
= N1
->Flags
& GepNode::Root
;
513 bool Root2
= N2
->Flags
& GepNode::Root
;
514 NodePair P
= node_pair(N1
, N2
);
515 // If the Root flag has different values, the nodes are different.
516 // If both nodes are root nodes, but their base pointers differ,
517 // they are different.
518 if (Root1
!= Root2
|| (Root1
&& N1
->BaseVal
!= N2
->BaseVal
)) {
522 // Here the root flags are identical, and for root nodes the
523 // base pointers are equal, so the root nodes are equal.
524 // For non-root nodes, compare their parent nodes.
525 if (Root1
|| node_eq(N1
->Parent
, N2
->Parent
, Eq
, Ne
)) {
532 void HexagonCommonGEP::common() {
533 // The essence of this commoning is finding gep nodes that are equal.
534 // To do this we need to compare all pairs of nodes. To save time,
535 // first, partition the set of all nodes into sets of potentially equal
536 // nodes, and then compare pairs from within each partition.
537 using NodeSetMap
= std::map
<unsigned, NodeSet
>;
540 for (NodeVect::iterator I
= Nodes
.begin(), E
= Nodes
.end(); I
!= E
; ++I
) {
542 unsigned H
= node_hash(N
);
543 MaybeEq
[H
].insert(N
);
546 // Compute the equivalence relation for the gep nodes. Use two caches,
547 // one for equality and the other for non-equality.
548 NodeSymRel EqRel
; // Equality relation (as set of equivalence classes).
549 NodePairSet Eq
, Ne
; // Caches.
550 for (NodeSetMap::iterator I
= MaybeEq
.begin(), E
= MaybeEq
.end();
552 NodeSet
&S
= I
->second
;
553 for (NodeSet::iterator NI
= S
.begin(), NE
= S
.end(); NI
!= NE
; ++NI
) {
555 // If node already has a class, then the class must have been created
556 // in a prior iteration of this loop. Since equality is transitive,
557 // nothing more will be added to that class, so skip it.
558 if (node_class(N
, EqRel
))
561 // Create a new class candidate now.
563 for (NodeSet::iterator NJ
= std::next(NI
); NJ
!= NE
; ++NJ
)
564 if (node_eq(N
, *NJ
, Eq
, Ne
))
566 // If Tmp is empty, N would be the only element in it. Don't bother
567 // creating a class for it then.
569 C
.insert(N
); // Finalize the set before adding it to the relation.
570 std::pair
<NodeSymRel::iterator
, bool> Ins
= EqRel
.insert(C
);
572 assert(Ins
.second
&& "Cannot add a class");
578 dbgs() << "Gep node equality:\n";
579 for (NodePairSet::iterator I
= Eq
.begin(), E
= Eq
.end(); I
!= E
; ++I
)
580 dbgs() << "{ " << I
->first
<< ", " << I
->second
<< " }\n";
582 dbgs() << "Gep equivalence classes:\n";
583 for (NodeSymRel::iterator I
= EqRel
.begin(), E
= EqRel
.end(); I
!= E
; ++I
) {
585 const NodeSet
&S
= *I
;
586 for (NodeSet::const_iterator J
= S
.begin(), F
= S
.end(); J
!= F
; ++J
) {
595 // Create a projection from a NodeSet to the minimal element in it.
596 using ProjMap
= std::map
<const NodeSet
*, GepNode
*>;
598 for (NodeSymRel::iterator I
= EqRel
.begin(), E
= EqRel
.end(); I
!= E
; ++I
) {
599 const NodeSet
&S
= *I
;
600 GepNode
*Min
= *std::min_element(S
.begin(), S
.end(), NodeOrder
);
601 std::pair
<ProjMap::iterator
,bool> Ins
= PM
.insert(std::make_pair(&S
, Min
));
603 assert(Ins
.second
&& "Cannot add minimal element");
605 // Update the min element's flags, and user list.
607 UseSet
&MinUs
= Uses
[Min
];
608 for (NodeSet::iterator J
= S
.begin(), F
= S
.end(); J
!= F
; ++J
) {
610 uint32_t NF
= N
->Flags
;
611 // If N is used, append all original values of N to the list of
612 // original values of Min.
613 if (NF
& GepNode::Used
)
614 MinUs
.insert(Uses
[N
].begin(), Uses
[N
].end());
620 // The collected flags should include all the flags from the min element.
621 assert((Min
->Flags
& Flags
) == Min
->Flags
);
625 // Commoning: for each non-root gep node, replace "Parent" with the
626 // selected (minimum) node from the corresponding equivalence class.
627 // If a given parent does not have an equivalence class, leave it
628 // unchanged (it means that it's the only element in its class).
629 for (NodeVect::iterator I
= Nodes
.begin(), E
= Nodes
.end(); I
!= E
; ++I
) {
631 if (N
->Flags
& GepNode::Root
)
633 const NodeSet
*PC
= node_class(N
->Parent
, EqRel
);
636 ProjMap::iterator F
= PM
.find(PC
);
639 // Found a replacement, use it.
640 GepNode
*Rep
= F
->second
;
644 LLVM_DEBUG(dbgs() << "Gep nodes after commoning:\n" << Nodes
);
646 // Finally, erase the nodes that are no longer used.
648 for (NodeVect::iterator I
= Nodes
.begin(), E
= Nodes
.end(); I
!= E
; ++I
) {
650 const NodeSet
*PC
= node_class(N
, EqRel
);
653 ProjMap::iterator F
= PM
.find(PC
);
661 NodeVect::iterator NewE
= remove_if(Nodes
, in_set(Erase
));
662 Nodes
.resize(std::distance(Nodes
.begin(), NewE
));
664 LLVM_DEBUG(dbgs() << "Gep nodes after post-commoning cleanup:\n" << Nodes
);
667 template <typename T
>
668 static BasicBlock
*nearest_common_dominator(DominatorTree
*DT
, T
&Blocks
) {
670 dbgs() << "NCD of {";
671 for (typename
T::iterator I
= Blocks
.begin(), E
= Blocks
.end(); I
!= E
;
675 BasicBlock
*B
= cast
<BasicBlock
>(*I
);
676 dbgs() << ' ' << B
->getName();
681 // Allow null basic blocks in Blocks. In such cases, return nullptr.
682 typename
T::iterator I
= Blocks
.begin(), E
= Blocks
.end();
685 BasicBlock
*Dom
= cast
<BasicBlock
>(*I
);
687 BasicBlock
*B
= cast_or_null
<BasicBlock
>(*I
);
688 Dom
= B
? DT
->findNearestCommonDominator(Dom
, B
) : nullptr;
692 LLVM_DEBUG(dbgs() << "computed:" << Dom
->getName() << '\n');
696 template <typename T
>
697 static BasicBlock
*nearest_common_dominatee(DominatorTree
*DT
, T
&Blocks
) {
698 // If two blocks, A and B, dominate a block C, then A dominates B,
700 typename
T::iterator I
= Blocks
.begin(), E
= Blocks
.end();
701 // Find the first non-null block.
702 while (I
!= E
&& !*I
)
705 return DT
->getRoot();
706 BasicBlock
*DomB
= cast
<BasicBlock
>(*I
);
710 BasicBlock
*B
= cast
<BasicBlock
>(*I
);
711 if (DT
->dominates(B
, DomB
))
713 if (!DT
->dominates(DomB
, B
))
720 // Find the first use in B of any value from Values. If no such use,
722 template <typename T
>
723 static BasicBlock::iterator
first_use_of_in_block(T
&Values
, BasicBlock
*B
) {
724 BasicBlock::iterator FirstUse
= B
->end(), BEnd
= B
->end();
726 using iterator
= typename
T::iterator
;
728 for (iterator I
= Values
.begin(), E
= Values
.end(); I
!= E
; ++I
) {
730 // If V is used in a PHI node, the use belongs to the incoming block,
731 // not the block with the PHI node. In the incoming block, the use
732 // would be considered as being at the end of it, so it cannot
733 // influence the position of the first use (which is assumed to be
734 // at the end to start with).
737 if (!isa
<Instruction
>(V
))
739 Instruction
*In
= cast
<Instruction
>(V
);
740 if (In
->getParent() != B
)
742 BasicBlock::iterator It
= In
->getIterator();
743 if (std::distance(FirstUse
, BEnd
) < std::distance(It
, BEnd
))
749 static bool is_empty(const BasicBlock
*B
) {
750 return B
->empty() || (&*B
->begin() == B
->getTerminator());
753 BasicBlock
*HexagonCommonGEP::recalculatePlacement(GepNode
*Node
,
754 NodeChildrenMap
&NCM
, NodeToValueMap
&Loc
) {
755 LLVM_DEBUG(dbgs() << "Loc for node:" << Node
<< '\n');
756 // Recalculate the placement for Node, assuming that the locations of
757 // its children in Loc are valid.
758 // Return nullptr if there is no valid placement for Node (for example, it
759 // uses an index value that is not available at the location required
760 // to dominate all children, etc.).
762 // Find the nearest common dominator for:
763 // - all users, if the node is used, and
766 if (Node
->Flags
& GepNode::Used
) {
767 // Append all blocks with uses of the original values to the
769 NodeToUsesMap::iterator UF
= Uses
.find(Node
);
770 assert(UF
!= Uses
.end() && "Used node with no use information");
771 UseSet
&Us
= UF
->second
;
772 for (UseSet::iterator I
= Us
.begin(), E
= Us
.end(); I
!= E
; ++I
) {
774 User
*R
= U
->getUser();
775 if (!isa
<Instruction
>(R
))
777 BasicBlock
*PB
= isa
<PHINode
>(R
)
778 ? cast
<PHINode
>(R
)->getIncomingBlock(*U
)
779 : cast
<Instruction
>(R
)->getParent();
783 // Append the location of each child.
784 NodeChildrenMap::iterator CF
= NCM
.find(Node
);
785 if (CF
!= NCM
.end()) {
786 NodeVect
&Cs
= CF
->second
;
787 for (NodeVect::iterator I
= Cs
.begin(), E
= Cs
.end(); I
!= E
; ++I
) {
789 NodeToValueMap::iterator LF
= Loc
.find(CN
);
790 // If the child is only used in GEP instructions (i.e. is not used in
791 // non-GEP instructions), the nearest dominator computed for it may
792 // have been null. In such case it won't have a location available.
795 Bs
.push_back(LF
->second
);
799 BasicBlock
*DomB
= nearest_common_dominator(DT
, Bs
);
802 // Check if the index used by Node dominates the computed dominator.
803 Instruction
*IdxI
= dyn_cast
<Instruction
>(Node
->Idx
);
804 if (IdxI
&& !DT
->dominates(IdxI
->getParent(), DomB
))
807 // Avoid putting nodes into empty blocks.
808 while (is_empty(DomB
)) {
809 DomTreeNode
*N
= (*DT
)[DomB
]->getIDom();
812 DomB
= N
->getBlock();
815 // Otherwise, DomB is fine. Update the location map.
820 BasicBlock
*HexagonCommonGEP::recalculatePlacementRec(GepNode
*Node
,
821 NodeChildrenMap
&NCM
, NodeToValueMap
&Loc
) {
822 LLVM_DEBUG(dbgs() << "LocRec begin for node:" << Node
<< '\n');
823 // Recalculate the placement of Node, after recursively recalculating the
824 // placements of all its children.
825 NodeChildrenMap::iterator CF
= NCM
.find(Node
);
826 if (CF
!= NCM
.end()) {
827 NodeVect
&Cs
= CF
->second
;
828 for (NodeVect::iterator I
= Cs
.begin(), E
= Cs
.end(); I
!= E
; ++I
)
829 recalculatePlacementRec(*I
, NCM
, Loc
);
831 BasicBlock
*LB
= recalculatePlacement(Node
, NCM
, Loc
);
832 LLVM_DEBUG(dbgs() << "LocRec end for node:" << Node
<< '\n');
836 bool HexagonCommonGEP::isInvariantIn(Value
*Val
, Loop
*L
) {
837 if (isa
<Constant
>(Val
) || isa
<Argument
>(Val
))
839 Instruction
*In
= dyn_cast
<Instruction
>(Val
);
842 BasicBlock
*HdrB
= L
->getHeader(), *DefB
= In
->getParent();
843 return DT
->properlyDominates(DefB
, HdrB
);
846 bool HexagonCommonGEP::isInvariantIn(GepNode
*Node
, Loop
*L
) {
847 if (Node
->Flags
& GepNode::Root
)
848 if (!isInvariantIn(Node
->BaseVal
, L
))
850 return isInvariantIn(Node
->Idx
, L
);
853 bool HexagonCommonGEP::isInMainPath(BasicBlock
*B
, Loop
*L
) {
854 BasicBlock
*HB
= L
->getHeader();
855 BasicBlock
*LB
= L
->getLoopLatch();
856 // B must post-dominate the loop header or dominate the loop latch.
857 if (PDT
->dominates(B
, HB
))
859 if (LB
&& DT
->dominates(B
, LB
))
864 static BasicBlock
*preheader(DominatorTree
*DT
, Loop
*L
) {
865 if (BasicBlock
*PH
= L
->getLoopPreheader())
869 DomTreeNode
*DN
= DT
->getNode(L
->getHeader());
872 return DN
->getIDom()->getBlock();
875 BasicBlock
*HexagonCommonGEP::adjustForInvariance(GepNode
*Node
,
876 NodeChildrenMap
&NCM
, NodeToValueMap
&Loc
) {
877 // Find the "topmost" location for Node: it must be dominated by both,
878 // its parent (or the BaseVal, if it's a root node), and by the index
881 if (Node
->Flags
& GepNode::Root
) {
882 if (Instruction
*PIn
= dyn_cast
<Instruction
>(Node
->BaseVal
))
883 Bs
.push_back(PIn
->getParent());
885 Bs
.push_back(Loc
[Node
->Parent
]);
887 if (Instruction
*IIn
= dyn_cast
<Instruction
>(Node
->Idx
))
888 Bs
.push_back(IIn
->getParent());
889 BasicBlock
*TopB
= nearest_common_dominatee(DT
, Bs
);
891 // Traverse the loop nest upwards until we find a loop in which Node
892 // is no longer invariant, or until we get to the upper limit of Node's
893 // placement. The traversal will also stop when a suitable "preheader"
894 // cannot be found for a given loop. The "preheader" may actually be
895 // a regular block outside of the loop (i.e. not guarded), in which case
896 // the Node will be speculated.
897 // For nodes that are not in the main path of the containing loop (i.e.
898 // are not executed in each iteration), do not move them out of the loop.
899 BasicBlock
*LocB
= cast_or_null
<BasicBlock
>(Loc
[Node
]);
901 Loop
*Lp
= LI
->getLoopFor(LocB
);
903 if (!isInvariantIn(Node
, Lp
) || !isInMainPath(LocB
, Lp
))
905 BasicBlock
*NewLoc
= preheader(DT
, Lp
);
906 if (!NewLoc
|| !DT
->dominates(TopB
, NewLoc
))
908 Lp
= Lp
->getParentLoop();
914 // Recursively compute the locations of all children nodes.
915 NodeChildrenMap::iterator CF
= NCM
.find(Node
);
916 if (CF
!= NCM
.end()) {
917 NodeVect
&Cs
= CF
->second
;
918 for (NodeVect::iterator I
= Cs
.begin(), E
= Cs
.end(); I
!= E
; ++I
)
919 adjustForInvariance(*I
, NCM
, Loc
);
926 struct LocationAsBlock
{
927 LocationAsBlock(const NodeToValueMap
&L
) : Map(L
) {}
929 const NodeToValueMap
&Map
;
932 raw_ostream
&operator<< (raw_ostream
&OS
,
933 const LocationAsBlock
&Loc
) LLVM_ATTRIBUTE_UNUSED
;
934 raw_ostream
&operator<< (raw_ostream
&OS
, const LocationAsBlock
&Loc
) {
935 for (NodeToValueMap::const_iterator I
= Loc
.Map
.begin(), E
= Loc
.Map
.end();
937 OS
<< I
->first
<< " -> ";
938 BasicBlock
*B
= cast
<BasicBlock
>(I
->second
);
939 OS
<< B
->getName() << '(' << B
<< ')';
945 inline bool is_constant(GepNode
*N
) {
946 return isa
<ConstantInt
>(N
->Idx
);
949 } // end anonymous namespace
951 void HexagonCommonGEP::separateChainForNode(GepNode
*Node
, Use
*U
,
952 NodeToValueMap
&Loc
) {
953 User
*R
= U
->getUser();
954 LLVM_DEBUG(dbgs() << "Separating chain for node (" << Node
<< ") user: " << *R
956 BasicBlock
*PB
= cast
<Instruction
>(R
)->getParent();
959 GepNode
*C
= nullptr, *NewNode
= nullptr;
960 while (is_constant(N
) && !(N
->Flags
& GepNode::Root
)) {
961 // XXX if (single-use) dont-replicate;
962 GepNode
*NewN
= new (*Mem
) GepNode(N
);
963 Nodes
.push_back(NewN
);
968 NewN
->Flags
&= ~GepNode::Used
;
977 // Move over all uses that share the same user as U from Node to NewNode.
978 NodeToUsesMap::iterator UF
= Uses
.find(Node
);
979 assert(UF
!= Uses
.end());
980 UseSet
&Us
= UF
->second
;
982 for (UseSet::iterator I
= Us
.begin(); I
!= Us
.end(); ) {
983 User
*S
= (*I
)->getUser();
984 UseSet::iterator Nx
= std::next(I
);
992 Node
->Flags
&= ~GepNode::Used
;
996 // Should at least have U in NewUs.
997 NewNode
->Flags
|= GepNode::Used
;
998 LLVM_DEBUG(dbgs() << "new node: " << NewNode
<< " " << *NewNode
<< '\n');
999 assert(!NewUs
.empty());
1000 Uses
[NewNode
] = NewUs
;
1003 void HexagonCommonGEP::separateConstantChains(GepNode
*Node
,
1004 NodeChildrenMap
&NCM
, NodeToValueMap
&Loc
) {
1005 // First approximation: extract all chains.
1007 nodes_for_root(Node
, NCM
, Ns
);
1009 LLVM_DEBUG(dbgs() << "Separating constant chains for node: " << Node
<< '\n');
1010 // Collect all used nodes together with the uses from loads and stores,
1011 // where the GEP node could be folded into the load/store instruction.
1012 NodeToUsesMap FNs
; // Foldable nodes.
1013 for (NodeSet::iterator I
= Ns
.begin(), E
= Ns
.end(); I
!= E
; ++I
) {
1015 if (!(N
->Flags
& GepNode::Used
))
1017 NodeToUsesMap::iterator UF
= Uses
.find(N
);
1018 assert(UF
!= Uses
.end());
1019 UseSet
&Us
= UF
->second
;
1020 // Loads/stores that use the node N.
1022 for (UseSet::iterator J
= Us
.begin(), F
= Us
.end(); J
!= F
; ++J
) {
1024 User
*R
= U
->getUser();
1025 // We're interested in uses that provide the address. It can happen
1026 // that the value may also be provided via GEP, but we won't handle
1027 // those cases here for now.
1028 if (LoadInst
*Ld
= dyn_cast
<LoadInst
>(R
)) {
1029 unsigned PtrX
= LoadInst::getPointerOperandIndex();
1030 if (&Ld
->getOperandUse(PtrX
) == U
)
1032 } else if (StoreInst
*St
= dyn_cast
<StoreInst
>(R
)) {
1033 unsigned PtrX
= StoreInst::getPointerOperandIndex();
1034 if (&St
->getOperandUse(PtrX
) == U
)
1038 // Even if the total use count is 1, separating the chain may still be
1039 // beneficial, since the constant chain may be longer than the GEP alone
1040 // would be (e.g. if the parent node has a constant index and also has
1043 FNs
.insert(std::make_pair(N
, LSs
));
1046 LLVM_DEBUG(dbgs() << "Nodes with foldable users:\n" << FNs
);
1048 for (NodeToUsesMap::iterator I
= FNs
.begin(), E
= FNs
.end(); I
!= E
; ++I
) {
1049 GepNode
*N
= I
->first
;
1050 UseSet
&Us
= I
->second
;
1051 for (UseSet::iterator J
= Us
.begin(), F
= Us
.end(); J
!= F
; ++J
)
1052 separateChainForNode(N
, *J
, Loc
);
1056 void HexagonCommonGEP::computeNodePlacement(NodeToValueMap
&Loc
) {
1057 // Compute the inverse of the Node.Parent links. Also, collect the set
1059 NodeChildrenMap NCM
;
1061 invert_find_roots(Nodes
, NCM
, Roots
);
1063 // Compute the initial placement determined by the users' locations, and
1064 // the locations of the child nodes.
1065 for (NodeVect::iterator I
= Roots
.begin(), E
= Roots
.end(); I
!= E
; ++I
)
1066 recalculatePlacementRec(*I
, NCM
, Loc
);
1068 LLVM_DEBUG(dbgs() << "Initial node placement:\n" << LocationAsBlock(Loc
));
1071 for (NodeVect::iterator I
= Roots
.begin(), E
= Roots
.end(); I
!= E
; ++I
)
1072 adjustForInvariance(*I
, NCM
, Loc
);
1074 LLVM_DEBUG(dbgs() << "Node placement after adjustment for invariance:\n"
1075 << LocationAsBlock(Loc
));
1077 if (OptEnableConst
) {
1078 for (NodeVect::iterator I
= Roots
.begin(), E
= Roots
.end(); I
!= E
; ++I
)
1079 separateConstantChains(*I
, NCM
, Loc
);
1081 LLVM_DEBUG(dbgs() << "Node use information:\n" << Uses
);
1083 // At the moment, there is no further refinement of the initial placement.
1084 // Such a refinement could include splitting the nodes if they are placed
1085 // too far from some of its users.
1087 LLVM_DEBUG(dbgs() << "Final node placement:\n" << LocationAsBlock(Loc
));
1090 Value
*HexagonCommonGEP::fabricateGEP(NodeVect
&NA
, BasicBlock::iterator At
,
1092 LLVM_DEBUG(dbgs() << "Fabricating GEP in " << LocB
->getName()
1095 unsigned Num
= NA
.size();
1096 GepNode
*RN
= NA
[0];
1097 assert((RN
->Flags
& GepNode::Root
) && "Creating GEP for non-root");
1099 GetElementPtrInst
*NewInst
= nullptr;
1100 Value
*Input
= RN
->BaseVal
;
1101 Value
**IdxList
= new Value
*[Num
+1];
1105 // If the type of the input of the first node is not a pointer,
1106 // we need to add an artificial i32 0 to the indices (because the
1107 // actual input in the IR will be a pointer).
1108 if (!NA
[nax
]->PTy
->isPointerTy()) {
1109 Type
*Int32Ty
= Type::getInt32Ty(*Ctx
);
1110 IdxList
[IdxC
++] = ConstantInt::get(Int32Ty
, 0);
1113 // Keep adding indices from NA until we have to stop and generate
1114 // an "intermediate" GEP.
1115 while (++nax
<= Num
) {
1116 GepNode
*N
= NA
[nax
-1];
1117 IdxList
[IdxC
++] = N
->Idx
;
1119 // We have to stop, if the expected type of the output of this node
1120 // is not the same as the input type of the next node.
1121 Type
*NextTy
= next_type(N
->PTy
, N
->Idx
);
1122 if (NextTy
!= NA
[nax
]->PTy
)
1126 ArrayRef
<Value
*> A(IdxList
, IdxC
);
1127 Type
*InpTy
= Input
->getType();
1128 Type
*ElTy
= cast
<PointerType
>(InpTy
->getScalarType())->getElementType();
1129 NewInst
= GetElementPtrInst::Create(ElTy
, Input
, A
, "cgep", &*At
);
1130 NewInst
->setIsInBounds(RN
->Flags
& GepNode::InBounds
);
1131 LLVM_DEBUG(dbgs() << "new GEP: " << *NewInst
<< '\n');
1133 } while (nax
<= Num
);
1139 void HexagonCommonGEP::getAllUsersForNode(GepNode
*Node
, ValueVect
&Values
,
1140 NodeChildrenMap
&NCM
) {
1142 Work
.push_back(Node
);
1144 while (!Work
.empty()) {
1145 NodeVect::iterator First
= Work
.begin();
1146 GepNode
*N
= *First
;
1148 if (N
->Flags
& GepNode::Used
) {
1149 NodeToUsesMap::iterator UF
= Uses
.find(N
);
1150 assert(UF
!= Uses
.end() && "No use information for used node");
1151 UseSet
&Us
= UF
->second
;
1152 for (UseSet::iterator I
= Us
.begin(), E
= Us
.end(); I
!= E
; ++I
)
1153 Values
.push_back((*I
)->getUser());
1155 NodeChildrenMap::iterator CF
= NCM
.find(N
);
1156 if (CF
!= NCM
.end()) {
1157 NodeVect
&Cs
= CF
->second
;
1158 Work
.insert(Work
.end(), Cs
.begin(), Cs
.end());
1163 void HexagonCommonGEP::materialize(NodeToValueMap
&Loc
) {
1164 LLVM_DEBUG(dbgs() << "Nodes before materialization:\n" << Nodes
<< '\n');
1165 NodeChildrenMap NCM
;
1167 // Compute the inversion again, since computing placement could alter
1168 // "parent" relation between nodes.
1169 invert_find_roots(Nodes
, NCM
, Roots
);
1171 while (!Roots
.empty()) {
1172 NodeVect::iterator First
= Roots
.begin();
1173 GepNode
*Root
= *First
, *Last
= *First
;
1176 NodeVect NA
; // Nodes to assemble.
1177 // Append to NA all child nodes up to (and including) the first child
1179 // (1) has more than 1 child, or
1181 // (3) has a child located in a different block.
1182 bool LastUsed
= false;
1183 unsigned LastCN
= 0;
1184 // The location may be null if the computation failed (it can legitimately
1185 // happen for nodes created from dead GEPs).
1186 Value
*LocV
= Loc
[Last
];
1189 BasicBlock
*LastB
= cast
<BasicBlock
>(LocV
);
1192 LastUsed
= (Last
->Flags
& GepNode::Used
);
1195 NodeChildrenMap::iterator CF
= NCM
.find(Last
);
1196 LastCN
= (CF
!= NCM
.end()) ? CF
->second
.size() : 0;
1199 GepNode
*Child
= CF
->second
.front();
1200 BasicBlock
*ChildB
= cast_or_null
<BasicBlock
>(Loc
[Child
]);
1201 if (ChildB
!= nullptr && LastB
!= ChildB
)
1206 BasicBlock::iterator InsertAt
= LastB
->getTerminator()->getIterator();
1207 if (LastUsed
|| LastCN
> 0) {
1209 getAllUsersForNode(Root
, Urs
, NCM
);
1210 BasicBlock::iterator FirstUse
= first_use_of_in_block(Urs
, LastB
);
1211 if (FirstUse
!= LastB
->end())
1212 InsertAt
= FirstUse
;
1215 // Generate a new instruction for NA.
1216 Value
*NewInst
= fabricateGEP(NA
, InsertAt
, LastB
);
1218 // Convert all the children of Last node into roots, and append them
1219 // to the Roots list.
1221 NodeVect
&Cs
= NCM
[Last
];
1222 for (NodeVect::iterator I
= Cs
.begin(), E
= Cs
.end(); I
!= E
; ++I
) {
1224 CN
->Flags
&= ~GepNode::Internal
;
1225 CN
->Flags
|= GepNode::Root
;
1226 CN
->BaseVal
= NewInst
;
1227 Roots
.push_back(CN
);
1231 // Lastly, if the Last node was used, replace all uses with the new GEP.
1232 // The uses reference the original GEP values.
1234 NodeToUsesMap::iterator UF
= Uses
.find(Last
);
1235 assert(UF
!= Uses
.end() && "No use information found");
1236 UseSet
&Us
= UF
->second
;
1237 for (UseSet::iterator I
= Us
.begin(), E
= Us
.end(); I
!= E
; ++I
) {
1245 void HexagonCommonGEP::removeDeadCode() {
1247 BO
.push_back(&Fn
->front());
1249 for (unsigned i
= 0; i
< BO
.size(); ++i
) {
1250 BasicBlock
*B
= cast
<BasicBlock
>(BO
[i
]);
1251 for (auto DTN
: children
<DomTreeNode
*>(DT
->getNode(B
)))
1252 BO
.push_back(DTN
->getBlock());
1255 for (unsigned i
= BO
.size(); i
> 0; --i
) {
1256 BasicBlock
*B
= cast
<BasicBlock
>(BO
[i
-1]);
1257 BasicBlock::InstListType
&IL
= B
->getInstList();
1259 using reverse_iterator
= BasicBlock::InstListType::reverse_iterator
;
1262 for (reverse_iterator I
= IL
.rbegin(), E
= IL
.rend(); I
!= E
; ++I
)
1264 for (ValueVect::iterator I
= Ins
.begin(), E
= Ins
.end(); I
!= E
; ++I
) {
1265 Instruction
*In
= cast
<Instruction
>(*I
);
1266 if (isInstructionTriviallyDead(In
))
1267 In
->eraseFromParent();
1272 bool HexagonCommonGEP::runOnFunction(Function
&F
) {
1273 if (skipFunction(F
))
1276 // For now bail out on C++ exception handling.
1277 for (Function::iterator A
= F
.begin(), Z
= F
.end(); A
!= Z
; ++A
)
1278 for (BasicBlock::iterator I
= A
->begin(), E
= A
->end(); I
!= E
; ++I
)
1279 if (isa
<InvokeInst
>(I
) || isa
<LandingPadInst
>(I
))
1283 DT
= &getAnalysis
<DominatorTreeWrapperPass
>().getDomTree();
1284 PDT
= &getAnalysis
<PostDominatorTreeWrapperPass
>().getPostDomTree();
1285 LI
= &getAnalysis
<LoopInfoWrapperPass
>().getLoopInfo();
1286 Ctx
= &F
.getContext();
1292 SpecificBumpPtrAllocator
<GepNode
> Allocator
;
1299 computeNodePlacement(Loc
);
1303 #ifdef EXPENSIVE_CHECKS
1304 // Run this only when expensive checks are enabled.
1312 FunctionPass
*createHexagonCommonGEP() {
1313 return new HexagonCommonGEP();
1316 } // end namespace llvm