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 24 using namespace mlir; 25 using namespace mlir::LLVM; 26 27 static 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 worse 34 // performance 35 static 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 limiting 41 // the number of TBAA access tag attributes attached to operations. 42 // It is set to kTagAttachmentUnlimited by default denoting "no limit". 43 static constexpr unsigned kTagAttachmentUnlimited = 44 std::numeric_limits<unsigned>::max(); 45 static llvm::cl::opt<unsigned> 46 tagAttachmentLimit("tbaa-attach-tag-max", llvm::cl::desc(""), 47 llvm::cl::init(kTagAttachmentUnlimited)); 48 49 namespace fir { 50 51 TBAABuilder::TBAABuilder(MLIRContext *context, bool applyTBAA, 52 bool forceUnifiedTree) 53 : enableTBAA(applyTBAA && !disableTBAA), 54 trees(/*separatePerFunction=*/perFunctionTBAATrees && !forceUnifiedTree) { 55 if (!enableTBAA) 56 return; 57 } 58 59 TBAATagAttr 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 71 TBAATagAttr TBAABuilder::getAnyBoxAccessTag(mlir::LLVM::LLVMFuncOp func) { 72 TBAATypeDescriptorAttr boxMemberTypeDesc = trees[func].boxMemberTypeDesc; 73 return getAccessTag(boxMemberTypeDesc, boxMemberTypeDesc, /*offset=*/0); 74 } 75 76 TBAATagAttr TBAABuilder::getBoxAccessTag(Type baseFIRType, Type accessFIRType, 77 GEPOp gep, 78 mlir::LLVM::LLVMFuncOp func) { 79 return getAnyBoxAccessTag(func); 80 } 81 82 TBAATagAttr TBAABuilder::getAnyDataAccessTag(mlir::LLVM::LLVMFuncOp func) { 83 TBAATypeDescriptorAttr anyDataAccessTypeDesc = trees[func].anyDataTypeDesc; 84 return getAccessTag(anyDataAccessTypeDesc, anyDataAccessTypeDesc, 85 /*offset=*/0); 86 } 87 88 TBAATagAttr TBAABuilder::getDataAccessTag(Type baseFIRType, Type accessFIRType, 89 GEPOp gep, 90 mlir::LLVM::LLVMFuncOp func) { 91 return getAnyDataAccessTag(func); 92 } 93 94 TBAATagAttr TBAABuilder::getAnyAccessTag(mlir::LLVM::LLVMFuncOp func) { 95 TBAATypeDescriptorAttr anyAccessTypeDesc = trees[func].anyAccessDesc; 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 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 (mlir::isa<fir::BaseBoxType>(baseFIRType)) { 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