LLVM  14.0.0git
BPFIRPeephole.cpp
Go to the documentation of this file.
1 //===------------ BPFIRPeephole.cpp - IR Peephole Transformation ----------===//
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 // IR level peephole optimization, specifically removing @llvm.stacksave() and
10 // @llvm.stackrestore().
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "BPF.h"
15 #include "llvm/IR/Instruction.h"
16 #include "llvm/IR/Instructions.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/IR/PassManager.h"
19 #include "llvm/IR/Type.h"
20 #include "llvm/IR/User.h"
21 #include "llvm/IR/Value.h"
22 #include "llvm/Pass.h"
23 
24 #define DEBUG_TYPE "bpf-ir-peephole"
25 
26 using namespace llvm;
27 
28 namespace {
29 
30 static bool BPFIRPeepholeImpl(Function &F) {
31  LLVM_DEBUG(dbgs() << "******** BPF IR Peephole ********\n");
32 
33  bool Changed = false;
34  Instruction *ToErase = nullptr;
35  for (auto &BB : F) {
36  for (auto &I : BB) {
37  // The following code pattern is handled:
38  // %3 = call i8* @llvm.stacksave()
39  // store i8* %3, i8** %saved_stack, align 8
40  // ...
41  // %4 = load i8*, i8** %saved_stack, align 8
42  // call void @llvm.stackrestore(i8* %4)
43  // ...
44  // The goal is to remove the above four instructions,
45  // so we won't have instructions with r11 (stack pointer)
46  // if eventually there is no variable length stack allocation.
47  // InstrCombine also tries to remove the above instructions,
48  // if it is proven safe (constant alloca etc.), but depending
49  // on code pattern, it may still miss some.
50  //
51  // With unconditionally removing these instructions, if alloca is
52  // constant, we are okay then. Otherwise, SelectionDag will complain
53  // since BPF does not support dynamic allocation yet.
54  if (ToErase) {
55  ToErase->eraseFromParent();
56  ToErase = nullptr;
57  }
58 
59  if (auto *Call = dyn_cast<CallInst>(&I)) {
60  if (auto *GV = dyn_cast<GlobalValue>(Call->getCalledOperand())) {
61  if (!GV->getName().equals("llvm.stacksave"))
62  continue;
63  if (!Call->hasOneUser())
64  continue;
65  auto *Inst = cast<Instruction>(*Call->user_begin());
66  LLVM_DEBUG(dbgs() << "Remove:"; I.dump());
67  LLVM_DEBUG(dbgs() << "Remove:"; Inst->dump(); dbgs() << '\n');
68  Changed = true;
69  Inst->eraseFromParent();
70  ToErase = &I;
71  }
72  continue;
73  }
74 
75  if (auto *LD = dyn_cast<LoadInst>(&I)) {
76  if (!LD->hasOneUser())
77  continue;
78  auto *Call = dyn_cast<CallInst>(*LD->user_begin());
79  if (!Call)
80  continue;
81  auto *GV = dyn_cast<GlobalValue>(Call->getCalledOperand());
82  if (!GV)
83  continue;
84  if (!GV->getName().equals("llvm.stackrestore"))
85  continue;
86  LLVM_DEBUG(dbgs() << "Remove:"; I.dump());
87  LLVM_DEBUG(dbgs() << "Remove:"; Call->dump(); dbgs() << '\n');
88  Changed = true;
89  Call->eraseFromParent();
90  ToErase = &I;
91  }
92  }
93  }
94 
95  return Changed;
96 }
97 
98 class BPFIRPeephole final : public FunctionPass {
99  bool runOnFunction(Function &F) override;
100 
101 public:
102  static char ID;
103  BPFIRPeephole() : FunctionPass(ID) {}
104 };
105 } // End anonymous namespace
106 
107 char BPFIRPeephole::ID = 0;
108 INITIALIZE_PASS(BPFIRPeephole, DEBUG_TYPE, "BPF IR Peephole", false, false)
109 
110 FunctionPass *llvm::createBPFIRPeephole() { return new BPFIRPeephole(); }
111 
112 bool BPFIRPeephole::runOnFunction(Function &F) { return BPFIRPeepholeImpl(F); }
113 
116  return BPFIRPeepholeImpl(F) ? PreservedAnalyses::none()
118 }
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:155
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::Function
Definition: Function.h:62
Pass.h
llvm::ARM_MB::LD
@ LD
Definition: ARMBaseInfo.h:72
llvm::PreservedAnalyses::none
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:158
Module.h
BPF.h
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
Instruction.h
INITIALIZE_PASS
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:37
llvm::Instruction
Definition: Instruction.h:45
Type.h
DEBUG_TYPE
#define DEBUG_TYPE
Definition: BPFIRPeephole.cpp:24
llvm::Instruction::eraseFromParent
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:78
I
#define I(x, y, z)
Definition: MD5.cpp:59
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:69
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:161
PassManager.h
Instructions.h
User.h
llvm::createBPFIRPeephole
FunctionPass * createBPFIRPeephole()
Definition: BPFIRPeephole.cpp:110
llvm::BPFIRPeepholePass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: BPFIRPeephole.cpp:114
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:44
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
Value.h
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38