See RFC at https://discourse.llvm.org/t/rfc-propagate-fir-alias-analysis-information-using-tbaa/73755 This pass adds TBAA tags to all accesses to non-pointer/target dummy arguments. These TBAA tags tell LLVM that these accesses cannot alias: allowing better dead code elimination, hoisting out of loops, and vectorization. Each function has its own TBAA tree so that accesses between funtions MayAlias after inlining. I also included code for adding tags for local allocations and for global variables. Enabling all three kinds of tag is known to produce a miscompile and so these are disabled by default. But it isn't much code and I thought it could be interesting to play with these later if one is looking at a benchmark which looks like it would benefit from more alias information. I'm open to removing this code too. TBAA tags are also added separately by TBAABuilder during CodeGen. TBAABuilder has to run during CodeGen because it adds tags to box accesses, many of which are implicit in FIR. This pass cannot (easily) run in CodeGen because fir::AliasAnalysis has difficulty tracing values between blocks, and by the time CodeGen runs, structured control flow has already been lowered. Coming in follow up patches - Change CodeGen/TBAABuilder to use TBAAForest to add tags within the same per-function trees as are used here (delayed to a later patch to make it easier to revert) - Command line argument processing to actually enable the pass
61 lines
2.6 KiB
C++
61 lines
2.6 KiB
C++
//===- TBAAForest.cpp - Per-functon TBAA Trees ----------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "flang/Optimizer/Analysis/TBAAForest.h"
|
|
#include <mlir/Dialect/LLVMIR/LLVMAttrs.h>
|
|
|
|
mlir::LLVM::TBAATagAttr
|
|
fir::TBAATree::SubtreeState::getTag(llvm::StringRef uniqueName) const {
|
|
// mlir::LLVM::TBAATagAttr &tag = tagDedup[uniqueName];
|
|
// if (tag)
|
|
// return tag;
|
|
std::string id = (parentId + "/" + uniqueName).str();
|
|
mlir::LLVM::TBAATypeDescriptorAttr type =
|
|
mlir::LLVM::TBAATypeDescriptorAttr::get(
|
|
context, id, mlir::LLVM::TBAAMemberAttr::get(parent, 0));
|
|
return mlir::LLVM::TBAATagAttr::get(type, type, 0);
|
|
// return tag;
|
|
}
|
|
|
|
fir::TBAATree fir::TBAATree::buildTree(mlir::StringAttr func) {
|
|
llvm::StringRef funcName = func.getValue();
|
|
std::string rootId = ("Flang function root " + funcName).str();
|
|
mlir::MLIRContext *ctx = func.getContext();
|
|
mlir::LLVM::TBAARootAttr funcRoot =
|
|
mlir::LLVM::TBAARootAttr::get(ctx, mlir::StringAttr::get(ctx, rootId));
|
|
|
|
static constexpr llvm::StringRef anyAccessTypeDescId = "any access";
|
|
mlir::LLVM::TBAATypeDescriptorAttr anyAccess =
|
|
mlir::LLVM::TBAATypeDescriptorAttr::get(
|
|
ctx, anyAccessTypeDescId,
|
|
mlir::LLVM::TBAAMemberAttr::get(funcRoot, 0));
|
|
|
|
static constexpr llvm::StringRef anyDataAccessTypeDescId = "any data access";
|
|
mlir::LLVM::TBAATypeDescriptorAttr dataRoot =
|
|
mlir::LLVM::TBAATypeDescriptorAttr::get(
|
|
ctx, anyDataAccessTypeDescId,
|
|
mlir::LLVM::TBAAMemberAttr::get(anyAccess, 0));
|
|
|
|
static constexpr llvm::StringRef boxMemberTypeDescId = "descriptor member";
|
|
mlir::LLVM::TBAATypeDescriptorAttr boxMemberTypeDesc =
|
|
mlir::LLVM::TBAATypeDescriptorAttr::get(
|
|
ctx, boxMemberTypeDescId,
|
|
mlir::LLVM::TBAAMemberAttr::get(anyAccess, 0));
|
|
|
|
return TBAATree{anyAccess, dataRoot, boxMemberTypeDesc};
|
|
}
|
|
|
|
fir::TBAATree::TBAATree(mlir::LLVM::TBAATypeDescriptorAttr anyAccess,
|
|
mlir::LLVM::TBAATypeDescriptorAttr dataRoot,
|
|
mlir::LLVM::TBAATypeDescriptorAttr boxMemberTypeDesc)
|
|
: globalDataTree(dataRoot.getContext(), "global data", dataRoot),
|
|
allocatedDataTree(dataRoot.getContext(), "allocated data", dataRoot),
|
|
dummyArgDataTree(dataRoot.getContext(), "dummy arg data", dataRoot),
|
|
anyAccessDesc(anyAccess), boxMemberTypeDesc(boxMemberTypeDesc),
|
|
anyDataTypeDesc(dataRoot) {}
|