10b57cec5SDimitry Andric //===- BitTracker.cpp -----------------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric // SSA-based bit propagation. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric // The purpose of this code is, for a given virtual register, to provide 120b57cec5SDimitry Andric // information about the value of each bit in the register. The values 130b57cec5SDimitry Andric // of bits are represented by the class BitValue, and take one of four 140b57cec5SDimitry Andric // cases: 0, 1, "ref" and "bottom". The 0 and 1 are rather clear, the 150b57cec5SDimitry Andric // "ref" value means that the bit is a copy of another bit (which itself 160b57cec5SDimitry Andric // cannot be a copy of yet another bit---such chains are not allowed). 170b57cec5SDimitry Andric // A "ref" value is associated with a BitRef structure, which indicates 180b57cec5SDimitry Andric // which virtual register, and which bit in that register is the origin 190b57cec5SDimitry Andric // of the value. For example, given an instruction 200b57cec5SDimitry Andric // %2 = ASL %1, 1 210b57cec5SDimitry Andric // assuming that nothing is known about bits of %1, bit 1 of %2 220b57cec5SDimitry Andric // will be a "ref" to (%1, 0). If there is a subsequent instruction 230b57cec5SDimitry Andric // %3 = ASL %2, 2 240b57cec5SDimitry Andric // then bit 3 of %3 will be a "ref" to (%1, 0) as well. 250b57cec5SDimitry Andric // The "bottom" case means that the bit's value cannot be determined, 260b57cec5SDimitry Andric // and that this virtual register actually defines it. The "bottom" case 270b57cec5SDimitry Andric // is discussed in detail in BitTracker.h. In fact, "bottom" is a "ref 280b57cec5SDimitry Andric // to self", so for the %1 above, the bit 0 of it will be a "ref" to 290b57cec5SDimitry Andric // (%1, 0), bit 1 will be a "ref" to (%1, 1), etc. 300b57cec5SDimitry Andric // 310b57cec5SDimitry Andric // The tracker implements the Wegman-Zadeck algorithm, originally developed 320b57cec5SDimitry Andric // for SSA-based constant propagation. Each register is represented as 330b57cec5SDimitry Andric // a sequence of bits, with the convention that bit 0 is the least signi- 340b57cec5SDimitry Andric // ficant bit. Each bit is propagated individually. The class RegisterCell 350b57cec5SDimitry Andric // implements the register's representation, and is also the subject of 360b57cec5SDimitry Andric // the lattice operations in the tracker. 370b57cec5SDimitry Andric // 380b57cec5SDimitry Andric // The intended usage of the bit tracker is to create a target-specific 390b57cec5SDimitry Andric // machine instruction evaluator, pass the evaluator to the BitTracker 400b57cec5SDimitry Andric // object, and run the tracker. The tracker will then collect the bit 410b57cec5SDimitry Andric // value information for a given machine function. After that, it can be 420b57cec5SDimitry Andric // queried for the cells for each virtual register. 430b57cec5SDimitry Andric // Sample code: 440b57cec5SDimitry Andric // const TargetSpecificEvaluator TSE(TRI, MRI); 450b57cec5SDimitry Andric // BitTracker BT(TSE, MF); 460b57cec5SDimitry Andric // BT.run(); 470b57cec5SDimitry Andric // ... 480b57cec5SDimitry Andric // unsigned Reg = interestingRegister(); 490b57cec5SDimitry Andric // RegisterCell RC = BT.get(Reg); 500b57cec5SDimitry Andric // if (RC[3].is(1)) 510b57cec5SDimitry Andric // Reg0bit3 = 1; 520b57cec5SDimitry Andric // 530b57cec5SDimitry Andric // The code below is intended to be fully target-independent. 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric #include "BitTracker.h" 560b57cec5SDimitry Andric #include "llvm/ADT/APInt.h" 570b57cec5SDimitry Andric #include "llvm/ADT/BitVector.h" 580b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 590b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 600b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 610b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 620b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 630b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 640b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 650b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 660b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 670b57cec5SDimitry Andric #include <cassert> 680b57cec5SDimitry Andric #include <cstdint> 690b57cec5SDimitry Andric #include <iterator> 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric using namespace llvm; 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric using BT = BitTracker; 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric namespace { 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric // Local trickery to pretty print a register (without the whole "%number" 780b57cec5SDimitry Andric // business). 790b57cec5SDimitry Andric struct printv { 800b57cec5SDimitry Andric printv(unsigned r) : R(r) {} 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric unsigned R; 830b57cec5SDimitry Andric }; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric raw_ostream &operator<< (raw_ostream &OS, const printv &PV) { 860b57cec5SDimitry Andric if (PV.R) 878bcb0991SDimitry Andric OS << 'v' << Register::virtReg2Index(PV.R); 880b57cec5SDimitry Andric else 890b57cec5SDimitry Andric OS << 's'; 900b57cec5SDimitry Andric return OS; 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric } // end anonymous namespace 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric namespace llvm { 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const BT::BitValue &BV) { 980b57cec5SDimitry Andric switch (BV.Type) { 990b57cec5SDimitry Andric case BT::BitValue::Top: 1000b57cec5SDimitry Andric OS << 'T'; 1010b57cec5SDimitry Andric break; 1020b57cec5SDimitry Andric case BT::BitValue::Zero: 1030b57cec5SDimitry Andric OS << '0'; 1040b57cec5SDimitry Andric break; 1050b57cec5SDimitry Andric case BT::BitValue::One: 1060b57cec5SDimitry Andric OS << '1'; 1070b57cec5SDimitry Andric break; 1080b57cec5SDimitry Andric case BT::BitValue::Ref: 1090b57cec5SDimitry Andric OS << printv(BV.RefI.Reg) << '[' << BV.RefI.Pos << ']'; 1100b57cec5SDimitry Andric break; 1110b57cec5SDimitry Andric } 1120b57cec5SDimitry Andric return OS; 1130b57cec5SDimitry Andric } 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const BT::RegisterCell &RC) { 1160b57cec5SDimitry Andric unsigned n = RC.Bits.size(); 1170b57cec5SDimitry Andric OS << "{ w:" << n; 1180b57cec5SDimitry Andric // Instead of printing each bit value individually, try to group them 1190b57cec5SDimitry Andric // into logical segments, such as sequences of 0 or 1 bits or references 1200b57cec5SDimitry Andric // to consecutive bits (e.g. "bits 3-5 are same as bits 7-9 of reg xyz"). 1210b57cec5SDimitry Andric // "Start" will be the index of the beginning of the most recent segment. 1220b57cec5SDimitry Andric unsigned Start = 0; 1230b57cec5SDimitry Andric bool SeqRef = false; // A sequence of refs to consecutive bits. 1240b57cec5SDimitry Andric bool ConstRef = false; // A sequence of refs to the same bit. 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric for (unsigned i = 1, n = RC.Bits.size(); i < n; ++i) { 1270b57cec5SDimitry Andric const BT::BitValue &V = RC[i]; 1280b57cec5SDimitry Andric const BT::BitValue &SV = RC[Start]; 1290b57cec5SDimitry Andric bool IsRef = (V.Type == BT::BitValue::Ref); 1300b57cec5SDimitry Andric // If the current value is the same as Start, skip to the next one. 1310b57cec5SDimitry Andric if (!IsRef && V == SV) 1320b57cec5SDimitry Andric continue; 1330b57cec5SDimitry Andric if (IsRef && SV.Type == BT::BitValue::Ref && V.RefI.Reg == SV.RefI.Reg) { 1340b57cec5SDimitry Andric if (Start+1 == i) { 1350b57cec5SDimitry Andric SeqRef = (V.RefI.Pos == SV.RefI.Pos+1); 1360b57cec5SDimitry Andric ConstRef = (V.RefI.Pos == SV.RefI.Pos); 1370b57cec5SDimitry Andric } 1380b57cec5SDimitry Andric if (SeqRef && V.RefI.Pos == SV.RefI.Pos+(i-Start)) 1390b57cec5SDimitry Andric continue; 1400b57cec5SDimitry Andric if (ConstRef && V.RefI.Pos == SV.RefI.Pos) 1410b57cec5SDimitry Andric continue; 1420b57cec5SDimitry Andric } 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric // The current value is different. Print the previous one and reset 1450b57cec5SDimitry Andric // the Start. 1460b57cec5SDimitry Andric OS << " [" << Start; 1470b57cec5SDimitry Andric unsigned Count = i - Start; 1480b57cec5SDimitry Andric if (Count == 1) { 1490b57cec5SDimitry Andric OS << "]:" << SV; 1500b57cec5SDimitry Andric } else { 1510b57cec5SDimitry Andric OS << '-' << i-1 << "]:"; 1520b57cec5SDimitry Andric if (SV.Type == BT::BitValue::Ref && SeqRef) 1530b57cec5SDimitry Andric OS << printv(SV.RefI.Reg) << '[' << SV.RefI.Pos << '-' 1540b57cec5SDimitry Andric << SV.RefI.Pos+(Count-1) << ']'; 1550b57cec5SDimitry Andric else 1560b57cec5SDimitry Andric OS << SV; 1570b57cec5SDimitry Andric } 1580b57cec5SDimitry Andric Start = i; 1590b57cec5SDimitry Andric SeqRef = ConstRef = false; 1600b57cec5SDimitry Andric } 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric OS << " [" << Start; 1630b57cec5SDimitry Andric unsigned Count = n - Start; 1640b57cec5SDimitry Andric if (n-Start == 1) { 1650b57cec5SDimitry Andric OS << "]:" << RC[Start]; 1660b57cec5SDimitry Andric } else { 1670b57cec5SDimitry Andric OS << '-' << n-1 << "]:"; 1680b57cec5SDimitry Andric const BT::BitValue &SV = RC[Start]; 1690b57cec5SDimitry Andric if (SV.Type == BT::BitValue::Ref && SeqRef) 1700b57cec5SDimitry Andric OS << printv(SV.RefI.Reg) << '[' << SV.RefI.Pos << '-' 1710b57cec5SDimitry Andric << SV.RefI.Pos+(Count-1) << ']'; 1720b57cec5SDimitry Andric else 1730b57cec5SDimitry Andric OS << SV; 1740b57cec5SDimitry Andric } 1750b57cec5SDimitry Andric OS << " }"; 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric return OS; 1780b57cec5SDimitry Andric } 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric } // end namespace llvm 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric void BitTracker::print_cells(raw_ostream &OS) const { 1830b57cec5SDimitry Andric for (const std::pair<unsigned, RegisterCell> P : Map) 1840b57cec5SDimitry Andric dbgs() << printReg(P.first, &ME.TRI) << " -> " << P.second << "\n"; 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric BitTracker::BitTracker(const MachineEvaluator &E, MachineFunction &F) 1880b57cec5SDimitry Andric : ME(E), MF(F), MRI(F.getRegInfo()), Map(*new CellMapType), Trace(false) { 1890b57cec5SDimitry Andric } 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric BitTracker::~BitTracker() { 1920b57cec5SDimitry Andric delete ⤅ 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric // If we were allowed to update a cell for a part of a register, the meet 1960b57cec5SDimitry Andric // operation would need to be parametrized by the register number and the 1970b57cec5SDimitry Andric // exact part of the register, so that the computer BitRefs correspond to 1980b57cec5SDimitry Andric // the actual bits of the "self" register. 1990b57cec5SDimitry Andric // While this cannot happen in the current implementation, I'm not sure 2000b57cec5SDimitry Andric // if this should be ruled out in the future. 201e8d8bef9SDimitry Andric bool BT::RegisterCell::meet(const RegisterCell &RC, Register SelfR) { 2020b57cec5SDimitry Andric // An example when "meet" can be invoked with SelfR == 0 is a phi node 2030b57cec5SDimitry Andric // with a physical register as an operand. 204e8d8bef9SDimitry Andric assert(SelfR == 0 || SelfR.isVirtual()); 2050b57cec5SDimitry Andric bool Changed = false; 2060b57cec5SDimitry Andric for (uint16_t i = 0, n = Bits.size(); i < n; ++i) { 2070b57cec5SDimitry Andric const BitValue &RCV = RC[i]; 2080b57cec5SDimitry Andric Changed |= Bits[i].meet(RCV, BitRef(SelfR, i)); 2090b57cec5SDimitry Andric } 2100b57cec5SDimitry Andric return Changed; 2110b57cec5SDimitry Andric } 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric // Insert the entire cell RC into the current cell at position given by M. 2140b57cec5SDimitry Andric BT::RegisterCell &BT::RegisterCell::insert(const BT::RegisterCell &RC, 2150b57cec5SDimitry Andric const BitMask &M) { 2160b57cec5SDimitry Andric uint16_t B = M.first(), E = M.last(), W = width(); 2174824e7fdSDimitry Andric // M must be a valid mask for *this. 2180b57cec5SDimitry Andric assert(B < W && E < W); 2194824e7fdSDimitry Andric // The masked part of *this must have the same number of bits 2200b57cec5SDimitry Andric // as the source. 2210b57cec5SDimitry Andric assert(B > E || E-B+1 == RC.width()); // B <= E => E-B+1 = |RC|. 2220b57cec5SDimitry Andric assert(B <= E || E+(W-B)+1 == RC.width()); // E < B => E+(W-B)+1 = |RC|. 2230b57cec5SDimitry Andric if (B <= E) { 2240b57cec5SDimitry Andric for (uint16_t i = 0; i <= E-B; ++i) 2250b57cec5SDimitry Andric Bits[i+B] = RC[i]; 2260b57cec5SDimitry Andric } else { 2270b57cec5SDimitry Andric for (uint16_t i = 0; i < W-B; ++i) 2280b57cec5SDimitry Andric Bits[i+B] = RC[i]; 2290b57cec5SDimitry Andric for (uint16_t i = 0; i <= E; ++i) 2300b57cec5SDimitry Andric Bits[i] = RC[i+(W-B)]; 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric return *this; 2330b57cec5SDimitry Andric } 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric BT::RegisterCell BT::RegisterCell::extract(const BitMask &M) const { 2360b57cec5SDimitry Andric uint16_t B = M.first(), E = M.last(), W = width(); 2370b57cec5SDimitry Andric assert(B < W && E < W); 2380b57cec5SDimitry Andric if (B <= E) { 2390b57cec5SDimitry Andric RegisterCell RC(E-B+1); 2400b57cec5SDimitry Andric for (uint16_t i = B; i <= E; ++i) 2410b57cec5SDimitry Andric RC.Bits[i-B] = Bits[i]; 2420b57cec5SDimitry Andric return RC; 2430b57cec5SDimitry Andric } 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric RegisterCell RC(E+(W-B)+1); 2460b57cec5SDimitry Andric for (uint16_t i = 0; i < W-B; ++i) 2470b57cec5SDimitry Andric RC.Bits[i] = Bits[i+B]; 2480b57cec5SDimitry Andric for (uint16_t i = 0; i <= E; ++i) 2490b57cec5SDimitry Andric RC.Bits[i+(W-B)] = Bits[i]; 2500b57cec5SDimitry Andric return RC; 2510b57cec5SDimitry Andric } 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andric BT::RegisterCell &BT::RegisterCell::rol(uint16_t Sh) { 2540b57cec5SDimitry Andric // Rotate left (i.e. towards increasing bit indices). 2550b57cec5SDimitry Andric // Swap the two parts: [0..W-Sh-1] [W-Sh..W-1] 2560b57cec5SDimitry Andric uint16_t W = width(); 2570b57cec5SDimitry Andric Sh = Sh % W; 2580b57cec5SDimitry Andric if (Sh == 0) 2590b57cec5SDimitry Andric return *this; 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric RegisterCell Tmp(W-Sh); 2620b57cec5SDimitry Andric // Tmp = [0..W-Sh-1]. 2630b57cec5SDimitry Andric for (uint16_t i = 0; i < W-Sh; ++i) 2640b57cec5SDimitry Andric Tmp[i] = Bits[i]; 2650b57cec5SDimitry Andric // Shift [W-Sh..W-1] to [0..Sh-1]. 2660b57cec5SDimitry Andric for (uint16_t i = 0; i < Sh; ++i) 2670b57cec5SDimitry Andric Bits[i] = Bits[W-Sh+i]; 2680b57cec5SDimitry Andric // Copy Tmp to [Sh..W-1]. 2690b57cec5SDimitry Andric for (uint16_t i = 0; i < W-Sh; ++i) 2700b57cec5SDimitry Andric Bits[i+Sh] = Tmp.Bits[i]; 2710b57cec5SDimitry Andric return *this; 2720b57cec5SDimitry Andric } 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric BT::RegisterCell &BT::RegisterCell::fill(uint16_t B, uint16_t E, 2750b57cec5SDimitry Andric const BitValue &V) { 2760b57cec5SDimitry Andric assert(B <= E); 2770b57cec5SDimitry Andric while (B < E) 2780b57cec5SDimitry Andric Bits[B++] = V; 2790b57cec5SDimitry Andric return *this; 2800b57cec5SDimitry Andric } 2810b57cec5SDimitry Andric 2820b57cec5SDimitry Andric BT::RegisterCell &BT::RegisterCell::cat(const RegisterCell &RC) { 2830b57cec5SDimitry Andric // Append the cell given as the argument to the "this" cell. 2840b57cec5SDimitry Andric // Bit 0 of RC becomes bit W of the result, where W is this->width(). 2850b57cec5SDimitry Andric uint16_t W = width(), WRC = RC.width(); 2860b57cec5SDimitry Andric Bits.resize(W+WRC); 2870b57cec5SDimitry Andric for (uint16_t i = 0; i < WRC; ++i) 2880b57cec5SDimitry Andric Bits[i+W] = RC.Bits[i]; 2890b57cec5SDimitry Andric return *this; 2900b57cec5SDimitry Andric } 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric uint16_t BT::RegisterCell::ct(bool B) const { 2930b57cec5SDimitry Andric uint16_t W = width(); 2940b57cec5SDimitry Andric uint16_t C = 0; 2950b57cec5SDimitry Andric BitValue V = B; 2960b57cec5SDimitry Andric while (C < W && Bits[C] == V) 2970b57cec5SDimitry Andric C++; 2980b57cec5SDimitry Andric return C; 2990b57cec5SDimitry Andric } 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric uint16_t BT::RegisterCell::cl(bool B) const { 3020b57cec5SDimitry Andric uint16_t W = width(); 3030b57cec5SDimitry Andric uint16_t C = 0; 3040b57cec5SDimitry Andric BitValue V = B; 3050b57cec5SDimitry Andric while (C < W && Bits[W-(C+1)] == V) 3060b57cec5SDimitry Andric C++; 3070b57cec5SDimitry Andric return C; 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric bool BT::RegisterCell::operator== (const RegisterCell &RC) const { 3110b57cec5SDimitry Andric uint16_t W = Bits.size(); 3120b57cec5SDimitry Andric if (RC.Bits.size() != W) 3130b57cec5SDimitry Andric return false; 3140b57cec5SDimitry Andric for (uint16_t i = 0; i < W; ++i) 3150b57cec5SDimitry Andric if (Bits[i] != RC[i]) 3160b57cec5SDimitry Andric return false; 3170b57cec5SDimitry Andric return true; 3180b57cec5SDimitry Andric } 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric BT::RegisterCell &BT::RegisterCell::regify(unsigned R) { 3210b57cec5SDimitry Andric for (unsigned i = 0, n = width(); i < n; ++i) { 3220b57cec5SDimitry Andric const BitValue &V = Bits[i]; 3230b57cec5SDimitry Andric if (V.Type == BitValue::Ref && V.RefI.Reg == 0) 3240b57cec5SDimitry Andric Bits[i].RefI = BitRef(R, i); 3250b57cec5SDimitry Andric } 3260b57cec5SDimitry Andric return *this; 3270b57cec5SDimitry Andric } 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric uint16_t BT::MachineEvaluator::getRegBitWidth(const RegisterRef &RR) const { 3300b57cec5SDimitry Andric // The general problem is with finding a register class that corresponds 3310b57cec5SDimitry Andric // to a given reference reg:sub. There can be several such classes, and 3320b57cec5SDimitry Andric // since we only care about the register size, it does not matter which 3330b57cec5SDimitry Andric // such class we would find. 3340b57cec5SDimitry Andric // The easiest way to accomplish what we want is to 3350b57cec5SDimitry Andric // 1. find a physical register PhysR from the same class as RR.Reg, 3360b57cec5SDimitry Andric // 2. find a physical register PhysS that corresponds to PhysR:RR.Sub, 3370b57cec5SDimitry Andric // 3. find a register class that contains PhysS. 338e8d8bef9SDimitry Andric if (RR.Reg.isVirtual()) { 3390b57cec5SDimitry Andric const auto &VC = composeWithSubRegIndex(*MRI.getRegClass(RR.Reg), RR.Sub); 3400b57cec5SDimitry Andric return TRI.getRegSizeInBits(VC); 3410b57cec5SDimitry Andric } 342e8d8bef9SDimitry Andric assert(RR.Reg.isPhysical()); 343e8d8bef9SDimitry Andric MCRegister PhysR = 344e8d8bef9SDimitry Andric (RR.Sub == 0) ? RR.Reg.asMCReg() : TRI.getSubReg(RR.Reg, RR.Sub); 3450b57cec5SDimitry Andric return getPhysRegBitWidth(PhysR); 3460b57cec5SDimitry Andric } 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::getCell(const RegisterRef &RR, 3490b57cec5SDimitry Andric const CellMapType &M) const { 3500b57cec5SDimitry Andric uint16_t BW = getRegBitWidth(RR); 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric // Physical registers are assumed to be present in the map with an unknown 3530b57cec5SDimitry Andric // value. Don't actually insert anything in the map, just return the cell. 354e8d8bef9SDimitry Andric if (RR.Reg.isPhysical()) 3550b57cec5SDimitry Andric return RegisterCell::self(0, BW); 3560b57cec5SDimitry Andric 357e8d8bef9SDimitry Andric assert(RR.Reg.isVirtual()); 3580b57cec5SDimitry Andric // For virtual registers that belong to a class that is not tracked, 3590b57cec5SDimitry Andric // generate an "unknown" value as well. 3600b57cec5SDimitry Andric const TargetRegisterClass *C = MRI.getRegClass(RR.Reg); 3610b57cec5SDimitry Andric if (!track(C)) 3620b57cec5SDimitry Andric return RegisterCell::self(0, BW); 3630b57cec5SDimitry Andric 3640b57cec5SDimitry Andric CellMapType::const_iterator F = M.find(RR.Reg); 3650b57cec5SDimitry Andric if (F != M.end()) { 3660b57cec5SDimitry Andric if (!RR.Sub) 3670b57cec5SDimitry Andric return F->second; 3680b57cec5SDimitry Andric BitMask M = mask(RR.Reg, RR.Sub); 3690b57cec5SDimitry Andric return F->second.extract(M); 3700b57cec5SDimitry Andric } 3710b57cec5SDimitry Andric // If not found, create a "top" entry, but do not insert it in the map. 3720b57cec5SDimitry Andric return RegisterCell::top(BW); 3730b57cec5SDimitry Andric } 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric void BT::MachineEvaluator::putCell(const RegisterRef &RR, RegisterCell RC, 3760b57cec5SDimitry Andric CellMapType &M) const { 3770b57cec5SDimitry Andric // While updating the cell map can be done in a meaningful way for 3780b57cec5SDimitry Andric // a part of a register, it makes little sense to implement it as the 3790b57cec5SDimitry Andric // SSA representation would never contain such "partial definitions". 380e8d8bef9SDimitry Andric if (!RR.Reg.isVirtual()) 3810b57cec5SDimitry Andric return; 3820b57cec5SDimitry Andric assert(RR.Sub == 0 && "Unexpected sub-register in definition"); 3830b57cec5SDimitry Andric // Eliminate all ref-to-reg-0 bit values: replace them with "self". 3840b57cec5SDimitry Andric M[RR.Reg] = RC.regify(RR.Reg); 3850b57cec5SDimitry Andric } 3860b57cec5SDimitry Andric 3870b57cec5SDimitry Andric // Check if the cell represents a compile-time integer value. 3880b57cec5SDimitry Andric bool BT::MachineEvaluator::isInt(const RegisterCell &A) const { 3890b57cec5SDimitry Andric uint16_t W = A.width(); 3900b57cec5SDimitry Andric for (uint16_t i = 0; i < W; ++i) 3910b57cec5SDimitry Andric if (!A[i].is(0) && !A[i].is(1)) 3920b57cec5SDimitry Andric return false; 3930b57cec5SDimitry Andric return true; 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric // Convert a cell to the integer value. The result must fit in uint64_t. 3970b57cec5SDimitry Andric uint64_t BT::MachineEvaluator::toInt(const RegisterCell &A) const { 3980b57cec5SDimitry Andric assert(isInt(A)); 3990b57cec5SDimitry Andric uint64_t Val = 0; 4000b57cec5SDimitry Andric uint16_t W = A.width(); 4010b57cec5SDimitry Andric for (uint16_t i = 0; i < W; ++i) { 4020b57cec5SDimitry Andric Val <<= 1; 4030b57cec5SDimitry Andric Val |= A[i].is(1); 4040b57cec5SDimitry Andric } 4050b57cec5SDimitry Andric return Val; 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric // Evaluator helper functions. These implement some common operation on 4090b57cec5SDimitry Andric // register cells that can be used to implement target-specific instructions 4100b57cec5SDimitry Andric // in a target-specific evaluator. 4110b57cec5SDimitry Andric 4120b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eIMM(int64_t V, uint16_t W) const { 4130b57cec5SDimitry Andric RegisterCell Res(W); 4140b57cec5SDimitry Andric // For bits beyond the 63rd, this will generate the sign bit of V. 4150b57cec5SDimitry Andric for (uint16_t i = 0; i < W; ++i) { 4160b57cec5SDimitry Andric Res[i] = BitValue(V & 1); 4170b57cec5SDimitry Andric V >>= 1; 4180b57cec5SDimitry Andric } 4190b57cec5SDimitry Andric return Res; 4200b57cec5SDimitry Andric } 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eIMM(const ConstantInt *CI) const { 4230b57cec5SDimitry Andric const APInt &A = CI->getValue(); 4240b57cec5SDimitry Andric uint16_t BW = A.getBitWidth(); 4250b57cec5SDimitry Andric assert((unsigned)BW == A.getBitWidth() && "BitWidth overflow"); 4260b57cec5SDimitry Andric RegisterCell Res(BW); 4270b57cec5SDimitry Andric for (uint16_t i = 0; i < BW; ++i) 4280b57cec5SDimitry Andric Res[i] = A[i]; 4290b57cec5SDimitry Andric return Res; 4300b57cec5SDimitry Andric } 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eADD(const RegisterCell &A1, 4330b57cec5SDimitry Andric const RegisterCell &A2) const { 4340b57cec5SDimitry Andric uint16_t W = A1.width(); 4350b57cec5SDimitry Andric assert(W == A2.width()); 4360b57cec5SDimitry Andric RegisterCell Res(W); 4370b57cec5SDimitry Andric bool Carry = false; 4380b57cec5SDimitry Andric uint16_t I; 4390b57cec5SDimitry Andric for (I = 0; I < W; ++I) { 4400b57cec5SDimitry Andric const BitValue &V1 = A1[I]; 4410b57cec5SDimitry Andric const BitValue &V2 = A2[I]; 4420b57cec5SDimitry Andric if (!V1.num() || !V2.num()) 4430b57cec5SDimitry Andric break; 4440b57cec5SDimitry Andric unsigned S = bool(V1) + bool(V2) + Carry; 4450b57cec5SDimitry Andric Res[I] = BitValue(S & 1); 4460b57cec5SDimitry Andric Carry = (S > 1); 4470b57cec5SDimitry Andric } 4480b57cec5SDimitry Andric for (; I < W; ++I) { 4490b57cec5SDimitry Andric const BitValue &V1 = A1[I]; 4500b57cec5SDimitry Andric const BitValue &V2 = A2[I]; 4510b57cec5SDimitry Andric // If the next bit is same as Carry, the result will be 0 plus the 4520b57cec5SDimitry Andric // other bit. The Carry bit will remain unchanged. 4530b57cec5SDimitry Andric if (V1.is(Carry)) 4540b57cec5SDimitry Andric Res[I] = BitValue::ref(V2); 4550b57cec5SDimitry Andric else if (V2.is(Carry)) 4560b57cec5SDimitry Andric Res[I] = BitValue::ref(V1); 4570b57cec5SDimitry Andric else 4580b57cec5SDimitry Andric break; 4590b57cec5SDimitry Andric } 4600b57cec5SDimitry Andric for (; I < W; ++I) 4610b57cec5SDimitry Andric Res[I] = BitValue::self(); 4620b57cec5SDimitry Andric return Res; 4630b57cec5SDimitry Andric } 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eSUB(const RegisterCell &A1, 4660b57cec5SDimitry Andric const RegisterCell &A2) const { 4670b57cec5SDimitry Andric uint16_t W = A1.width(); 4680b57cec5SDimitry Andric assert(W == A2.width()); 4690b57cec5SDimitry Andric RegisterCell Res(W); 4700b57cec5SDimitry Andric bool Borrow = false; 4710b57cec5SDimitry Andric uint16_t I; 4720b57cec5SDimitry Andric for (I = 0; I < W; ++I) { 4730b57cec5SDimitry Andric const BitValue &V1 = A1[I]; 4740b57cec5SDimitry Andric const BitValue &V2 = A2[I]; 4750b57cec5SDimitry Andric if (!V1.num() || !V2.num()) 4760b57cec5SDimitry Andric break; 4770b57cec5SDimitry Andric unsigned S = bool(V1) - bool(V2) - Borrow; 4780b57cec5SDimitry Andric Res[I] = BitValue(S & 1); 4790b57cec5SDimitry Andric Borrow = (S > 1); 4800b57cec5SDimitry Andric } 4810b57cec5SDimitry Andric for (; I < W; ++I) { 4820b57cec5SDimitry Andric const BitValue &V1 = A1[I]; 4830b57cec5SDimitry Andric const BitValue &V2 = A2[I]; 4840b57cec5SDimitry Andric if (V1.is(Borrow)) { 4850b57cec5SDimitry Andric Res[I] = BitValue::ref(V2); 4860b57cec5SDimitry Andric break; 4870b57cec5SDimitry Andric } 4880b57cec5SDimitry Andric if (V2.is(Borrow)) 4890b57cec5SDimitry Andric Res[I] = BitValue::ref(V1); 4900b57cec5SDimitry Andric else 4910b57cec5SDimitry Andric break; 4920b57cec5SDimitry Andric } 4930b57cec5SDimitry Andric for (; I < W; ++I) 4940b57cec5SDimitry Andric Res[I] = BitValue::self(); 4950b57cec5SDimitry Andric return Res; 4960b57cec5SDimitry Andric } 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eMLS(const RegisterCell &A1, 4990b57cec5SDimitry Andric const RegisterCell &A2) const { 5000b57cec5SDimitry Andric uint16_t W = A1.width() + A2.width(); 5010b57cec5SDimitry Andric uint16_t Z = A1.ct(false) + A2.ct(false); 5020b57cec5SDimitry Andric RegisterCell Res(W); 5030b57cec5SDimitry Andric Res.fill(0, Z, BitValue::Zero); 5040b57cec5SDimitry Andric Res.fill(Z, W, BitValue::self()); 5050b57cec5SDimitry Andric return Res; 5060b57cec5SDimitry Andric } 5070b57cec5SDimitry Andric 5080b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eMLU(const RegisterCell &A1, 5090b57cec5SDimitry Andric const RegisterCell &A2) const { 5100b57cec5SDimitry Andric uint16_t W = A1.width() + A2.width(); 5110b57cec5SDimitry Andric uint16_t Z = A1.ct(false) + A2.ct(false); 5120b57cec5SDimitry Andric RegisterCell Res(W); 5130b57cec5SDimitry Andric Res.fill(0, Z, BitValue::Zero); 5140b57cec5SDimitry Andric Res.fill(Z, W, BitValue::self()); 5150b57cec5SDimitry Andric return Res; 5160b57cec5SDimitry Andric } 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eASL(const RegisterCell &A1, 5190b57cec5SDimitry Andric uint16_t Sh) const { 5200b57cec5SDimitry Andric assert(Sh <= A1.width()); 5210b57cec5SDimitry Andric RegisterCell Res = RegisterCell::ref(A1); 5220b57cec5SDimitry Andric Res.rol(Sh); 5230b57cec5SDimitry Andric Res.fill(0, Sh, BitValue::Zero); 5240b57cec5SDimitry Andric return Res; 5250b57cec5SDimitry Andric } 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eLSR(const RegisterCell &A1, 5280b57cec5SDimitry Andric uint16_t Sh) const { 5290b57cec5SDimitry Andric uint16_t W = A1.width(); 5300b57cec5SDimitry Andric assert(Sh <= W); 5310b57cec5SDimitry Andric RegisterCell Res = RegisterCell::ref(A1); 5320b57cec5SDimitry Andric Res.rol(W-Sh); 5330b57cec5SDimitry Andric Res.fill(W-Sh, W, BitValue::Zero); 5340b57cec5SDimitry Andric return Res; 5350b57cec5SDimitry Andric } 5360b57cec5SDimitry Andric 5370b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eASR(const RegisterCell &A1, 5380b57cec5SDimitry Andric uint16_t Sh) const { 5390b57cec5SDimitry Andric uint16_t W = A1.width(); 5400b57cec5SDimitry Andric assert(Sh <= W); 5410b57cec5SDimitry Andric RegisterCell Res = RegisterCell::ref(A1); 5420b57cec5SDimitry Andric BitValue Sign = Res[W-1]; 5430b57cec5SDimitry Andric Res.rol(W-Sh); 5440b57cec5SDimitry Andric Res.fill(W-Sh, W, Sign); 5450b57cec5SDimitry Andric return Res; 5460b57cec5SDimitry Andric } 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eAND(const RegisterCell &A1, 5490b57cec5SDimitry Andric const RegisterCell &A2) const { 5500b57cec5SDimitry Andric uint16_t W = A1.width(); 5510b57cec5SDimitry Andric assert(W == A2.width()); 5520b57cec5SDimitry Andric RegisterCell Res(W); 5530b57cec5SDimitry Andric for (uint16_t i = 0; i < W; ++i) { 5540b57cec5SDimitry Andric const BitValue &V1 = A1[i]; 5550b57cec5SDimitry Andric const BitValue &V2 = A2[i]; 5560b57cec5SDimitry Andric if (V1.is(1)) 5570b57cec5SDimitry Andric Res[i] = BitValue::ref(V2); 5580b57cec5SDimitry Andric else if (V2.is(1)) 5590b57cec5SDimitry Andric Res[i] = BitValue::ref(V1); 5600b57cec5SDimitry Andric else if (V1.is(0) || V2.is(0)) 5610b57cec5SDimitry Andric Res[i] = BitValue::Zero; 5620b57cec5SDimitry Andric else if (V1 == V2) 5630b57cec5SDimitry Andric Res[i] = V1; 5640b57cec5SDimitry Andric else 5650b57cec5SDimitry Andric Res[i] = BitValue::self(); 5660b57cec5SDimitry Andric } 5670b57cec5SDimitry Andric return Res; 5680b57cec5SDimitry Andric } 5690b57cec5SDimitry Andric 5700b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eORL(const RegisterCell &A1, 5710b57cec5SDimitry Andric const RegisterCell &A2) const { 5720b57cec5SDimitry Andric uint16_t W = A1.width(); 5730b57cec5SDimitry Andric assert(W == A2.width()); 5740b57cec5SDimitry Andric RegisterCell Res(W); 5750b57cec5SDimitry Andric for (uint16_t i = 0; i < W; ++i) { 5760b57cec5SDimitry Andric const BitValue &V1 = A1[i]; 5770b57cec5SDimitry Andric const BitValue &V2 = A2[i]; 5780b57cec5SDimitry Andric if (V1.is(1) || V2.is(1)) 5790b57cec5SDimitry Andric Res[i] = BitValue::One; 5800b57cec5SDimitry Andric else if (V1.is(0)) 5810b57cec5SDimitry Andric Res[i] = BitValue::ref(V2); 5820b57cec5SDimitry Andric else if (V2.is(0)) 5830b57cec5SDimitry Andric Res[i] = BitValue::ref(V1); 5840b57cec5SDimitry Andric else if (V1 == V2) 5850b57cec5SDimitry Andric Res[i] = V1; 5860b57cec5SDimitry Andric else 5870b57cec5SDimitry Andric Res[i] = BitValue::self(); 5880b57cec5SDimitry Andric } 5890b57cec5SDimitry Andric return Res; 5900b57cec5SDimitry Andric } 5910b57cec5SDimitry Andric 5920b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eXOR(const RegisterCell &A1, 5930b57cec5SDimitry Andric const RegisterCell &A2) const { 5940b57cec5SDimitry Andric uint16_t W = A1.width(); 5950b57cec5SDimitry Andric assert(W == A2.width()); 5960b57cec5SDimitry Andric RegisterCell Res(W); 5970b57cec5SDimitry Andric for (uint16_t i = 0; i < W; ++i) { 5980b57cec5SDimitry Andric const BitValue &V1 = A1[i]; 5990b57cec5SDimitry Andric const BitValue &V2 = A2[i]; 6000b57cec5SDimitry Andric if (V1.is(0)) 6010b57cec5SDimitry Andric Res[i] = BitValue::ref(V2); 6020b57cec5SDimitry Andric else if (V2.is(0)) 6030b57cec5SDimitry Andric Res[i] = BitValue::ref(V1); 6040b57cec5SDimitry Andric else if (V1 == V2) 6050b57cec5SDimitry Andric Res[i] = BitValue::Zero; 6060b57cec5SDimitry Andric else 6070b57cec5SDimitry Andric Res[i] = BitValue::self(); 6080b57cec5SDimitry Andric } 6090b57cec5SDimitry Andric return Res; 6100b57cec5SDimitry Andric } 6110b57cec5SDimitry Andric 6120b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eNOT(const RegisterCell &A1) const { 6130b57cec5SDimitry Andric uint16_t W = A1.width(); 6140b57cec5SDimitry Andric RegisterCell Res(W); 6150b57cec5SDimitry Andric for (uint16_t i = 0; i < W; ++i) { 6160b57cec5SDimitry Andric const BitValue &V = A1[i]; 6170b57cec5SDimitry Andric if (V.is(0)) 6180b57cec5SDimitry Andric Res[i] = BitValue::One; 6190b57cec5SDimitry Andric else if (V.is(1)) 6200b57cec5SDimitry Andric Res[i] = BitValue::Zero; 6210b57cec5SDimitry Andric else 6220b57cec5SDimitry Andric Res[i] = BitValue::self(); 6230b57cec5SDimitry Andric } 6240b57cec5SDimitry Andric return Res; 6250b57cec5SDimitry Andric } 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eSET(const RegisterCell &A1, 6280b57cec5SDimitry Andric uint16_t BitN) const { 6290b57cec5SDimitry Andric assert(BitN < A1.width()); 6300b57cec5SDimitry Andric RegisterCell Res = RegisterCell::ref(A1); 6310b57cec5SDimitry Andric Res[BitN] = BitValue::One; 6320b57cec5SDimitry Andric return Res; 6330b57cec5SDimitry Andric } 6340b57cec5SDimitry Andric 6350b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eCLR(const RegisterCell &A1, 6360b57cec5SDimitry Andric uint16_t BitN) const { 6370b57cec5SDimitry Andric assert(BitN < A1.width()); 6380b57cec5SDimitry Andric RegisterCell Res = RegisterCell::ref(A1); 6390b57cec5SDimitry Andric Res[BitN] = BitValue::Zero; 6400b57cec5SDimitry Andric return Res; 6410b57cec5SDimitry Andric } 6420b57cec5SDimitry Andric 6430b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eCLB(const RegisterCell &A1, bool B, 6440b57cec5SDimitry Andric uint16_t W) const { 6450b57cec5SDimitry Andric uint16_t C = A1.cl(B), AW = A1.width(); 6460b57cec5SDimitry Andric // If the last leading non-B bit is not a constant, then we don't know 6470b57cec5SDimitry Andric // the real count. 6480b57cec5SDimitry Andric if ((C < AW && A1[AW-1-C].num()) || C == AW) 6490b57cec5SDimitry Andric return eIMM(C, W); 6500b57cec5SDimitry Andric return RegisterCell::self(0, W); 6510b57cec5SDimitry Andric } 6520b57cec5SDimitry Andric 6530b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eCTB(const RegisterCell &A1, bool B, 6540b57cec5SDimitry Andric uint16_t W) const { 6550b57cec5SDimitry Andric uint16_t C = A1.ct(B), AW = A1.width(); 6560b57cec5SDimitry Andric // If the last trailing non-B bit is not a constant, then we don't know 6570b57cec5SDimitry Andric // the real count. 6580b57cec5SDimitry Andric if ((C < AW && A1[C].num()) || C == AW) 6590b57cec5SDimitry Andric return eIMM(C, W); 6600b57cec5SDimitry Andric return RegisterCell::self(0, W); 6610b57cec5SDimitry Andric } 6620b57cec5SDimitry Andric 6630b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eSXT(const RegisterCell &A1, 6640b57cec5SDimitry Andric uint16_t FromN) const { 6650b57cec5SDimitry Andric uint16_t W = A1.width(); 6660b57cec5SDimitry Andric assert(FromN <= W); 6670b57cec5SDimitry Andric RegisterCell Res = RegisterCell::ref(A1); 6680b57cec5SDimitry Andric BitValue Sign = Res[FromN-1]; 6690b57cec5SDimitry Andric // Sign-extend "inreg". 6700b57cec5SDimitry Andric Res.fill(FromN, W, Sign); 6710b57cec5SDimitry Andric return Res; 6720b57cec5SDimitry Andric } 6730b57cec5SDimitry Andric 6740b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eZXT(const RegisterCell &A1, 6750b57cec5SDimitry Andric uint16_t FromN) const { 6760b57cec5SDimitry Andric uint16_t W = A1.width(); 6770b57cec5SDimitry Andric assert(FromN <= W); 6780b57cec5SDimitry Andric RegisterCell Res = RegisterCell::ref(A1); 6790b57cec5SDimitry Andric Res.fill(FromN, W, BitValue::Zero); 6800b57cec5SDimitry Andric return Res; 6810b57cec5SDimitry Andric } 6820b57cec5SDimitry Andric 6830b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eXTR(const RegisterCell &A1, 6840b57cec5SDimitry Andric uint16_t B, uint16_t E) const { 6850b57cec5SDimitry Andric uint16_t W = A1.width(); 6860b57cec5SDimitry Andric assert(B < W && E <= W); 6870b57cec5SDimitry Andric if (B == E) 6880b57cec5SDimitry Andric return RegisterCell(0); 6890b57cec5SDimitry Andric uint16_t Last = (E > 0) ? E-1 : W-1; 6900b57cec5SDimitry Andric RegisterCell Res = RegisterCell::ref(A1).extract(BT::BitMask(B, Last)); 6910b57cec5SDimitry Andric // Return shorter cell. 6920b57cec5SDimitry Andric return Res; 6930b57cec5SDimitry Andric } 6940b57cec5SDimitry Andric 6950b57cec5SDimitry Andric BT::RegisterCell BT::MachineEvaluator::eINS(const RegisterCell &A1, 6960b57cec5SDimitry Andric const RegisterCell &A2, uint16_t AtN) const { 6970b57cec5SDimitry Andric uint16_t W1 = A1.width(), W2 = A2.width(); 6980b57cec5SDimitry Andric (void)W1; 6990b57cec5SDimitry Andric assert(AtN < W1 && AtN+W2 <= W1); 7000b57cec5SDimitry Andric // Copy bits from A1, insert A2 at position AtN. 7010b57cec5SDimitry Andric RegisterCell Res = RegisterCell::ref(A1); 7020b57cec5SDimitry Andric if (W2 > 0) 7030b57cec5SDimitry Andric Res.insert(RegisterCell::ref(A2), BT::BitMask(AtN, AtN+W2-1)); 7040b57cec5SDimitry Andric return Res; 7050b57cec5SDimitry Andric } 7060b57cec5SDimitry Andric 707e8d8bef9SDimitry Andric BT::BitMask BT::MachineEvaluator::mask(Register Reg, unsigned Sub) const { 7080b57cec5SDimitry Andric assert(Sub == 0 && "Generic BitTracker::mask called for Sub != 0"); 7090b57cec5SDimitry Andric uint16_t W = getRegBitWidth(Reg); 7100b57cec5SDimitry Andric assert(W > 0 && "Cannot generate mask for empty register"); 7110b57cec5SDimitry Andric return BitMask(0, W-1); 7120b57cec5SDimitry Andric } 7130b57cec5SDimitry Andric 714e8d8bef9SDimitry Andric uint16_t BT::MachineEvaluator::getPhysRegBitWidth(MCRegister Reg) const { 7150b57cec5SDimitry Andric const TargetRegisterClass &PC = *TRI.getMinimalPhysRegClass(Reg); 7160b57cec5SDimitry Andric return TRI.getRegSizeInBits(PC); 7170b57cec5SDimitry Andric } 7180b57cec5SDimitry Andric 7190b57cec5SDimitry Andric bool BT::MachineEvaluator::evaluate(const MachineInstr &MI, 7200b57cec5SDimitry Andric const CellMapType &Inputs, 7210b57cec5SDimitry Andric CellMapType &Outputs) const { 7220b57cec5SDimitry Andric unsigned Opc = MI.getOpcode(); 7230b57cec5SDimitry Andric switch (Opc) { 7240b57cec5SDimitry Andric case TargetOpcode::REG_SEQUENCE: { 7250b57cec5SDimitry Andric RegisterRef RD = MI.getOperand(0); 7260b57cec5SDimitry Andric assert(RD.Sub == 0); 7270b57cec5SDimitry Andric RegisterRef RS = MI.getOperand(1); 7280b57cec5SDimitry Andric unsigned SS = MI.getOperand(2).getImm(); 7290b57cec5SDimitry Andric RegisterRef RT = MI.getOperand(3); 7300b57cec5SDimitry Andric unsigned ST = MI.getOperand(4).getImm(); 7310b57cec5SDimitry Andric assert(SS != ST); 7320b57cec5SDimitry Andric 7330b57cec5SDimitry Andric uint16_t W = getRegBitWidth(RD); 7340b57cec5SDimitry Andric RegisterCell Res(W); 7350b57cec5SDimitry Andric Res.insert(RegisterCell::ref(getCell(RS, Inputs)), mask(RD.Reg, SS)); 7360b57cec5SDimitry Andric Res.insert(RegisterCell::ref(getCell(RT, Inputs)), mask(RD.Reg, ST)); 7370b57cec5SDimitry Andric putCell(RD, Res, Outputs); 7380b57cec5SDimitry Andric break; 7390b57cec5SDimitry Andric } 7400b57cec5SDimitry Andric 7410b57cec5SDimitry Andric case TargetOpcode::COPY: { 7420b57cec5SDimitry Andric // COPY can transfer a smaller register into a wider one. 7430b57cec5SDimitry Andric // If that is the case, fill the remaining high bits with 0. 7440b57cec5SDimitry Andric RegisterRef RD = MI.getOperand(0); 7450b57cec5SDimitry Andric RegisterRef RS = MI.getOperand(1); 7460b57cec5SDimitry Andric assert(RD.Sub == 0); 7470b57cec5SDimitry Andric uint16_t WD = getRegBitWidth(RD); 7480b57cec5SDimitry Andric uint16_t WS = getRegBitWidth(RS); 7490b57cec5SDimitry Andric assert(WD >= WS); 7500b57cec5SDimitry Andric RegisterCell Src = getCell(RS, Inputs); 7510b57cec5SDimitry Andric RegisterCell Res(WD); 7520b57cec5SDimitry Andric Res.insert(Src, BitMask(0, WS-1)); 7530b57cec5SDimitry Andric Res.fill(WS, WD, BitValue::Zero); 7540b57cec5SDimitry Andric putCell(RD, Res, Outputs); 7550b57cec5SDimitry Andric break; 7560b57cec5SDimitry Andric } 7570b57cec5SDimitry Andric 7580b57cec5SDimitry Andric default: 7590b57cec5SDimitry Andric return false; 7600b57cec5SDimitry Andric } 7610b57cec5SDimitry Andric 7620b57cec5SDimitry Andric return true; 7630b57cec5SDimitry Andric } 7640b57cec5SDimitry Andric 7650b57cec5SDimitry Andric bool BT::UseQueueType::Cmp::operator()(const MachineInstr *InstA, 7660b57cec5SDimitry Andric const MachineInstr *InstB) const { 7670b57cec5SDimitry Andric // This is a comparison function for a priority queue: give higher priority 7680b57cec5SDimitry Andric // to earlier instructions. 7690b57cec5SDimitry Andric // This operator is used as "less", so returning "true" gives InstB higher 7700b57cec5SDimitry Andric // priority (because then InstA < InstB). 7710b57cec5SDimitry Andric if (InstA == InstB) 7720b57cec5SDimitry Andric return false; 7730b57cec5SDimitry Andric const MachineBasicBlock *BA = InstA->getParent(); 7740b57cec5SDimitry Andric const MachineBasicBlock *BB = InstB->getParent(); 7750b57cec5SDimitry Andric if (BA != BB) { 7760b57cec5SDimitry Andric // If the blocks are different, ideally the dominating block would 7770b57cec5SDimitry Andric // have a higher priority, but it may be too expensive to check. 7780b57cec5SDimitry Andric return BA->getNumber() > BB->getNumber(); 7790b57cec5SDimitry Andric } 7800b57cec5SDimitry Andric 7810b57cec5SDimitry Andric auto getDist = [this] (const MachineInstr *MI) { 7820b57cec5SDimitry Andric auto F = Dist.find(MI); 7830b57cec5SDimitry Andric if (F != Dist.end()) 7840b57cec5SDimitry Andric return F->second; 7850b57cec5SDimitry Andric MachineBasicBlock::const_iterator I = MI->getParent()->begin(); 7860b57cec5SDimitry Andric MachineBasicBlock::const_iterator E = MI->getIterator(); 7870b57cec5SDimitry Andric unsigned D = std::distance(I, E); 7880b57cec5SDimitry Andric Dist.insert(std::make_pair(MI, D)); 7890b57cec5SDimitry Andric return D; 7900b57cec5SDimitry Andric }; 7910b57cec5SDimitry Andric 7920b57cec5SDimitry Andric return getDist(InstA) > getDist(InstB); 7930b57cec5SDimitry Andric } 7940b57cec5SDimitry Andric 7950b57cec5SDimitry Andric // Main W-Z implementation. 7960b57cec5SDimitry Andric 7970b57cec5SDimitry Andric void BT::visitPHI(const MachineInstr &PI) { 7980b57cec5SDimitry Andric int ThisN = PI.getParent()->getNumber(); 7990b57cec5SDimitry Andric if (Trace) 8000b57cec5SDimitry Andric dbgs() << "Visit FI(" << printMBBReference(*PI.getParent()) << "): " << PI; 8010b57cec5SDimitry Andric 8020b57cec5SDimitry Andric const MachineOperand &MD = PI.getOperand(0); 8030b57cec5SDimitry Andric assert(MD.getSubReg() == 0 && "Unexpected sub-register in definition"); 8040b57cec5SDimitry Andric RegisterRef DefRR(MD); 8050b57cec5SDimitry Andric uint16_t DefBW = ME.getRegBitWidth(DefRR); 8060b57cec5SDimitry Andric 8070b57cec5SDimitry Andric RegisterCell DefC = ME.getCell(DefRR, Map); 8080b57cec5SDimitry Andric if (DefC == RegisterCell::self(DefRR.Reg, DefBW)) // XXX slow 8090b57cec5SDimitry Andric return; 8100b57cec5SDimitry Andric 8110b57cec5SDimitry Andric bool Changed = false; 8120b57cec5SDimitry Andric 8130b57cec5SDimitry Andric for (unsigned i = 1, n = PI.getNumOperands(); i < n; i += 2) { 8140b57cec5SDimitry Andric const MachineBasicBlock *PB = PI.getOperand(i + 1).getMBB(); 8150b57cec5SDimitry Andric int PredN = PB->getNumber(); 8160b57cec5SDimitry Andric if (Trace) 8170b57cec5SDimitry Andric dbgs() << " edge " << printMBBReference(*PB) << "->" 8180b57cec5SDimitry Andric << printMBBReference(*PI.getParent()); 8190b57cec5SDimitry Andric if (!EdgeExec.count(CFGEdge(PredN, ThisN))) { 8200b57cec5SDimitry Andric if (Trace) 8210b57cec5SDimitry Andric dbgs() << " not executable\n"; 8220b57cec5SDimitry Andric continue; 8230b57cec5SDimitry Andric } 8240b57cec5SDimitry Andric 8250b57cec5SDimitry Andric RegisterRef RU = PI.getOperand(i); 8260b57cec5SDimitry Andric RegisterCell ResC = ME.getCell(RU, Map); 8270b57cec5SDimitry Andric if (Trace) 8280b57cec5SDimitry Andric dbgs() << " input reg: " << printReg(RU.Reg, &ME.TRI, RU.Sub) 8290b57cec5SDimitry Andric << " cell: " << ResC << "\n"; 8300b57cec5SDimitry Andric Changed |= DefC.meet(ResC, DefRR.Reg); 8310b57cec5SDimitry Andric } 8320b57cec5SDimitry Andric 8330b57cec5SDimitry Andric if (Changed) { 8340b57cec5SDimitry Andric if (Trace) 8350b57cec5SDimitry Andric dbgs() << "Output: " << printReg(DefRR.Reg, &ME.TRI, DefRR.Sub) 8360b57cec5SDimitry Andric << " cell: " << DefC << "\n"; 8370b57cec5SDimitry Andric ME.putCell(DefRR, DefC, Map); 8380b57cec5SDimitry Andric visitUsesOf(DefRR.Reg); 8390b57cec5SDimitry Andric } 8400b57cec5SDimitry Andric } 8410b57cec5SDimitry Andric 8420b57cec5SDimitry Andric void BT::visitNonBranch(const MachineInstr &MI) { 8430b57cec5SDimitry Andric if (Trace) 8440b57cec5SDimitry Andric dbgs() << "Visit MI(" << printMBBReference(*MI.getParent()) << "): " << MI; 8450b57cec5SDimitry Andric if (MI.isDebugInstr()) 8460b57cec5SDimitry Andric return; 8470b57cec5SDimitry Andric assert(!MI.isBranch() && "Unexpected branch instruction"); 8480b57cec5SDimitry Andric 8490b57cec5SDimitry Andric CellMapType ResMap; 8500b57cec5SDimitry Andric bool Eval = ME.evaluate(MI, Map, ResMap); 8510b57cec5SDimitry Andric 8520b57cec5SDimitry Andric if (Trace && Eval) { 8534824e7fdSDimitry Andric for (const MachineOperand &MO : MI.operands()) { 8540b57cec5SDimitry Andric if (!MO.isReg() || !MO.isUse()) 8550b57cec5SDimitry Andric continue; 8560b57cec5SDimitry Andric RegisterRef RU(MO); 8570b57cec5SDimitry Andric dbgs() << " input reg: " << printReg(RU.Reg, &ME.TRI, RU.Sub) 8580b57cec5SDimitry Andric << " cell: " << ME.getCell(RU, Map) << "\n"; 8590b57cec5SDimitry Andric } 8600b57cec5SDimitry Andric dbgs() << "Outputs:\n"; 861480093f4SDimitry Andric for (const std::pair<const unsigned, RegisterCell> &P : ResMap) { 8620b57cec5SDimitry Andric RegisterRef RD(P.first); 8630b57cec5SDimitry Andric dbgs() << " " << printReg(P.first, &ME.TRI) << " cell: " 8640b57cec5SDimitry Andric << ME.getCell(RD, ResMap) << "\n"; 8650b57cec5SDimitry Andric } 8660b57cec5SDimitry Andric } 8670b57cec5SDimitry Andric 8680b57cec5SDimitry Andric // Iterate over all definitions of the instruction, and update the 8690b57cec5SDimitry Andric // cells accordingly. 8700b57cec5SDimitry Andric for (const MachineOperand &MO : MI.operands()) { 8710b57cec5SDimitry Andric // Visit register defs only. 8720b57cec5SDimitry Andric if (!MO.isReg() || !MO.isDef()) 8730b57cec5SDimitry Andric continue; 8740b57cec5SDimitry Andric RegisterRef RD(MO); 8750b57cec5SDimitry Andric assert(RD.Sub == 0 && "Unexpected sub-register in definition"); 876e8d8bef9SDimitry Andric if (!RD.Reg.isVirtual()) 8770b57cec5SDimitry Andric continue; 8780b57cec5SDimitry Andric 8790b57cec5SDimitry Andric bool Changed = false; 8800b57cec5SDimitry Andric if (!Eval || ResMap.count(RD.Reg) == 0) { 8810b57cec5SDimitry Andric // Set to "ref" (aka "bottom"). 8820b57cec5SDimitry Andric uint16_t DefBW = ME.getRegBitWidth(RD); 8830b57cec5SDimitry Andric RegisterCell RefC = RegisterCell::self(RD.Reg, DefBW); 8840b57cec5SDimitry Andric if (RefC != ME.getCell(RD, Map)) { 8850b57cec5SDimitry Andric ME.putCell(RD, RefC, Map); 8860b57cec5SDimitry Andric Changed = true; 8870b57cec5SDimitry Andric } 8880b57cec5SDimitry Andric } else { 8890b57cec5SDimitry Andric RegisterCell DefC = ME.getCell(RD, Map); 8900b57cec5SDimitry Andric RegisterCell ResC = ME.getCell(RD, ResMap); 8910b57cec5SDimitry Andric // This is a non-phi instruction, so the values of the inputs come 8920b57cec5SDimitry Andric // from the same registers each time this instruction is evaluated. 8930b57cec5SDimitry Andric // During the propagation, the values of the inputs can become lowered 8940b57cec5SDimitry Andric // in the sense of the lattice operation, which may cause different 8950b57cec5SDimitry Andric // results to be calculated in subsequent evaluations. This should 8960b57cec5SDimitry Andric // not cause the bottoming of the result in the map, since the new 8970b57cec5SDimitry Andric // result is already reflecting the lowered inputs. 8980b57cec5SDimitry Andric for (uint16_t i = 0, w = DefC.width(); i < w; ++i) { 8990b57cec5SDimitry Andric BitValue &V = DefC[i]; 9000b57cec5SDimitry Andric // Bits that are already "bottom" should not be updated. 9010b57cec5SDimitry Andric if (V.Type == BitValue::Ref && V.RefI.Reg == RD.Reg) 9020b57cec5SDimitry Andric continue; 9030b57cec5SDimitry Andric // Same for those that are identical in DefC and ResC. 9040b57cec5SDimitry Andric if (V == ResC[i]) 9050b57cec5SDimitry Andric continue; 9060b57cec5SDimitry Andric V = ResC[i]; 9070b57cec5SDimitry Andric Changed = true; 9080b57cec5SDimitry Andric } 9090b57cec5SDimitry Andric if (Changed) 9100b57cec5SDimitry Andric ME.putCell(RD, DefC, Map); 9110b57cec5SDimitry Andric } 9120b57cec5SDimitry Andric if (Changed) 9130b57cec5SDimitry Andric visitUsesOf(RD.Reg); 9140b57cec5SDimitry Andric } 9150b57cec5SDimitry Andric } 9160b57cec5SDimitry Andric 9170b57cec5SDimitry Andric void BT::visitBranchesFrom(const MachineInstr &BI) { 9180b57cec5SDimitry Andric const MachineBasicBlock &B = *BI.getParent(); 9190b57cec5SDimitry Andric MachineBasicBlock::const_iterator It = BI, End = B.end(); 9200b57cec5SDimitry Andric BranchTargetList Targets, BTs; 9210b57cec5SDimitry Andric bool FallsThrough = true, DefaultToAll = false; 9220b57cec5SDimitry Andric int ThisN = B.getNumber(); 9230b57cec5SDimitry Andric 9240b57cec5SDimitry Andric do { 9250b57cec5SDimitry Andric BTs.clear(); 9260b57cec5SDimitry Andric const MachineInstr &MI = *It; 9270b57cec5SDimitry Andric if (Trace) 9280b57cec5SDimitry Andric dbgs() << "Visit BR(" << printMBBReference(B) << "): " << MI; 9290b57cec5SDimitry Andric assert(MI.isBranch() && "Expecting branch instruction"); 9300b57cec5SDimitry Andric InstrExec.insert(&MI); 9310b57cec5SDimitry Andric bool Eval = ME.evaluate(MI, Map, BTs, FallsThrough); 9320b57cec5SDimitry Andric if (!Eval) { 9330b57cec5SDimitry Andric // If the evaluation failed, we will add all targets. Keep going in 9340b57cec5SDimitry Andric // the loop to mark all executable branches as such. 9350b57cec5SDimitry Andric DefaultToAll = true; 9360b57cec5SDimitry Andric FallsThrough = true; 9370b57cec5SDimitry Andric if (Trace) 9380b57cec5SDimitry Andric dbgs() << " failed to evaluate: will add all CFG successors\n"; 9390b57cec5SDimitry Andric } else if (!DefaultToAll) { 9400b57cec5SDimitry Andric // If evaluated successfully add the targets to the cumulative list. 9410b57cec5SDimitry Andric if (Trace) { 9420b57cec5SDimitry Andric dbgs() << " adding targets:"; 943*04eeddc0SDimitry Andric for (const MachineBasicBlock *BT : BTs) 944*04eeddc0SDimitry Andric dbgs() << " " << printMBBReference(*BT); 9450b57cec5SDimitry Andric if (FallsThrough) 9460b57cec5SDimitry Andric dbgs() << "\n falls through\n"; 9470b57cec5SDimitry Andric else 9480b57cec5SDimitry Andric dbgs() << "\n does not fall through\n"; 9490b57cec5SDimitry Andric } 9500b57cec5SDimitry Andric Targets.insert(BTs.begin(), BTs.end()); 9510b57cec5SDimitry Andric } 9520b57cec5SDimitry Andric ++It; 9530b57cec5SDimitry Andric } while (FallsThrough && It != End); 9540b57cec5SDimitry Andric 9555ffd83dbSDimitry Andric if (B.mayHaveInlineAsmBr()) 9565ffd83dbSDimitry Andric DefaultToAll = true; 9575ffd83dbSDimitry Andric 9580b57cec5SDimitry Andric if (!DefaultToAll) { 9590b57cec5SDimitry Andric // Need to add all CFG successors that lead to EH landing pads. 9600b57cec5SDimitry Andric // There won't be explicit branches to these blocks, but they must 9610b57cec5SDimitry Andric // be processed. 9620b57cec5SDimitry Andric for (const MachineBasicBlock *SB : B.successors()) { 9630b57cec5SDimitry Andric if (SB->isEHPad()) 9640b57cec5SDimitry Andric Targets.insert(SB); 9650b57cec5SDimitry Andric } 9660b57cec5SDimitry Andric if (FallsThrough) { 9670b57cec5SDimitry Andric MachineFunction::const_iterator BIt = B.getIterator(); 9680b57cec5SDimitry Andric MachineFunction::const_iterator Next = std::next(BIt); 9690b57cec5SDimitry Andric if (Next != MF.end()) 9700b57cec5SDimitry Andric Targets.insert(&*Next); 9710b57cec5SDimitry Andric } 9720b57cec5SDimitry Andric } else { 9730b57cec5SDimitry Andric for (const MachineBasicBlock *SB : B.successors()) 9740b57cec5SDimitry Andric Targets.insert(SB); 9750b57cec5SDimitry Andric } 9760b57cec5SDimitry Andric 9770b57cec5SDimitry Andric for (const MachineBasicBlock *TB : Targets) 9780b57cec5SDimitry Andric FlowQ.push(CFGEdge(ThisN, TB->getNumber())); 9790b57cec5SDimitry Andric } 9800b57cec5SDimitry Andric 981e8d8bef9SDimitry Andric void BT::visitUsesOf(Register Reg) { 9820b57cec5SDimitry Andric if (Trace) 9830b57cec5SDimitry Andric dbgs() << "queuing uses of modified reg " << printReg(Reg, &ME.TRI) 9840b57cec5SDimitry Andric << " cell: " << ME.getCell(Reg, Map) << '\n'; 9850b57cec5SDimitry Andric 9860b57cec5SDimitry Andric for (MachineInstr &UseI : MRI.use_nodbg_instructions(Reg)) 9870b57cec5SDimitry Andric UseQ.push(&UseI); 9880b57cec5SDimitry Andric } 9890b57cec5SDimitry Andric 9900b57cec5SDimitry Andric BT::RegisterCell BT::get(RegisterRef RR) const { 9910b57cec5SDimitry Andric return ME.getCell(RR, Map); 9920b57cec5SDimitry Andric } 9930b57cec5SDimitry Andric 9940b57cec5SDimitry Andric void BT::put(RegisterRef RR, const RegisterCell &RC) { 9950b57cec5SDimitry Andric ME.putCell(RR, RC, Map); 9960b57cec5SDimitry Andric } 9970b57cec5SDimitry Andric 9980b57cec5SDimitry Andric // Replace all references to bits from OldRR with the corresponding bits 9990b57cec5SDimitry Andric // in NewRR. 10000b57cec5SDimitry Andric void BT::subst(RegisterRef OldRR, RegisterRef NewRR) { 10010b57cec5SDimitry Andric assert(Map.count(OldRR.Reg) > 0 && "OldRR not present in map"); 10020b57cec5SDimitry Andric BitMask OM = ME.mask(OldRR.Reg, OldRR.Sub); 10030b57cec5SDimitry Andric BitMask NM = ME.mask(NewRR.Reg, NewRR.Sub); 10040b57cec5SDimitry Andric uint16_t OMB = OM.first(), OME = OM.last(); 10050b57cec5SDimitry Andric uint16_t NMB = NM.first(), NME = NM.last(); 10060b57cec5SDimitry Andric (void)NME; 10070b57cec5SDimitry Andric assert((OME-OMB == NME-NMB) && 10080b57cec5SDimitry Andric "Substituting registers of different lengths"); 10090b57cec5SDimitry Andric for (std::pair<const unsigned, RegisterCell> &P : Map) { 10100b57cec5SDimitry Andric RegisterCell &RC = P.second; 10110b57cec5SDimitry Andric for (uint16_t i = 0, w = RC.width(); i < w; ++i) { 10120b57cec5SDimitry Andric BitValue &V = RC[i]; 10130b57cec5SDimitry Andric if (V.Type != BitValue::Ref || V.RefI.Reg != OldRR.Reg) 10140b57cec5SDimitry Andric continue; 10150b57cec5SDimitry Andric if (V.RefI.Pos < OMB || V.RefI.Pos > OME) 10160b57cec5SDimitry Andric continue; 10170b57cec5SDimitry Andric V.RefI.Reg = NewRR.Reg; 10180b57cec5SDimitry Andric V.RefI.Pos += NMB-OMB; 10190b57cec5SDimitry Andric } 10200b57cec5SDimitry Andric } 10210b57cec5SDimitry Andric } 10220b57cec5SDimitry Andric 10230b57cec5SDimitry Andric // Check if the block has been "executed" during propagation. (If not, the 10240b57cec5SDimitry Andric // block is dead, but it may still appear to be reachable.) 10250b57cec5SDimitry Andric bool BT::reached(const MachineBasicBlock *B) const { 10260b57cec5SDimitry Andric int BN = B->getNumber(); 10270b57cec5SDimitry Andric assert(BN >= 0); 10280b57cec5SDimitry Andric return ReachedBB.count(BN); 10290b57cec5SDimitry Andric } 10300b57cec5SDimitry Andric 10310b57cec5SDimitry Andric // Visit an individual instruction. This could be a newly added instruction, 10320b57cec5SDimitry Andric // or one that has been modified by an optimization. 10330b57cec5SDimitry Andric void BT::visit(const MachineInstr &MI) { 10340b57cec5SDimitry Andric assert(!MI.isBranch() && "Only non-branches are allowed"); 10350b57cec5SDimitry Andric InstrExec.insert(&MI); 10360b57cec5SDimitry Andric visitNonBranch(MI); 10370b57cec5SDimitry Andric // Make sure to flush all the pending use updates. 10380b57cec5SDimitry Andric runUseQueue(); 10390b57cec5SDimitry Andric // The call to visitNonBranch could propagate the changes until a branch 10400b57cec5SDimitry Andric // is actually visited. This could result in adding CFG edges to the flow 10410b57cec5SDimitry Andric // queue. Since the queue won't be processed, clear it. 10420b57cec5SDimitry Andric while (!FlowQ.empty()) 10430b57cec5SDimitry Andric FlowQ.pop(); 10440b57cec5SDimitry Andric } 10450b57cec5SDimitry Andric 10460b57cec5SDimitry Andric void BT::reset() { 10470b57cec5SDimitry Andric EdgeExec.clear(); 10480b57cec5SDimitry Andric InstrExec.clear(); 10490b57cec5SDimitry Andric Map.clear(); 10500b57cec5SDimitry Andric ReachedBB.clear(); 10510b57cec5SDimitry Andric ReachedBB.reserve(MF.size()); 10520b57cec5SDimitry Andric } 10530b57cec5SDimitry Andric 10540b57cec5SDimitry Andric void BT::runEdgeQueue(BitVector &BlockScanned) { 10550b57cec5SDimitry Andric while (!FlowQ.empty()) { 10560b57cec5SDimitry Andric CFGEdge Edge = FlowQ.front(); 10570b57cec5SDimitry Andric FlowQ.pop(); 10580b57cec5SDimitry Andric 10590b57cec5SDimitry Andric if (EdgeExec.count(Edge)) 10600b57cec5SDimitry Andric return; 10610b57cec5SDimitry Andric EdgeExec.insert(Edge); 10620b57cec5SDimitry Andric ReachedBB.insert(Edge.second); 10630b57cec5SDimitry Andric 10640b57cec5SDimitry Andric const MachineBasicBlock &B = *MF.getBlockNumbered(Edge.second); 10650b57cec5SDimitry Andric MachineBasicBlock::const_iterator It = B.begin(), End = B.end(); 10660b57cec5SDimitry Andric // Visit PHI nodes first. 10670b57cec5SDimitry Andric while (It != End && It->isPHI()) { 10680b57cec5SDimitry Andric const MachineInstr &PI = *It++; 10690b57cec5SDimitry Andric InstrExec.insert(&PI); 10700b57cec5SDimitry Andric visitPHI(PI); 10710b57cec5SDimitry Andric } 10720b57cec5SDimitry Andric 10730b57cec5SDimitry Andric // If this block has already been visited through a flow graph edge, 10740b57cec5SDimitry Andric // then the instructions have already been processed. Any updates to 10750b57cec5SDimitry Andric // the cells would now only happen through visitUsesOf... 10760b57cec5SDimitry Andric if (BlockScanned[Edge.second]) 10770b57cec5SDimitry Andric return; 10780b57cec5SDimitry Andric BlockScanned[Edge.second] = true; 10790b57cec5SDimitry Andric 10800b57cec5SDimitry Andric // Visit non-branch instructions. 10810b57cec5SDimitry Andric while (It != End && !It->isBranch()) { 10820b57cec5SDimitry Andric const MachineInstr &MI = *It++; 10830b57cec5SDimitry Andric InstrExec.insert(&MI); 10840b57cec5SDimitry Andric visitNonBranch(MI); 10850b57cec5SDimitry Andric } 10860b57cec5SDimitry Andric // If block end has been reached, add the fall-through edge to the queue. 10870b57cec5SDimitry Andric if (It == End) { 10880b57cec5SDimitry Andric MachineFunction::const_iterator BIt = B.getIterator(); 10890b57cec5SDimitry Andric MachineFunction::const_iterator Next = std::next(BIt); 10900b57cec5SDimitry Andric if (Next != MF.end() && B.isSuccessor(&*Next)) { 10910b57cec5SDimitry Andric int ThisN = B.getNumber(); 10920b57cec5SDimitry Andric int NextN = Next->getNumber(); 10930b57cec5SDimitry Andric FlowQ.push(CFGEdge(ThisN, NextN)); 10940b57cec5SDimitry Andric } 10950b57cec5SDimitry Andric } else { 10960b57cec5SDimitry Andric // Handle the remaining sequence of branches. This function will update 10970b57cec5SDimitry Andric // the work queue. 10980b57cec5SDimitry Andric visitBranchesFrom(*It); 10990b57cec5SDimitry Andric } 11000b57cec5SDimitry Andric } // while (!FlowQ->empty()) 11010b57cec5SDimitry Andric } 11020b57cec5SDimitry Andric 11030b57cec5SDimitry Andric void BT::runUseQueue() { 11040b57cec5SDimitry Andric while (!UseQ.empty()) { 11050b57cec5SDimitry Andric MachineInstr &UseI = *UseQ.front(); 11060b57cec5SDimitry Andric UseQ.pop(); 11070b57cec5SDimitry Andric 11080b57cec5SDimitry Andric if (!InstrExec.count(&UseI)) 11090b57cec5SDimitry Andric continue; 11100b57cec5SDimitry Andric if (UseI.isPHI()) 11110b57cec5SDimitry Andric visitPHI(UseI); 11120b57cec5SDimitry Andric else if (!UseI.isBranch()) 11130b57cec5SDimitry Andric visitNonBranch(UseI); 11140b57cec5SDimitry Andric else 11150b57cec5SDimitry Andric visitBranchesFrom(UseI); 11160b57cec5SDimitry Andric } 11170b57cec5SDimitry Andric } 11180b57cec5SDimitry Andric 11190b57cec5SDimitry Andric void BT::run() { 11200b57cec5SDimitry Andric reset(); 11210b57cec5SDimitry Andric assert(FlowQ.empty()); 11220b57cec5SDimitry Andric 11230b57cec5SDimitry Andric using MachineFlowGraphTraits = GraphTraits<const MachineFunction*>; 11240b57cec5SDimitry Andric const MachineBasicBlock *Entry = MachineFlowGraphTraits::getEntryNode(&MF); 11250b57cec5SDimitry Andric 11260b57cec5SDimitry Andric unsigned MaxBN = 0; 11270b57cec5SDimitry Andric for (const MachineBasicBlock &B : MF) { 11280b57cec5SDimitry Andric assert(B.getNumber() >= 0 && "Disconnected block"); 11290b57cec5SDimitry Andric unsigned BN = B.getNumber(); 11300b57cec5SDimitry Andric if (BN > MaxBN) 11310b57cec5SDimitry Andric MaxBN = BN; 11320b57cec5SDimitry Andric } 11330b57cec5SDimitry Andric 11340b57cec5SDimitry Andric // Keep track of visited blocks. 11350b57cec5SDimitry Andric BitVector BlockScanned(MaxBN+1); 11360b57cec5SDimitry Andric 11370b57cec5SDimitry Andric int EntryN = Entry->getNumber(); 11380b57cec5SDimitry Andric // Generate a fake edge to get something to start with. 11390b57cec5SDimitry Andric FlowQ.push(CFGEdge(-1, EntryN)); 11400b57cec5SDimitry Andric 11410b57cec5SDimitry Andric while (!FlowQ.empty() || !UseQ.empty()) { 11420b57cec5SDimitry Andric runEdgeQueue(BlockScanned); 11430b57cec5SDimitry Andric runUseQueue(); 11440b57cec5SDimitry Andric } 11450b57cec5SDimitry Andric UseQ.reset(); 11460b57cec5SDimitry Andric 11470b57cec5SDimitry Andric if (Trace) 11480b57cec5SDimitry Andric print_cells(dbgs() << "Cells after propagation:\n"); 11490b57cec5SDimitry Andric } 1150