Path: blob/main/contrib/llvm-project/llvm/lib/Target/Hexagon/BitTracker.cpp
35266 views
//===- BitTracker.cpp -----------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78// SSA-based bit propagation.9//10// The purpose of this code is, for a given virtual register, to provide11// information about the value of each bit in the register. The values12// of bits are represented by the class BitValue, and take one of four13// cases: 0, 1, "ref" and "bottom". The 0 and 1 are rather clear, the14// "ref" value means that the bit is a copy of another bit (which itself15// cannot be a copy of yet another bit---such chains are not allowed).16// A "ref" value is associated with a BitRef structure, which indicates17// which virtual register, and which bit in that register is the origin18// of the value. For example, given an instruction19// %2 = ASL %1, 120// assuming that nothing is known about bits of %1, bit 1 of %221// will be a "ref" to (%1, 0). If there is a subsequent instruction22// %3 = ASL %2, 223// then bit 3 of %3 will be a "ref" to (%1, 0) as well.24// The "bottom" case means that the bit's value cannot be determined,25// and that this virtual register actually defines it. The "bottom" case26// is discussed in detail in BitTracker.h. In fact, "bottom" is a "ref27// to self", so for the %1 above, the bit 0 of it will be a "ref" to28// (%1, 0), bit 1 will be a "ref" to (%1, 1), etc.29//30// The tracker implements the Wegman-Zadeck algorithm, originally developed31// for SSA-based constant propagation. Each register is represented as32// a sequence of bits, with the convention that bit 0 is the least signi-33// ficant bit. Each bit is propagated individually. The class RegisterCell34// implements the register's representation, and is also the subject of35// the lattice operations in the tracker.36//37// The intended usage of the bit tracker is to create a target-specific38// machine instruction evaluator, pass the evaluator to the BitTracker39// object, and run the tracker. The tracker will then collect the bit40// value information for a given machine function. After that, it can be41// queried for the cells for each virtual register.42// Sample code:43// const TargetSpecificEvaluator TSE(TRI, MRI);44// BitTracker BT(TSE, MF);45// BT.run();46// ...47// unsigned Reg = interestingRegister();48// RegisterCell RC = BT.get(Reg);49// if (RC[3].is(1))50// Reg0bit3 = 1;51//52// The code below is intended to be fully target-independent.5354#include "BitTracker.h"55#include "llvm/ADT/APInt.h"56#include "llvm/ADT/BitVector.h"57#include "llvm/CodeGen/MachineBasicBlock.h"58#include "llvm/CodeGen/MachineFunction.h"59#include "llvm/CodeGen/MachineInstr.h"60#include "llvm/CodeGen/MachineOperand.h"61#include "llvm/CodeGen/MachineRegisterInfo.h"62#include "llvm/CodeGen/TargetRegisterInfo.h"63#include "llvm/IR/Constants.h"64#include "llvm/Support/Debug.h"65#include "llvm/Support/raw_ostream.h"66#include <cassert>67#include <cstdint>68#include <iterator>6970using namespace llvm;7172using BT = BitTracker;7374namespace {7576// Local trickery to pretty print a register (without the whole "%number"77// business).78struct printv {79printv(unsigned r) : R(r) {}8081unsigned R;82};8384raw_ostream &operator<< (raw_ostream &OS, const printv &PV) {85if (PV.R)86OS << 'v' << Register::virtReg2Index(PV.R);87else88OS << 's';89return OS;90}9192} // end anonymous namespace9394namespace llvm {9596raw_ostream &operator<<(raw_ostream &OS, const BT::BitValue &BV) {97switch (BV.Type) {98case BT::BitValue::Top:99OS << 'T';100break;101case BT::BitValue::Zero:102OS << '0';103break;104case BT::BitValue::One:105OS << '1';106break;107case BT::BitValue::Ref:108OS << printv(BV.RefI.Reg) << '[' << BV.RefI.Pos << ']';109break;110}111return OS;112}113114raw_ostream &operator<<(raw_ostream &OS, const BT::RegisterCell &RC) {115unsigned n = RC.Bits.size();116OS << "{ w:" << n;117// Instead of printing each bit value individually, try to group them118// into logical segments, such as sequences of 0 or 1 bits or references119// to consecutive bits (e.g. "bits 3-5 are same as bits 7-9 of reg xyz").120// "Start" will be the index of the beginning of the most recent segment.121unsigned Start = 0;122bool SeqRef = false; // A sequence of refs to consecutive bits.123bool ConstRef = false; // A sequence of refs to the same bit.124125for (unsigned i = 1, n = RC.Bits.size(); i < n; ++i) {126const BT::BitValue &V = RC[i];127const BT::BitValue &SV = RC[Start];128bool IsRef = (V.Type == BT::BitValue::Ref);129// If the current value is the same as Start, skip to the next one.130if (!IsRef && V == SV)131continue;132if (IsRef && SV.Type == BT::BitValue::Ref && V.RefI.Reg == SV.RefI.Reg) {133if (Start+1 == i) {134SeqRef = (V.RefI.Pos == SV.RefI.Pos+1);135ConstRef = (V.RefI.Pos == SV.RefI.Pos);136}137if (SeqRef && V.RefI.Pos == SV.RefI.Pos+(i-Start))138continue;139if (ConstRef && V.RefI.Pos == SV.RefI.Pos)140continue;141}142143// The current value is different. Print the previous one and reset144// the Start.145OS << " [" << Start;146unsigned Count = i - Start;147if (Count == 1) {148OS << "]:" << SV;149} else {150OS << '-' << i-1 << "]:";151if (SV.Type == BT::BitValue::Ref && SeqRef)152OS << printv(SV.RefI.Reg) << '[' << SV.RefI.Pos << '-'153<< SV.RefI.Pos+(Count-1) << ']';154else155OS << SV;156}157Start = i;158SeqRef = ConstRef = false;159}160161OS << " [" << Start;162unsigned Count = n - Start;163if (n-Start == 1) {164OS << "]:" << RC[Start];165} else {166OS << '-' << n-1 << "]:";167const BT::BitValue &SV = RC[Start];168if (SV.Type == BT::BitValue::Ref && SeqRef)169OS << printv(SV.RefI.Reg) << '[' << SV.RefI.Pos << '-'170<< SV.RefI.Pos+(Count-1) << ']';171else172OS << SV;173}174OS << " }";175176return OS;177}178179} // end namespace llvm180181void BitTracker::print_cells(raw_ostream &OS) const {182for (const std::pair<unsigned, RegisterCell> P : Map)183dbgs() << printReg(P.first, &ME.TRI) << " -> " << P.second << "\n";184}185186BitTracker::BitTracker(const MachineEvaluator &E, MachineFunction &F)187: ME(E), MF(F), MRI(F.getRegInfo()), Map(*new CellMapType), Trace(false) {188}189190BitTracker::~BitTracker() {191delete ⤅192}193194// If we were allowed to update a cell for a part of a register, the meet195// operation would need to be parametrized by the register number and the196// exact part of the register, so that the computer BitRefs correspond to197// the actual bits of the "self" register.198// While this cannot happen in the current implementation, I'm not sure199// if this should be ruled out in the future.200bool BT::RegisterCell::meet(const RegisterCell &RC, Register SelfR) {201// An example when "meet" can be invoked with SelfR == 0 is a phi node202// with a physical register as an operand.203assert(SelfR == 0 || SelfR.isVirtual());204bool Changed = false;205for (uint16_t i = 0, n = Bits.size(); i < n; ++i) {206const BitValue &RCV = RC[i];207Changed |= Bits[i].meet(RCV, BitRef(SelfR, i));208}209return Changed;210}211212// Insert the entire cell RC into the current cell at position given by M.213BT::RegisterCell &BT::RegisterCell::insert(const BT::RegisterCell &RC,214const BitMask &M) {215uint16_t B = M.first(), E = M.last(), W = width();216// M must be a valid mask for *this.217assert(B < W && E < W);218// The masked part of *this must have the same number of bits219// as the source.220assert(B > E || E-B+1 == RC.width()); // B <= E => E-B+1 = |RC|.221assert(B <= E || E+(W-B)+1 == RC.width()); // E < B => E+(W-B)+1 = |RC|.222if (B <= E) {223for (uint16_t i = 0; i <= E-B; ++i)224Bits[i+B] = RC[i];225} else {226for (uint16_t i = 0; i < W-B; ++i)227Bits[i+B] = RC[i];228for (uint16_t i = 0; i <= E; ++i)229Bits[i] = RC[i+(W-B)];230}231return *this;232}233234BT::RegisterCell BT::RegisterCell::extract(const BitMask &M) const {235uint16_t B = M.first(), E = M.last(), W = width();236assert(B < W && E < W);237if (B <= E) {238RegisterCell RC(E-B+1);239for (uint16_t i = B; i <= E; ++i)240RC.Bits[i-B] = Bits[i];241return RC;242}243244RegisterCell RC(E+(W-B)+1);245for (uint16_t i = 0; i < W-B; ++i)246RC.Bits[i] = Bits[i+B];247for (uint16_t i = 0; i <= E; ++i)248RC.Bits[i+(W-B)] = Bits[i];249return RC;250}251252BT::RegisterCell &BT::RegisterCell::rol(uint16_t Sh) {253// Rotate left (i.e. towards increasing bit indices).254// Swap the two parts: [0..W-Sh-1] [W-Sh..W-1]255uint16_t W = width();256Sh = Sh % W;257if (Sh == 0)258return *this;259260RegisterCell Tmp(W-Sh);261// Tmp = [0..W-Sh-1].262for (uint16_t i = 0; i < W-Sh; ++i)263Tmp[i] = Bits[i];264// Shift [W-Sh..W-1] to [0..Sh-1].265for (uint16_t i = 0; i < Sh; ++i)266Bits[i] = Bits[W-Sh+i];267// Copy Tmp to [Sh..W-1].268for (uint16_t i = 0; i < W-Sh; ++i)269Bits[i+Sh] = Tmp.Bits[i];270return *this;271}272273BT::RegisterCell &BT::RegisterCell::fill(uint16_t B, uint16_t E,274const BitValue &V) {275assert(B <= E);276while (B < E)277Bits[B++] = V;278return *this;279}280281BT::RegisterCell &BT::RegisterCell::cat(const RegisterCell &RC) {282// Append the cell given as the argument to the "this" cell.283// Bit 0 of RC becomes bit W of the result, where W is this->width().284uint16_t W = width(), WRC = RC.width();285Bits.resize(W+WRC);286for (uint16_t i = 0; i < WRC; ++i)287Bits[i+W] = RC.Bits[i];288return *this;289}290291uint16_t BT::RegisterCell::ct(bool B) const {292uint16_t W = width();293uint16_t C = 0;294BitValue V = B;295while (C < W && Bits[C] == V)296C++;297return C;298}299300uint16_t BT::RegisterCell::cl(bool B) const {301uint16_t W = width();302uint16_t C = 0;303BitValue V = B;304while (C < W && Bits[W-(C+1)] == V)305C++;306return C;307}308309bool BT::RegisterCell::operator== (const RegisterCell &RC) const {310uint16_t W = Bits.size();311if (RC.Bits.size() != W)312return false;313for (uint16_t i = 0; i < W; ++i)314if (Bits[i] != RC[i])315return false;316return true;317}318319BT::RegisterCell &BT::RegisterCell::regify(unsigned R) {320for (unsigned i = 0, n = width(); i < n; ++i) {321const BitValue &V = Bits[i];322if (V.Type == BitValue::Ref && V.RefI.Reg == 0)323Bits[i].RefI = BitRef(R, i);324}325return *this;326}327328uint16_t BT::MachineEvaluator::getRegBitWidth(const RegisterRef &RR) const {329// The general problem is with finding a register class that corresponds330// to a given reference reg:sub. There can be several such classes, and331// since we only care about the register size, it does not matter which332// such class we would find.333// The easiest way to accomplish what we want is to334// 1. find a physical register PhysR from the same class as RR.Reg,335// 2. find a physical register PhysS that corresponds to PhysR:RR.Sub,336// 3. find a register class that contains PhysS.337if (RR.Reg.isVirtual()) {338const auto &VC = composeWithSubRegIndex(*MRI.getRegClass(RR.Reg), RR.Sub);339return TRI.getRegSizeInBits(VC);340}341assert(RR.Reg.isPhysical());342MCRegister PhysR =343(RR.Sub == 0) ? RR.Reg.asMCReg() : TRI.getSubReg(RR.Reg, RR.Sub);344return getPhysRegBitWidth(PhysR);345}346347BT::RegisterCell BT::MachineEvaluator::getCell(const RegisterRef &RR,348const CellMapType &M) const {349uint16_t BW = getRegBitWidth(RR);350351// Physical registers are assumed to be present in the map with an unknown352// value. Don't actually insert anything in the map, just return the cell.353if (RR.Reg.isPhysical())354return RegisterCell::self(0, BW);355356assert(RR.Reg.isVirtual());357// For virtual registers that belong to a class that is not tracked,358// generate an "unknown" value as well.359const TargetRegisterClass *C = MRI.getRegClass(RR.Reg);360if (!track(C))361return RegisterCell::self(0, BW);362363CellMapType::const_iterator F = M.find(RR.Reg);364if (F != M.end()) {365if (!RR.Sub)366return F->second;367BitMask M = mask(RR.Reg, RR.Sub);368return F->second.extract(M);369}370// If not found, create a "top" entry, but do not insert it in the map.371return RegisterCell::top(BW);372}373374void BT::MachineEvaluator::putCell(const RegisterRef &RR, RegisterCell RC,375CellMapType &M) const {376// While updating the cell map can be done in a meaningful way for377// a part of a register, it makes little sense to implement it as the378// SSA representation would never contain such "partial definitions".379if (!RR.Reg.isVirtual())380return;381assert(RR.Sub == 0 && "Unexpected sub-register in definition");382// Eliminate all ref-to-reg-0 bit values: replace them with "self".383M[RR.Reg] = RC.regify(RR.Reg);384}385386// Check if the cell represents a compile-time integer value.387bool BT::MachineEvaluator::isInt(const RegisterCell &A) const {388uint16_t W = A.width();389for (uint16_t i = 0; i < W; ++i)390if (!A[i].is(0) && !A[i].is(1))391return false;392return true;393}394395// Convert a cell to the integer value. The result must fit in uint64_t.396uint64_t BT::MachineEvaluator::toInt(const RegisterCell &A) const {397assert(isInt(A));398uint64_t Val = 0;399uint16_t W = A.width();400for (uint16_t i = 0; i < W; ++i) {401Val <<= 1;402Val |= A[i].is(1);403}404return Val;405}406407// Evaluator helper functions. These implement some common operation on408// register cells that can be used to implement target-specific instructions409// in a target-specific evaluator.410411BT::RegisterCell BT::MachineEvaluator::eIMM(int64_t V, uint16_t W) const {412RegisterCell Res(W);413// For bits beyond the 63rd, this will generate the sign bit of V.414for (uint16_t i = 0; i < W; ++i) {415Res[i] = BitValue(V & 1);416V >>= 1;417}418return Res;419}420421BT::RegisterCell BT::MachineEvaluator::eIMM(const ConstantInt *CI) const {422const APInt &A = CI->getValue();423uint16_t BW = A.getBitWidth();424assert((unsigned)BW == A.getBitWidth() && "BitWidth overflow");425RegisterCell Res(BW);426for (uint16_t i = 0; i < BW; ++i)427Res[i] = A[i];428return Res;429}430431BT::RegisterCell BT::MachineEvaluator::eADD(const RegisterCell &A1,432const RegisterCell &A2) const {433uint16_t W = A1.width();434assert(W == A2.width());435RegisterCell Res(W);436bool Carry = false;437uint16_t I;438for (I = 0; I < W; ++I) {439const BitValue &V1 = A1[I];440const BitValue &V2 = A2[I];441if (!V1.num() || !V2.num())442break;443unsigned S = bool(V1) + bool(V2) + Carry;444Res[I] = BitValue(S & 1);445Carry = (S > 1);446}447for (; I < W; ++I) {448const BitValue &V1 = A1[I];449const BitValue &V2 = A2[I];450// If the next bit is same as Carry, the result will be 0 plus the451// other bit. The Carry bit will remain unchanged.452if (V1.is(Carry))453Res[I] = BitValue::ref(V2);454else if (V2.is(Carry))455Res[I] = BitValue::ref(V1);456else457break;458}459for (; I < W; ++I)460Res[I] = BitValue::self();461return Res;462}463464BT::RegisterCell BT::MachineEvaluator::eSUB(const RegisterCell &A1,465const RegisterCell &A2) const {466uint16_t W = A1.width();467assert(W == A2.width());468RegisterCell Res(W);469bool Borrow = false;470uint16_t I;471for (I = 0; I < W; ++I) {472const BitValue &V1 = A1[I];473const BitValue &V2 = A2[I];474if (!V1.num() || !V2.num())475break;476unsigned S = bool(V1) - bool(V2) - Borrow;477Res[I] = BitValue(S & 1);478Borrow = (S > 1);479}480for (; I < W; ++I) {481const BitValue &V1 = A1[I];482const BitValue &V2 = A2[I];483if (V1.is(Borrow)) {484Res[I] = BitValue::ref(V2);485break;486}487if (V2.is(Borrow))488Res[I] = BitValue::ref(V1);489else490break;491}492for (; I < W; ++I)493Res[I] = BitValue::self();494return Res;495}496497BT::RegisterCell BT::MachineEvaluator::eMLS(const RegisterCell &A1,498const RegisterCell &A2) const {499uint16_t W = A1.width() + A2.width();500uint16_t Z = A1.ct(false) + A2.ct(false);501RegisterCell Res(W);502Res.fill(0, Z, BitValue::Zero);503Res.fill(Z, W, BitValue::self());504return Res;505}506507BT::RegisterCell BT::MachineEvaluator::eMLU(const RegisterCell &A1,508const RegisterCell &A2) const {509uint16_t W = A1.width() + A2.width();510uint16_t Z = A1.ct(false) + A2.ct(false);511RegisterCell Res(W);512Res.fill(0, Z, BitValue::Zero);513Res.fill(Z, W, BitValue::self());514return Res;515}516517BT::RegisterCell BT::MachineEvaluator::eASL(const RegisterCell &A1,518uint16_t Sh) const {519assert(Sh <= A1.width());520RegisterCell Res = RegisterCell::ref(A1);521Res.rol(Sh);522Res.fill(0, Sh, BitValue::Zero);523return Res;524}525526BT::RegisterCell BT::MachineEvaluator::eLSR(const RegisterCell &A1,527uint16_t Sh) const {528uint16_t W = A1.width();529assert(Sh <= W);530RegisterCell Res = RegisterCell::ref(A1);531Res.rol(W-Sh);532Res.fill(W-Sh, W, BitValue::Zero);533return Res;534}535536BT::RegisterCell BT::MachineEvaluator::eASR(const RegisterCell &A1,537uint16_t Sh) const {538uint16_t W = A1.width();539assert(Sh <= W);540RegisterCell Res = RegisterCell::ref(A1);541BitValue Sign = Res[W-1];542Res.rol(W-Sh);543Res.fill(W-Sh, W, Sign);544return Res;545}546547BT::RegisterCell BT::MachineEvaluator::eAND(const RegisterCell &A1,548const RegisterCell &A2) const {549uint16_t W = A1.width();550assert(W == A2.width());551RegisterCell Res(W);552for (uint16_t i = 0; i < W; ++i) {553const BitValue &V1 = A1[i];554const BitValue &V2 = A2[i];555if (V1.is(1))556Res[i] = BitValue::ref(V2);557else if (V2.is(1))558Res[i] = BitValue::ref(V1);559else if (V1.is(0) || V2.is(0))560Res[i] = BitValue::Zero;561else if (V1 == V2)562Res[i] = V1;563else564Res[i] = BitValue::self();565}566return Res;567}568569BT::RegisterCell BT::MachineEvaluator::eORL(const RegisterCell &A1,570const RegisterCell &A2) const {571uint16_t W = A1.width();572assert(W == A2.width());573RegisterCell Res(W);574for (uint16_t i = 0; i < W; ++i) {575const BitValue &V1 = A1[i];576const BitValue &V2 = A2[i];577if (V1.is(1) || V2.is(1))578Res[i] = BitValue::One;579else if (V1.is(0))580Res[i] = BitValue::ref(V2);581else if (V2.is(0))582Res[i] = BitValue::ref(V1);583else if (V1 == V2)584Res[i] = V1;585else586Res[i] = BitValue::self();587}588return Res;589}590591BT::RegisterCell BT::MachineEvaluator::eXOR(const RegisterCell &A1,592const RegisterCell &A2) const {593uint16_t W = A1.width();594assert(W == A2.width());595RegisterCell Res(W);596for (uint16_t i = 0; i < W; ++i) {597const BitValue &V1 = A1[i];598const BitValue &V2 = A2[i];599if (V1.is(0))600Res[i] = BitValue::ref(V2);601else if (V2.is(0))602Res[i] = BitValue::ref(V1);603else if (V1 == V2)604Res[i] = BitValue::Zero;605else606Res[i] = BitValue::self();607}608return Res;609}610611BT::RegisterCell BT::MachineEvaluator::eNOT(const RegisterCell &A1) const {612uint16_t W = A1.width();613RegisterCell Res(W);614for (uint16_t i = 0; i < W; ++i) {615const BitValue &V = A1[i];616if (V.is(0))617Res[i] = BitValue::One;618else if (V.is(1))619Res[i] = BitValue::Zero;620else621Res[i] = BitValue::self();622}623return Res;624}625626BT::RegisterCell BT::MachineEvaluator::eSET(const RegisterCell &A1,627uint16_t BitN) const {628assert(BitN < A1.width());629RegisterCell Res = RegisterCell::ref(A1);630Res[BitN] = BitValue::One;631return Res;632}633634BT::RegisterCell BT::MachineEvaluator::eCLR(const RegisterCell &A1,635uint16_t BitN) const {636assert(BitN < A1.width());637RegisterCell Res = RegisterCell::ref(A1);638Res[BitN] = BitValue::Zero;639return Res;640}641642BT::RegisterCell BT::MachineEvaluator::eCLB(const RegisterCell &A1, bool B,643uint16_t W) const {644uint16_t C = A1.cl(B), AW = A1.width();645// If the last leading non-B bit is not a constant, then we don't know646// the real count.647if ((C < AW && A1[AW-1-C].num()) || C == AW)648return eIMM(C, W);649return RegisterCell::self(0, W);650}651652BT::RegisterCell BT::MachineEvaluator::eCTB(const RegisterCell &A1, bool B,653uint16_t W) const {654uint16_t C = A1.ct(B), AW = A1.width();655// If the last trailing non-B bit is not a constant, then we don't know656// the real count.657if ((C < AW && A1[C].num()) || C == AW)658return eIMM(C, W);659return RegisterCell::self(0, W);660}661662BT::RegisterCell BT::MachineEvaluator::eSXT(const RegisterCell &A1,663uint16_t FromN) const {664uint16_t W = A1.width();665assert(FromN <= W);666RegisterCell Res = RegisterCell::ref(A1);667BitValue Sign = Res[FromN-1];668// Sign-extend "inreg".669Res.fill(FromN, W, Sign);670return Res;671}672673BT::RegisterCell BT::MachineEvaluator::eZXT(const RegisterCell &A1,674uint16_t FromN) const {675uint16_t W = A1.width();676assert(FromN <= W);677RegisterCell Res = RegisterCell::ref(A1);678Res.fill(FromN, W, BitValue::Zero);679return Res;680}681682BT::RegisterCell BT::MachineEvaluator::eXTR(const RegisterCell &A1,683uint16_t B, uint16_t E) const {684uint16_t W = A1.width();685assert(B < W && E <= W);686if (B == E)687return RegisterCell(0);688uint16_t Last = (E > 0) ? E-1 : W-1;689RegisterCell Res = RegisterCell::ref(A1).extract(BT::BitMask(B, Last));690// Return shorter cell.691return Res;692}693694BT::RegisterCell BT::MachineEvaluator::eINS(const RegisterCell &A1,695const RegisterCell &A2, uint16_t AtN) const {696uint16_t W1 = A1.width(), W2 = A2.width();697(void)W1;698assert(AtN < W1 && AtN+W2 <= W1);699// Copy bits from A1, insert A2 at position AtN.700RegisterCell Res = RegisterCell::ref(A1);701if (W2 > 0)702Res.insert(RegisterCell::ref(A2), BT::BitMask(AtN, AtN+W2-1));703return Res;704}705706BT::BitMask BT::MachineEvaluator::mask(Register Reg, unsigned Sub) const {707assert(Sub == 0 && "Generic BitTracker::mask called for Sub != 0");708uint16_t W = getRegBitWidth(Reg);709assert(W > 0 && "Cannot generate mask for empty register");710return BitMask(0, W-1);711}712713uint16_t BT::MachineEvaluator::getPhysRegBitWidth(MCRegister Reg) const {714const TargetRegisterClass &PC = *TRI.getMinimalPhysRegClass(Reg);715return TRI.getRegSizeInBits(PC);716}717718bool BT::MachineEvaluator::evaluate(const MachineInstr &MI,719const CellMapType &Inputs,720CellMapType &Outputs) const {721unsigned Opc = MI.getOpcode();722switch (Opc) {723case TargetOpcode::REG_SEQUENCE: {724RegisterRef RD = MI.getOperand(0);725assert(RD.Sub == 0);726RegisterRef RS = MI.getOperand(1);727unsigned SS = MI.getOperand(2).getImm();728RegisterRef RT = MI.getOperand(3);729unsigned ST = MI.getOperand(4).getImm();730assert(SS != ST);731732uint16_t W = getRegBitWidth(RD);733RegisterCell Res(W);734Res.insert(RegisterCell::ref(getCell(RS, Inputs)), mask(RD.Reg, SS));735Res.insert(RegisterCell::ref(getCell(RT, Inputs)), mask(RD.Reg, ST));736putCell(RD, Res, Outputs);737break;738}739740case TargetOpcode::COPY: {741// COPY can transfer a smaller register into a wider one.742// If that is the case, fill the remaining high bits with 0.743RegisterRef RD = MI.getOperand(0);744RegisterRef RS = MI.getOperand(1);745assert(RD.Sub == 0);746uint16_t WD = getRegBitWidth(RD);747uint16_t WS = getRegBitWidth(RS);748assert(WD >= WS);749RegisterCell Src = getCell(RS, Inputs);750RegisterCell Res(WD);751Res.insert(Src, BitMask(0, WS-1));752Res.fill(WS, WD, BitValue::Zero);753putCell(RD, Res, Outputs);754break;755}756757default:758return false;759}760761return true;762}763764bool BT::UseQueueType::Cmp::operator()(const MachineInstr *InstA,765const MachineInstr *InstB) const {766// This is a comparison function for a priority queue: give higher priority767// to earlier instructions.768// This operator is used as "less", so returning "true" gives InstB higher769// priority (because then InstA < InstB).770if (InstA == InstB)771return false;772const MachineBasicBlock *BA = InstA->getParent();773const MachineBasicBlock *BB = InstB->getParent();774if (BA != BB) {775// If the blocks are different, ideally the dominating block would776// have a higher priority, but it may be too expensive to check.777return BA->getNumber() > BB->getNumber();778}779780auto getDist = [this] (const MachineInstr *MI) {781auto F = Dist.find(MI);782if (F != Dist.end())783return F->second;784MachineBasicBlock::const_iterator I = MI->getParent()->begin();785MachineBasicBlock::const_iterator E = MI->getIterator();786unsigned D = std::distance(I, E);787Dist.insert(std::make_pair(MI, D));788return D;789};790791return getDist(InstA) > getDist(InstB);792}793794// Main W-Z implementation.795796void BT::visitPHI(const MachineInstr &PI) {797int ThisN = PI.getParent()->getNumber();798if (Trace)799dbgs() << "Visit FI(" << printMBBReference(*PI.getParent()) << "): " << PI;800801const MachineOperand &MD = PI.getOperand(0);802assert(MD.getSubReg() == 0 && "Unexpected sub-register in definition");803RegisterRef DefRR(MD);804uint16_t DefBW = ME.getRegBitWidth(DefRR);805806RegisterCell DefC = ME.getCell(DefRR, Map);807if (DefC == RegisterCell::self(DefRR.Reg, DefBW)) // XXX slow808return;809810bool Changed = false;811812for (unsigned i = 1, n = PI.getNumOperands(); i < n; i += 2) {813const MachineBasicBlock *PB = PI.getOperand(i + 1).getMBB();814int PredN = PB->getNumber();815if (Trace)816dbgs() << " edge " << printMBBReference(*PB) << "->"817<< printMBBReference(*PI.getParent());818if (!EdgeExec.count(CFGEdge(PredN, ThisN))) {819if (Trace)820dbgs() << " not executable\n";821continue;822}823824RegisterRef RU = PI.getOperand(i);825RegisterCell ResC = ME.getCell(RU, Map);826if (Trace)827dbgs() << " input reg: " << printReg(RU.Reg, &ME.TRI, RU.Sub)828<< " cell: " << ResC << "\n";829Changed |= DefC.meet(ResC, DefRR.Reg);830}831832if (Changed) {833if (Trace)834dbgs() << "Output: " << printReg(DefRR.Reg, &ME.TRI, DefRR.Sub)835<< " cell: " << DefC << "\n";836ME.putCell(DefRR, DefC, Map);837visitUsesOf(DefRR.Reg);838}839}840841void BT::visitNonBranch(const MachineInstr &MI) {842if (Trace)843dbgs() << "Visit MI(" << printMBBReference(*MI.getParent()) << "): " << MI;844if (MI.isDebugInstr())845return;846assert(!MI.isBranch() && "Unexpected branch instruction");847848CellMapType ResMap;849bool Eval = ME.evaluate(MI, Map, ResMap);850851if (Trace && Eval) {852for (const MachineOperand &MO : MI.operands()) {853if (!MO.isReg() || !MO.isUse())854continue;855RegisterRef RU(MO);856dbgs() << " input reg: " << printReg(RU.Reg, &ME.TRI, RU.Sub)857<< " cell: " << ME.getCell(RU, Map) << "\n";858}859dbgs() << "Outputs:\n";860for (const std::pair<const unsigned, RegisterCell> &P : ResMap) {861RegisterRef RD(P.first);862dbgs() << " " << printReg(P.first, &ME.TRI) << " cell: "863<< ME.getCell(RD, ResMap) << "\n";864}865}866867// Iterate over all definitions of the instruction, and update the868// cells accordingly.869for (const MachineOperand &MO : MI.operands()) {870// Visit register defs only.871if (!MO.isReg() || !MO.isDef())872continue;873RegisterRef RD(MO);874assert(RD.Sub == 0 && "Unexpected sub-register in definition");875if (!RD.Reg.isVirtual())876continue;877878bool Changed = false;879if (!Eval || ResMap.count(RD.Reg) == 0) {880// Set to "ref" (aka "bottom").881uint16_t DefBW = ME.getRegBitWidth(RD);882RegisterCell RefC = RegisterCell::self(RD.Reg, DefBW);883if (RefC != ME.getCell(RD, Map)) {884ME.putCell(RD, RefC, Map);885Changed = true;886}887} else {888RegisterCell DefC = ME.getCell(RD, Map);889RegisterCell ResC = ME.getCell(RD, ResMap);890// This is a non-phi instruction, so the values of the inputs come891// from the same registers each time this instruction is evaluated.892// During the propagation, the values of the inputs can become lowered893// in the sense of the lattice operation, which may cause different894// results to be calculated in subsequent evaluations. This should895// not cause the bottoming of the result in the map, since the new896// result is already reflecting the lowered inputs.897for (uint16_t i = 0, w = DefC.width(); i < w; ++i) {898BitValue &V = DefC[i];899// Bits that are already "bottom" should not be updated.900if (V.Type == BitValue::Ref && V.RefI.Reg == RD.Reg)901continue;902// Same for those that are identical in DefC and ResC.903if (V == ResC[i])904continue;905V = ResC[i];906Changed = true;907}908if (Changed)909ME.putCell(RD, DefC, Map);910}911if (Changed)912visitUsesOf(RD.Reg);913}914}915916void BT::visitBranchesFrom(const MachineInstr &BI) {917const MachineBasicBlock &B = *BI.getParent();918MachineBasicBlock::const_iterator It = BI, End = B.end();919BranchTargetList Targets, BTs;920bool FallsThrough = true, DefaultToAll = false;921int ThisN = B.getNumber();922923do {924BTs.clear();925const MachineInstr &MI = *It;926if (Trace)927dbgs() << "Visit BR(" << printMBBReference(B) << "): " << MI;928assert(MI.isBranch() && "Expecting branch instruction");929InstrExec.insert(&MI);930bool Eval = ME.evaluate(MI, Map, BTs, FallsThrough);931if (!Eval) {932// If the evaluation failed, we will add all targets. Keep going in933// the loop to mark all executable branches as such.934DefaultToAll = true;935FallsThrough = true;936if (Trace)937dbgs() << " failed to evaluate: will add all CFG successors\n";938} else if (!DefaultToAll) {939// If evaluated successfully add the targets to the cumulative list.940if (Trace) {941dbgs() << " adding targets:";942for (const MachineBasicBlock *BT : BTs)943dbgs() << " " << printMBBReference(*BT);944if (FallsThrough)945dbgs() << "\n falls through\n";946else947dbgs() << "\n does not fall through\n";948}949Targets.insert(BTs.begin(), BTs.end());950}951++It;952} while (FallsThrough && It != End);953954if (B.mayHaveInlineAsmBr())955DefaultToAll = true;956957if (!DefaultToAll) {958// Need to add all CFG successors that lead to EH landing pads.959// There won't be explicit branches to these blocks, but they must960// be processed.961for (const MachineBasicBlock *SB : B.successors()) {962if (SB->isEHPad())963Targets.insert(SB);964}965if (FallsThrough) {966MachineFunction::const_iterator BIt = B.getIterator();967MachineFunction::const_iterator Next = std::next(BIt);968if (Next != MF.end())969Targets.insert(&*Next);970}971} else {972for (const MachineBasicBlock *SB : B.successors())973Targets.insert(SB);974}975976for (const MachineBasicBlock *TB : Targets)977FlowQ.push(CFGEdge(ThisN, TB->getNumber()));978}979980void BT::visitUsesOf(Register Reg) {981if (Trace)982dbgs() << "queuing uses of modified reg " << printReg(Reg, &ME.TRI)983<< " cell: " << ME.getCell(Reg, Map) << '\n';984985for (MachineInstr &UseI : MRI.use_nodbg_instructions(Reg))986UseQ.push(&UseI);987}988989BT::RegisterCell BT::get(RegisterRef RR) const {990return ME.getCell(RR, Map);991}992993void BT::put(RegisterRef RR, const RegisterCell &RC) {994ME.putCell(RR, RC, Map);995}996997// Replace all references to bits from OldRR with the corresponding bits998// in NewRR.999void BT::subst(RegisterRef OldRR, RegisterRef NewRR) {1000assert(Map.count(OldRR.Reg) > 0 && "OldRR not present in map");1001BitMask OM = ME.mask(OldRR.Reg, OldRR.Sub);1002BitMask NM = ME.mask(NewRR.Reg, NewRR.Sub);1003uint16_t OMB = OM.first(), OME = OM.last();1004uint16_t NMB = NM.first(), NME = NM.last();1005(void)NME;1006assert((OME-OMB == NME-NMB) &&1007"Substituting registers of different lengths");1008for (std::pair<const unsigned, RegisterCell> &P : Map) {1009RegisterCell &RC = P.second;1010for (uint16_t i = 0, w = RC.width(); i < w; ++i) {1011BitValue &V = RC[i];1012if (V.Type != BitValue::Ref || V.RefI.Reg != OldRR.Reg)1013continue;1014if (V.RefI.Pos < OMB || V.RefI.Pos > OME)1015continue;1016V.RefI.Reg = NewRR.Reg;1017V.RefI.Pos += NMB-OMB;1018}1019}1020}10211022// Check if the block has been "executed" during propagation. (If not, the1023// block is dead, but it may still appear to be reachable.)1024bool BT::reached(const MachineBasicBlock *B) const {1025int BN = B->getNumber();1026assert(BN >= 0);1027return ReachedBB.count(BN);1028}10291030// Visit an individual instruction. This could be a newly added instruction,1031// or one that has been modified by an optimization.1032void BT::visit(const MachineInstr &MI) {1033assert(!MI.isBranch() && "Only non-branches are allowed");1034InstrExec.insert(&MI);1035visitNonBranch(MI);1036// Make sure to flush all the pending use updates.1037runUseQueue();1038// The call to visitNonBranch could propagate the changes until a branch1039// is actually visited. This could result in adding CFG edges to the flow1040// queue. Since the queue won't be processed, clear it.1041while (!FlowQ.empty())1042FlowQ.pop();1043}10441045void BT::reset() {1046EdgeExec.clear();1047InstrExec.clear();1048Map.clear();1049ReachedBB.clear();1050ReachedBB.reserve(MF.size());1051}10521053void BT::runEdgeQueue(BitVector &BlockScanned) {1054while (!FlowQ.empty()) {1055CFGEdge Edge = FlowQ.front();1056FlowQ.pop();10571058if (!EdgeExec.insert(Edge).second)1059return;1060ReachedBB.insert(Edge.second);10611062const MachineBasicBlock &B = *MF.getBlockNumbered(Edge.second);1063MachineBasicBlock::const_iterator It = B.begin(), End = B.end();1064// Visit PHI nodes first.1065while (It != End && It->isPHI()) {1066const MachineInstr &PI = *It++;1067InstrExec.insert(&PI);1068visitPHI(PI);1069}10701071// If this block has already been visited through a flow graph edge,1072// then the instructions have already been processed. Any updates to1073// the cells would now only happen through visitUsesOf...1074if (BlockScanned[Edge.second])1075return;1076BlockScanned[Edge.second] = true;10771078// Visit non-branch instructions.1079while (It != End && !It->isBranch()) {1080const MachineInstr &MI = *It++;1081InstrExec.insert(&MI);1082visitNonBranch(MI);1083}1084// If block end has been reached, add the fall-through edge to the queue.1085if (It == End) {1086MachineFunction::const_iterator BIt = B.getIterator();1087MachineFunction::const_iterator Next = std::next(BIt);1088if (Next != MF.end() && B.isSuccessor(&*Next)) {1089int ThisN = B.getNumber();1090int NextN = Next->getNumber();1091FlowQ.push(CFGEdge(ThisN, NextN));1092}1093} else {1094// Handle the remaining sequence of branches. This function will update1095// the work queue.1096visitBranchesFrom(*It);1097}1098} // while (!FlowQ->empty())1099}11001101void BT::runUseQueue() {1102while (!UseQ.empty()) {1103MachineInstr &UseI = *UseQ.front();1104UseQ.pop();11051106if (!InstrExec.count(&UseI))1107continue;1108if (UseI.isPHI())1109visitPHI(UseI);1110else if (!UseI.isBranch())1111visitNonBranch(UseI);1112else1113visitBranchesFrom(UseI);1114}1115}11161117void BT::run() {1118reset();1119assert(FlowQ.empty());11201121using MachineFlowGraphTraits = GraphTraits<const MachineFunction*>;1122const MachineBasicBlock *Entry = MachineFlowGraphTraits::getEntryNode(&MF);11231124unsigned MaxBN = 0;1125for (const MachineBasicBlock &B : MF) {1126assert(B.getNumber() >= 0 && "Disconnected block");1127unsigned BN = B.getNumber();1128if (BN > MaxBN)1129MaxBN = BN;1130}11311132// Keep track of visited blocks.1133BitVector BlockScanned(MaxBN+1);11341135int EntryN = Entry->getNumber();1136// Generate a fake edge to get something to start with.1137FlowQ.push(CFGEdge(-1, EntryN));11381139while (!FlowQ.empty() || !UseQ.empty()) {1140runEdgeQueue(BlockScanned);1141runUseQueue();1142}1143UseQ.reset();11441145if (Trace)1146print_cells(dbgs() << "Cells after propagation:\n");1147}114811491150