1 //===- bolt/Passes/LoopInversionPass.h --------------------------*- C++ -*-===// 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 #ifndef BOLT_PASSES_LOOPINVERSION_H 10 #define BOLT_PASSES_LOOPINVERSION_H 11 12 #include "bolt/Passes/BinaryPasses.h" 13 14 // This pass founds cases when BBs have layout: 15 // #BB0: 16 // .... 17 // #BB1: 18 // cmp 19 // cond_jmp #BB3 20 // #BB2: 21 // <loop body> 22 // jmp #BB1 23 // #BB3: 24 // <loop exit> 25 // 26 // And swaps BB1 and BB2: 27 // #BB0: 28 // .... 29 // jmp #BB1 30 // #BB2: 31 // <loop body> 32 // #BB1: 33 // cmp 34 // cond_njmp #BB2 35 // #BB3: 36 // <loop exit> 37 // 38 // And vice versa depending on the profile information. 39 // The advantage is that the loop uses only one conditional jump, 40 // the unconditional jump is only used once on the loop start. 41 42 namespace llvm { 43 namespace bolt { 44 45 class LoopInversionPass : public BinaryFunctionPass { 46 public: LoopInversionPass()47 explicit LoopInversionPass() : BinaryFunctionPass(false) {} 48 getName()49 const char *getName() const override { return "loop-inversion-opt"; } 50 51 /// Pass entry point 52 Error runOnFunctions(BinaryContext &BC) override; 53 bool runOnFunction(BinaryFunction &Function); 54 }; 55 56 } // namespace bolt 57 } // namespace llvm 58 59 #endif 60