BPFIRPeephole.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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. #include "BPF.h"
  14. #include "llvm/IR/Instruction.h"
  15. #include "llvm/IR/Instructions.h"
  16. #include "llvm/IR/IntrinsicInst.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. #define DEBUG_TYPE "bpf-ir-peephole"
  24. using namespace llvm;
  25. namespace {
  26. static bool BPFIRPeepholeImpl(Function &F) {
  27. LLVM_DEBUG(dbgs() << "******** BPF IR Peephole ********\n");
  28. bool Changed = false;
  29. Instruction *ToErase = nullptr;
  30. for (auto &BB : F) {
  31. for (auto &I : BB) {
  32. // The following code pattern is handled:
  33. // %3 = call i8* @llvm.stacksave()
  34. // store i8* %3, i8** %saved_stack, align 8
  35. // ...
  36. // %4 = load i8*, i8** %saved_stack, align 8
  37. // call void @llvm.stackrestore(i8* %4)
  38. // ...
  39. // The goal is to remove the above four instructions,
  40. // so we won't have instructions with r11 (stack pointer)
  41. // if eventually there is no variable length stack allocation.
  42. // InstrCombine also tries to remove the above instructions,
  43. // if it is proven safe (constant alloca etc.), but depending
  44. // on code pattern, it may still miss some.
  45. //
  46. // With unconditionally removing these instructions, if alloca is
  47. // constant, we are okay then. Otherwise, SelectionDag will complain
  48. // since BPF does not support dynamic allocation yet.
  49. if (ToErase) {
  50. ToErase->eraseFromParent();
  51. ToErase = nullptr;
  52. }
  53. if (auto *II = dyn_cast<IntrinsicInst>(&I)) {
  54. if (II->getIntrinsicID() != Intrinsic::stacksave)
  55. continue;
  56. if (!II->hasOneUser())
  57. continue;
  58. auto *Inst = cast<Instruction>(*II->user_begin());
  59. LLVM_DEBUG(dbgs() << "Remove:"; I.dump());
  60. LLVM_DEBUG(dbgs() << "Remove:"; Inst->dump(); dbgs() << '\n');
  61. Changed = true;
  62. Inst->eraseFromParent();
  63. ToErase = &I;
  64. continue;
  65. }
  66. if (auto *LD = dyn_cast<LoadInst>(&I)) {
  67. if (!LD->hasOneUser())
  68. continue;
  69. auto *II = dyn_cast<IntrinsicInst>(*LD->user_begin());
  70. if (!II)
  71. continue;
  72. if (II->getIntrinsicID() != Intrinsic::stackrestore)
  73. continue;
  74. LLVM_DEBUG(dbgs() << "Remove:"; I.dump());
  75. LLVM_DEBUG(dbgs() << "Remove:"; II->dump(); dbgs() << '\n');
  76. Changed = true;
  77. II->eraseFromParent();
  78. ToErase = &I;
  79. }
  80. }
  81. }
  82. return Changed;
  83. }
  84. class BPFIRPeephole final : public FunctionPass {
  85. bool runOnFunction(Function &F) override;
  86. public:
  87. static char ID;
  88. BPFIRPeephole() : FunctionPass(ID) {}
  89. };
  90. } // End anonymous namespace
  91. char BPFIRPeephole::ID = 0;
  92. INITIALIZE_PASS(BPFIRPeephole, DEBUG_TYPE, "BPF IR Peephole", false, false)
  93. FunctionPass *llvm::createBPFIRPeephole() { return new BPFIRPeephole(); }
  94. bool BPFIRPeephole::runOnFunction(Function &F) { return BPFIRPeepholeImpl(F); }
  95. PreservedAnalyses BPFIRPeepholePass::run(Function &F,
  96. FunctionAnalysisManager &AM) {
  97. return BPFIRPeepholeImpl(F) ? PreservedAnalyses::none()
  98. : PreservedAnalyses::all();
  99. }