|
98 | 98 | #define LLVM_TRANSFORMS_IPO_ATTRIBUTOR_H |
99 | 99 |
|
100 | 100 | #include "llvm/ADT/DenseSet.h" |
| 101 | +#include "llvm/ADT/DirectedGraph.h" |
101 | 102 | #include "llvm/ADT/GraphTraits.h" |
102 | 103 | #include "llvm/ADT/MapVector.h" |
| 104 | +#include "llvm/ADT/PriorityQueue.h" |
103 | 105 | #include "llvm/ADT/STLExtras.h" |
104 | 106 | #include "llvm/ADT/SetOperations.h" |
105 | 107 | #include "llvm/ADT/SetVector.h" |
106 | 108 | #include "llvm/ADT/SmallSet.h" |
| 109 | +#include "llvm/ADT/SmallVector.h" |
107 | 110 | #include "llvm/ADT/iterator.h" |
108 | 111 | #include "llvm/Analysis/AssumeBundleQueries.h" |
109 | 112 | #include "llvm/Analysis/CFG.h" |
110 | 113 | #include "llvm/Analysis/CGSCCPassManager.h" |
| 114 | +#include "llvm/Analysis/DDG.h" |
111 | 115 | #include "llvm/Analysis/LazyCallGraph.h" |
112 | 116 | #include "llvm/Analysis/LoopInfo.h" |
113 | 117 | #include "llvm/Analysis/MemoryLocation.h" |
|
140 | 144 | #include <limits> |
141 | 145 | #include <map> |
142 | 146 | #include <optional> |
| 147 | +#include <tuple> |
143 | 148 |
|
144 | 149 | namespace llvm { |
145 | 150 |
|
@@ -6372,6 +6377,107 @@ struct AAAllocationInfo : public StateWrapper<BooleanState, AbstractAttribute> { |
6372 | 6377 |
|
6373 | 6378 | using NewOffsetsTy = DenseMap<AA::RangeTy, AA::RangeTy>; |
6374 | 6379 | virtual const NewOffsetsTy &getNewOffsets() const = 0; |
| 6380 | + struct FieldAccessGraphEdge; |
| 6381 | + struct FieldAccessGraphNode; |
| 6382 | + |
| 6383 | + struct PriorityQueueGraphNode { |
| 6384 | + PriorityQueueGraphNode(int Priority, FieldAccessGraphNode *Node) |
| 6385 | + : Priority(Priority), Node(Node) {} |
| 6386 | + |
| 6387 | + public: |
| 6388 | + int Priority; |
| 6389 | + FieldAccessGraphNode *Node; |
| 6390 | + |
| 6391 | + int getPriority() { return Priority; } |
| 6392 | + FieldAccessGraphNode *getNode() { return Node; } |
| 6393 | + |
| 6394 | + bool operator<(const PriorityQueueGraphNode *A) { |
| 6395 | + return A->Priority > Priority; |
| 6396 | + } |
| 6397 | + |
| 6398 | + bool operator==(const PriorityQueueGraphNode *A) { |
| 6399 | + return A->Priority == Priority; |
| 6400 | + } |
| 6401 | + |
| 6402 | + bool operator>(const PriorityQueueGraphNode *A) { |
| 6403 | + return A->Priority > Priority; |
| 6404 | + } |
| 6405 | + }; |
| 6406 | + |
| 6407 | + // A Edge Type for the field access graph edge |
| 6408 | + struct FieldAccessGraphEdge |
| 6409 | + : public DGEdge<FieldAccessGraphNode, FieldAccessGraphEdge> { |
| 6410 | + FieldAccessGraphEdge(FieldAccessGraphNode &TargetNode, int EdgeWeight) |
| 6411 | + : DGEdge<FieldAccessGraphNode, FieldAccessGraphEdge>(TargetNode), |
| 6412 | + EdgeWeight(EdgeWeight) {} |
| 6413 | + |
| 6414 | + public: |
| 6415 | + FieldAccessGraphNode *SrcNode; |
| 6416 | + int EdgeWeight; |
| 6417 | + int getEdgeWeight() { return EdgeWeight; } |
| 6418 | + void setSrcNode(FieldAccessGraphNode *SourceNode) { SrcNode = SourceNode; } |
| 6419 | + FieldAccessGraphNode *getSourceNode() { return SrcNode; } |
| 6420 | + }; |
| 6421 | + |
| 6422 | + // A node type for the field access graph node |
| 6423 | + struct FieldAccessGraphNode |
| 6424 | + : public DGNode<FieldAccessGraphNode, FieldAccessGraphEdge> { |
| 6425 | + FieldAccessGraphNode(const AA::RangeTy &Node, FieldAccessGraphEdge &Edge) |
| 6426 | + : DGNode<FieldAccessGraphNode, FieldAccessGraphEdge>(Edge), |
| 6427 | + BinRange(Node) {} |
| 6428 | + FieldAccessGraphNode(const AA::RangeTy &Node) : BinRange(Node) {} |
| 6429 | + |
| 6430 | + public: |
| 6431 | + const AA::RangeTy BinRange; |
| 6432 | + const AA::RangeTy &getBinRange() const { return BinRange; } |
| 6433 | + }; |
| 6434 | + |
| 6435 | + struct FieldAccessGraph |
| 6436 | + : public DirectedGraph<FieldAccessGraphNode, FieldAccessGraphEdge> { |
| 6437 | + FieldAccessGraph() {} |
| 6438 | + |
| 6439 | + public: |
| 6440 | + FieldAccessGraphNode *getNode(const AA::RangeTy &Range) { |
| 6441 | + for (FieldAccessGraphNode *N : Nodes) { |
| 6442 | + if (N->getBinRange() == Range) { |
| 6443 | + return N; |
| 6444 | + } |
| 6445 | + } |
| 6446 | + return nullptr; |
| 6447 | + } |
| 6448 | + |
| 6449 | + bool findNode(const AA::RangeTy &Range) { |
| 6450 | + for (FieldAccessGraphNode *N : Nodes) { |
| 6451 | + if (N->getBinRange() == Range) { |
| 6452 | + return true; |
| 6453 | + } |
| 6454 | + } |
| 6455 | + return false; |
| 6456 | + } |
| 6457 | + |
| 6458 | + bool edgeExists(const AA::RangeTy &HeadNode, |
| 6459 | + FieldAccessGraphNode *TargetNode) { |
| 6460 | + for (FieldAccessGraphNode *N : Nodes) { |
| 6461 | + if (N->getBinRange() == HeadNode) { |
| 6462 | + return N->hasEdgeTo(*TargetNode); |
| 6463 | + } |
| 6464 | + } |
| 6465 | + return false; |
| 6466 | + } |
| 6467 | + |
| 6468 | + // return all nodes that have no incoming edges. |
| 6469 | + void getAllRoots(std::vector<FieldAccessGraphNode *> &Roots) { |
| 6470 | + assert(Roots.empty() && "Root set should be empty at the begining!"); |
| 6471 | + for (FieldAccessGraphNode *N : Nodes) { |
| 6472 | + SmallVector<FieldAccessGraphEdge *> EL; |
| 6473 | + if (!findIncomingEdgesToNode(*N, EL)) { |
| 6474 | + Roots.push_back(N); |
| 6475 | + } |
| 6476 | + } |
| 6477 | + } |
| 6478 | + }; |
| 6479 | + |
| 6480 | + virtual const FieldAccessGraph &getBinAccessGraph() const = 0; |
6375 | 6481 |
|
6376 | 6482 | /// See AbstractAttribute::getName() |
6377 | 6483 | const std::string getName() const override { return "AAAllocationInfo"; } |
|
0 commit comments