Files
clang-p2996/bolt/BinaryBasicBlock.cpp
Theodoros Kasampalis a9bb3320ad Identical Code Folding (ICF) pass
Summary:
Added an ICF pass to BOLT, that can recognize identical functions
and replace references to these functions with references to just one
representative.

(cherry picked from FBD3460297)
2016-06-09 11:36:55 -07:00

113 lines
3.2 KiB
C++

//===--- BinaryBasicBlock.cpp - Interface for assembly-level basic block --===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//===----------------------------------------------------------------------===//
#include "BinaryBasicBlock.h"
#include "BinaryContext.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
#include <limits>
#include <string>
#undef DEBUG_TYPE
#define DEBUG_TYPE "bolt"
namespace llvm {
namespace bolt {
bool operator<(const BinaryBasicBlock &LHS, const BinaryBasicBlock &RHS) {
return LHS.Offset < RHS.Offset;
}
BinaryBasicBlock *BinaryBasicBlock::getSuccessor(const MCSymbol *Label) const {
for (BinaryBasicBlock *BB : successors()) {
if (BB->getLabel() == Label)
return BB;
}
return nullptr;
}
BinaryBasicBlock *BinaryBasicBlock::getLandingPad(const MCSymbol *Label) const {
for (BinaryBasicBlock *BB : landing_pads()) {
if (BB->getLabel() == Label)
return BB;
}
return nullptr;
}
void BinaryBasicBlock::addSuccessor(BinaryBasicBlock *Succ,
uint64_t Count,
uint64_t MispredictedCount) {
Successors.push_back(Succ);
BranchInfo.push_back({Count, MispredictedCount});
Succ->Predecessors.push_back(this);
}
void BinaryBasicBlock::removeSuccessor(BinaryBasicBlock *Succ) {
Succ->removePredecessor(this);
auto I = succ_begin();
auto BI = BranchInfo.begin();
for (; I != succ_end(); ++I) {
assert(BI != BranchInfo.end() && "missing BranchInfo entry");
if (*I == Succ)
break;
++BI;
}
assert(I != succ_end() && "no such successor!");
Successors.erase(I);
BranchInfo.erase(BI);
}
void BinaryBasicBlock::addPredecessor(BinaryBasicBlock *Pred) {
Predecessors.push_back(Pred);
}
void BinaryBasicBlock::removePredecessor(BinaryBasicBlock *Pred) {
auto I = std::find(pred_begin(), pred_end(), Pred);
assert(I != pred_end() && "Pred is not a predecessor of this block!");
Predecessors.erase(I);
}
void BinaryBasicBlock::addLandingPad(BinaryBasicBlock *LPBlock) {
LandingPads.insert(LPBlock);
LPBlock->Throwers.insert(this);
}
bool BinaryBasicBlock::analyzeBranch(const MCInstrAnalysis &MIA,
const MCSymbol *&TBB,
const MCSymbol *&FBB,
MCInst *&CondBranch,
MCInst *&UncondBranch) {
return MIA.analyzeBranch(Instructions, TBB, FBB, CondBranch, UncondBranch);
}
void BinaryBasicBlock::dump(BinaryContext& BC) const {
if (Label) dbgs() << Label->getName() << ":\n";
BC.printInstructions(dbgs(), Instructions.begin(), Instructions.end(), Offset);
dbgs() << "preds:";
for (auto itr = pred_begin(); itr != pred_end(); ++itr) {
dbgs() << " " << (*itr)->getName();
}
dbgs() << "\nsuccs:";
for (auto itr = succ_begin(); itr != succ_end(); ++itr) {
dbgs() << " " << (*itr)->getName();
}
dbgs() << "\n";
}
} // namespace bolt
} // namespace llvm