1 //===------------ BPFCheckAndAdjustIR.cpp - Check and Adjust IR -----------===//
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
7 //===----------------------------------------------------------------------===//
9 // Check IR and adjust IR for verifier friendly codes.
10 // The following are done for IR checking:
11 // - no relocation globals in PHI node.
12 // The following are done for IR adjustment:
13 // - remove __builtin_bpf_passthrough builtins. Target independent IR
14 // optimizations are done and those builtins can be removed.
16 //===----------------------------------------------------------------------===//
20 #include "BPFTargetMachine.h"
21 #include "llvm/IR/DebugInfoMetadata.h"
22 #include "llvm/IR/GlobalVariable.h"
23 #include "llvm/IR/Instruction.h"
24 #include "llvm/IR/Instructions.h"
25 #include "llvm/IR/Module.h"
26 #include "llvm/IR/Type.h"
27 #include "llvm/IR/User.h"
28 #include "llvm/IR/Value.h"
29 #include "llvm/Pass.h"
30 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
32 #define DEBUG_TYPE "bpf-check-and-opt-ir"
38 class BPFCheckAndAdjustIR final
: public ModulePass
{
39 bool runOnModule(Module
&F
) override
;
43 BPFCheckAndAdjustIR() : ModulePass(ID
) {}
46 void checkIR(Module
&M
);
47 bool adjustIR(Module
&M
);
48 bool removePassThroughBuiltin(Module
&M
);
50 } // End anonymous namespace
52 char BPFCheckAndAdjustIR::ID
= 0;
53 INITIALIZE_PASS(BPFCheckAndAdjustIR
, DEBUG_TYPE
, "BPF Check And Adjust IR",
56 ModulePass
*llvm::createBPFCheckAndAdjustIR() {
57 return new BPFCheckAndAdjustIR();
60 void BPFCheckAndAdjustIR::checkIR(Module
&M
) {
61 // Ensure relocation global won't appear in PHI node
62 // This may happen if the compiler generated the following code:
64 // g1 = @llvm.skb_buff:0:1...
68 // g2 = @llvm.skb_buff:0:2...
75 // If anything likes the above "g = PHI(g1, g2)", issue a fatal error.
79 PHINode
*PN
= dyn_cast
<PHINode
>(&I
);
80 if (!PN
|| PN
->use_empty())
82 for (int i
= 0, e
= PN
->getNumIncomingValues(); i
< e
; ++i
) {
83 auto *GV
= dyn_cast
<GlobalVariable
>(PN
->getIncomingValue(i
));
86 if (GV
->hasAttribute(BPFCoreSharedInfo::AmaAttr
) ||
87 GV
->hasAttribute(BPFCoreSharedInfo::TypeIdAttr
))
88 report_fatal_error("relocation global in PHI node");
93 bool BPFCheckAndAdjustIR::removePassThroughBuiltin(Module
&M
) {
94 // Remove __builtin_bpf_passthrough()'s which are used to prevent
95 // certain IR optimizations. Now major IR optimizations are done,
98 CallInst
*ToBeDeleted
= nullptr;
103 ToBeDeleted
->eraseFromParent();
104 ToBeDeleted
= nullptr;
107 auto *Call
= dyn_cast
<CallInst
>(&I
);
110 auto *GV
= dyn_cast
<GlobalValue
>(Call
->getCalledOperand());
113 if (!GV
->getName().startswith("llvm.bpf.passthrough"))
116 Value
*Arg
= Call
->getArgOperand(1);
117 Call
->replaceAllUsesWith(Arg
);
123 bool BPFCheckAndAdjustIR::adjustIR(Module
&M
) {
124 return removePassThroughBuiltin(M
);
127 bool BPFCheckAndAdjustIR::runOnModule(Module
&M
) {