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#include <mlir/Dialect/LLVMIR/LLVMAttrs.h>
19#include <mlir/Dialect/LLVMIR/LLVMDialect.h>
20#include <mlir/Dialect/LLVMIR/LLVMTypes.h>
21
22#define DEBUG_TYPE "flang-tbaa-builder"
23
24using namespace mlir;
25using namespace mlir::LLVM;
26
27static llvm::cl::opt<bool> disableTBAA(
28 "disable-tbaa",
29 llvm::cl::desc("disable attaching TBAA tags to memory accessing operations "
30 "to override default Flang behavior"),
31 llvm::cl::init(Val: false));
32
33// disabling this will play badly with the FIR TBAA pass, leading to worse
34// performance
35static llvm::cl::opt<bool> perFunctionTBAATrees(
36 "per-function-tbaa-trees",
37 llvm::cl::desc("Give each function an independent TBAA tree (default)"),
38 llvm::cl::init(Val: true), llvm::cl::Hidden);
39
40// tagAttachmentLimit is a debugging option that allows limiting
41// the number of TBAA access tag attributes attached to operations.
42// It is set to kTagAttachmentUnlimited by default denoting "no limit".
43static constexpr unsigned kTagAttachmentUnlimited =
44 std::numeric_limits<unsigned>::max();
45static llvm::cl::opt<unsigned>
46 tagAttachmentLimit("tbaa-attach-tag-max", llvm::cl::desc(""),
47 llvm::cl::init(Val: kTagAttachmentUnlimited));
48
49namespace fir {
50
51TBAABuilder::TBAABuilder(MLIRContext *context, bool applyTBAA,
52 bool forceUnifiedTree)
53 : enableTBAA(applyTBAA && !disableTBAA),
54 trees(/*separatePerFunction=*/perFunctionTBAATrees && !forceUnifiedTree) {
55 if (!enableTBAA)
56 return;
57}
58
59TBAATagAttr TBAABuilder::getAccessTag(TBAATypeDescriptorAttr baseTypeDesc,
60 TBAATypeDescriptorAttr accessTypeDesc,
61 int64_t offset) {
62 TBAATagAttr &tag = tagsMap[{baseTypeDesc, accessTypeDesc, offset}];
63 if (tag)
64 return tag;
65
66 // Initialize new tag.
67 tag = TBAATagAttr::get(baseTypeDesc, accessTypeDesc, offset);
68 return tag;
69}
70
71TBAATagAttr TBAABuilder::getAnyBoxAccessTag(mlir::LLVM::LLVMFuncOp func) {
72 TBAATypeDescriptorAttr boxMemberTypeDesc = trees[func].boxMemberTypeDesc;
73 return getAccessTag(boxMemberTypeDesc, boxMemberTypeDesc, /*offset=*/0);
74}
75
76TBAATagAttr TBAABuilder::getBoxAccessTag(Type baseFIRType, Type accessFIRType,
77 GEPOp gep,
78 mlir::LLVM::LLVMFuncOp func) {
79 return getAnyBoxAccessTag(func);
80}
81
82TBAATagAttr TBAABuilder::getAnyDataAccessTag(mlir::LLVM::LLVMFuncOp func) {
83 TBAATypeDescriptorAttr anyDataAccessTypeDesc = trees[func].anyDataTypeDesc;
84 return getAccessTag(anyDataAccessTypeDesc, anyDataAccessTypeDesc,
85 /*offset=*/0);
86}
87
88TBAATagAttr TBAABuilder::getDataAccessTag(Type baseFIRType, Type accessFIRType,
89 GEPOp gep,
90 mlir::LLVM::LLVMFuncOp func) {
91 return getAnyDataAccessTag(func);
92}
93
94TBAATagAttr TBAABuilder::getAnyAccessTag(mlir::LLVM::LLVMFuncOp func) {
95 TBAATypeDescriptorAttr anyAccessTypeDesc = trees[func].anyAccessDesc;
96 return getAccessTag(anyAccessTypeDesc, anyAccessTypeDesc, /*offset=*/0);
97}
98
99void TBAABuilder::attachTBAATag(AliasAnalysisOpInterface op, Type baseFIRType,
100 Type accessFIRType, GEPOp gep) {
101 if (!enableTBAA)
102 return;
103
104 mlir::LLVM::LLVMFuncOp func = op->getParentOfType<mlir::LLVM::LLVMFuncOp>();
105 if (!func)
106 return;
107
108 ++tagAttachmentCounter;
109 if (tagAttachmentLimit != kTagAttachmentUnlimited &&
110 tagAttachmentCounter > tagAttachmentLimit)
111 return;
112
113 LLVM_DEBUG(llvm::dbgs() << "Attaching TBAA tag #" << tagAttachmentCounter
114 << "\n");
115
116 TBAATagAttr tbaaTagSym;
117 if (fir::isRecordWithDescriptorMember(baseFIRType)) {
118 // A memory access that addresses an aggregate that contains
119 // a mix of data members and descriptor members may alias
120 // with both data and descriptor accesses.
121 // Conservatively set any-access tag if there is any descriptor member.
122 tbaaTagSym = getAnyAccessTag(func);
123 } else if (baseFIRType.isa<fir::BaseBoxType>()) {
124 tbaaTagSym = getBoxAccessTag(baseFIRType, accessFIRType, gep, func);
125 } else {
126 tbaaTagSym = getDataAccessTag(baseFIRType, accessFIRType, gep, func);
127 }
128
129 if (!tbaaTagSym)
130 return;
131
132 op.setTBAATags(ArrayAttr::get(op->getContext(), tbaaTagSym));
133}
134
135} // namespace fir
136

source code of flang/lib/Optimizer/CodeGen/TBAABuilder.cpp