1 //===------------ BPFIRPeephole.cpp - IR Peephole Transformation ----------===//
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 // IR level peephole optimization, specifically removing @llvm.stacksave() and
10 // @llvm.stackrestore().
12 //===----------------------------------------------------------------------===//
15 #include "llvm/IR/Instruction.h"
16 #include "llvm/IR/Instructions.h"
17 #include "llvm/IR/IntrinsicInst.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/IR/PassManager.h"
20 #include "llvm/IR/Type.h"
21 #include "llvm/IR/User.h"
22 #include "llvm/IR/Value.h"
23 #include "llvm/Pass.h"
25 #define DEBUG_TYPE "bpf-ir-peephole"
31 static bool BPFIRPeepholeImpl(Function
&F
) {
32 LLVM_DEBUG(dbgs() << "******** BPF IR Peephole ********\n");
35 Instruction
*ToErase
= nullptr;
38 // The following code pattern is handled:
39 // %3 = call i8* @llvm.stacksave()
40 // store i8* %3, i8** %saved_stack, align 8
42 // %4 = load i8*, i8** %saved_stack, align 8
43 // call void @llvm.stackrestore(i8* %4)
45 // The goal is to remove the above four instructions,
46 // so we won't have instructions with r11 (stack pointer)
47 // if eventually there is no variable length stack allocation.
48 // InstrCombine also tries to remove the above instructions,
49 // if it is proven safe (constant alloca etc.), but depending
50 // on code pattern, it may still miss some.
52 // With unconditionally removing these instructions, if alloca is
53 // constant, we are okay then. Otherwise, SelectionDag will complain
54 // since BPF does not support dynamic allocation yet.
56 ToErase
->eraseFromParent();
60 if (auto *II
= dyn_cast
<IntrinsicInst
>(&I
)) {
61 if (II
->getIntrinsicID() != Intrinsic::stacksave
)
63 if (!II
->hasOneUser())
65 auto *Inst
= cast
<Instruction
>(*II
->user_begin());
66 LLVM_DEBUG(dbgs() << "Remove:"; I
.dump());
67 LLVM_DEBUG(dbgs() << "Remove:"; Inst
->dump(); dbgs() << '\n');
69 Inst
->eraseFromParent();
74 if (auto *LD
= dyn_cast
<LoadInst
>(&I
)) {
75 if (!LD
->hasOneUser())
77 auto *II
= dyn_cast
<IntrinsicInst
>(*LD
->user_begin());
80 if (II
->getIntrinsicID() != Intrinsic::stackrestore
)
82 LLVM_DEBUG(dbgs() << "Remove:"; I
.dump());
83 LLVM_DEBUG(dbgs() << "Remove:"; II
->dump(); dbgs() << '\n');
85 II
->eraseFromParent();
93 } // End anonymous namespace
95 PreservedAnalyses
BPFIRPeepholePass::run(Function
&F
,
96 FunctionAnalysisManager
&AM
) {
97 return BPFIRPeepholeImpl(F
) ? PreservedAnalyses::none()
98 : PreservedAnalyses::all();