FLANG
TBAAForest.h
1//===-- TBAAForest.h - A TBAA tree for each function -----------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef FORTRAN_OPTIMIZER_ANALYSIS_TBAA_FOREST_H
10#define FORTRAN_OPTIMIZER_ANALYSIS_TBAA_FOREST_H
11
12#include "flang/Optimizer/Dialect/FIROpsSupport.h"
13#include "mlir/Dialect/Func/IR/FuncOps.h"
14#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
15#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
16#include "mlir/IR/Attributes.h"
17#include "mlir/IR/MLIRContext.h"
18#include "llvm/ADT/DenseMap.h"
19#include <string>
20
21namespace fir {
22
23//===----------------------------------------------------------------------===//
24// TBAATree
25//===----------------------------------------------------------------------===//
28struct TBAATree {
29 //===----------------------------------------------------------------------===//
30 // TBAAForrest::TBAATree::SubtreeState
31 //===----------------------------------------------------------------------===//
34 class SubtreeState {
35 friend TBAATree; // only allow construction by TBAATree
36 public:
37 SubtreeState() = delete;
38 SubtreeState(const SubtreeState &) = delete;
39 SubtreeState(SubtreeState &&) = default;
40
41 mlir::LLVM::TBAATagAttr getTag(llvm::StringRef uniqueId) const;
42
45 mlir::LLVM::TBAATagAttr getTag() const;
46
47 mlir::LLVM::TBAATypeDescriptorAttr getRoot() const { return parent; }
48
53 SubtreeState &getOrCreateNamedSubtree(mlir::StringAttr name);
54
55 private:
56 SubtreeState(mlir::MLIRContext *ctx, std::string name,
57 mlir::LLVM::TBAANodeAttr grandParent)
58 : parentId{std::move(name)}, context(ctx) {
59 parent = mlir::LLVM::TBAATypeDescriptorAttr::get(
60 context, parentId, mlir::LLVM::TBAAMemberAttr::get(grandParent, 0));
61 }
62
63 const std::string parentId;
64 mlir::MLIRContext *const context;
65 mlir::LLVM::TBAATypeDescriptorAttr parent;
66 // A map of named sub-trees, e.g. sub-trees of the COMMON blocks
67 // placed under the "global data" root.
68 llvm::DenseMap<mlir::StringAttr, SubtreeState> namedSubtrees;
69 };
70
89 mlir::LLVM::TBAATypeDescriptorAttr anyAccessDesc;
90 mlir::LLVM::TBAATypeDescriptorAttr boxMemberTypeDesc;
91 mlir::LLVM::TBAATypeDescriptorAttr anyDataTypeDesc;
92
93 // Structure of the created tree:
94 // Function root
95 // |
96 // "any access"
97 // |
98 // |- "descriptor member"
99 // |- "any data access"
100 // |
101 // |- "dummy arg data"
102 // |- "target data"
103 // |
104 // |- "allocated data"
105 // |- "direct data"
106 // |- "global data"
107 static TBAATree buildTree(mlir::StringAttr functionName);
108
109private:
110 TBAATree(mlir::LLVM::TBAATypeDescriptorAttr anyAccess,
111 mlir::LLVM::TBAATypeDescriptorAttr dataRoot,
112 mlir::LLVM::TBAATypeDescriptorAttr boxMemberTypeDesc);
113};
114
115//===----------------------------------------------------------------------===//
116// TBAAForrest
117//===----------------------------------------------------------------------===//
120class TBAAForrest {
121public:
122 explicit TBAAForrest(bool separatePerFunction = true)
123 : separatePerFunction{separatePerFunction} {}
124
125 inline const TBAATree &operator[](mlir::func::FuncOp func) {
126 return getFuncTree(func.getSymNameAttr());
127 }
128 inline const TBAATree &operator[](mlir::LLVM::LLVMFuncOp func) {
129 // the external name conversion pass may rename some functions. Their old
130 // name must be used so that we add to the tbaa tree added in the FIR pass
131 mlir::Attribute attr = func->getAttr(getInternalFuncNameAttrName());
132 if (attr) {
133 return getFuncTree(mlir::cast<mlir::StringAttr>(attr));
134 }
135 return getFuncTree(func.getSymNameAttr());
136 }
137 // Returns the TBAA tree associated with the scope enclosed
138 // within the given function. With MLIR inlining, there may
139 // be multiple scopes within a single function. It is the caller's
140 // responsibility to provide unique name for the scope.
141 // If the scope string is empty, returns the TBAA tree for the
142 // "root" scope of the given function.
143 inline TBAATree &getMutableFuncTreeWithScope(mlir::func::FuncOp func,
144 llvm::StringRef scope) {
145 mlir::StringAttr name = func.getSymNameAttr();
146 if (!scope.empty())
147 name = mlir::StringAttr::get(name.getContext(),
148 llvm::Twine(name) + " - " + scope);
149 return getFuncTree(name);
150 }
151
152 inline const TBAATree &getFuncTreeWithScope(mlir::func::FuncOp func,
153 llvm::StringRef scope) {
154 return getMutableFuncTreeWithScope(func, scope);
155 }
156
157private:
158 TBAATree &getFuncTree(mlir::StringAttr symName) {
159 if (!separatePerFunction)
160 symName = mlir::StringAttr::get(symName.getContext(), "");
161 if (!trees.contains(symName))
162 trees.insert({symName, TBAATree::buildTree(symName)});
163 auto it = trees.find(symName);
164 assert(it != trees.end());
165 return it->second;
166 }
167
168 // Should each function use a different tree?
169 const bool separatePerFunction;
170 // TBAA tree per function
171 llvm::DenseMap<mlir::StringAttr, TBAATree> trees;
172};
173
174} // namespace fir
175
176#endif // FORTRAN_OPTIMIZER_ANALYSIS_TBAA_FOREST_H
Definition TBAAForest.h:34
SubtreeState & getOrCreateNamedSubtree(mlir::StringAttr name)
Definition TBAAForest.cpp:22
mlir::LLVM::TBAATagAttr getTag() const
Definition TBAAForest.cpp:33
Definition AbstractConverter.h:34
Definition TBAAForest.h:28
SubtreeState directDataTree
A subtree for global variables descriptors.
Definition TBAAForest.h:88
SubtreeState globalDataTree
A subtree for global variables data (e.g. user module variables).
Definition TBAAForest.h:77
SubtreeState targetDataTree
Definition TBAAForest.h:75
SubtreeState allocatedDataTree
A subtree for variables allocated via fir.alloca or fir.allocmem.
Definition TBAAForest.h:79
SubtreeState dummyArgDataTree
Definition TBAAForest.h:86