#include "HexagonInstrInfo.h"
#include "HexagonRegisterInfo.h"
#include "HexagonSubtarget.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Register.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
#include <set>
#include <utility>
#include <vector>
#define DEBUG_TYPE …
usingnamespacellvm;
static cl::opt<unsigned> CountThreshold(
"hexagon-cext-threshold", cl::init(3), cl::Hidden,
cl::desc("Minimum number of extenders to trigger replacement"));
static cl::opt<unsigned>
ReplaceLimit("hexagon-cext-limit", cl::init(0), cl::Hidden,
cl::desc("Maximum number of replacements"));
namespace llvm {
void initializeHexagonConstExtendersPass(PassRegistry&);
FunctionPass *createHexagonConstExtenders();
}
static int32_t adjustUp(int32_t V, uint8_t A, uint8_t O) { … }
static int32_t adjustDown(int32_t V, uint8_t A, uint8_t O) { … }
namespace {
struct OffsetRange { … };
struct RangeTree { … };
struct Loc { … };
struct HexagonConstExtenders : public MachineFunctionPass { … };
HCE;
LLVM_ATTRIBUTE_UNUSED
raw_ostream &operator<< (raw_ostream &OS, const OffsetRange &OR) { … }
struct PrintRegister { … };
LLVM_ATTRIBUTE_UNUSED
raw_ostream &operator<< (raw_ostream &OS, const PrintRegister &P) { … }
struct PrintExpr { … };
LLVM_ATTRIBUTE_UNUSED
raw_ostream &operator<< (raw_ostream &OS, const PrintExpr &P) { … }
struct PrintInit { … };
LLVM_ATTRIBUTE_UNUSED
raw_ostream &operator<< (raw_ostream &OS, const PrintInit &P) { … }
LLVM_ATTRIBUTE_UNUSED
raw_ostream &operator<< (raw_ostream &OS, const HCE::ExtDesc &ED) { … }
LLVM_ATTRIBUTE_UNUSED
raw_ostream &operator<< (raw_ostream &OS, const HCE::ExtRoot &ER) { … }
LLVM_ATTRIBUTE_UNUSED
raw_ostream &operator<< (raw_ostream &OS, const HCE::ExtValue &EV) { … }
struct PrintIMap { … };
LLVM_ATTRIBUTE_UNUSED
raw_ostream &operator<< (raw_ostream &OS, const PrintIMap &P) { … }
}
INITIALIZE_PASS_BEGIN(HexagonConstExtenders, "hexagon-cext-opt",
"Hexagon constant-extender optimization", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
INITIALIZE_PASS_END(HexagonConstExtenders, "hexagon-cext-opt",
"Hexagon constant-extender optimization", false, false)
static unsigned ReplaceCounter = …;
char HCE::ID = …;
#ifndef NDEBUG
LLVM_DUMP_METHOD void RangeTree::dump() const {
dbgs() << "Root: " << Root << '\n';
if (Root)
dump(Root);
}
LLVM_DUMP_METHOD void RangeTree::dump(const Node *N) const {
dbgs() << "Node: " << N << '\n';
dbgs() << " Height: " << N->Height << '\n';
dbgs() << " Count: " << N->Count << '\n';
dbgs() << " MaxEnd: " << N->MaxEnd << '\n';
dbgs() << " Range: " << N->Range << '\n';
dbgs() << " Left: " << N->Left << '\n';
dbgs() << " Right: " << N->Right << "\n\n";
if (N->Left)
dump(N->Left);
if (N->Right)
dump(N->Right);
}
#endif
void RangeTree::order(Node *N, SmallVectorImpl<Node*> &Seq) const { … }
void RangeTree::nodesWith(Node *N, int32_t P, bool CheckA,
SmallVectorImpl<Node*> &Seq) const { … }
RangeTree::Node *RangeTree::add(Node *N, const OffsetRange &R) { … }
RangeTree::Node *RangeTree::remove(Node *N, const Node *D) { … }
RangeTree::Node *RangeTree::rotateLeft(Node *Lower, Node *Higher) { … }
RangeTree::Node *RangeTree::rotateRight(Node *Lower, Node *Higher) { … }
HCE::ExtRoot::ExtRoot(const MachineOperand &Op) { … }
bool HCE::ExtRoot::operator< (const HCE::ExtRoot &ER) const { … }
HCE::ExtValue::ExtValue(const MachineOperand &Op) : … { … }
bool HCE::ExtValue::operator< (const HCE::ExtValue &EV) const { … }
operator MachineOperand()
bool HCE::isStoreImmediate(unsigned Opc) const { … }
bool HCE::isRegOffOpcode(unsigned Opc) const { … }
unsigned HCE::getRegOffOpcode(unsigned ExtOpc) const { … }
unsigned HCE::getDirectRegReplacement(unsigned ExtOpc) const { … }
OffsetRange HCE::getOffsetRange(Register Rb, const MachineInstr &MI) const { … }
OffsetRange HCE::getOffsetRange(const ExtDesc &ED) const { … }
OffsetRange HCE::getOffsetRange(Register Rd) const { … }
void HCE::recordExtender(MachineInstr &MI, unsigned OpNum) { … }
void HCE::collectInstr(MachineInstr &MI) { … }
void HCE::collect(MachineFunction &MF) { … }
void HCE::assignInits(const ExtRoot &ER, unsigned Begin, unsigned End,
AssignmentMap &IMap) { … }
void HCE::calculatePlacement(const ExtenderInit &ExtI, const IndexList &Refs,
LocDefList &Defs) { … }
HCE::Register HCE::insertInitializer(Loc DefL, const ExtenderInit &ExtI) { … }
bool HCE::replaceInstrExact(const ExtDesc &ED, Register ExtR) { … }
bool HCE::replaceInstrExpr(const ExtDesc &ED, const ExtenderInit &ExtI,
Register ExtR, int32_t &Diff) { … }
bool HCE::replaceInstr(unsigned Idx, Register ExtR, const ExtenderInit &ExtI) { … }
bool HCE::replaceExtenders(const AssignmentMap &IMap) { … }
unsigned HCE::getOperandIndex(const MachineInstr &MI,
const MachineOperand &Op) const { … }
const MachineOperand &HCE::getPredicateOp(const MachineInstr &MI) const { … }
const MachineOperand &HCE::getLoadResultOp(const MachineInstr &MI) const { … }
const MachineOperand &HCE::getStoredValueOp(const MachineInstr &MI) const { … }
bool HCE::runOnMachineFunction(MachineFunction &MF) { … }
FunctionPass *llvm::createHexagonConstExtenders() { … }