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 //===----------------------------------------------------------------------===//
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
43 private:
44 SubtreeState(mlir::MLIRContext *ctx, std::string name,
45 mlir::LLVM::TBAANodeAttr grandParent)
46 : parentId{std::move(name)}, context(ctx) {
47 parent = mlir::LLVM::TBAATypeDescriptorAttr::get(
48 context, parentId, mlir::LLVM::TBAAMemberAttr::get(grandParent, 0));
49 }
50
51 const std::string parentId;
52 mlir::MLIRContext *const context;
53 mlir::LLVM::TBAATypeDescriptorAttr parent;
54 llvm::DenseMap<llvm::StringRef, mlir::LLVM::TBAATagAttr> tagDedup;
55 };
56
57 SubtreeState globalDataTree;
58 SubtreeState allocatedDataTree;
59 SubtreeState dummyArgDataTree;
60 SubtreeState directDataTree;
61 mlir::LLVM::TBAATypeDescriptorAttr anyAccessDesc;
62 mlir::LLVM::TBAATypeDescriptorAttr boxMemberTypeDesc;
63 mlir::LLVM::TBAATypeDescriptorAttr anyDataTypeDesc;
64
65 static TBAATree buildTree(mlir::StringAttr functionName);
66
67private:
68 TBAATree(mlir::LLVM::TBAATypeDescriptorAttr anyAccess,
69 mlir::LLVM::TBAATypeDescriptorAttr dataRoot,
70 mlir::LLVM::TBAATypeDescriptorAttr boxMemberTypeDesc);
71};
72
73//===----------------------------------------------------------------------===//
74// TBAAForrest
75//===----------------------------------------------------------------------===//
79public:
80 explicit TBAAForrest(bool separatePerFunction = true)
81 : separatePerFunction{separatePerFunction} {}
82
83 inline const TBAATree &operator[](mlir::func::FuncOp func) {
84 return getFuncTree(func.getSymNameAttr());
85 }
86 inline const TBAATree &operator[](mlir::LLVM::LLVMFuncOp func) {
87 // the external name conversion pass may rename some functions. Their old
88 // name must be used so that we add to the tbaa tree added in the FIR pass
89 mlir::Attribute attr = func->getAttr(getInternalFuncNameAttrName());
90 if (attr) {
91 return getFuncTree(mlir::cast<mlir::StringAttr>(attr));
92 }
93 return getFuncTree(func.getSymNameAttr());
94 }
95 // Returns the TBAA tree associated with the scope enclosed
96 // within the given function. With MLIR inlining, there may
97 // be multiple scopes within a single function. It is the caller's
98 // responsibility to provide unique name for the scope.
99 // If the scope string is empty, returns the TBAA tree for the
100 // "root" scope of the given function.
101 inline const TBAATree &getFuncTreeWithScope(mlir::func::FuncOp func,
102 llvm::StringRef scope) {
103 mlir::StringAttr name = func.getSymNameAttr();
104 if (!scope.empty())
105 name = mlir::StringAttr::get(name.getContext(),
106 llvm::Twine(name) + " - " + scope);
107 return getFuncTree(name);
108 }
109
110private:
111 const TBAATree &getFuncTree(mlir::StringAttr symName) {
112 if (!separatePerFunction)
113 symName = mlir::StringAttr::get(symName.getContext(), "");
114 if (!trees.contains(symName))
115 trees.insert({symName, TBAATree::buildTree(symName)});
116 return trees.at(symName);
117 }
118
119 // Should each function use a different tree?
120 const bool separatePerFunction;
121 // TBAA tree per function
122 llvm::DenseMap<mlir::StringAttr, TBAATree> trees;
123};
124
125} // namespace fir
126
127#endif // FORTRAN_OPTIMIZER_ANALYSIS_TBAA_FOREST_H
Definition: TBAAForest.h:78
Definition: TBAAForest.h:34
Definition: AbstractConverter.h:31
Definition: TBAAForest.h:28