Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/BPF/BPFASpaceCastSimplifyPass.cpp
35294 views
1
//===-- BPFASpaceCastSimplifyPass.cpp - BPF addrspacecast simplications --===//
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
#include "BPF.h"
10
#include <optional>
11
12
#define DEBUG_TYPE "bpf-aspace-simplify"
13
14
using namespace llvm;
15
16
namespace {
17
18
struct CastGEPCast {
19
AddrSpaceCastInst *OuterCast;
20
21
// Match chain of instructions:
22
// %inner = addrspacecast N->M
23
// %gep = getelementptr %inner, ...
24
// %outer = addrspacecast M->N %gep
25
// Where I is %outer.
26
static std::optional<CastGEPCast> match(Value *I) {
27
auto *OuterCast = dyn_cast<AddrSpaceCastInst>(I);
28
if (!OuterCast)
29
return std::nullopt;
30
auto *GEP = dyn_cast<GetElementPtrInst>(OuterCast->getPointerOperand());
31
if (!GEP)
32
return std::nullopt;
33
auto *InnerCast = dyn_cast<AddrSpaceCastInst>(GEP->getPointerOperand());
34
if (!InnerCast)
35
return std::nullopt;
36
if (InnerCast->getSrcAddressSpace() != OuterCast->getDestAddressSpace())
37
return std::nullopt;
38
if (InnerCast->getDestAddressSpace() != OuterCast->getSrcAddressSpace())
39
return std::nullopt;
40
return CastGEPCast{OuterCast};
41
}
42
43
static PointerType *changeAddressSpace(PointerType *Ty, unsigned AS) {
44
return Ty->get(Ty->getContext(), AS);
45
}
46
47
// Assuming match(this->OuterCast) is true, convert:
48
// (addrspacecast M->N (getelementptr (addrspacecast N->M ptr) ...))
49
// To:
50
// (getelementptr ptr ...)
51
GetElementPtrInst *rewrite() {
52
auto *GEP = cast<GetElementPtrInst>(OuterCast->getPointerOperand());
53
auto *InnerCast = cast<AddrSpaceCastInst>(GEP->getPointerOperand());
54
unsigned AS = OuterCast->getDestAddressSpace();
55
auto *NewGEP = cast<GetElementPtrInst>(GEP->clone());
56
NewGEP->setName(GEP->getName());
57
NewGEP->insertAfter(OuterCast);
58
NewGEP->setOperand(0, InnerCast->getPointerOperand());
59
auto *GEPTy = cast<PointerType>(GEP->getType());
60
NewGEP->mutateType(changeAddressSpace(GEPTy, AS));
61
OuterCast->replaceAllUsesWith(NewGEP);
62
OuterCast->eraseFromParent();
63
if (GEP->use_empty())
64
GEP->eraseFromParent();
65
if (InnerCast->use_empty())
66
InnerCast->eraseFromParent();
67
return NewGEP;
68
}
69
};
70
71
} // anonymous namespace
72
73
PreservedAnalyses BPFASpaceCastSimplifyPass::run(Function &F,
74
FunctionAnalysisManager &AM) {
75
SmallVector<CastGEPCast, 16> WorkList;
76
bool Changed = false;
77
for (BasicBlock &BB : F) {
78
for (Instruction &I : BB)
79
if (auto It = CastGEPCast::match(&I))
80
WorkList.push_back(It.value());
81
Changed |= !WorkList.empty();
82
83
while (!WorkList.empty()) {
84
CastGEPCast InsnChain = WorkList.pop_back_val();
85
GetElementPtrInst *NewGEP = InsnChain.rewrite();
86
for (User *U : NewGEP->users())
87
if (auto It = CastGEPCast::match(U))
88
WorkList.push_back(It.value());
89
}
90
}
91
return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
92
}
93
94