75 printv(
unsigned r) : R(r) {}
82 OS <<
'v' <<
Register(PV.R).virtRegIndex();
94 case BT::BitValue::Top:
97 case BT::BitValue::Zero:
100 case BT::BitValue::One:
103 case BT::BitValue::Ref:
111 unsigned n = RC.Bits.
size();
119 bool ConstRef =
false;
121 for (
unsigned i = 1, n = RC.Bits.
size(); i < n; ++i) {
124 bool IsRef = (V.Type == BT::BitValue::Ref);
126 if (!IsRef && V == SV)
128 if (IsRef && SV.
Type == BT::BitValue::Ref && V.RefI.Reg == SV.
RefI.
Reg) {
130 SeqRef = (V.RefI.Pos == SV.
RefI.
Pos+1);
131 ConstRef = (V.RefI.Pos == SV.
RefI.
Pos);
133 if (SeqRef && V.RefI.Pos == SV.
RefI.
Pos+(i-Start))
135 if (ConstRef && V.RefI.Pos == SV.
RefI.
Pos)
142 unsigned Count = i - Start;
146 OS <<
'-' << i-1 <<
"]:";
147 if (SV.
Type == BT::BitValue::Ref && SeqRef)
154 SeqRef = ConstRef =
false;
158 unsigned Count = n - Start;
160 OS <<
"]:" << RC[Start];
162 OS <<
'-' << n-1 <<
"]:";
164 if (SV.
Type == BT::BitValue::Ref && SeqRef)
178 for (
const std::pair<unsigned, RegisterCell>
P : Map)
179 dbgs() <<
printReg(
P.first, &ME.TRI) <<
" -> " <<
P.second <<
"\n";
201 for (
uint16_t i = 0, n = Bits.size(); i < n; ++i) {
225 Bits[i] = RC[i+(W-
B)];
236 RC.Bits[i-
B] = Bits[i];
242 RC.Bits[i] = Bits[i+
B];
244 RC.Bits[i+(W-
B)] = Bits[i];
262 Bits[i] = Bits[W-Sh+i];
265 Bits[i+Sh] = Tmp.Bits[i];
283 Bits[i+W] = RC.Bits[i];
291 while (
C < W && Bits[
C] == V)
300 while (
C < W && Bits[W-(
C+1)] == V)
307 if (RC.Bits.
size() != W)
310 if (Bits[i] != RC[i])
316 for (
unsigned i = 0, n =
width(); i < n; ++i) {
335 return TRI.getRegSizeInBits(VC);
359 CellMapType::const_iterator
F = M.find(RR.
Reg);
364 return F->second.extract(M);
377 assert(RR.
Sub == 0 &&
"Unexpected sub-register in definition");
386 if (!
A[i].is(0) && !
A[i].is(1))
420 assert((
unsigned)BW ==
A.getBitWidth() &&
"BitWidth overflow");
434 for (
I = 0;
I < W; ++
I) {
437 if (!V1.
num() || !V2.
num())
439 unsigned S =
bool(V1) +
bool(V2) + Carry;
450 else if (V2.
is(Carry))
467 for (
I = 0;
I < W; ++
I) {
470 if (!V1.
num() || !V2.
num())
472 unsigned S =
bool(V1) -
bool(V2) - Borrow;
539 Res.
fill(W-Sh, W, Sign);
555 else if (V1.
is(0) || V2.
is(0))
573 if (V1.
is(1) || V2.
is(1))
643 if ((
C < AW && A1[AW-1-
C].num()) ||
C == AW)
653 if ((
C < AW && A1[
C].num()) ||
C == AW)
665 Res.
fill(FromN, W, Sign);
694 assert(AtN < W1 && AtN+W2 <= W1);
703 assert(
Sub == 0 &&
"Generic BitTracker::mask called for Sub != 0");
705 assert(W > 0 &&
"Cannot generate mask for empty register");
711 return TRI.getRegSizeInBits(PC);
717 unsigned Opc =
MI.getOpcode();
719 case TargetOpcode::REG_SEQUENCE: {
723 unsigned SS =
MI.getOperand(2).getImm();
725 unsigned ST =
MI.getOperand(4).getImm();
736 case TargetOpcode::COPY: {
760bool BT::UseQueueType::Cmp::operator()(
const MachineInstr *InstA,
777 auto F = Dist.find(
MI);
782 unsigned D = std::distance(
I, E);
783 Dist.insert(std::make_pair(
MI,
D));
787 return getDist(InstA) > getDist(InstB);
792void BT::visitPHI(
const MachineInstr &PI) {
798 assert(MD.
getSubReg() == 0 &&
"Unexpected sub-register in definition");
800 uint16_t DefBW = ME.getRegBitWidth(DefRR);
810 int PredN =
PB->getNumber();
814 if (!EdgeExec.count(CFGEdge(PredN, ThisN))) {
816 dbgs() <<
" not executable\n";
823 dbgs() <<
" input reg: " <<
printReg(RU.Reg, &ME.TRI, RU.Sub)
824 <<
" cell: " << ResC <<
"\n";
825 Changed |= DefC.meet(ResC, DefRR.Reg);
830 dbgs() <<
"Output: " <<
printReg(DefRR.Reg, &ME.TRI, DefRR.Sub)
831 <<
" cell: " << DefC <<
"\n";
832 ME.putCell(DefRR, DefC, Map);
833 visitUsesOf(DefRR.Reg);
837void BT::visitNonBranch(
const MachineInstr &
MI) {
840 if (
MI.isDebugInstr())
842 assert(!
MI.isBranch() &&
"Unexpected branch instruction");
845 bool Eval = ME.evaluate(
MI, Map, ResMap);
848 for (
const MachineOperand &MO :
MI.operands()) {
849 if (!MO.isReg() || !MO.isUse())
852 dbgs() <<
" input reg: " <<
printReg(RU.Reg, &ME.TRI, RU.Sub)
853 <<
" cell: " << ME.getCell(RU, Map) <<
"\n";
855 dbgs() <<
"Outputs:\n";
856 for (
const std::pair<const unsigned, RegisterCell> &
P : ResMap) {
859 << ME.getCell(RD, ResMap) <<
"\n";
865 for (
const MachineOperand &MO :
MI.operands()) {
867 if (!MO.isReg() || !MO.isDef())
870 assert(RD.Sub == 0 &&
"Unexpected sub-register in definition");
871 if (!RD.Reg.isVirtual())
875 if (!Eval || ResMap.count(RD.Reg) == 0) {
877 uint16_t DefBW = ME.getRegBitWidth(RD);
879 if (RefC != ME.getCell(RD, Map)) {
880 ME.putCell(RD, RefC, Map);
893 for (uint16_t i = 0, w = DefC.width(); i < w; ++i) {
905 ME.putCell(RD, DefC, Map);
912void BT::visitBranchesFrom(
const MachineInstr &BI) {
916 bool FallsThrough =
true, DefaultToAll =
false;
917 int ThisN =
B.getNumber();
921 const MachineInstr &
MI = *It;
924 assert(
MI.isBranch() &&
"Expecting branch instruction");
925 InstrExec.insert(&
MI);
926 bool Eval = ME.evaluate(
MI, Map, BTs, FallsThrough);
933 dbgs() <<
" failed to evaluate: will add all CFG successors\n";
934 }
else if (!DefaultToAll) {
937 dbgs() <<
" adding targets:";
938 for (
const MachineBasicBlock *
BT : BTs)
941 dbgs() <<
"\n falls through\n";
943 dbgs() <<
"\n does not fall through\n";
945 Targets.insert_range(BTs);
948 }
while (FallsThrough && It != End);
950 if (
B.mayHaveInlineAsmBr())
957 for (
const MachineBasicBlock *SB :
B.successors()) {
964 if (
Next != MF.end())
965 Targets.insert(&*
Next);
968 Targets.insert_range(
B.successors());
971 for (
const MachineBasicBlock *TB : Targets)
972 FlowQ.push(CFGEdge(ThisN,
TB->getNumber()));
978 <<
" cell: " << ME.getCell(
Reg, Map) <<
'\n';
980 for (MachineInstr &UseI : MRI.use_nodbg_instructions(
Reg))
985 return ME.getCell(RR, Map);
989 ME.putCell(RR, RC, Map);
995 assert(Map.count(OldRR.
Reg) > 0 &&
"OldRR not present in map");
1001 assert((OME-OMB == NME-NMB) &&
1002 "Substituting registers of different lengths");
1003 for (std::pair<const unsigned, RegisterCell> &
P : Map) {
1009 if (V.RefI.Pos < OMB || V.RefI.Pos > OME)
1011 V.RefI.Reg = NewRR.
Reg;
1012 V.RefI.Pos += NMB-OMB;
1020 int BN =
B->getNumber();
1022 return ReachedBB.count(BN);
1028 assert(!
MI.isBranch() &&
"Only non-branches are allowed");
1029 InstrExec.insert(&
MI);
1036 while (!FlowQ.empty())
1048void BT::runEdgeQueue(
BitVector &BlockScanned) {
1049 while (!FlowQ.empty()) {
1050 CFGEdge Edge = FlowQ.front();
1053 if (!EdgeExec.insert(Edge).second)
1055 ReachedBB.
insert(Edge.second);
1060 while (It != End && It->isPHI()) {
1062 InstrExec.insert(&PI);
1069 if (BlockScanned[
Edge.second])
1071 BlockScanned[
Edge.second] =
true;
1074 while (It != End && !It->isBranch()) {
1075 const MachineInstr &
MI = *It++;
1076 InstrExec.insert(&
MI);
1083 if (
Next != MF.end() &&
B.isSuccessor(&*
Next)) {
1084 int ThisN =
B.getNumber();
1085 int NextN =
Next->getNumber();
1086 FlowQ.push(CFGEdge(ThisN, NextN));
1091 visitBranchesFrom(*It);
1096void BT::runUseQueue() {
1097 while (!UseQ.empty()) {
1098 MachineInstr &UseI = *UseQ.front();
1101 if (!InstrExec.count(&UseI))
1106 visitNonBranch(UseI);
1108 visitBranchesFrom(UseI);
1121 assert(
B.getNumber() >= 0 &&
"Disconnected block");
1122 unsigned BN =
B.getNumber();
1130 int EntryN = Entry->getNumber();
1132 FlowQ.push(CFGEdge(-1, EntryN));
1134 while (!FlowQ.empty() || !UseQ.empty()) {
1135 runEdgeQueue(BlockScanned);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the BitVector class.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Promote Memory to Register
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
std::pair< BasicBlock *, BasicBlock * > Edge
Class for arbitrary precision integers.
This is the shared class of boolean and integer constants.
const APInt & getValue() const
Return the constant as an APInt value reference.
Wrapper class representing physical registers. Should be passed by value.
MachineInstrBundleIterator< const MachineInstr > const_iterator
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
MachineBasicBlock * getBlockNumbered(unsigned N) const
getBlockNumbered - MachineBasicBlocks are automatically numbered when they are inserted into the mach...
BasicBlockListType::const_iterator const_iterator
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
unsigned getNumOperands() const
Retuns the total number of operands.
bool isBranch(QueryType Type=AnyInBundle) const
Returns true if this is a conditional, unconditional, or indirect branch.
const MachineOperand & getOperand(unsigned i) const
unsigned getSubReg() const
MachineBasicBlock * getMBB() const
Wrapper class representing virtual and physical registers.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
std::pair< iterator, bool > insert(const ValueT &V)
void reserve(size_t Size)
Grow the DenseSet so that it can contain at least NumEntries items before resizing again.
This class implements an extremely fast bulk output stream that can only output to a stream.
@ C
The default llvm calling convention, compatible with C.
@ TB
TB - TwoByte - Set if this instruction has a two byte opcode, which starts with a 0x0F byte before th...
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionAddr VTableAddr Count
@ Sub
Subtraction of integers.
FunctionAddr VTableAddr Next
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
static BitValue ref(const BitValue &V)
bool is(unsigned T) const
static BitValue self(const BitRef &Self=BitRef())
const TargetRegisterInfo & TRI
RegisterCell eIMM(int64_t V, uint16_t W) const
uint16_t getRegBitWidth(const RegisterRef &RR) const
bool isInt(const RegisterCell &A) const
MachineRegisterInfo & MRI
virtual const TargetRegisterClass & composeWithSubRegIndex(const TargetRegisterClass &RC, unsigned Idx) const
virtual bool track(const TargetRegisterClass *RC) const
void putCell(const RegisterRef &RR, RegisterCell RC, CellMapType &M) const
virtual uint16_t getPhysRegBitWidth(MCRegister Reg) const
RegisterCell getCell(const RegisterRef &RR, const CellMapType &M) const
virtual BitMask mask(Register Reg, unsigned Sub) const
static RegisterCell self(unsigned Reg, uint16_t Width)
static RegisterCell ref(const RegisterCell &C)
RegisterCell & fill(uint16_t B, uint16_t E, const BitValue &V)
RegisterCell extract(const BitMask &M) const
RegisterCell & regify(unsigned R)
uint16_t ct(bool B) const
RegisterCell & insert(const RegisterCell &RC, const BitMask &M)
static RegisterCell top(uint16_t Width)
uint16_t cl(bool B) const
RegisterCell(uint16_t Width=DefaultBitN)
RegisterCell & rol(uint16_t Sh)
SetVector< const MachineBasicBlock * > BranchTargetList
bool reached(const MachineBasicBlock *B) const
void subst(RegisterRef OldRR, RegisterRef NewRR)
void print_cells(raw_ostream &OS) const
std::map< unsigned, RegisterCell > CellMapType
void put(RegisterRef RR, const RegisterCell &RC)
BitTracker(const MachineEvaluator &E, MachineFunction &F)
void visit(const MachineInstr &MI)
RegisterCell get(RegisterRef RR) const