Skip to content

Commit 82c036e

Browse files
authored
[flang] Restructured TBAA trees in AddAliasTags pass. (#136725)
This patch produces the following TBAA tree for a function: ``` Function root | "any access" | |- "descriptor member" |- "any data access" | |- "dummy arg data" |- "target data" | |- "allocated data" |- "direct data" |- "global data" ``` The TBAA tags are assigned using the following logic: * All POINTER variables point to the root of "target data". * Dummy arguments without POINTER/TARGET point to their leafs under "dummy arg data". * Dummy arguments with TARGET point to the root of "target data". * Global variables without descriptors point to their leafs under "global data" (including the ones with TARGET). * Global variables with descriptors point to their leafs under "direct data" (including the ones with TARGET). * Locally allocated variables point to their leafs under "allocated data" (including the ones with TARGET). This change makes it possible to disambiguate globals like: ``` module data real, allocatable :: a(:) real, allocatable, target :: b(:) end ``` Indeed, two direct references to global vars cannot alias even if any/both of them have TARGET attribute. In addition, the dummy arguments without POINTER/TARGET cannot alias any other variable even with POINTER/TARGET. This was not expressed in TBAA before this change. As before, any "unknown" memory references (such as with Indirect source, as classified by FIR alias analysis) may alias with anything, as long as they point to the root of "any access". Please think of the counterexamples for which this structure may not work.
1 parent 5cec6f6 commit 82c036e

File tree

11 files changed

+666
-171
lines changed

11 files changed

+666
-171
lines changed

flang/include/flang/Optimizer/Analysis/AliasAnalysis.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,12 @@ struct AliasAnalysis {
155155
/// Return true, if Target or Pointer attribute is set.
156156
bool isTargetOrPointer() const;
157157

158+
/// Return true, if Target attribute is set.
159+
bool isTarget() const;
160+
161+
/// Return true, if Pointer attribute is set.
162+
bool isPointer() const;
163+
158164
bool isDummyArgument() const;
159165
bool isData() const;
160166
bool isBoxData() const;

flang/include/flang/Optimizer/Analysis/TBAAForest.h

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ struct TBAATree {
4040

4141
mlir::LLVM::TBAATagAttr getTag(llvm::StringRef uniqueId) const;
4242

43+
/// Create a TBAA tag pointing to the root of this subtree,
44+
/// i.e. all the children tags will alias with this tag.
45+
mlir::LLVM::TBAATagAttr getTag() const;
46+
47+
mlir::LLVM::TBAATypeDescriptorAttr getRoot() const { return parent; }
48+
4349
private:
4450
SubtreeState(mlir::MLIRContext *ctx, std::string name,
4551
mlir::LLVM::TBAANodeAttr grandParent)
@@ -51,17 +57,44 @@ struct TBAATree {
5157
const std::string parentId;
5258
mlir::MLIRContext *const context;
5359
mlir::LLVM::TBAATypeDescriptorAttr parent;
54-
llvm::DenseMap<llvm::StringRef, mlir::LLVM::TBAATagAttr> tagDedup;
5560
};
5661

62+
/// A subtree for POINTER/TARGET variables data.
63+
/// Any POINTER variable must use a tag that points
64+
/// to the root of this subtree.
65+
/// A TARGET dummy argument must also point to this root.
66+
SubtreeState targetDataTree;
67+
/// A subtree for global variables data (e.g. user module variables).
5768
SubtreeState globalDataTree;
69+
/// A subtree for variables allocated via fir.alloca or fir.allocmem.
5870
SubtreeState allocatedDataTree;
71+
/// A subtree for subprogram's dummy arguments.
72+
/// It only contains children for the dummy arguments
73+
/// that are not POINTER/TARGET. They all do not conflict
74+
/// with each other and with any other data access, except
75+
/// with unknown data accesses (FIR alias analysis uses
76+
/// SourceKind::Indirect for sources of such accesses).
5977
SubtreeState dummyArgDataTree;
78+
/// A subtree for global variables descriptors.
6079
SubtreeState directDataTree;
6180
mlir::LLVM::TBAATypeDescriptorAttr anyAccessDesc;
6281
mlir::LLVM::TBAATypeDescriptorAttr boxMemberTypeDesc;
6382
mlir::LLVM::TBAATypeDescriptorAttr anyDataTypeDesc;
6483

84+
// Structure of the created tree:
85+
// Function root
86+
// |
87+
// "any access"
88+
// |
89+
// |- "descriptor member"
90+
// |- "any data access"
91+
// |
92+
// |- "dummy arg data"
93+
// |- "target data"
94+
// |
95+
// |- "allocated data"
96+
// |- "direct data"
97+
// |- "global data"
6598
static TBAATree buildTree(mlir::StringAttr functionName);
6699

67100
private:

flang/lib/Optimizer/Analysis/AliasAnalysis.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,14 @@ bool AliasAnalysis::Source::isTargetOrPointer() const {
110110
attributes.test(Attribute::Target);
111111
}
112112

113+
bool AliasAnalysis::Source::isTarget() const {
114+
return attributes.test(Attribute::Target);
115+
}
116+
117+
bool AliasAnalysis::Source::isPointer() const {
118+
return attributes.test(Attribute::Pointer);
119+
}
120+
113121
bool AliasAnalysis::Source::isDummyArgument() const {
114122
if (auto v = origin.u.dyn_cast<mlir::Value>()) {
115123
return fir::isDummyArgument(v);

flang/lib/Optimizer/Analysis/TBAAForest.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@
1111

1212
mlir::LLVM::TBAATagAttr
1313
fir::TBAATree::SubtreeState::getTag(llvm::StringRef uniqueName) const {
14-
// mlir::LLVM::TBAATagAttr &tag = tagDedup[uniqueName];
15-
// if (tag)
16-
// return tag;
1714
std::string id = (parentId + "/" + uniqueName).str();
1815
mlir::LLVM::TBAATypeDescriptorAttr type =
1916
mlir::LLVM::TBAATypeDescriptorAttr::get(
@@ -22,6 +19,10 @@ fir::TBAATree::SubtreeState::getTag(llvm::StringRef uniqueName) const {
2219
// return tag;
2320
}
2421

22+
mlir::LLVM::TBAATagAttr fir::TBAATree::SubtreeState::getTag() const {
23+
return mlir::LLVM::TBAATagAttr::get(parent, parent, 0);
24+
}
25+
2526
fir::TBAATree fir::TBAATree::buildTree(mlir::StringAttr func) {
2627
llvm::StringRef funcName = func.getValue();
2728
std::string rootId = ("Flang function root " + funcName).str();
@@ -53,9 +54,13 @@ fir::TBAATree fir::TBAATree::buildTree(mlir::StringAttr func) {
5354
fir::TBAATree::TBAATree(mlir::LLVM::TBAATypeDescriptorAttr anyAccess,
5455
mlir::LLVM::TBAATypeDescriptorAttr dataRoot,
5556
mlir::LLVM::TBAATypeDescriptorAttr boxMemberTypeDesc)
56-
: globalDataTree(dataRoot.getContext(), "global data", dataRoot),
57-
allocatedDataTree(dataRoot.getContext(), "allocated data", dataRoot),
57+
: targetDataTree(dataRoot.getContext(), "target data", dataRoot),
58+
globalDataTree(dataRoot.getContext(), "global data",
59+
targetDataTree.getRoot()),
60+
allocatedDataTree(dataRoot.getContext(), "allocated data",
61+
targetDataTree.getRoot()),
5862
dummyArgDataTree(dataRoot.getContext(), "dummy arg data", dataRoot),
59-
directDataTree(dataRoot.getContext(), "direct data", dataRoot),
63+
directDataTree(dataRoot.getContext(), "direct data",
64+
targetDataTree.getRoot()),
6065
anyAccessDesc(anyAccess), boxMemberTypeDesc(boxMemberTypeDesc),
6166
anyDataTypeDesc(dataRoot) {}

flang/lib/Optimizer/Transforms/AddAliasTags.cpp

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -198,12 +198,6 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
198198
LLVM_DEBUG(llvm::dbgs() << "Analysing " << op << "\n");
199199

200200
const fir::AliasAnalysis::Source &source = state.getSource(memref);
201-
if (source.isTargetOrPointer()) {
202-
LLVM_DEBUG(llvm::dbgs().indent(2) << "Skipping TARGET/POINTER\n");
203-
// These will get an "any data access" tag in TBAABuilder (CodeGen): causing
204-
// them to "MayAlias" with all non-box accesses
205-
return;
206-
}
207201

208202
// Process the scopes, if not processed yet.
209203
state.processFunctionScopes(func);
@@ -228,37 +222,48 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
228222
LLVM_DEBUG(llvm::dbgs().indent(2)
229223
<< "Found reference to dummy argument at " << *op << "\n");
230224
std::string name = getFuncArgName(llvm::cast<mlir::Value>(source.origin.u));
231-
if (!name.empty())
225+
// If it is a TARGET or POINTER, then we do not care about the name,
226+
// because the tag points to the root of the subtree currently.
227+
if (source.isTargetOrPointer()) {
228+
tag = state.getFuncTreeWithScope(func, scopeOp).targetDataTree.getTag();
229+
} else if (!name.empty()) {
232230
tag = state.getFuncTreeWithScope(func, scopeOp)
233231
.dummyArgDataTree.getTag(name);
234-
else
232+
} else {
235233
LLVM_DEBUG(llvm::dbgs().indent(2)
236234
<< "WARN: couldn't find a name for dummy argument " << *op
237235
<< "\n");
236+
tag = state.getFuncTreeWithScope(func, scopeOp).dummyArgDataTree.getTag();
237+
}
238238

239-
// TBAA for global variables
239+
// TBAA for global variables without descriptors
240240
} else if (enableGlobals &&
241241
source.kind == fir::AliasAnalysis::SourceKind::Global &&
242242
!source.isBoxData()) {
243243
mlir::SymbolRefAttr glbl = llvm::cast<mlir::SymbolRefAttr>(source.origin.u);
244244
const char *name = glbl.getRootReference().data();
245245
LLVM_DEBUG(llvm::dbgs().indent(2) << "Found reference to global " << name
246246
<< " at " << *op << "\n");
247-
tag = state.getFuncTreeWithScope(func, scopeOp).globalDataTree.getTag(name);
247+
if (source.isPointer())
248+
tag = state.getFuncTreeWithScope(func, scopeOp).targetDataTree.getTag();
249+
else
250+
tag =
251+
state.getFuncTreeWithScope(func, scopeOp).globalDataTree.getTag(name);
248252

249-
// TBAA for SourceKind::Direct
253+
// TBAA for global variables with descriptors
250254
} else if (enableDirect &&
251255
source.kind == fir::AliasAnalysis::SourceKind::Global &&
252256
source.isBoxData()) {
253257
if (auto glbl = llvm::dyn_cast<mlir::SymbolRefAttr>(source.origin.u)) {
254258
const char *name = glbl.getRootReference().data();
255259
LLVM_DEBUG(llvm::dbgs().indent(2) << "Found reference to direct " << name
256260
<< " at " << *op << "\n");
257-
tag =
258-
state.getFuncTreeWithScope(func, scopeOp).directDataTree.getTag(name);
261+
if (source.isPointer())
262+
tag = state.getFuncTreeWithScope(func, scopeOp).targetDataTree.getTag();
263+
else
264+
tag = state.getFuncTreeWithScope(func, scopeOp)
265+
.directDataTree.getTag(name);
259266
} else {
260-
// SourceKind::Direct is likely to be extended to cases which are not a
261-
// SymbolRefAttr in the future
262267
LLVM_DEBUG(llvm::dbgs().indent(2) << "Can't get name for direct "
263268
<< source << " at " << *op << "\n");
264269
}
@@ -269,11 +274,23 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
269274
std::optional<llvm::StringRef> name;
270275
mlir::Operation *sourceOp =
271276
llvm::cast<mlir::Value>(source.origin.u).getDefiningOp();
277+
bool unknownAllocOp = false;
272278
if (auto alloc = mlir::dyn_cast_or_null<fir::AllocaOp>(sourceOp))
273279
name = alloc.getUniqName();
274280
else if (auto alloc = mlir::dyn_cast_or_null<fir::AllocMemOp>(sourceOp))
275281
name = alloc.getUniqName();
276-
if (name) {
282+
else
283+
unknownAllocOp = true;
284+
285+
if (unknownAllocOp) {
286+
LLVM_DEBUG(llvm::dbgs().indent(2)
287+
<< "WARN: unknown defining op for SourceKind::Allocate " << *op
288+
<< "\n");
289+
} else if (source.isPointer()) {
290+
LLVM_DEBUG(llvm::dbgs().indent(2)
291+
<< "Found reference to allocation at " << *op << "\n");
292+
tag = state.getFuncTreeWithScope(func, scopeOp).targetDataTree.getTag();
293+
} else if (name) {
277294
LLVM_DEBUG(llvm::dbgs().indent(2) << "Found reference to allocation "
278295
<< name << " at " << *op << "\n");
279296
tag = state.getFuncTreeWithScope(func, scopeOp)
@@ -282,6 +299,8 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
282299
LLVM_DEBUG(llvm::dbgs().indent(2)
283300
<< "WARN: couldn't find a name for allocation " << *op
284301
<< "\n");
302+
tag =
303+
state.getFuncTreeWithScope(func, scopeOp).allocatedDataTree.getTag();
285304
}
286305
} else {
287306
if (source.kind != fir::AliasAnalysis::SourceKind::Argument &&

0 commit comments

Comments
 (0)