brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.4 KiB · 66469e2 Raw
177 lines · cpp
1//===----------------------------------------------------------------------===//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// This file implements MemorySlot-related interfaces for CIR dialect10// operations.11//12//===----------------------------------------------------------------------===//13 14#include "clang/CIR/Dialect/IR/CIRDialect.h"15 16using namespace mlir;17 18/// Conditions the deletion of the operation to the removal of all its uses.19static bool forwardToUsers(Operation *op,20                           SmallVectorImpl<OpOperand *> &newBlockingUses) {21  for (Value result : op->getResults())22    for (OpOperand &use : result.getUses())23      newBlockingUses.push_back(&use);24  return true;25}26 27//===----------------------------------------------------------------------===//28// Interfaces for AllocaOp29//===----------------------------------------------------------------------===//30 31llvm::SmallVector<MemorySlot> cir::AllocaOp::getPromotableSlots() {32  return {MemorySlot{getResult(), getAllocaType()}};33}34 35Value cir::AllocaOp::getDefaultValue(const MemorySlot &slot,36                                     OpBuilder &builder) {37  return cir::ConstantOp::create(builder, getLoc(),38                                 cir::UndefAttr::get(slot.elemType));39}40 41void cir::AllocaOp::handleBlockArgument(const MemorySlot &slot,42                                        BlockArgument argument,43                                        OpBuilder &builder) {}44 45std::optional<PromotableAllocationOpInterface>46cir::AllocaOp::handlePromotionComplete(const MemorySlot &slot,47                                       Value defaultValue, OpBuilder &builder) {48  if (defaultValue && defaultValue.use_empty())49    defaultValue.getDefiningOp()->erase();50  this->erase();51  return std::nullopt;52}53 54//===----------------------------------------------------------------------===//55// Interfaces for LoadOp56//===----------------------------------------------------------------------===//57 58bool cir::LoadOp::loadsFrom(const MemorySlot &slot) {59  return getAddr() == slot.ptr;60}61 62bool cir::LoadOp::storesTo(const MemorySlot &slot) { return false; }63 64Value cir::LoadOp::getStored(const MemorySlot &slot, OpBuilder &builder,65                             Value reachingDef, const DataLayout &dataLayout) {66  llvm_unreachable("getStored should not be called on LoadOp");67}68 69bool cir::LoadOp::canUsesBeRemoved(70    const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,71    SmallVectorImpl<OpOperand *> &newBlockingUses,72    const DataLayout &dataLayout) {73  if (blockingUses.size() != 1)74    return false;75  Value blockingUse = (*blockingUses.begin())->get();76  return blockingUse == slot.ptr && getAddr() == slot.ptr &&77         getType() == slot.elemType;78}79 80DeletionKind cir::LoadOp::removeBlockingUses(81    const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,82    OpBuilder &builder, Value reachingDefinition,83    const DataLayout &dataLayout) {84  getResult().replaceAllUsesWith(reachingDefinition);85  return DeletionKind::Delete;86}87 88//===----------------------------------------------------------------------===//89// Interfaces for StoreOp90//===----------------------------------------------------------------------===//91 92bool cir::StoreOp::loadsFrom(const MemorySlot &slot) { return false; }93 94bool cir::StoreOp::storesTo(const MemorySlot &slot) {95  return getAddr() == slot.ptr;96}97 98Value cir::StoreOp::getStored(const MemorySlot &slot, OpBuilder &builder,99                              Value reachingDef, const DataLayout &dataLayout) {100  return getValue();101}102 103bool cir::StoreOp::canUsesBeRemoved(104    const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,105    SmallVectorImpl<OpOperand *> &newBlockingUses,106    const DataLayout &dataLayout) {107  if (blockingUses.size() != 1)108    return false;109  Value blockingUse = (*blockingUses.begin())->get();110  return blockingUse == slot.ptr && getAddr() == slot.ptr &&111         getValue() != slot.ptr && slot.elemType == getValue().getType();112}113 114DeletionKind cir::StoreOp::removeBlockingUses(115    const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,116    OpBuilder &builder, Value reachingDefinition,117    const DataLayout &dataLayout) {118  return DeletionKind::Delete;119}120 121//===----------------------------------------------------------------------===//122// Interfaces for CopyOp123//===----------------------------------------------------------------------===//124 125bool cir::CopyOp::loadsFrom(const MemorySlot &slot) {126  return getSrc() == slot.ptr;127}128 129bool cir::CopyOp::storesTo(const MemorySlot &slot) {130  return getDst() == slot.ptr;131}132 133Value cir::CopyOp::getStored(const MemorySlot &slot, OpBuilder &builder,134                             Value reachingDef, const DataLayout &dataLayout) {135  return cir::LoadOp::create(builder, getLoc(), slot.elemType, getSrc());136}137 138DeletionKind cir::CopyOp::removeBlockingUses(139    const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,140    OpBuilder &builder, mlir::Value reachingDefinition,141    const DataLayout &dataLayout) {142  if (loadsFrom(slot))143    cir::StoreOp::create(builder, getLoc(), reachingDefinition, getDst(),144                         /*isVolatile=*/false,145                         /*alignment=*/mlir::IntegerAttr{},146                         /*mem-order=*/cir::MemOrderAttr());147  return DeletionKind::Delete;148}149 150bool cir::CopyOp::canUsesBeRemoved(151    const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,152    SmallVectorImpl<OpOperand *> &newBlockingUses,153    const DataLayout &dataLayout) {154  if (getDst() == getSrc())155    return false;156 157  return getLength(dataLayout) == dataLayout.getTypeSize(slot.elemType);158}159 160//===----------------------------------------------------------------------===//161// Interfaces for CastOp162//===----------------------------------------------------------------------===//163 164bool cir::CastOp::canUsesBeRemoved(165    const SmallPtrSetImpl<OpOperand *> &blockingUses,166    SmallVectorImpl<OpOperand *> &newBlockingUses,167    const DataLayout &dataLayout) {168  if (getKind() == cir::CastKind::bitcast)169    return forwardToUsers(*this, newBlockingUses);170  return false;171}172 173DeletionKind cir::CastOp::removeBlockingUses(174    const SmallPtrSetImpl<OpOperand *> &blockingUses, OpBuilder &builder) {175  return DeletionKind::Delete;176}177