brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.0 KiB · 662681e Raw
255 lines · cpp
1//===- Location.cpp - MLIR Location Classes -------------------------------===//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#include "mlir/IR/Location.h"10#include "mlir/IR/AttributeSupport.h"11#include "mlir/IR/BuiltinAttributes.h"12#include "mlir/IR/BuiltinDialect.h"13#include "mlir/IR/MLIRContext.h"14#include "mlir/IR/Visitors.h"15#include "mlir/Support/LLVM.h"16#include "llvm/ADT/ArrayRef.h"17#include "llvm/ADT/Hashing.h"18#include "llvm/ADT/PointerIntPair.h"19#include "llvm/ADT/STLExtras.h"20#include "llvm/ADT/SetVector.h"21#include "llvm/Support/Casting.h"22#include "llvm/Support/TrailingObjects.h"23#include <cassert>24#include <tuple>25#include <utility>26 27using namespace mlir;28using namespace mlir::detail;29 30namespace mlir::detail {31struct FileLineColRangeAttrStorage final32    : public ::mlir::AttributeStorage,33      private llvm::TrailingObjects<FileLineColRangeAttrStorage, unsigned> {34  friend llvm::TrailingObjects<FileLineColRangeAttrStorage, unsigned>;35  using PointerPair = llvm::PointerIntPair<StringAttr, 2>;36  using KeyTy = std::tuple<StringAttr, ::llvm::ArrayRef<unsigned>>;37 38  FileLineColRangeAttrStorage(StringAttr filename, int numLocs)39      : filenameAndTrailing(filename, numLocs) {}40 41  static FileLineColRangeAttrStorage *42  construct(::mlir::AttributeStorageAllocator &allocator, KeyTy &&tblgenKey) {43    auto numInArray = std::get<1>(tblgenKey).size();44    // Note: Considered asserting that numInArray is at least 1, but this45    // is not needed in memory or in printed form. This should very rarely be46    // 0 here as that means a NamedLoc would have been more efficient. But this47    // does allow for location with just a file, and also having the interface48    // be more uniform.49    auto locEnc = numInArray == 0 ? 1 : numInArray;50    // Allocate a new storage instance.51    auto byteSize =52        FileLineColRangeAttrStorage::totalSizeToAlloc<unsigned>(locEnc - 1);53    auto *rawMem =54        allocator.allocate(byteSize, alignof(FileLineColRangeAttrStorage));55    auto *result = ::new (rawMem)56        FileLineColRangeAttrStorage(std::get<0>(tblgenKey), locEnc - 1);57    if (numInArray > 0) {58      ArrayRef<unsigned> elements = std::get<1>(tblgenKey);59      result->startLine = elements[0];60      // Copy in the element types into the trailing storage.61      llvm::uninitialized_copy(elements.drop_front(),62                               result->getTrailingObjects());63    }64    return result;65  }66 67  // Return the number of held types.68  unsigned size() const { return filenameAndTrailing.getInt() + 1; }69 70  bool operator==(const KeyTy &tblgenKey) const {71    return (filenameAndTrailing.getPointer() == std::get<0>(tblgenKey)) &&72           (size() == std::get<1>(tblgenKey).size()) &&73           (startLine == std::get<1>(tblgenKey)[0]) &&74           (getTrailingObjects(size() - 1) ==75            std::get<1>(tblgenKey).drop_front());76  }77 78  unsigned getLineCols(unsigned index) const {79    return getTrailingObjects()[index - 1];80  }81 82  unsigned getStartLine() const { return startLine; }83  unsigned getStartColumn() const {84    if (size() <= 1)85      return 0;86    return getLineCols(1);87  }88  unsigned getEndColumn() const {89    if (size() <= 2)90      return getStartColumn();91    return getLineCols(2);92  }93  unsigned getEndLine() const {94    if (size() <= 3)95      return getStartLine();96    return getLineCols(3);97  }98 99  static ::llvm::hash_code hashKey(const KeyTy &tblgenKey) {100    return ::llvm::hash_combine(std::get<0>(tblgenKey), std::get<1>(tblgenKey));101  }102 103  // Supports104  //  - 0 (file:line)105  //  - 1 (file:line:col)106  //  - 2 (file:line:start_col to file:line:end_col) and107  //  - 3 (file:start_line:start_col to file:end_line:end_col)108  llvm::PointerIntPair<StringAttr, 2> filenameAndTrailing;109  unsigned startLine = 0;110};111} // namespace mlir::detail112 113//===----------------------------------------------------------------------===//114/// Tablegen Attribute Definitions115//===----------------------------------------------------------------------===//116 117#define GET_ATTRDEF_CLASSES118#include "mlir/IR/BuiltinLocationAttributes.cpp.inc"119 120//===----------------------------------------------------------------------===//121// LocationAttr122//===----------------------------------------------------------------------===//123 124WalkResult LocationAttr::walk(function_ref<WalkResult(Location)> walkFn) {125  AttrTypeWalker walker;126  // Walk locations, but skip any other attribute.127  walker.addWalk([&](Attribute attr) {128    if (auto loc = llvm::dyn_cast<LocationAttr>(attr))129      return walkFn(loc);130 131    return WalkResult::skip();132  });133  return walker.walk<WalkOrder::PreOrder>(*this);134}135 136/// Methods for support type inquiry through isa, cast, and dyn_cast.137bool LocationAttr::classof(Attribute attr) {138  return attr.hasTrait<AttributeTrait::IsLocation>();139}140 141//===----------------------------------------------------------------------===//142// CallSiteLoc143//===----------------------------------------------------------------------===//144 145CallSiteLoc CallSiteLoc::get(Location name, ArrayRef<Location> frames) {146  assert(!frames.empty() && "required at least 1 call frame");147  Location caller = frames.back();148  for (auto frame : llvm::reverse(frames.drop_back()))149    caller = CallSiteLoc::get(frame, caller);150  return CallSiteLoc::get(name, caller);151}152 153//===----------------------------------------------------------------------===//154// FileLineColLoc155//===----------------------------------------------------------------------===//156 157FileLineColLoc FileLineColLoc::get(StringAttr filename, unsigned line,158                                   unsigned column) {159  return llvm::cast<FileLineColLoc>(160      FileLineColRange::get(filename, line, column));161}162 163FileLineColLoc FileLineColLoc::get(MLIRContext *context, StringRef fileName,164                                   unsigned line, unsigned column) {165  return llvm::cast<FileLineColLoc>(166      FileLineColRange::get(context, fileName, line, column));167}168 169StringAttr FileLineColLoc::getFilename() const {170  return FileLineColRange::getFilename();171}172 173unsigned FileLineColLoc::getLine() const { return getStartLine(); }174 175unsigned FileLineColLoc::getColumn() const { return getStartColumn(); }176 177bool mlir::isStrictFileLineColLoc(Location loc) {178  if (auto range = mlir::dyn_cast<FileLineColRange>(loc))179    return range.getImpl()->size() == 2;180  return false;181}182 183//===----------------------------------------------------------------------===//184// FileLineColRange185//===----------------------------------------------------------------------===//186 187StringAttr FileLineColRange::getFilename() const {188  return getImpl()->filenameAndTrailing.getPointer();189}190 191unsigned FileLineColRange::getStartLine() const {192  return getImpl()->getStartLine();193}194unsigned FileLineColRange::getStartColumn() const {195  return getImpl()->getStartColumn();196}197unsigned FileLineColRange::getEndColumn() const {198  return getImpl()->getEndColumn();199}200unsigned FileLineColRange::getEndLine() const {201  return getImpl()->getEndLine();202}203 204//===----------------------------------------------------------------------===//205// FusedLoc206//===----------------------------------------------------------------------===//207 208Location FusedLoc::get(ArrayRef<Location> locs, Attribute metadata,209                       MLIRContext *context) {210  // Unique the set of locations to be fused.211  llvm::SmallSetVector<Location, 4> decomposedLocs;212  for (auto loc : locs) {213    // If the location is a fused location we decompose it if it has no214    // metadata or the metadata is the same as the top level metadata.215    if (auto fusedLoc = llvm::dyn_cast<FusedLoc>(loc)) {216      if (fusedLoc.getMetadata() == metadata) {217        // UnknownLoc's have already been removed from FusedLocs so we can218        // simply add all of the internal locations.219        decomposedLocs.insert_range(fusedLoc.getLocations());220        continue;221      }222    }223    // Otherwise, only add known locations to the set.224    if (!llvm::isa<UnknownLoc>(loc))225      decomposedLocs.insert(loc);226  }227  locs = decomposedLocs.getArrayRef();228 229  // Handle the simple cases of less than two locations. Ensure the metadata (if230  // provided) is not dropped.231  if (locs.empty()) {232    if (!metadata)233      return UnknownLoc::get(context);234    // TODO: Investigate ASAN failure when using implicit conversion from235    // Location to ArrayRef<Location> below.236    return Base::get(context, ArrayRef<Location>{UnknownLoc::get(context)},237                     metadata);238  }239  if (locs.size() == 1 && !metadata)240    return locs.front();241 242  return Base::get(context, locs, metadata);243}244 245//===----------------------------------------------------------------------===//246// BuiltinDialect247//===----------------------------------------------------------------------===//248 249void BuiltinDialect::registerLocationAttributes() {250  addAttributes<251#define GET_ATTRDEF_LIST252#include "mlir/IR/BuiltinLocationAttributes.cpp.inc"253      >();254}255