Path: blob/main/contrib/llvm-project/llvm/lib/Target/BPF/BPFASpaceCastSimplifyPass.cpp
35294 views
//===-- BPFASpaceCastSimplifyPass.cpp - BPF addrspacecast simplications --===//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//===----------------------------------------------------------------------===//78#include "BPF.h"9#include <optional>1011#define DEBUG_TYPE "bpf-aspace-simplify"1213using namespace llvm;1415namespace {1617struct CastGEPCast {18AddrSpaceCastInst *OuterCast;1920// Match chain of instructions:21// %inner = addrspacecast N->M22// %gep = getelementptr %inner, ...23// %outer = addrspacecast M->N %gep24// Where I is %outer.25static std::optional<CastGEPCast> match(Value *I) {26auto *OuterCast = dyn_cast<AddrSpaceCastInst>(I);27if (!OuterCast)28return std::nullopt;29auto *GEP = dyn_cast<GetElementPtrInst>(OuterCast->getPointerOperand());30if (!GEP)31return std::nullopt;32auto *InnerCast = dyn_cast<AddrSpaceCastInst>(GEP->getPointerOperand());33if (!InnerCast)34return std::nullopt;35if (InnerCast->getSrcAddressSpace() != OuterCast->getDestAddressSpace())36return std::nullopt;37if (InnerCast->getDestAddressSpace() != OuterCast->getSrcAddressSpace())38return std::nullopt;39return CastGEPCast{OuterCast};40}4142static PointerType *changeAddressSpace(PointerType *Ty, unsigned AS) {43return Ty->get(Ty->getContext(), AS);44}4546// Assuming match(this->OuterCast) is true, convert:47// (addrspacecast M->N (getelementptr (addrspacecast N->M ptr) ...))48// To:49// (getelementptr ptr ...)50GetElementPtrInst *rewrite() {51auto *GEP = cast<GetElementPtrInst>(OuterCast->getPointerOperand());52auto *InnerCast = cast<AddrSpaceCastInst>(GEP->getPointerOperand());53unsigned AS = OuterCast->getDestAddressSpace();54auto *NewGEP = cast<GetElementPtrInst>(GEP->clone());55NewGEP->setName(GEP->getName());56NewGEP->insertAfter(OuterCast);57NewGEP->setOperand(0, InnerCast->getPointerOperand());58auto *GEPTy = cast<PointerType>(GEP->getType());59NewGEP->mutateType(changeAddressSpace(GEPTy, AS));60OuterCast->replaceAllUsesWith(NewGEP);61OuterCast->eraseFromParent();62if (GEP->use_empty())63GEP->eraseFromParent();64if (InnerCast->use_empty())65InnerCast->eraseFromParent();66return NewGEP;67}68};6970} // anonymous namespace7172PreservedAnalyses BPFASpaceCastSimplifyPass::run(Function &F,73FunctionAnalysisManager &AM) {74SmallVector<CastGEPCast, 16> WorkList;75bool Changed = false;76for (BasicBlock &BB : F) {77for (Instruction &I : BB)78if (auto It = CastGEPCast::match(&I))79WorkList.push_back(It.value());80Changed |= !WorkList.empty();8182while (!WorkList.empty()) {83CastGEPCast InsnChain = WorkList.pop_back_val();84GetElementPtrInst *NewGEP = InsnChain.rewrite();85for (User *U : NewGEP->users())86if (auto It = CastGEPCast::match(U))87WorkList.push_back(It.value());88}89}90return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();91}929394