Files
llvm/bolt/lib/Passes/LoopInversionPass.cpp
Rafael Auler a34c753fe7 Rebase: [NFC] Refactor sources to be buildable in shared mode
Summary:
Moves source files into separate components, and make explicit
component dependency on each other, so LLVM build system knows how to
build BOLT in BUILD_SHARED_LIBS=ON.

Please use the -c merge.renamelimit=230 git option when rebasing your
work on top of this change.

To achieve this, we create a new library to hold core IR files (most
classes beginning with Binary in their names), a new library to hold
Utils, some command line options shared across both RewriteInstance
and core IR files, a new library called Rewrite to hold most classes
concerned with running top-level functions coordinating the binary
rewriting process, and a new library called Profile to hold classes
dealing with profile reading and writing.

To remove the dependency from BinaryContext into X86-specific classes,
we do some refactoring on the BinaryContext constructor to receive a
reference to the specific backend directly from RewriteInstance. Then,
the dependency on X86 or AArch64-specific classes is transfered to the
Rewrite library. We can't have the Core library depend on targets
because targets depend on Core (which would create a cycle).

Files implementing the entry point of a tool are transferred to the
tools/ folder. All header files are transferred to the include/
folder. The src/ folder was renamed to lib/.

(cherry picked from FBD32746834)
2021-10-08 11:47:10 -07:00

104 lines
3.3 KiB
C++

//===--------- Passes/LoopInversionPass.cpp -------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//===----------------------------------------------------------------------===//
#include "bolt/Passes/LoopInversionPass.h"
#include "bolt/Core/ParallelUtilities.h"
using namespace llvm;
namespace opts {
extern cl::OptionCategory BoltCategory;
extern cl::opt<bolt::ReorderBasicBlocks::LayoutType> ReorderBlocks;
static cl::opt<bool> LoopReorder(
"loop-inversion-opt",
cl::desc("reorder unconditional jump instructions in loops optimization"),
cl::init(true), cl::cat(BoltCategory), cl::ReallyHidden);
} // namespace opts
namespace llvm {
namespace bolt {
bool LoopInversionPass::runOnFunction(BinaryFunction &BF) {
bool IsChanged = false;
if (BF.layout_size() < 3 || !BF.hasValidProfile())
return false;
BF.updateLayoutIndices();
for (BinaryBasicBlock *BB : BF.layout()) {
if (BB->succ_size() != 1 || BB->pred_size() != 1)
continue;
BinaryBasicBlock *SuccBB = *BB->succ_begin();
BinaryBasicBlock *PredBB = *BB->pred_begin();
const unsigned BBIndex = BB->getLayoutIndex();
const unsigned SuccBBIndex = SuccBB->getLayoutIndex();
if (SuccBB == PredBB && BB != SuccBB && BBIndex != 0 && SuccBBIndex != 0 &&
SuccBB->succ_size() == 2 && BB->isCold() == SuccBB->isCold()) {
// Get the second successor (after loop BB)
BinaryBasicBlock *SecondSucc = nullptr;
for (BinaryBasicBlock *Succ : SuccBB->successors()) {
if (Succ != &*BB) {
SecondSucc = Succ;
break;
}
}
assert(SecondSucc != nullptr && "Unable to find second BB successor");
const uint64_t BBCount = SuccBB->getBranchInfo(*BB).Count;
const uint64_t OtherCount = SuccBB->getBranchInfo(*SecondSucc).Count;
if ((BBCount < OtherCount) && (BBIndex > SuccBBIndex))
continue;
IsChanged = true;
BB->setLayoutIndex(SuccBBIndex);
SuccBB->setLayoutIndex(BBIndex);
}
}
if (IsChanged) {
BinaryFunction::BasicBlockOrderType NewOrder = BF.getLayout();
std::sort(NewOrder.begin(), NewOrder.end(),
[&](BinaryBasicBlock *BB1, BinaryBasicBlock *BB2) {
return BB1->getLayoutIndex() < BB2->getLayoutIndex();
});
BF.updateBasicBlockLayout(NewOrder);
}
return IsChanged;
}
void LoopInversionPass::runOnFunctions(BinaryContext &BC) {
std::atomic<uint64_t> ModifiedFuncCount{0};
if (opts::ReorderBlocks == ReorderBasicBlocks::LT_NONE ||
opts::LoopReorder == false)
return;
ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
if (runOnFunction(BF))
++ModifiedFuncCount;
};
ParallelUtilities::PredicateTy SkipFunc = [&](const BinaryFunction &BF) {
return !shouldOptimize(BF);
};
ParallelUtilities::runOnEachFunction(
BC, ParallelUtilities::SchedulingPolicy::SP_TRIVIAL, WorkFun, SkipFunc,
"LoopInversionPass");
outs() << "BOLT-INFO: " << ModifiedFuncCount
<< " Functions were reordered by LoopInversionPass\n";
}
} // end namespace bolt
} // end namespace llvm