xref: /llvm-project/flang/lib/Optimizer/CodeGen/TBAABuilder.cpp (revision cfe8ae3805de5150141a03b55589b7bc9a91236b)
1 //===-- TBAABuilder.cpp -- TBAA builder definitions -----------------------===//
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 // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "flang/Optimizer/CodeGen/TBAABuilder.h"
14 #include "flang/Optimizer/Dialect/FIRType.h"
15 #include "llvm/ADT/TypeSwitch.h"
16 #include "llvm/Support/CommandLine.h"
17 #include "llvm/Support/Debug.h"
18 
19 #define DEBUG_TYPE "flang-tbaa-builder"
20 
21 using namespace mlir;
22 using namespace mlir::LLVM;
23 
24 static llvm::cl::opt<bool> disableTBAA(
25     "disable-tbaa",
26     llvm::cl::desc("disable attaching TBAA tags to memory accessing operations "
27                    "to override default Flang behavior"),
28     llvm::cl::init(false));
29 
30 // tagAttachmentLimit is a debugging option that allows limiting
31 // the number of TBAA access tag attributes attached to operations.
32 // It is set to kTagAttachmentUnlimited by default denoting "no limit".
33 static constexpr unsigned kTagAttachmentUnlimited =
34     std::numeric_limits<unsigned>::max();
35 static llvm::cl::opt<unsigned>
36     tagAttachmentLimit("tbaa-attach-tag-max", llvm::cl::desc(""),
37                        llvm::cl::init(kTagAttachmentUnlimited));
38 
39 namespace fir {
40 
41 TBAABuilder::TBAABuilder(MLIRContext *context, bool applyTBAA)
42     : enableTBAA(applyTBAA && !disableTBAA) {
43   if (!enableTBAA)
44     return;
45 
46   // Root node.
47   flangTBAARoot =
48       TBAARootAttr::get(context, StringAttr::get(context, flangTBAARootId));
49 
50   // Any access node.
51   anyAccessTypeDesc = TBAATypeDescriptorAttr::get(
52       context, anyAccessTypeDescId, TBAAMemberAttr::get(flangTBAARoot, 0));
53 
54   // Any data access node.
55   anyDataAccessTypeDesc =
56       TBAATypeDescriptorAttr::get(context, anyDataAccessTypeDescId,
57                                   TBAAMemberAttr::get(anyAccessTypeDesc, 0));
58 
59   // Box member access node.
60   boxMemberTypeDesc = TBAATypeDescriptorAttr::get(
61       context, boxMemberTypeDescId, TBAAMemberAttr::get(anyAccessTypeDesc, 0));
62 }
63 
64 TBAATagAttr TBAABuilder::getAccessTag(TBAATypeDescriptorAttr baseTypeDesc,
65                                       TBAATypeDescriptorAttr accessTypeDesc,
66                                       int64_t offset) {
67   TBAATagAttr &tag = tagsMap[{baseTypeDesc, accessTypeDesc, offset}];
68   if (tag)
69     return tag;
70 
71   // Initialize new tag.
72   tag = TBAATagAttr::get(baseTypeDesc, accessTypeDesc, offset);
73   return tag;
74 }
75 
76 TBAATagAttr TBAABuilder::getAnyBoxAccessTag() {
77   return getAccessTag(boxMemberTypeDesc, boxMemberTypeDesc, /*offset=*/0);
78 }
79 
80 TBAATagAttr TBAABuilder::getBoxAccessTag(Type baseFIRType, Type accessFIRType,
81                                          GEPOp gep) {
82   return getAnyBoxAccessTag();
83 }
84 
85 TBAATagAttr TBAABuilder::getAnyDataAccessTag() {
86   return getAccessTag(anyDataAccessTypeDesc, anyDataAccessTypeDesc,
87                       /*offset=*/0);
88 }
89 
90 TBAATagAttr TBAABuilder::getDataAccessTag(Type baseFIRType, Type accessFIRType,
91                                           GEPOp gep) {
92   return getAnyDataAccessTag();
93 }
94 
95 TBAATagAttr TBAABuilder::getAnyAccessTag() {
96   return getAccessTag(anyAccessTypeDesc, anyAccessTypeDesc, /*offset=*/0);
97 }
98 
99 void TBAABuilder::attachTBAATag(AliasAnalysisOpInterface op, Type baseFIRType,
100                                 Type accessFIRType, GEPOp gep) {
101   if (!enableTBAA)
102     return;
103 
104   ++tagAttachmentCounter;
105   if (tagAttachmentLimit != kTagAttachmentUnlimited &&
106       tagAttachmentCounter > tagAttachmentLimit)
107     return;
108 
109   LLVM_DEBUG(llvm::dbgs() << "Attaching TBAA tag #" << tagAttachmentCounter
110                           << "\n");
111 
112   TBAATagAttr tbaaTagSym;
113   if (fir::isRecordWithDescriptorMember(baseFIRType)) {
114     // A memory access that addresses an aggregate that contains
115     // a mix of data members and descriptor members may alias
116     // with both data and descriptor accesses.
117     // Conservatively set any-access tag if there is any descriptor member.
118     tbaaTagSym = getAnyAccessTag();
119   } else if (baseFIRType.isa<fir::BaseBoxType>()) {
120     tbaaTagSym = getBoxAccessTag(baseFIRType, accessFIRType, gep);
121   } else {
122     tbaaTagSym = getDataAccessTag(baseFIRType, accessFIRType, gep);
123   }
124 
125   if (!tbaaTagSym)
126     return;
127 
128   op.setTBAATags(ArrayAttr::get(op->getContext(), tbaaTagSym));
129 }
130 
131 } // namespace fir
132