Path: blob/main/contrib/llvm-project/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp
213845 views
//===----------------------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements MemorySlot-related interfaces for CIR dialect9// operations.10//11//===----------------------------------------------------------------------===//1213#include "clang/CIR/Dialect/IR/CIRDialect.h"1415using namespace mlir;1617/// Conditions the deletion of the operation to the removal of all its uses.18static bool forwardToUsers(Operation *op,19SmallVectorImpl<OpOperand *> &newBlockingUses) {20for (Value result : op->getResults())21for (OpOperand &use : result.getUses())22newBlockingUses.push_back(&use);23return true;24}2526//===----------------------------------------------------------------------===//27// Interfaces for AllocaOp28//===----------------------------------------------------------------------===//2930llvm::SmallVector<MemorySlot> cir::AllocaOp::getPromotableSlots() {31return {MemorySlot{getResult(), getAllocaType()}};32}3334Value cir::AllocaOp::getDefaultValue(const MemorySlot &slot,35OpBuilder &builder) {36return builder.create<cir::ConstantOp>(getLoc(),37cir::UndefAttr::get(slot.elemType));38}3940void cir::AllocaOp::handleBlockArgument(const MemorySlot &slot,41BlockArgument argument,42OpBuilder &builder) {}4344std::optional<PromotableAllocationOpInterface>45cir::AllocaOp::handlePromotionComplete(const MemorySlot &slot,46Value defaultValue, OpBuilder &builder) {47if (defaultValue && defaultValue.use_empty())48defaultValue.getDefiningOp()->erase();49this->erase();50return std::nullopt;51}5253//===----------------------------------------------------------------------===//54// Interfaces for LoadOp55//===----------------------------------------------------------------------===//5657bool cir::LoadOp::loadsFrom(const MemorySlot &slot) {58return getAddr() == slot.ptr;59}6061bool cir::LoadOp::storesTo(const MemorySlot &slot) { return false; }6263Value cir::LoadOp::getStored(const MemorySlot &slot, OpBuilder &builder,64Value reachingDef, const DataLayout &dataLayout) {65llvm_unreachable("getStored should not be called on LoadOp");66}6768bool cir::LoadOp::canUsesBeRemoved(69const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,70SmallVectorImpl<OpOperand *> &newBlockingUses,71const DataLayout &dataLayout) {72if (blockingUses.size() != 1)73return false;74Value blockingUse = (*blockingUses.begin())->get();75return blockingUse == slot.ptr && getAddr() == slot.ptr &&76getType() == slot.elemType;77}7879DeletionKind cir::LoadOp::removeBlockingUses(80const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,81OpBuilder &builder, Value reachingDefinition,82const DataLayout &dataLayout) {83getResult().replaceAllUsesWith(reachingDefinition);84return DeletionKind::Delete;85}8687//===----------------------------------------------------------------------===//88// Interfaces for StoreOp89//===----------------------------------------------------------------------===//9091bool cir::StoreOp::loadsFrom(const MemorySlot &slot) { return false; }9293bool cir::StoreOp::storesTo(const MemorySlot &slot) {94return getAddr() == slot.ptr;95}9697Value cir::StoreOp::getStored(const MemorySlot &slot, OpBuilder &builder,98Value reachingDef, const DataLayout &dataLayout) {99return getValue();100}101102bool cir::StoreOp::canUsesBeRemoved(103const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,104SmallVectorImpl<OpOperand *> &newBlockingUses,105const DataLayout &dataLayout) {106if (blockingUses.size() != 1)107return false;108Value blockingUse = (*blockingUses.begin())->get();109return blockingUse == slot.ptr && getAddr() == slot.ptr &&110getValue() != slot.ptr && slot.elemType == getValue().getType();111}112113DeletionKind cir::StoreOp::removeBlockingUses(114const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,115OpBuilder &builder, Value reachingDefinition,116const DataLayout &dataLayout) {117return DeletionKind::Delete;118}119120//===----------------------------------------------------------------------===//121// Interfaces for CastOp122//===----------------------------------------------------------------------===//123124bool cir::CastOp::canUsesBeRemoved(125const SmallPtrSetImpl<OpOperand *> &blockingUses,126SmallVectorImpl<OpOperand *> &newBlockingUses,127const DataLayout &dataLayout) {128if (getKind() == cir::CastKind::bitcast)129return forwardToUsers(*this, newBlockingUses);130return false;131}132133DeletionKind cir::CastOp::removeBlockingUses(134const SmallPtrSetImpl<OpOperand *> &blockingUses, OpBuilder &builder) {135return DeletionKind::Delete;136}137138139