brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.5 KiB · 7a3f3b5 Raw
168 lines · cpp
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-exception6//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(false));32 33// disabling this will play badly with the FIR TBAA pass, leading to worse34// performance35static 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(true), llvm::cl::Hidden);39 40// tagAttachmentLimit is a debugging option that allows limiting41// 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(kTagAttachmentUnlimited));48 49namespace fir {50 51TBAABuilder::TBAABuilder(MLIRContext *context, bool applyTBAA,52                         bool forceUnifiedTree)53    : enableTBAA(applyTBAA && !disableTBAA),54      trees(/*separatePerFunction=*/perFunctionTBAATrees && !forceUnifiedTree) {55  // TODO: the TBAA tags created here are rooted in the root scope56  // of the enclosing function. This does not work best with MLIR inlining.57  // A better approach is to root them according to the scopes they belong to58  // and that were used by AddAliasTagsPass to create TBAA tags before59  // the CodeGen. For example:60  //   subroutine caller(a, b, ptr)61  //     real, target :: a(:), b(:)62  //     integer, pointer :: ptr(:)63  //     call callee(a, b, ptr)64  //   end65  //   subroutine callee(a, b, ptr)66  //     real :: a(:), b(:)67  //     integer, pointer :: ptr(:)68  //     do i=...69  //       a(ptr(i)) = b(ptr(i))70  //     end do71  //   end72  //73  // When callee is inlined, the dummy arguments 'a' and 'b' will74  // be rooted in TBAA tree corresponding to the `call callee` call site,75  // saying that the references to 'a' and 'b' cannot alias each other.76  // These tags will be created by AddAliasTagsPass, but it will not be able77  // to create any tags for 'ptr' references.78  // During the CodeGen, we create 'any data access' tags for the79  // 'ptr' acceses. If they are rooted within the root scope of `caller`,80  // they end up in a different TBAA tree with the 'a' and 'b' access81  // tags, so 'ptr', 'a' and 'b' references MayAlias. Moreover,82  // the box access of 'ptr' will also be in a different TBAA tree83  // with 'a' and 'b' tags, meaning they can also alias.84  // This will prevent LLVM vectorization even with memory conflict checks.85  // It seems that we'd better move all TBAA tags assignment to86  // AddAliasTagsPass, which can at least rely on the dummy arguments scopes.87  if (!enableTBAA)88    return;89}90 91TBAATagAttr TBAABuilder::getAccessTag(TBAATypeDescriptorAttr baseTypeDesc,92                                      TBAATypeDescriptorAttr accessTypeDesc,93                                      int64_t offset) {94  TBAATagAttr &tag = tagsMap[{baseTypeDesc, accessTypeDesc, offset}];95  if (tag)96    return tag;97 98  // Initialize new tag.99  tag = TBAATagAttr::get(baseTypeDesc, accessTypeDesc, offset);100  return tag;101}102 103TBAATagAttr TBAABuilder::getAnyBoxAccessTag(mlir::LLVM::LLVMFuncOp func) {104  TBAATypeDescriptorAttr boxMemberTypeDesc = trees[func].boxMemberTypeDesc;105  return getAccessTag(boxMemberTypeDesc, boxMemberTypeDesc, /*offset=*/0);106}107 108TBAATagAttr TBAABuilder::getBoxAccessTag(Type baseFIRType, Type accessFIRType,109                                         GEPOp gep,110                                         mlir::LLVM::LLVMFuncOp func) {111  return getAnyBoxAccessTag(func);112}113 114TBAATagAttr TBAABuilder::getAnyDataAccessTag(mlir::LLVM::LLVMFuncOp func) {115  TBAATypeDescriptorAttr anyDataAccessTypeDesc = trees[func].anyDataTypeDesc;116  return getAccessTag(anyDataAccessTypeDesc, anyDataAccessTypeDesc,117                      /*offset=*/0);118}119 120TBAATagAttr TBAABuilder::getDataAccessTag(Type baseFIRType, Type accessFIRType,121                                          GEPOp gep,122                                          mlir::LLVM::LLVMFuncOp func) {123  return getAnyDataAccessTag(func);124}125 126TBAATagAttr TBAABuilder::getAnyAccessTag(mlir::LLVM::LLVMFuncOp func) {127  TBAATypeDescriptorAttr anyAccessTypeDesc = trees[func].anyAccessDesc;128  return getAccessTag(anyAccessTypeDesc, anyAccessTypeDesc, /*offset=*/0);129}130 131void TBAABuilder::attachTBAATag(AliasAnalysisOpInterface op, Type baseFIRType,132                                Type accessFIRType, GEPOp gep) {133  if (!enableTBAA)134    return;135 136  mlir::LLVM::LLVMFuncOp func = op->getParentOfType<mlir::LLVM::LLVMFuncOp>();137  if (!func)138    return;139 140  ++tagAttachmentCounter;141  if (tagAttachmentLimit != kTagAttachmentUnlimited &&142      tagAttachmentCounter > tagAttachmentLimit)143    return;144 145  LLVM_DEBUG(llvm::dbgs() << "Attaching TBAA tag #" << tagAttachmentCounter146                          << "\n");147 148  TBAATagAttr tbaaTagSym;149  if (fir::isRecordWithDescriptorMember(baseFIRType)) {150    // A memory access that addresses an aggregate that contains151    // a mix of data members and descriptor members may alias152    // with both data and descriptor accesses.153    // Conservatively set any-access tag if there is any descriptor member.154    tbaaTagSym = getAnyAccessTag(func);155  } else if (mlir::isa<fir::BaseBoxType>(baseFIRType)) {156    tbaaTagSym = getBoxAccessTag(baseFIRType, accessFIRType, gep, func);157  } else {158    tbaaTagSym = getDataAccessTag(baseFIRType, accessFIRType, gep, func);159  }160 161  if (!tbaaTagSym)162    return;163 164  op.setTBAATags(ArrayAttr::get(op->getContext(), tbaaTagSym));165}166 167} // namespace fir168