diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonConstPropagation.cpp | 140 | ||||
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonEarlyIfConv.cpp | 100 | ||||
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp | 76 | ||||
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonGenExtract.cpp | 47 | ||||
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonGenInsert.cpp | 170 |
5 files changed, 249 insertions, 284 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonConstPropagation.cpp b/llvm/lib/Target/Hexagon/HexagonConstPropagation.cpp index 3cec6def6b5..783b916e04b 100644 --- a/llvm/lib/Target/Hexagon/HexagonConstPropagation.cpp +++ b/llvm/lib/Target/Hexagon/HexagonConstPropagation.cpp @@ -12,27 +12,40 @@ #include "HexagonInstrInfo.h" #include "HexagonRegisterInfo.h" #include "HexagonSubtarget.h" - +#include "llvm/ADT/APFloat.h" +#include "llvm/ADT/APInt.h" #include "llvm/ADT/PostOrderIterator.h" #include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/IR/Constants.h" -#include "llvm/Support/CommandLine.h" +#include "llvm/Pass.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetInstrInfo.h" - +#include "llvm/Target/TargetRegisterInfo.h" +#include <cassert> +#include <cstdint> +#include <cstring> +#include <iterator> #include <map> #include <queue> #include <set> +#include <utility> +#include <vector> using namespace llvm; namespace { - class LatticeCell; // Properties of a value that are tracked by the propagation. // A property that is marked as present (i.e. bit is set) dentes that the @@ -62,23 +75,24 @@ namespace { static uint32_t deduce(const Constant *C); }; - // A representation of a register as it can appear in a MachineOperand, // i.e. a pair register:subregister. struct Register { unsigned Reg, SubReg; + explicit Register(unsigned R, unsigned SR = 0) : Reg(R), SubReg(SR) {} explicit Register(const MachineOperand &MO) : Reg(MO.getReg()), SubReg(MO.getSubReg()) {} - void print(const TargetRegisterInfo *TRI = 0) const { + + void print(const TargetRegisterInfo *TRI = nullptr) const { dbgs() << PrintReg(Reg, TRI, SubReg); } + bool operator== (const Register &R) const { return (Reg == R.Reg) && (SubReg == R.SubReg); } }; - // Lattice cell, based on that was described in the W-Z paper on constant // propagation. // Latice cell will be allowed to hold multiple constant values. While @@ -89,7 +103,9 @@ namespace { class LatticeCell { private: enum { Normal, Top, Bottom }; + static const unsigned MaxCellSize = 4; + unsigned Kind:2; unsigned Size:3; unsigned IsSpecial:1; @@ -104,7 +120,7 @@ namespace { LatticeCell() : Kind(Top), Size(0), IsSpecial(false) { for (unsigned i = 0; i < MaxCellSize; ++i) - Values[i] = 0; + Values[i] = nullptr; } bool meet(const LatticeCell &L); @@ -130,6 +146,7 @@ namespace { bool isProperty() const { return IsSpecial; } bool isTop() const { return Kind == Top; } bool isBottom() const { return Kind == Bottom; } + bool setBottom() { bool Changed = (Kind != Bottom); Kind = Bottom; @@ -137,6 +154,7 @@ namespace { IsSpecial = false; return Changed; } + void print(raw_ostream &os) const; private: @@ -145,6 +163,7 @@ namespace { Size = 0; Kind = Normal; } + bool convertToProperty(); }; @@ -177,7 +196,9 @@ namespace { assert(Top.isTop()); Bottom.setBottom(); } + void clear() { Map.clear(); } + bool has(unsigned R) const { // All non-virtual registers are considered "bottom". if (!TargetRegisterInfo::isVirtualRegister(R)) @@ -185,6 +206,7 @@ namespace { MapType::const_iterator F = Map.find(R); return F != Map.end(); } + const LatticeCell &get(unsigned R) const { if (!TargetRegisterInfo::isVirtualRegister(R)) return Bottom; @@ -193,11 +215,14 @@ namespace { return F->second; return Top; } + // Invalidates any const references. void update(unsigned R, const LatticeCell &L) { Map[R] = L; } + void print(raw_ostream &os, const TargetRegisterInfo &TRI) const; + private: typedef std::map<unsigned,LatticeCell> MapType; MapType Map; @@ -205,6 +230,7 @@ namespace { // this cell in "get". Also, have a "Bottom" cell to return from // get when a value of a physical register is requested. LatticeCell Top, Bottom; + public: typedef MapType::const_iterator const_iterator; const_iterator begin() const { return Map.begin(); } @@ -240,7 +266,6 @@ namespace { QueueOfCFGEdge FlowQ; }; - // The "evaluator/rewriter" of machine instructions. This is an abstract // base class that provides the interface that the propagator will use, // as well as some helper functions that are target-independent. @@ -249,7 +274,7 @@ namespace { MachineConstEvaluator(MachineFunction &Fn) : TRI(*Fn.getSubtarget().getRegisterInfo()), MF(Fn), CX(Fn.getFunction()->getContext()) {} - virtual ~MachineConstEvaluator() {} + virtual ~MachineConstEvaluator() = default; // The required interface: // - A set of three "evaluate" functions. Each returns "true" if the @@ -299,6 +324,7 @@ namespace { GTu = G | U, GEu = G | EQ | U }; + static uint32_t negate(uint32_t Cmp) { if (Cmp == EQ) return NE; @@ -381,7 +407,7 @@ namespace { APInt &Result); }; -} +} // end anonymous namespace uint32_t ConstantProperties::deduce(const Constant *C) { if (isa<ConstantInt>(C)) { @@ -413,7 +439,6 @@ uint32_t ConstantProperties::deduce(const Constant *C) { return Unknown; } - // Convert a cell from a set of specific values to a cell that tracks // properties. bool LatticeCell::convertToProperty() { @@ -433,7 +458,6 @@ bool LatticeCell::convertToProperty() { return true; } - void LatticeCell::print(raw_ostream &os) const { if (isProperty()) { os << "{ "; @@ -472,7 +496,6 @@ void LatticeCell::print(raw_ostream &os) const { os << " }"; } - // "Meet" operation on two cells. This is the key of the propagation // algorithm. bool LatticeCell::meet(const LatticeCell &L) { @@ -497,7 +520,6 @@ bool LatticeCell::meet(const LatticeCell &L) { return Changed; } - // Add a new constant to the cell. This is actually where the cell update // happens. If a cell has room for more constants, the new constant is added. // Otherwise, the cell is converted to a "property" cell (i.e. a cell that @@ -545,7 +567,6 @@ bool LatticeCell::add(const Constant *LC) { return Changed; } - // Add a property to the cell. This will force the cell to become a property- // tracking cell. bool LatticeCell::add(uint32_t Property) { @@ -557,7 +578,6 @@ bool LatticeCell::add(uint32_t Property) { return true; } - // Return the properties of the values in the cell. This is valid for any // cell, and does not alter the cell itself. uint32_t LatticeCell::properties() const { @@ -577,14 +597,12 @@ uint32_t LatticeCell::properties() const { return Ps; } - void MachineConstPropagator::CellMap::print(raw_ostream &os, const TargetRegisterInfo &TRI) const { for (auto &I : Map) dbgs() << " " << PrintReg(I.first, &TRI) << " -> " << I.second << '\n'; } - void MachineConstPropagator::visitPHI(const MachineInstr &PN) { const MachineBasicBlock *MB = PN.getParent(); unsigned MBN = MB->getNumber(); @@ -642,7 +660,6 @@ Bottomize: visitUsesOf(DefR.Reg); } - void MachineConstPropagator::visitNonBranch(const MachineInstr &MI) { DEBUG(dbgs() << "Visiting MI(BB#" << MI.getParent()->getNumber() << "): " << MI); @@ -686,7 +703,6 @@ void MachineConstPropagator::visitNonBranch(const MachineInstr &MI) { } } - // \brief Starting at a given branch, visit remaining branches in the block. // Traverse over the subsequent branches for as long as the preceding one // can fall through. Add all the possible targets to the flow work queue, @@ -750,7 +766,6 @@ void MachineConstPropagator::visitBranchesFrom(const MachineInstr &BrI) { } } - void MachineConstPropagator::visitUsesOf(unsigned Reg) { DEBUG(dbgs() << "Visiting uses of " << PrintReg(Reg, &MCE.TRI) << Cells.get(Reg) << '\n'); @@ -814,7 +829,6 @@ bool MachineConstPropagator::computeBlockSuccessors(const MachineBasicBlock *MB, return true; } - void MachineConstPropagator::removeCFGEdge(MachineBasicBlock *From, MachineBasicBlock *To) { // First, remove the CFG successor/predecessor information. @@ -834,7 +848,6 @@ void MachineConstPropagator::removeCFGEdge(MachineBasicBlock *From, } } - void MachineConstPropagator::propagate(MachineFunction &MF) { MachineBasicBlock *Entry = GraphTraits<MachineFunction*>::getEntryNode(&MF); unsigned EntryNum = Entry->getNumber(); @@ -916,7 +929,6 @@ void MachineConstPropagator::propagate(MachineFunction &MF) { }); } - bool MachineConstPropagator::rewrite(MachineFunction &MF) { bool Changed = false; // Rewrite all instructions based on the collected cell information. @@ -1013,7 +1025,6 @@ bool MachineConstPropagator::rewrite(MachineFunction &MF) { return Changed; } - // This is the constant propagation algorithm as described by Wegman-Zadeck. // Most of the terminology comes from there. bool MachineConstPropagator::run(MachineFunction &MF) { @@ -1037,7 +1048,6 @@ bool MachineConstPropagator::run(MachineFunction &MF) { return Changed; } - // -------------------------------------------------------------------- // Machine const evaluator. @@ -1054,7 +1064,6 @@ bool MachineConstEvaluator::getCell(const Register &R, const CellMap &Inputs, return Eval && !RC.isBottom(); } - bool MachineConstEvaluator::constToInt(const Constant *C, APInt &Val) const { const ConstantInt *CI = dyn_cast<ConstantInt>(C); @@ -1064,12 +1073,10 @@ bool MachineConstEvaluator::constToInt(const Constant *C, return true; } - const ConstantInt *MachineConstEvaluator::intToConst(const APInt &Val) const { return ConstantInt::get(CX, Val); } - bool MachineConstEvaluator::evaluateCMPrr(uint32_t Cmp, const Register &R1, const Register &R2, const CellMap &Inputs, bool &Result) { assert(Inputs.has(R1.Reg) && Inputs.has(R2.Reg)); @@ -1109,7 +1116,6 @@ bool MachineConstEvaluator::evaluateCMPrr(uint32_t Cmp, const Register &R1, return IsTrue || IsFalse; } - bool MachineConstEvaluator::evaluateCMPri(uint32_t Cmp, const Register &R1, const APInt &A2, const CellMap &Inputs, bool &Result) { assert(Inputs.has(R1.Reg)); @@ -1137,7 +1143,6 @@ bool MachineConstEvaluator::evaluateCMPri(uint32_t Cmp, const Register &R1, return IsTrue || IsFalse; } - bool MachineConstEvaluator::evaluateCMPrp(uint32_t Cmp, const Register &R1, uint64_t Props2, const CellMap &Inputs, bool &Result) { assert(Inputs.has(R1.Reg)); @@ -1164,7 +1169,6 @@ bool MachineConstEvaluator::evaluateCMPrp(uint32_t Cmp, const Register &R1, return IsTrue || IsFalse; } - bool MachineConstEvaluator::evaluateCMPii(uint32_t Cmp, const APInt &A1, const APInt &A2, bool &Result) { // NE is a special kind of comparison (not composed of smaller properties). @@ -1206,7 +1210,6 @@ bool MachineConstEvaluator::evaluateCMPii(uint32_t Cmp, const APInt &A1, return true; } - bool MachineConstEvaluator::evaluateCMPpi(uint32_t Cmp, uint32_t Props, const APInt &A2, bool &Result) { if (Props == ConstantProperties::Unknown) @@ -1273,7 +1276,6 @@ bool MachineConstEvaluator::evaluateCMPpi(uint32_t Cmp, uint32_t Props, return false; } - bool MachineConstEvaluator::evaluateCMPpp(uint32_t Cmp, uint32_t Props1, uint32_t Props2, bool &Result) { typedef ConstantProperties P; @@ -1333,13 +1335,11 @@ bool MachineConstEvaluator::evaluateCMPpp(uint32_t Cmp, uint32_t Props1, return false; } - bool MachineConstEvaluator::evaluateCOPY(const Register &R1, const CellMap &Inputs, LatticeCell &Result) { return getCell(R1, Inputs, Result); } - bool MachineConstEvaluator::evaluateANDrr(const Register &R1, const Register &R2, const CellMap &Inputs, LatticeCell &Result) { assert(Inputs.has(R1.Reg) && Inputs.has(R2.Reg)); @@ -1371,7 +1371,6 @@ bool MachineConstEvaluator::evaluateANDrr(const Register &R1, return !Result.isBottom(); } - bool MachineConstEvaluator::evaluateANDri(const Register &R1, const APInt &A2, const CellMap &Inputs, LatticeCell &Result) { assert(Inputs.has(R1.Reg)); @@ -1402,14 +1401,12 @@ bool MachineConstEvaluator::evaluateANDri(const Register &R1, return !Result.isBottom(); } - bool MachineConstEvaluator::evaluateANDii(const APInt &A1, const APInt &A2, APInt &Result) { Result = A1 & A2; return true; } - bool MachineConstEvaluator::evaluateORrr(const Register &R1, const Register &R2, const CellMap &Inputs, LatticeCell &Result) { assert(Inputs.has(R1.Reg) && Inputs.has(R2.Reg)); @@ -1441,7 +1438,6 @@ bool MachineConstEvaluator::evaluateORrr(const Register &R1, return !Result.isBottom(); } - bool MachineConstEvaluator::evaluateORri(const Register &R1, const APInt &A2, const CellMap &Inputs, LatticeCell &Result) { assert(Inputs.has(R1.Reg)); @@ -1472,14 +1468,12 @@ bool MachineConstEvaluator::evaluateORri(const Register &R1, return !Result.isBottom(); } - bool MachineConstEvaluator::evaluateORii(const APInt &A1, const APInt &A2, APInt &Result) { Result = A1 | A2; return true; } - bool MachineConstEvaluator::evaluateXORrr(const Register &R1, const Register &R2, const CellMap &Inputs, LatticeCell &Result) { assert(Inputs.has(R1.Reg) && Inputs.has(R2.Reg)); @@ -1509,7 +1503,6 @@ bool MachineConstEvaluator::evaluateXORrr(const Register &R1, return !Result.isBottom(); } - bool MachineConstEvaluator::evaluateXORri(const Register &R1, const APInt &A2, const CellMap &Inputs, LatticeCell &Result) { assert(Inputs.has(R1.Reg)); @@ -1537,14 +1530,12 @@ bool MachineConstEvaluator::evaluateXORri(const Register &R1, return !Result.isBottom(); } - bool MachineConstEvaluator::evaluateXORii(const APInt &A1, const APInt &A2, APInt &Result) { Result = A1 ^ A2; return true; } - bool MachineConstEvaluator::evaluateZEXTr(const Register &R1, unsigned Width, unsigned Bits, const CellMap &Inputs, LatticeCell &Result) { assert(Inputs.has(R1.Reg)); @@ -1566,7 +1557,6 @@ bool MachineConstEvaluator::evaluateZEXTr(const Register &R1, unsigned Width, return true; } - bool MachineConstEvaluator::evaluateZEXTi(const APInt &A1, unsigned Width, unsigned Bits, APInt &Result) { unsigned BW = A1.getBitWidth(); @@ -1577,7 +1567,6 @@ bool MachineConstEvaluator::evaluateZEXTi(const APInt &A1, unsigned Width, return true; } - bool MachineConstEvaluator::evaluateSEXTr(const Register &R1, unsigned Width, unsigned Bits, const CellMap &Inputs, LatticeCell &Result) { assert(Inputs.has(R1.Reg)); @@ -1599,7 +1588,6 @@ bool MachineConstEvaluator::evaluateSEXTr(const Register &R1, unsigned Width, return true; } - bool MachineConstEvaluator::evaluateSEXTi(const APInt &A1, unsigned Width, unsigned Bits, APInt &Result) { unsigned BW = A1.getBitWidth(); @@ -1644,7 +1632,6 @@ bool MachineConstEvaluator::evaluateSEXTi(const APInt &A1, unsigned Width, return true; } - bool MachineConstEvaluator::evaluateCLBr(const Register &R1, bool Zeros, bool Ones, const CellMap &Inputs, LatticeCell &Result) { assert(Inputs.has(R1.Reg)); @@ -1666,7 +1653,6 @@ bool MachineConstEvaluator::evaluateCLBr(const Register &R1, bool Zeros, return true; } - bool MachineConstEvaluator::evaluateCLBi(const APInt &A1, bool Zeros, bool Ones, APInt &Result) { unsigned BW = A1.getBitWidth(); @@ -1681,7 +1667,6 @@ bool MachineConstEvaluator::evaluateCLBi(const APInt &A1, bool Zeros, return true; } - bool MachineConstEvaluator::evaluateCTBr(const Register &R1, bool Zeros, bool Ones, const CellMap &Inputs, LatticeCell &Result) { assert(Inputs.has(R1.Reg)); @@ -1703,7 +1688,6 @@ bool MachineConstEvaluator::evaluateCTBr(const Register &R1, bool Zeros, return true; } - bool MachineConstEvaluator::evaluateCTBi(const APInt &A1, bool Zeros, bool Ones, APInt &Result) { unsigned BW = A1.getBitWidth(); @@ -1718,7 +1702,6 @@ bool MachineConstEvaluator::evaluateCTBi(const APInt &A1, bool Zeros, return true; } - bool MachineConstEvaluator::evaluateEXTRACTr(const Register &R1, unsigned Width, unsigned Bits, unsigned Offset, bool Signed, const CellMap &Inputs, LatticeCell &Result) { @@ -1751,7 +1734,6 @@ bool MachineConstEvaluator::evaluateEXTRACTr(const Register &R1, return true; } - bool MachineConstEvaluator::evaluateEXTRACTi(const APInt &A1, unsigned Bits, unsigned Offset, bool Signed, APInt &Result) { unsigned BW = A1.getBitWidth(); @@ -1778,7 +1760,6 @@ bool MachineConstEvaluator::evaluateEXTRACTi(const APInt &A1, unsigned Bits, return true; } - bool MachineConstEvaluator::evaluateSplatr(const Register &R1, unsigned Bits, unsigned Count, const CellMap &Inputs, LatticeCell &Result) { @@ -1801,7 +1782,6 @@ bool MachineConstEvaluator::evaluateSplatr(const Register &R1, return true; } - bool MachineConstEvaluator::evaluateSplati(const APInt &A1, unsigned Bits, unsigned Count, APInt &Result) { assert(Count > 0); @@ -1819,16 +1799,18 @@ bool MachineConstEvaluator::evaluateSplati(const APInt &A1, unsigned Bits, return true; } - // ---------------------------------------------------------------------- // Hexagon-specific code. namespace llvm { + FunctionPass *createHexagonConstPropagationPass(); void initializeHexagonConstPropagationPass(PassRegistry &Registry); -} + +} // end namespace llvm namespace { + class HexagonConstEvaluator : public MachineConstEvaluator { public: HexagonConstEvaluator(MachineFunction &Fn); @@ -1842,7 +1824,6 @@ namespace { override; bool rewrite(MachineInstr &MI, const CellMap &Inputs) override; - private: unsigned getRegBitWidth(unsigned Reg) const; @@ -1880,17 +1861,19 @@ namespace { const HexagonRegisterInfo &HRI; }; - class HexagonConstPropagation : public MachineFunctionPass { public: static char ID; + HexagonConstPropagation() : MachineFunctionPass(ID) { PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeHexagonConstPropagationPass(Registry); } + StringRef getPassName() const override { return "Hexagon Constant Propagation"; } + bool runOnMachineFunction(MachineFunction &MF) override { const Function *F = MF.getFunction(); if (!F) @@ -1904,12 +1887,12 @@ namespace { }; char HexagonConstPropagation::ID = 0; -} + +} // end anonymous namespace INITIALIZE_PASS(HexagonConstPropagation, "hcp", "Hexagon Constant Propagation", false, false) - HexagonConstEvaluator::HexagonConstEvaluator(MachineFunction &Fn) : MachineConstEvaluator(Fn), HII(*Fn.getSubtarget<HexagonSubtarget>().getInstrInfo()), @@ -1917,7 +1900,6 @@ HexagonConstEvaluator::HexagonConstEvaluator(MachineFunction &Fn) MRI = &Fn.getRegInfo(); } - bool HexagonConstEvaluator::evaluate(const MachineInstr &MI, const CellMap &Inputs, CellMap &Outputs) { if (MI.isCall()) @@ -2081,6 +2063,7 @@ bool HexagonConstEvaluator::evaluate(const MachineInstr &MI, case Hexagon::S2_ct1p: { using namespace Hexagon; + bool Ones = (Opc == S2_ct1) || (Opc == S2_ct1p); Register R1(MI.getOperand(1)); assert(Inputs.has(R1.Reg)); @@ -2111,6 +2094,7 @@ bool HexagonConstEvaluator::evaluate(const MachineInstr &MI, case Hexagon::S2_clbp: { using namespace Hexagon; + bool OnlyZeros = (Opc == S2_cl0) || (Opc == S2_cl0p); bool OnlyOnes = (Opc == S2_cl1) || (Opc == S2_cl1p); Register R1(MI.getOperand(1)); @@ -2192,7 +2176,6 @@ bool HexagonConstEvaluator::evaluate(const MachineInstr &MI, return true; } - bool HexagonConstEvaluator::evaluate(const Register &R, const LatticeCell &Input, LatticeCell &Result) { if (!R.SubReg) { @@ -2248,7 +2231,6 @@ bool HexagonConstEvaluator::evaluate(const Register &R, return true; } - bool HexagonConstEvaluator::evaluate(const MachineInstr &BrI, const CellMap &Inputs, SetVector<const MachineBasicBlock*> &Targets, bool &FallsThru) { @@ -2317,7 +2299,6 @@ Undetermined: return true; } - bool HexagonConstEvaluator::rewrite(MachineInstr &MI, const CellMap &Inputs) { if (MI.isBranch()) return rewriteHexBranch(MI, Inputs); @@ -2350,7 +2331,6 @@ bool HexagonConstEvaluator::rewrite(MachineInstr &MI, const CellMap &Inputs) { return Changed; } - unsigned HexagonConstEvaluator::getRegBitWidth(unsigned Reg) const { const TargetRegisterClass *RC = MRI->getRegClass(Reg); if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) @@ -2363,7 +2343,6 @@ unsigned HexagonConstEvaluator::getRegBitWidth(unsigned Reg) const { return 0; } - uint32_t HexagonConstEvaluator::getCmp(unsigned Opc) { switch (Opc) { case Hexagon::C2_cmpeq: @@ -2459,7 +2438,6 @@ uint32_t HexagonConstEvaluator::getCmp(unsigned Opc) { return Comparison::Unk; } - APInt HexagonConstEvaluator::getCmpImm(unsigned Opc, unsigned OpX, const MachineOperand &MO) { bool Signed = false; @@ -2502,14 +2480,12 @@ APInt HexagonConstEvaluator::getCmpImm(unsigned Opc, unsigned OpX, return APInt(32, Val, Signed); } - void HexagonConstEvaluator::replaceWithNop(MachineInstr &MI) { MI.setDesc(HII.get(Hexagon::A2_nop)); while (MI.getNumOperands() > 0) MI.RemoveOperand(0); } - bool HexagonConstEvaluator::evaluateHexRSEQ32(Register RL, Register RH, const CellMap &Inputs, LatticeCell &Result) { assert(Inputs.has(RL.Reg) && Inputs.has(RH.Reg)); @@ -2547,7 +2523,6 @@ bool HexagonConstEvaluator::evaluateHexRSEQ32(Register RL, Register RH, return !Result.isBottom(); } - bool HexagonConstEvaluator::evaluateHexCompare(const MachineInstr &MI, const CellMap &Inputs, CellMap &Outputs) { unsigned Opc = MI.getOpcode(); @@ -2593,7 +2568,6 @@ bool HexagonConstEvaluator::evaluateHexCompare(const MachineInstr &MI, return false; } - bool HexagonConstEvaluator::evaluateHexCompare2(unsigned Opc, const MachineOperand &Src1, const MachineOperand &Src2, const CellMap &Inputs, bool &Result) { @@ -2624,7 +2598,6 @@ bool HexagonConstEvaluator::evaluateHexCompare2(unsigned Opc, return false; } - bool HexagonConstEvaluator::evaluateHexLogical(const MachineInstr &MI, const CellMap &Inputs, CellMap &Outputs) { unsigned Opc = MI.getOpcode(); @@ -2668,7 +2641,6 @@ bool HexagonConstEvaluator::evaluateHexLogical(const MachineInstr &MI, return Eval; } - bool HexagonConstEvaluator::evaluateHexCondMove(const MachineInstr &MI, const CellMap &Inputs, CellMap &Outputs) { // Dst0 = Cond1 ? Src2 : Src3 @@ -2712,7 +2684,6 @@ bool HexagonConstEvaluator::evaluateHexCondMove(const MachineInstr &MI, return false; } - bool HexagonConstEvaluator::evaluateHexExt(const MachineInstr &MI, const CellMap &Inputs, CellMap &Outputs) { // Dst0 = ext R1 @@ -2755,7 +2726,6 @@ bool HexagonConstEvaluator::evaluateHexExt(const MachineInstr &MI, return true; } - bool HexagonConstEvaluator::evaluateHexVector1(const MachineInstr &MI, const CellMap &Inputs, CellMap &Outputs) { // DefR = op R1 @@ -2785,7 +2755,6 @@ bool HexagonConstEvaluator::evaluateHexVector1(const MachineInstr &MI, return true; } - bool HexagonConstEvaluator::rewriteHexConstDefs(MachineInstr &MI, const CellMap &Inputs, bool &AllDefs) { AllDefs = false; @@ -2793,8 +2762,7 @@ bool HexagonConstEvaluator::rewriteHexConstDefs(MachineInstr &MI, // Some diagnostics. // DEBUG({...}) gets confused with all this code as an argument. #ifndef NDEBUG - bool Debugging = llvm::DebugFlag && - llvm::isCurrentDebugType(DEBUG_TYPE); + bool Debugging = DebugFlag && isCurrentDebugType(DEBUG_TYPE); if (Debugging) { bool Const = true, HasUse = false; for (const MachineOperand &MO : MI.operands()) { @@ -2950,7 +2918,6 @@ bool HexagonConstEvaluator::rewriteHexConstDefs(MachineInstr &MI, return ChangedNum > 0; } - bool HexagonConstEvaluator::rewriteHexConstUses(MachineInstr &MI, const CellMap &Inputs) { bool Changed = false; @@ -2958,7 +2925,7 @@ bool HexagonConstEvaluator::rewriteHexConstUses(MachineInstr &MI, MachineBasicBlock &B = *MI.getParent(); const DebugLoc &DL = MI.getDebugLoc(); MachineBasicBlock::iterator At = MI.getIterator(); - MachineInstr *NewMI = NULL; + MachineInstr *NewMI = nullptr; switch (Opc) { case Hexagon::M2_maci: @@ -3115,7 +3082,6 @@ bool HexagonConstEvaluator::rewriteHexConstUses(MachineInstr &MI, return Changed; } - void HexagonConstEvaluator::replaceAllRegUsesWith(unsigned FromReg, unsigned ToReg) { assert(TargetRegisterInfo::isVirtualRegister(FromReg)); @@ -3127,7 +3093,6 @@ void HexagonConstEvaluator::replaceAllRegUsesWith(unsigned FromReg, } } - bool HexagonConstEvaluator::rewriteHexBranch(MachineInstr &BrI, const CellMap &Inputs) { MachineBasicBlock &B = *BrI.getParent(); @@ -3179,9 +3144,6 @@ bool HexagonConstEvaluator::rewriteHexBranch(MachineInstr &BrI, return true; } - -// -------------------------------------------------------------------- FunctionPass *llvm::createHexagonConstPropagationPass() { return new HexagonConstPropagation(); } - diff --git a/llvm/lib/Target/Hexagon/HexagonEarlyIfConv.cpp b/llvm/lib/Target/Hexagon/HexagonEarlyIfConv.cpp index d9a6f05c858..a5351cd08da 100644 --- a/llvm/lib/Target/Hexagon/HexagonEarlyIfConv.cpp +++ b/llvm/lib/Target/Hexagon/HexagonEarlyIfConv.cpp @@ -61,32 +61,46 @@ #define DEBUG_TYPE "hexagon-eif" +#include "Hexagon.h" +#include "HexagonInstrInfo.h" +#include "HexagonSubtarget.h" #include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineBranchProbabilityInfo.h" #include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/Passes.h" +#include "llvm/IR/DebugLoc.h" +#include "llvm/Pass.h" +#include "llvm/Support/BranchProbability.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "HexagonTargetMachine.h" - -#include <functional> +#include "llvm/Target/TargetRegisterInfo.h" +#include <cassert> +#include <iterator> using namespace llvm; namespace llvm { + FunctionPass *createHexagonEarlyIfConversion(); void initializeHexagonEarlyIfConversionPass(PassRegistry& Registry); -} + +} // end namespace llvm namespace { + cl::opt<bool> EnableHexagonBP("enable-hexagon-br-prob", cl::Hidden, cl::init(false), cl::desc("Enable branch probability info")); cl::opt<unsigned> SizeLimit("eif-limit", cl::init(6), cl::Hidden, @@ -103,18 +117,22 @@ namespace { } struct FlowPattern { - FlowPattern() : SplitB(0), TrueB(0), FalseB(0), JoinB(0), PredR(0) {} + FlowPattern() = default; FlowPattern(MachineBasicBlock *B, unsigned PR, MachineBasicBlock *TB, MachineBasicBlock *FB, MachineBasicBlock *JB) : SplitB(B), TrueB(TB), FalseB(FB), JoinB(JB), PredR(PR) {} - MachineBasicBlock *SplitB; - MachineBasicBlock *TrueB, *FalseB, *JoinB; - unsigned PredR; + MachineBasicBlock *SplitB = nullptr; + MachineBasicBlock *TrueB = nullptr; + MachineBasicBlock *FalseB = nullptr; + MachineBasicBlock *JoinB = nullptr; + unsigned PredR = 0; }; + struct PrintFP { PrintFP(const FlowPattern &P, const TargetRegisterInfo &T) : FP(P), TRI(T) {} + const FlowPattern &FP; const TargetRegisterInfo &TRI; friend raw_ostream &operator<< (raw_ostream &OS, const PrintFP &P); @@ -133,13 +151,17 @@ namespace { class HexagonEarlyIfConversion : public MachineFunctionPass { public: static char ID; + HexagonEarlyIfConversion() : MachineFunctionPass(ID), - HII(0), TRI(0), MFN(0), MRI(0), MDT(0), MLI(0) { + HII(nullptr), TRI(nullptr), MFN(nullptr), MRI(nullptr), MDT(nullptr), + MLI(nullptr) { initializeHexagonEarlyIfConversionPass(*PassRegistry::getPassRegistry()); } + StringRef getPassName() const override { return "Hexagon early if conversion"; } + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired<MachineBranchProbabilityInfo>(); AU.addRequired<MachineDominatorTree>(); @@ -147,6 +169,7 @@ namespace { AU.addRequired<MachineLoopInfo>(); MachineFunctionPass::getAnalysisUsage(AU); } + bool runOnMachineFunction(MachineFunction &MF) override; private: @@ -196,7 +219,8 @@ namespace { }; char HexagonEarlyIfConversion::ID = 0; -} + +} // end anonymous namespace INITIALIZE_PASS(HexagonEarlyIfConversion, "hexagon-eif", "Hexagon early if conversion", false, false) @@ -209,7 +233,6 @@ bool HexagonEarlyIfConversion::isPreheader(const MachineBasicBlock *B) const { return L && SB == L->getHeader(); } - bool HexagonEarlyIfConversion::matchFlowPattern(MachineBasicBlock *B, MachineLoop *L, FlowPattern &FP) { DEBUG(dbgs() << "Checking flow pattern at BB#" << B->getNumber() << "\n"); @@ -217,7 +240,7 @@ bool HexagonEarlyIfConversion::matchFlowPattern(MachineBasicBlock *B, // Interested only in conditional branches, no .new, no new-value, etc. // Check the terminators directly, it's easier than handling all responses // from AnalyzeBranch. - MachineBasicBlock *TB = 0, *FB = 0; + MachineBasicBlock *TB = nullptr, *FB = nullptr; MachineBasicBlock::const_iterator T1I = B->getFirstTerminator(); if (T1I == B->end()) return false; @@ -228,7 +251,7 @@ bool HexagonEarlyIfConversion::matchFlowPattern(MachineBasicBlock *B, // Get the layout successor, or 0 if B does not have one. MachineFunction::iterator NextBI = std::next(MachineFunction::iterator(B)); - MachineBasicBlock *NextB = (NextBI != MFN->end()) ? &*NextBI : 0; + MachineBasicBlock *NextB = (NextBI != MFN->end()) ? &*NextBI : nullptr; MachineBasicBlock *T1B = T1I->getOperand(1).getMBB(); MachineBasicBlock::const_iterator T2I = std::next(T1I); @@ -273,9 +296,9 @@ bool HexagonEarlyIfConversion::matchFlowPattern(MachineBasicBlock *B, if (!TOk && !FOk) return false; - MachineBasicBlock *TSB = (TNS > 0) ? *TB->succ_begin() : 0; - MachineBasicBlock *FSB = (FNS > 0) ? *FB->succ_begin() : 0; - MachineBasicBlock *JB = 0; + MachineBasicBlock *TSB = (TNS > 0) ? *TB->succ_begin() : nullptr; + MachineBasicBlock *FSB = (FNS > 0) ? *FB->succ_begin() : nullptr; + MachineBasicBlock *JB = nullptr; if (TOk) { if (FOk) { @@ -286,14 +309,14 @@ bool HexagonEarlyIfConversion::matchFlowPattern(MachineBasicBlock *B, // TOk && !FOk if (TSB == FB) { JB = FB; - FB = 0; + FB = nullptr; } } } else { // !TOk && FOk (at least one must be true by now). if (FSB == TB) { JB = TB; - TB = 0; + TB = nullptr; } } // Don't try to predicate loop preheaders. @@ -308,7 +331,6 @@ bool HexagonEarlyIfConversion::matchFlowPattern(MachineBasicBlock *B, return true; } - // KLUDGE: HexagonInstrInfo::AnalyzeBranch won't work on a block that // contains EH_LABEL. bool HexagonEarlyIfConversion::hasEHLabel(const MachineBasicBlock *B) const { @@ -318,7 +340,6 @@ bool HexagonEarlyIfConversion::hasEHLabel(const MachineBasicBlock *B) const { return false; } - // KLUDGE: HexagonInstrInfo::AnalyzeBranch may be unable to recognize // that a block can never fall-through. bool HexagonEarlyIfConversion::hasUncondBranch(const MachineBasicBlock *B) @@ -332,7 +353,6 @@ bool HexagonEarlyIfConversion::hasUncondBranch(const MachineBasicBlock *B) return false; } - bool HexagonEarlyIfConversion::isValidCandidate(const MachineBasicBlock *B) const { if (!B) @@ -373,7 +393,6 @@ bool HexagonEarlyIfConversion::isValidCandidate(const MachineBasicBlock *B) return true; } - bool HexagonEarlyIfConversion::usesUndefVReg(const MachineInstr *MI) const { for (const MachineOperand &MO : MI->operands()) { if (!MO.isReg() || !MO.isUse()) @@ -390,7 +409,6 @@ bool HexagonEarlyIfConversion::usesUndefVReg(const MachineInstr *MI) const { return false; } - bool HexagonEarlyIfConversion::isValid(const FlowPattern &FP) const { if (hasEHLabel(FP.SplitB)) // KLUDGE: see function definition return false; @@ -424,7 +442,6 @@ bool HexagonEarlyIfConversion::isValid(const FlowPattern &FP) const { return true; } - unsigned HexagonEarlyIfConversion::computePhiCost(MachineBasicBlock *B) const { assert(B->pred_size() <= 2); if (B->pred_size() < 2) @@ -449,7 +466,6 @@ unsigned HexagonEarlyIfConversion::computePhiCost(MachineBasicBlock *B) const { return Cost; } - unsigned HexagonEarlyIfConversion::countPredicateDefs( const MachineBasicBlock *B) const { unsigned PredDefs = 0; @@ -467,7 +483,6 @@ unsigned HexagonEarlyIfConversion::countPredicateDefs( return PredDefs; } - bool HexagonEarlyIfConversion::isProfitable(const FlowPattern &FP) const { if (FP.TrueB && FP.FalseB) { @@ -547,7 +562,6 @@ bool HexagonEarlyIfConversion::isProfitable(const FlowPattern &FP) const { return true; } - bool HexagonEarlyIfConversion::visitBlock(MachineBasicBlock *B, MachineLoop *L) { bool Changed = false; @@ -593,9 +607,8 @@ bool HexagonEarlyIfConversion::visitBlock(MachineBasicBlock *B, return true; } - bool HexagonEarlyIfConversion::visitLoop(MachineLoop *L) { - MachineBasicBlock *HB = L ? L->getHeader() : 0; + MachineBasicBlock *HB = L ? L->getHeader() : nullptr; DEBUG((L ? dbgs() << "Visiting loop H:" << PrintMB(HB) : dbgs() << "Visiting function") << "\n"); bool Changed = false; @@ -609,7 +622,6 @@ bool HexagonEarlyIfConversion::visitLoop(MachineLoop *L) { return Changed; } - bool HexagonEarlyIfConversion::isPredicableStore(const MachineInstr *MI) const { // HexagonInstrInfo::isPredicable will consider these stores are non- @@ -634,7 +646,6 @@ bool HexagonEarlyIfConversion::isPredicableStore(const MachineInstr *MI) return MI->mayStore() && HII->isPredicable(const_cast<MachineInstr&>(*MI)); } - bool HexagonEarlyIfConversion::isSafeToSpeculate(const MachineInstr *MI) const { if (MI->mayLoad() || MI->mayStore()) @@ -647,13 +658,11 @@ bool HexagonEarlyIfConversion::isSafeToSpeculate(const MachineInstr *MI) return true; } - unsigned HexagonEarlyIfConversion::getCondStoreOpcode(unsigned Opc, bool IfTrue) const { return HII->getCondOpcode(Opc, !IfTrue); } - void HexagonEarlyIfConversion::predicateInstr(MachineBasicBlock *ToB, MachineBasicBlock::iterator At, MachineInstr *MI, unsigned PredR, bool IfTrue) { @@ -704,7 +713,6 @@ void HexagonEarlyIfConversion::predicateInstr(MachineBasicBlock *ToB, llvm_unreachable("Unexpected instruction"); } - // Predicate/speculate non-branch instructions from FromB into block ToB. // Leave the branches alone, they will be handled later. Btw, at this point // FromB should have at most one branch, and it should be unconditional. @@ -725,7 +733,6 @@ void HexagonEarlyIfConversion::predicateBlockNB(MachineBasicBlock *ToB, } } - void HexagonEarlyIfConversion::updatePhiNodes(MachineBasicBlock *WhereB, const FlowPattern &FP) { // Visit all PHI nodes in the WhereB block and generate MUX instructions @@ -755,6 +762,7 @@ void HexagonEarlyIfConversion::updatePhiNodes(MachineBasicBlock *WhereB, assert(TR && FR); using namespace Hexagon; + unsigned DR = PN->getOperand(0).getReg(); const TargetRegisterClass *RC = MRI->getRegClass(DR); unsigned Opc = 0; @@ -789,9 +797,8 @@ void HexagonEarlyIfConversion::updatePhiNodes(MachineBasicBlock *WhereB, } } - void HexagonEarlyIfConversion::convert(const FlowPattern &FP) { - MachineBasicBlock *TSB = 0, *FSB = 0; + MachineBasicBlock *TSB = nullptr, *FSB = nullptr; MachineBasicBlock::iterator OldTI = FP.SplitB->getFirstTerminator(); assert(OldTI != FP.SplitB->end()); DebugLoc DL = OldTI->getDebugLoc(); @@ -809,7 +816,7 @@ void HexagonEarlyIfConversion::convert(const FlowPattern &FP) { // Regenerate new terminators in the split block and update the successors. // First, remember any information that may be needed later and remove the // existing terminators/successors from the split block. - MachineBasicBlock *SSB = 0; + MachineBasicBlock *SSB = nullptr; FP.SplitB->erase(OldTI, FP.SplitB->end()); while (FP.SplitB->succ_size() > 0) { MachineBasicBlock *T = *FP.SplitB->succ_begin(); @@ -885,7 +892,6 @@ void HexagonEarlyIfConversion::convert(const FlowPattern &FP) { } } - void HexagonEarlyIfConversion::removeBlock(MachineBasicBlock *B) { DEBUG(dbgs() << "Removing block " << PrintMB(B) << "\n"); @@ -914,7 +920,6 @@ void HexagonEarlyIfConversion::removeBlock(MachineBasicBlock *B) { MFN->erase(B->getIterator()); } - void HexagonEarlyIfConversion::eliminatePhis(MachineBasicBlock *B) { DEBUG(dbgs() << "Removing phi nodes from block " << PrintMB(B) << "\n"); MachineBasicBlock::iterator I, NextI, NonPHI = B->getFirstNonPHI(); @@ -941,7 +946,6 @@ void HexagonEarlyIfConversion::eliminatePhis(MachineBasicBlock *B) { } } - void HexagonEarlyIfConversion::replacePhiEdges(MachineBasicBlock *OldB, MachineBasicBlock *NewB) { for (auto I = OldB->succ_begin(), E = OldB->succ_end(); I != E; ++I) { @@ -956,7 +960,6 @@ void HexagonEarlyIfConversion::replacePhiEdges(MachineBasicBlock *OldB, } } - void HexagonEarlyIfConversion::mergeBlocks(MachineBasicBlock *PredB, MachineBasicBlock *SuccB) { DEBUG(dbgs() << "Merging blocks " << PrintMB(PredB) << " and " @@ -976,7 +979,6 @@ void HexagonEarlyIfConversion::mergeBlocks(MachineBasicBlock *PredB, PredB->updateTerminator(); } - void HexagonEarlyIfConversion::simplifyFlowGraph(const FlowPattern &FP) { if (FP.TrueB) removeBlock(FP.TrueB); @@ -1000,7 +1002,6 @@ void HexagonEarlyIfConversion::simplifyFlowGraph(const FlowPattern &FP) { mergeBlocks(FP.SplitB, SB); } - bool HexagonEarlyIfConversion::runOnMachineFunction(MachineFunction &MF) { if (skipFunction(*MF.getFunction())) return false; @@ -1020,7 +1021,7 @@ bool HexagonEarlyIfConversion::runOnMachineFunction(MachineFunction &MF) { for (MachineLoopInfo::iterator I = MLI->begin(), E = MLI->end(); I != E; ++I) Changed |= visitLoop(*I); - Changed |= visitLoop(0); + Changed |= visitLoop(nullptr); return Changed; } @@ -1031,4 +1032,3 @@ bool HexagonEarlyIfConversion::runOnMachineFunction(MachineFunction &MF) { FunctionPass *llvm::createHexagonEarlyIfConversion() { return new HexagonEarlyIfConversion(); } - diff --git a/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp b/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp index a94c9080a56..f0e9c594dbf 100644 --- a/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp +++ b/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp @@ -88,23 +88,30 @@ #define DEBUG_TYPE "expand-condsets" -#include "HexagonTargetMachine.h" +#include "HexagonInstrInfo.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SetVector.h" -#include "llvm/CodeGen/Passes.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/CodeGen/LiveInterval.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" +#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/CodeGen/SlotIndexes.h" +#include "llvm/IR/DebugLoc.h" +#include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" - -#include <algorithm> +#include "llvm/Target/TargetRegisterInfo.h" +#include <cassert> #include <iterator> #include <set> #include <utility> @@ -117,17 +124,21 @@ static cl::opt<unsigned> OptCoaLimit("expand-condsets-coa-limit", cl::init(~0U), cl::Hidden, cl::desc("Max number of segment coalescings")); namespace llvm { + void initializeHexagonExpandCondsetsPass(PassRegistry&); FunctionPass *createHexagonExpandCondsets(); -} + +} // end namespace llvm namespace { + class HexagonExpandCondsets : public MachineFunctionPass { public: static char ID; + HexagonExpandCondsets() : - MachineFunctionPass(ID), HII(0), TRI(0), MRI(0), - LIS(0), CoaLimitActive(false), + MachineFunctionPass(ID), HII(nullptr), TRI(nullptr), MRI(nullptr), + LIS(nullptr), CoaLimitActive(false), TfrLimitActive(false), CoaCounter(0), TfrCounter(0) { if (OptCoaLimit.getPosition()) CoaLimitActive = true, CoaLimit = OptCoaLimit; @@ -137,6 +148,7 @@ namespace { } StringRef getPassName() const override { return "Hexagon Expand Condsets"; } + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired<LiveIntervals>(); AU.addPreserved<LiveIntervals>(); @@ -145,6 +157,7 @@ namespace { AU.addPreserved<MachineDominatorTree>(); MachineFunctionPass::getAnalysisUsage(AU); } + bool runOnMachineFunction(MachineFunction &MF) override; private: @@ -161,6 +174,7 @@ namespace { RegisterRef(const MachineOperand &Op) : Reg(Op.getReg()), Sub(Op.getSubReg()) {} RegisterRef(unsigned R = 0, unsigned S = 0) : Reg(R), Sub(S) {} + bool operator== (RegisterRef RR) const { return Reg == RR.Reg && Sub == RR.Sub; } @@ -168,6 +182,7 @@ namespace { bool operator< (RegisterRef RR) const { return Reg < RR.Reg || (Reg == RR.Reg && Sub < RR.Sub); } + unsigned Reg, Sub; }; @@ -218,13 +233,16 @@ namespace { bool coalesceSegments(const SmallVectorImpl<MachineInstr*> &Condsets, std::set<unsigned> &UpdRegs); }; -} + +} // end anonymous namespace char HexagonExpandCondsets::ID = 0; namespace llvm { + char &HexagonExpandCondsetsID = HexagonExpandCondsets::ID; -} + +} // end namespace llvm INITIALIZE_PASS_BEGIN(HexagonExpandCondsets, "expand-condsets", "Hexagon Expand Condsets", false, false) @@ -262,14 +280,12 @@ bool HexagonExpandCondsets::isCondset(const MachineInstr &MI) { return false; } - LaneBitmask HexagonExpandCondsets::getLaneMask(unsigned Reg, unsigned Sub) { assert(TargetRegisterInfo::isVirtualRegister(Reg)); return Sub != 0 ? TRI->getSubRegIndexLaneMask(Sub) : MRI->getMaxLaneMaskForVReg(Reg); } - void HexagonExpandCondsets::addRefToMap(RegisterRef RR, ReferenceMap &Map, unsigned Exec) { unsigned Mask = getMaskForSub(RR.Sub) | Exec; @@ -280,7 +296,6 @@ void HexagonExpandCondsets::addRefToMap(RegisterRef RR, ReferenceMap &Map, F->second |= Mask; } - bool HexagonExpandCondsets::isRefInMap(RegisterRef RR, ReferenceMap &Map, unsigned Exec) { ReferenceMap::iterator F = Map.find(RR.Reg); @@ -292,7 +307,6 @@ bool HexagonExpandCondsets::isRefInMap(RegisterRef RR, ReferenceMap &Map, return false; } - void HexagonExpandCondsets::updateKillFlags(unsigned Reg) { auto KillAt = [this,Reg] (SlotIndex K, LaneBitmask LM) -> void { // Set the <kill> flag on a use of Reg whose lane mask is contained in LM. @@ -342,7 +356,6 @@ void HexagonExpandCondsets::updateKillFlags(unsigned Reg) { } } - void HexagonExpandCondsets::updateDeadsInRange(unsigned Reg, LaneBitmask LM, LiveRange &Range) { assert(TargetRegisterInfo::isVirtualRegister(Reg)); @@ -475,7 +488,6 @@ void HexagonExpandCondsets::updateDeadsInRange(unsigned Reg, LaneBitmask LM, } } - void HexagonExpandCondsets::updateDeadFlags(unsigned Reg) { LiveInterval &LI = LIS->getInterval(Reg); if (LI.hasSubRanges()) { @@ -490,19 +502,16 @@ void HexagonExpandCondsets::updateDeadFlags(unsigned Reg) { } } - void HexagonExpandCondsets::recalculateLiveInterval(unsigned Reg) { LIS->removeInterval(Reg); LIS->createAndComputeVirtRegInterval(Reg); } - void HexagonExpandCondsets::removeInstr(MachineInstr &MI) { LIS->RemoveMachineInstrFromMaps(MI); MI.eraseFromParent(); } - void HexagonExpandCondsets::updateLiveness(std::set<unsigned> &RegSet, bool Recalc, bool UpdateKills, bool UpdateDeads) { UpdateKills |= UpdateDeads; @@ -521,12 +530,12 @@ void HexagonExpandCondsets::updateLiveness(std::set<unsigned> &RegSet, } } - /// Get the opcode for a conditional transfer of the value in SO (source /// operand). The condition (true/false) is given in Cond. unsigned HexagonExpandCondsets::getCondTfrOpcode(const MachineOperand &SO, bool IfTrue) { using namespace Hexagon; + if (SO.isReg()) { unsigned PhysR; RegisterRef RS = SO; @@ -553,7 +562,6 @@ unsigned HexagonExpandCondsets::getCondTfrOpcode(const MachineOperand &SO, llvm_unreachable("Unexpected source operand"); } - /// Generate a conditional transfer, copying the value SrcOp to the /// destination register DstR:DstSR, and using the predicate register from /// PredOp. The Cond argument specifies whether the predicate is to be @@ -596,7 +604,6 @@ MachineInstr *HexagonExpandCondsets::genCondTfrFor(MachineOperand &SrcOp, return &*MIB; } - /// Replace a MUX instruction MI with a pair A2_tfrt/A2_tfrf. This function /// performs all necessary changes to complete the replacement. bool HexagonExpandCondsets::split(MachineInstr &MI, @@ -672,7 +679,6 @@ bool HexagonExpandCondsets::isPredicable(MachineInstr *MI) { return true; } - /// Find the reaching definition for a predicated use of RD. The RD is used /// under the conditions given by PredR and Cond, and this function will ignore /// definitions that set RD under the opposite conditions. @@ -681,7 +687,7 @@ MachineInstr *HexagonExpandCondsets::getReachingDefForPred(RegisterRef RD, MachineBasicBlock &B = *UseIt->getParent(); MachineBasicBlock::iterator I = UseIt, S = B.begin(); if (I == S) - return 0; + return nullptr; bool PredValid = true; do { @@ -712,15 +718,14 @@ MachineInstr *HexagonExpandCondsets::getReachingDefForPred(RegisterRef RD, if (RR.Sub == RD.Sub) return MI; if (RR.Sub == 0 || RD.Sub == 0) - return 0; + return nullptr; // We have different subregisters, so we can continue looking. } } while (I != S); - return 0; + return nullptr; } - /// Check if the instruction MI can be safely moved over a set of instructions /// whose side-effects (in terms of register defs and uses) are expressed in /// the maps Defs and Uses. These maps reflect the conditional defs and uses @@ -750,7 +755,6 @@ bool HexagonExpandCondsets::canMoveOver(MachineInstr &MI, ReferenceMap &Defs, return true; } - /// Check if the instruction accessing memory (TheI) can be moved to the /// location ToI. bool HexagonExpandCondsets::canMoveMemTo(MachineInstr &TheI, MachineInstr &ToI, @@ -785,7 +789,6 @@ bool HexagonExpandCondsets::canMoveMemTo(MachineInstr &TheI, MachineInstr &ToI, return true; } - /// Generate a predicated version of MI (where the condition is given via /// PredR and Cond) at the point indicated by Where. void HexagonExpandCondsets::predicateAt(const MachineOperand &DefOp, @@ -846,7 +849,6 @@ void HexagonExpandCondsets::predicateAt(const MachineOperand &DefOp, UpdRegs.insert(Op.getReg()); } - /// In the range [First, Last], rename all references to the "old" register RO /// to the "new" register RN, but only in instructions predicated on the given /// condition. @@ -874,7 +876,6 @@ void HexagonExpandCondsets::renameInRange(RegisterRef RO, RegisterRef RN, } } - /// For a given conditional copy, predicate the definition of the source of /// the copy under the given condition (using the same predicate register as /// the copy). @@ -919,7 +920,7 @@ bool HexagonExpandCondsets::predicate(MachineInstr &TfrI, bool Cond, // conditions when collecting def and use information. bool PredValid = true; for (MachineBasicBlock::iterator I = std::next(DefIt); I != TfrIt; ++I) { - if (!I->modifiesRegister(PredR, 0)) + if (!I->modifiesRegister(PredR, nullptr)) continue; PredValid = false; break; @@ -1011,7 +1012,6 @@ bool HexagonExpandCondsets::predicate(MachineInstr &TfrI, bool Cond, return true; } - /// Predicate all cases of conditional copies in the specified block. bool HexagonExpandCondsets::predicateInBlock(MachineBasicBlock &B, std::set<unsigned> &UpdRegs) { @@ -1038,7 +1038,6 @@ bool HexagonExpandCondsets::predicateInBlock(MachineBasicBlock &B, return Changed; } - bool HexagonExpandCondsets::isIntReg(RegisterRef RR, unsigned &BW) { if (!TargetRegisterInfo::isVirtualRegister(RR.Reg)) return false; @@ -1054,7 +1053,6 @@ bool HexagonExpandCondsets::isIntReg(RegisterRef RR, unsigned &BW) { return false; } - bool HexagonExpandCondsets::isIntraBlocks(LiveInterval &LI) { for (LiveInterval::iterator I = LI.begin(), E = LI.end(); I != E; ++I) { LiveRange::Segment &LR = *I; @@ -1068,7 +1066,6 @@ bool HexagonExpandCondsets::isIntraBlocks(LiveInterval &LI) { return true; } - bool HexagonExpandCondsets::coalesceRegisters(RegisterRef R1, RegisterRef R2) { if (CoaLimitActive) { if (CoaCounter >= CoaLimit) @@ -1133,7 +1130,6 @@ bool HexagonExpandCondsets::coalesceRegisters(RegisterRef R1, RegisterRef R2) { return true; } - /// Attempt to coalesce one of the source registers to a MUX instruction with /// the destination register. This could lead to having only one predicated /// instruction in the end instead of two. @@ -1199,7 +1195,6 @@ bool HexagonExpandCondsets::coalesceSegments( return Changed; } - bool HexagonExpandCondsets::runOnMachineFunction(MachineFunction &MF) { if (skipFunction(*MF.getFunction())) return false; @@ -1279,7 +1274,6 @@ bool HexagonExpandCondsets::runOnMachineFunction(MachineFunction &MF) { return Changed; } - //===----------------------------------------------------------------------===// // Public Constructor Functions //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/Hexagon/HexagonGenExtract.cpp b/llvm/lib/Target/Hexagon/HexagonGenExtract.cpp index 5737f3f50b4..bb5e379ce01 100644 --- a/llvm/lib/Target/Hexagon/HexagonGenExtract.cpp +++ b/llvm/lib/Target/Hexagon/HexagonGenExtract.cpp @@ -7,19 +7,25 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/CFG.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" +#include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" -#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Intrinsics.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/PatternMatch.h" +#include "llvm/IR/Type.h" +#include "llvm/IR/Value.h" #include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cstdint> +#include <iterator> using namespace llvm; @@ -40,27 +46,34 @@ static cl::opt<bool> NeedAnd("extract-needand", cl::init(true), cl::Hidden, cl::desc("Require & in extract patterns")); namespace llvm { + void initializeHexagonGenExtractPass(PassRegistry&); FunctionPass *createHexagonGenExtract(); -} +} // end namespace llvm namespace { + class HexagonGenExtract : public FunctionPass { public: static char ID; + HexagonGenExtract() : FunctionPass(ID), ExtractCount(0) { initializeHexagonGenExtractPass(*PassRegistry::getPassRegistry()); } - virtual StringRef getPassName() const override { + + StringRef getPassName() const override { return "Hexagon generate \"extract\" instructions"; } - virtual bool runOnFunction(Function &F) override; - virtual void getAnalysisUsage(AnalysisUsage &AU) const override { + + bool runOnFunction(Function &F) override; + + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired<DominatorTreeWrapperPass>(); AU.addPreserved<DominatorTreeWrapperPass>(); FunctionPass::getAnalysisUsage(AU); } + private: bool visitBlock(BasicBlock *B); bool convert(Instruction *In); @@ -70,7 +83,8 @@ namespace { }; char HexagonGenExtract::ID = 0; -} + +} // end anonymous namespace INITIALIZE_PASS_BEGIN(HexagonGenExtract, "hextract", "Hexagon generate " "\"extract\" instructions", false, false) @@ -78,11 +92,11 @@ INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_END(HexagonGenExtract, "hextract", "Hexagon generate " "\"extract\" instructions", false, false) - bool HexagonGenExtract::convert(Instruction *In) { using namespace PatternMatch; - Value *BF = 0; - ConstantInt *CSL = 0, *CSR = 0, *CM = 0; + + Value *BF = nullptr; + ConstantInt *CSL = nullptr, *CSR = nullptr, *CM = nullptr; BasicBlock *BB = In->getParent(); LLVMContext &Ctx = BB->getContext(); bool LogicalSR; @@ -124,14 +138,14 @@ bool HexagonGenExtract::convert(Instruction *In) { m_ConstantInt(CM))); } if (!Match) { - CM = 0; + CM = nullptr; // (shl (lshr x, #sr), #sl) LogicalSR = true; Match = match(In, m_Shl(m_LShr(m_Value(BF), m_ConstantInt(CSR)), m_ConstantInt(CSL))); } if (!Match) { - CM = 0; + CM = nullptr; // (shl (ashr x, #sr), #sl) LogicalSR = false; Match = match(In, m_Shl(m_AShr(m_Value(BF), m_ConstantInt(CSR)), @@ -205,7 +219,6 @@ bool HexagonGenExtract::convert(Instruction *In) { return true; } - bool HexagonGenExtract::visitBlock(BasicBlock *B) { // Depth-first, bottom-up traversal. DomTreeNode *DTN = DT->getNode(B); @@ -238,7 +251,6 @@ bool HexagonGenExtract::visitBlock(BasicBlock *B) { return Changed; } - bool HexagonGenExtract::runOnFunction(Function &F) { if (skipFunction(F)) return false; @@ -254,7 +266,6 @@ bool HexagonGenExtract::runOnFunction(Function &F) { return Changed; } - FunctionPass *llvm::createHexagonGenExtract() { return new HexagonGenExtract(); } diff --git a/llvm/lib/Target/Hexagon/HexagonGenInsert.cpp b/llvm/lib/Target/Hexagon/HexagonGenInsert.cpp index 6f2ccfb079c..5a8e392d127 100644 --- a/llvm/lib/Target/Hexagon/HexagonGenInsert.cpp +++ b/llvm/lib/Target/Hexagon/HexagonGenInsert.cpp @@ -9,29 +9,39 @@ #define DEBUG_TYPE "hexinsert" +#include "BitTracker.h" +#include "HexagonBitTracker.h" +#include "HexagonInstrInfo.h" +#include "HexagonRegisterInfo.h" +#include "HexagonSubtarget.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PostOrderIterator.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/IR/Constants.h" +#include "llvm/IR/DebugLoc.h" #include "llvm/Pass.h" -#include "llvm/PassRegistry.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/Timer.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetMachine.h" +#include "llvm/Support/Timer.h" #include "llvm/Target/TargetRegisterInfo.h" - -#include "Hexagon.h" -#include "HexagonRegisterInfo.h" -#include "HexagonTargetMachine.h" -#include "HexagonBitTracker.h" - +#include <algorithm> +#include <cassert> +#include <cstdint> +#include <iterator> +#include <utility> #include <vector> using namespace llvm; @@ -59,20 +69,18 @@ static cl::opt<bool> OptSelectHas0("insert-has0", cl::init(false), cl::Hidden, static cl::opt<bool> OptConst("insert-const", cl::init(false), cl::Hidden, cl::ZeroOrMore); -namespace { - // The preprocessor gets confused when the DEBUG macro is passed larger - // chunks of code. Use this function to detect debugging. - inline bool isDebug() { +// The preprocessor gets confused when the DEBUG macro is passed larger +// chunks of code. Use this function to detect debugging. +inline static bool isDebug() { #ifndef NDEBUG - return ::llvm::DebugFlag && ::llvm::isCurrentDebugType(DEBUG_TYPE); + return DebugFlag && isCurrentDebugType(DEBUG_TYPE); #else - return false; + return false; #endif - } } - namespace { + // Set of virtual registers, based on BitVector. struct RegisterSet : private BitVector { RegisterSet() = default; @@ -146,20 +154,23 @@ namespace { if (size() <= Idx) resize(std::max(Idx+1, 32U)); } + static inline unsigned v2x(unsigned v) { return TargetRegisterInfo::virtReg2Index(v); } + static inline unsigned x2v(unsigned x) { return TargetRegisterInfo::index2VirtReg(x); } }; - struct PrintRegSet { PrintRegSet(const RegisterSet &S, const TargetRegisterInfo *RI) : RS(S), TRI(RI) {} + friend raw_ostream &operator<< (raw_ostream &OS, const PrintRegSet &P); + private: const RegisterSet &RS; const TargetRegisterInfo *TRI; @@ -172,14 +183,12 @@ namespace { OS << " }"; return OS; } -} - -namespace { // A convenience class to associate unsigned numbers (such as virtual // registers) with unsigned numbers. struct UnsignedMap : public DenseMap<unsigned,unsigned> { - UnsignedMap() : BaseType() {} + UnsignedMap() = default; + private: typedef DenseMap<unsigned,unsigned> BaseType; }; @@ -190,22 +199,21 @@ namespace { // by a potentially expensive comparison function, or obtained by a proce- // dure that should not be repeated each time two registers are compared. struct RegisterOrdering : public UnsignedMap { - RegisterOrdering() : UnsignedMap() {} + RegisterOrdering() = default; + unsigned operator[](unsigned VR) const { const_iterator F = find(VR); assert(F != end()); return F->second; } + // Add operator(), so that objects of this class can be used as // comparators in std::sort et al. bool operator() (unsigned VR1, unsigned VR2) const { return operator[](VR1) < operator[](VR2); } }; -} - -namespace { // Ordering of bit values. This class does not have operator[], but // is supplies a comparison operator() for use in std:: algorithms. // The order is as follows: @@ -214,12 +222,14 @@ namespace { // or ord(ref1.Reg) == ord(ref2.Reg), and ref1.Pos < ref2.Pos. struct BitValueOrdering { BitValueOrdering(const RegisterOrdering &RB) : BaseOrd(RB) {} + bool operator() (const BitTracker::BitValue &V1, const BitTracker::BitValue &V2) const; + const RegisterOrdering &BaseOrd; }; -} +} // end anonymous namespace bool BitValueOrdering::operator() (const BitTracker::BitValue &V1, const BitTracker::BitValue &V2) const { @@ -241,20 +251,21 @@ bool BitValueOrdering::operator() (const BitTracker::BitValue &V1, return V1.RefI.Pos < V2.RefI.Pos; } - namespace { + // Cache for the BitTracker's cell map. Map lookup has a logarithmic // complexity, this class will memoize the lookup results to reduce // the access time for repeated lookups of the same cell. struct CellMapShadow { CellMapShadow(const BitTracker &T) : BT(T) {} + const BitTracker::RegisterCell &lookup(unsigned VR) { unsigned RInd = TargetRegisterInfo::virtReg2Index(VR); // Grow the vector to at least 32 elements. if (RInd >= CVect.size()) - CVect.resize(std::max(RInd+16, 32U), 0); + CVect.resize(std::max(RInd+16, 32U), nullptr); const BitTracker::RegisterCell *CP = CVect[RInd]; - if (CP == 0) + if (CP == nullptr) CP = CVect[RInd] = &BT.lookup(VR); return *CP; } @@ -265,16 +276,15 @@ namespace { typedef std::vector<const BitTracker::RegisterCell*> CellVectType; CellVectType CVect; }; -} - -namespace { // Comparator class for lexicographic ordering of virtual registers // according to the corresponding BitTracker::RegisterCell objects. struct RegisterCellLexCompare { RegisterCellLexCompare(const BitValueOrdering &BO, CellMapShadow &M) : BitOrd(BO), CM(M) {} + bool operator() (unsigned VR1, unsigned VR2) const; + private: const BitValueOrdering &BitOrd; CellMapShadow &CM; @@ -290,15 +300,17 @@ namespace { RegisterCellBitCompareSel(unsigned R, unsigned B, unsigned N, const BitValueOrdering &BO, CellMapShadow &M) : SelR(R), SelB(B), BitN(N), BitOrd(BO), CM(M) {} + bool operator() (unsigned VR1, unsigned VR2) const; + private: const unsigned SelR, SelB; const unsigned BitN; const BitValueOrdering &BitOrd; CellMapShadow &CM; }; -} +} // end anonymous namespace bool RegisterCellLexCompare::operator() (unsigned VR1, unsigned VR2) const { // Ordering of registers, made up from two given orderings: @@ -327,7 +339,6 @@ bool RegisterCellLexCompare::operator() (unsigned VR1, unsigned VR2) const { return BitOrd.BaseOrd[VR1] < BitOrd.BaseOrd[VR2]; } - bool RegisterCellBitCompareSel::operator() (unsigned VR1, unsigned VR2) const { if (VR1 == VR2) return false; @@ -353,18 +364,22 @@ bool RegisterCellBitCompareSel::operator() (unsigned VR1, unsigned VR2) const { return false; } - namespace { + class OrderedRegisterList { typedef std::vector<unsigned> ListType; + public: OrderedRegisterList(const RegisterOrdering &RO) : Ord(RO) {} + void insert(unsigned VR); void remove(unsigned VR); + unsigned operator[](unsigned Idx) const { assert(Idx < Seq.size()); return Seq[Idx]; } + unsigned size() const { return Seq.size(); } @@ -378,16 +393,18 @@ namespace { // Convenience function to convert an iterator to the corresponding index. unsigned idx(iterator It) const { return It-begin(); } + private: ListType Seq; const RegisterOrdering &Ord; }; - struct PrintORL { PrintORL(const OrderedRegisterList &L, const TargetRegisterInfo *RI) : RL(L), TRI(RI) {} + friend raw_ostream &operator<< (raw_ostream &OS, const PrintORL &P); + private: const OrderedRegisterList &RL; const TargetRegisterInfo *TRI; @@ -404,8 +421,8 @@ namespace { OS << ')'; return OS; } -} +} // end anonymous namespace void OrderedRegisterList::insert(unsigned VR) { iterator L = std::lower_bound(Seq.begin(), Seq.end(), VR, Ord); @@ -415,21 +432,21 @@ void OrderedRegisterList::insert(unsigned VR) { Seq.insert(L, VR); } - void OrderedRegisterList::remove(unsigned VR) { iterator L = std::lower_bound(Seq.begin(), Seq.end(), VR, Ord); assert(L != Seq.end()); Seq.erase(L); } - namespace { + // A record of the insert form. The fields correspond to the operands // of the "insert" instruction: // ... = insert(SrcR, InsR, #Wdh, #Off) struct IFRecord { IFRecord(unsigned SR = 0, unsigned IR = 0, uint16_t W = 0, uint16_t O = 0) : SrcR(SR), InsR(IR), Wdh(W), Off(O) {} + unsigned SrcR, InsR; uint16_t Wdh, Off; }; @@ -437,10 +454,12 @@ namespace { struct PrintIFR { PrintIFR(const IFRecord &R, const TargetRegisterInfo *RI) : IFR(R), TRI(RI) {} + private: + friend raw_ostream &operator<< (raw_ostream &OS, const PrintIFR &P); + const IFRecord &IFR; const TargetRegisterInfo *TRI; - friend raw_ostream &operator<< (raw_ostream &OS, const PrintIFR &P); }; raw_ostream &operator<< (raw_ostream &OS, const PrintIFR &P) { @@ -451,31 +470,37 @@ namespace { } typedef std::pair<IFRecord,RegisterSet> IFRecordWithRegSet; -} +} // end anonymous namespace namespace llvm { + void initializeHexagonGenInsertPass(PassRegistry&); FunctionPass *createHexagonGenInsert(); -} +} // end namespace llvm namespace { + class HexagonGenInsert : public MachineFunctionPass { public: static char ID; - HexagonGenInsert() : MachineFunctionPass(ID), HII(0), HRI(0) { + + HexagonGenInsert() : MachineFunctionPass(ID), HII(nullptr), HRI(nullptr) { initializeHexagonGenInsertPass(*PassRegistry::getPassRegistry()); } - virtual StringRef getPassName() const { + + StringRef getPassName() const override { return "Hexagon generate \"insert\" instructions"; } - virtual void getAnalysisUsage(AnalysisUsage &AU) const { + + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired<MachineDominatorTree>(); AU.addPreserved<MachineDominatorTree>(); MachineFunctionPass::getAnalysisUsage(AU); } - virtual bool runOnMachineFunction(MachineFunction &MF); + + bool runOnMachineFunction(MachineFunction &MF) override; private: typedef DenseMap<std::pair<unsigned,unsigned>,unsigned> PairMapType; @@ -533,8 +558,8 @@ namespace { }; char HexagonGenInsert::ID = 0; -} +} // end anonymous namespace void HexagonGenInsert::dump_map() const { typedef IFMapType::const_iterator iterator; @@ -547,7 +572,6 @@ void HexagonGenInsert::dump_map() const { } } - void HexagonGenInsert::buildOrderingMF(RegisterOrdering &RO) const { unsigned Index = 0; typedef MachineFunction::const_iterator mf_iterator; @@ -574,7 +598,6 @@ void HexagonGenInsert::buildOrderingMF(RegisterOrdering &RO) const { // in the map. } - void HexagonGenInsert::buildOrderingBT(RegisterOrdering &RB, RegisterOrdering &RO) const { // Create a vector of all virtual registers (collect them from the base @@ -591,12 +614,10 @@ void HexagonGenInsert::buildOrderingBT(RegisterOrdering &RB, RO.insert(std::make_pair(VRs[i], i)); } - inline bool HexagonGenInsert::isIntClass(const TargetRegisterClass *RC) const { return RC == &Hexagon::IntRegsRegClass || RC == &Hexagon::DoubleRegsRegClass; } - bool HexagonGenInsert::isConstant(unsigned VR) const { const BitTracker::RegisterCell &RC = CMS->lookup(VR); uint16_t W = RC.width(); @@ -609,7 +630,6 @@ bool HexagonGenInsert::isConstant(unsigned VR) const { return true; } - bool HexagonGenInsert::isSmallConstant(unsigned VR) const { const BitTracker::RegisterCell &RC = CMS->lookup(VR); uint16_t W = RC.width(); @@ -633,7 +653,6 @@ bool HexagonGenInsert::isSmallConstant(unsigned VR) const { return isInt<8>(Lo_32(V)) && isInt<8>(Hi_32(V)); } - bool HexagonGenInsert::isValidInsertForm(unsigned DstR, unsigned SrcR, unsigned InsR, uint16_t L, uint16_t S) const { const TargetRegisterClass *DstRC = MRI->getRegClass(DstR); @@ -656,7 +675,6 @@ bool HexagonGenInsert::isValidInsertForm(unsigned DstR, unsigned SrcR, return true; } - bool HexagonGenInsert::findSelfReference(unsigned VR) const { const BitTracker::RegisterCell &RC = CMS->lookup(VR); for (uint16_t i = 0, w = RC.width(); i < w; ++i) { @@ -667,7 +685,6 @@ bool HexagonGenInsert::findSelfReference(unsigned VR) const { return false; } - bool HexagonGenInsert::findNonSelfReference(unsigned VR) const { BitTracker::RegisterCell RC = CMS->lookup(VR); for (uint16_t i = 0, w = RC.width(); i < w; ++i) { @@ -678,7 +695,6 @@ bool HexagonGenInsert::findNonSelfReference(unsigned VR) const { return false; } - void HexagonGenInsert::getInstrDefs(const MachineInstr *MI, RegisterSet &Defs) const { for (unsigned i = 0, n = MI->getNumOperands(); i < n; ++i) { @@ -692,7 +708,6 @@ void HexagonGenInsert::getInstrDefs(const MachineInstr *MI, } } - void HexagonGenInsert::getInstrUses(const MachineInstr *MI, RegisterSet &Uses) const { for (unsigned i = 0, n = MI->getNumOperands(); i < n; ++i) { @@ -706,7 +721,6 @@ void HexagonGenInsert::getInstrUses(const MachineInstr *MI, } } - unsigned HexagonGenInsert::distance(const MachineBasicBlock *FromB, const MachineBasicBlock *ToB, const UnsignedMap &RPO, PairMapType &M) const { @@ -740,7 +754,6 @@ unsigned HexagonGenInsert::distance(const MachineBasicBlock *FromB, return MaxD; } - unsigned HexagonGenInsert::distance(MachineBasicBlock::const_iterator FromI, MachineBasicBlock::const_iterator ToI, const UnsignedMap &RPO, PairMapType &M) const { @@ -753,7 +766,6 @@ unsigned HexagonGenInsert::distance(MachineBasicBlock::const_iterator FromI, return D1+D2+D3; } - bool HexagonGenInsert::findRecordInsertForms(unsigned VR, OrderedRegisterList &AVs) { if (isDebug()) { @@ -832,7 +844,6 @@ bool HexagonGenInsert::findRecordInsertForms(unsigned VR, } } - bool Recorded = false; for (iterator I = AVs.begin(), E = AVs.end(); I != E; ++I) { @@ -888,7 +899,6 @@ bool HexagonGenInsert::findRecordInsertForms(unsigned VR, return Recorded; } - void HexagonGenInsert::collectInBlock(MachineBasicBlock *B, OrderedRegisterList &AVs) { if (isDebug()) @@ -949,7 +959,6 @@ void HexagonGenInsert::collectInBlock(MachineBasicBlock *B, AVs.remove(VR); } - void HexagonGenInsert::findRemovableRegisters(unsigned VR, IFRecord IF, RegisterSet &RMs) const { // For a given register VR and a insert form, find the registers that are @@ -1001,7 +1010,6 @@ void HexagonGenInsert::findRemovableRegisters(unsigned VR, IFRecord IF, RMs.remove(VR); } - void HexagonGenInsert::computeRemovableRegisters() { for (IFMapType::iterator I = IFMap.begin(), E = IFMap.end(); I != E; ++I) { IFListType &LL = I->second; @@ -1010,21 +1018,19 @@ void HexagonGenInsert::computeRemovableRegisters() { } } - void HexagonGenInsert::pruneEmptyLists() { // Remove all entries from the map, where the register has no insert forms // associated with it. typedef SmallVector<IFMapType::iterator,16> IterListType; IterListType Prune; for (IFMapType::iterator I = IFMap.begin(), E = IFMap.end(); I != E; ++I) { - if (I->second.size() == 0) + if (I->second.empty()) Prune.push_back(I); } for (unsigned i = 0, n = Prune.size(); i < n; ++i) IFMap.erase(Prune[i]); } - void HexagonGenInsert::pruneCoveredSets(unsigned VR) { IFMapType::iterator F = IFMap.find(VR); assert(F != IFMap.end()); @@ -1052,7 +1058,7 @@ void HexagonGenInsert::pruneCoveredSets(unsigned VR) { auto IsEmpty = [] (const IFRecordWithRegSet &IR) -> bool { return IR.second.empty(); }; - auto End = remove_if(LL, IsEmpty); + auto End = llvm::remove_if(LL, IsEmpty); if (End != LL.end()) LL.erase(End, LL.end()); } else { @@ -1112,7 +1118,6 @@ void HexagonGenInsert::pruneCoveredSets(unsigned VR) { } } - void HexagonGenInsert::pruneUsesTooFar(unsigned VR, const UnsignedMap &RPO, PairMapType &M) { IFMapType::iterator F = IFMap.find(VR); @@ -1135,7 +1140,6 @@ void HexagonGenInsert::pruneUsesTooFar(unsigned VR, const UnsignedMap &RPO, } } - void HexagonGenInsert::pruneRegCopies(unsigned VR) { IFMapType::iterator F = IFMap.find(VR); assert(F != IFMap.end()); @@ -1144,12 +1148,11 @@ void HexagonGenInsert::pruneRegCopies(unsigned VR) { auto IsCopy = [] (const IFRecordWithRegSet &IR) -> bool { return IR.first.Wdh == 32 && (IR.first.Off == 0 || IR.first.Off == 32); }; - auto End = remove_if(LL, IsCopy); + auto End = llvm::remove_if(LL, IsCopy); if (End != LL.end()) LL.erase(End, LL.end()); } - void HexagonGenInsert::pruneCandidates() { // Remove candidates that are not beneficial, regardless of the final // selection method. @@ -1176,8 +1179,8 @@ void HexagonGenInsert::pruneCandidates() { pruneRegCopies(I->first); } - namespace { + // Class for comparing IF candidates for registers that have multiple of // them. The smaller the candidate, according to this ordering, the better. // First, compare the number of zeros in the associated potentially remova- @@ -1189,16 +1192,19 @@ namespace { struct IFOrdering { IFOrdering(const UnsignedMap &UC, const RegisterOrdering &BO) : UseC(UC), BaseOrd(BO) {} + bool operator() (const IFRecordWithRegSet &A, const IFRecordWithRegSet &B) const; + private: void stats(const RegisterSet &Rs, unsigned &Size, unsigned &Zero, unsigned &Sum) const; + const UnsignedMap &UseC; const RegisterOrdering &BaseOrd; }; -} +} // end anonymous namespace bool IFOrdering::operator() (const IFRecordWithRegSet &A, const IFRecordWithRegSet &B) const { @@ -1228,7 +1234,6 @@ bool IFOrdering::operator() (const IFRecordWithRegSet &A, return A.first.Off < B.first.Off; } - void IFOrdering::stats(const RegisterSet &Rs, unsigned &Size, unsigned &Zero, unsigned &Sum) const { for (unsigned R = Rs.find_first(); R; R = Rs.find_next(R)) { @@ -1242,7 +1247,6 @@ void IFOrdering::stats(const RegisterSet &Rs, unsigned &Size, unsigned &Zero, } } - void HexagonGenInsert::selectCandidates() { // Some registers may have multiple valid candidates. Pick the best one // (or decide not to use any). @@ -1280,7 +1284,6 @@ void HexagonGenInsert::selectCandidates() { UseC[R] = (C > D) ? C-D : 0; // doz } - bool SelectAll0 = OptSelectAll0, SelectHas0 = OptSelectHas0; if (!SelectAll0 && !SelectHas0) SelectAll0 = true; @@ -1345,12 +1348,12 @@ void HexagonGenInsert::selectCandidates() { AllRMs.clear(); for (IFMapType::iterator I = IFMap.begin(); I != End; ++I) { const IFListType &LL = I->second; - if (LL.size() > 0) + if (!LL.empty()) AllRMs.insert(LL[0].second); } for (IFMapType::iterator I = IFMap.begin(); I != End; ++I) { IFListType &LL = I->second; - if (LL.size() == 0) + if (LL.empty()) continue; unsigned SR = LL[0].first.SrcR, IR = LL[0].first.InsR; if (AllRMs[SR] || AllRMs[IR]) @@ -1360,7 +1363,6 @@ void HexagonGenInsert::selectCandidates() { pruneEmptyLists(); } - bool HexagonGenInsert::generateInserts() { // Create a new register for each one from IFMap, and store them in the // map. @@ -1418,7 +1420,6 @@ bool HexagonGenInsert::generateInserts() { return true; } - bool HexagonGenInsert::removeDeadCode(MachineDomTreeNode *N) { bool Changed = false; typedef GraphTraits<MachineDomTreeNode*> GTN; @@ -1467,7 +1468,6 @@ bool HexagonGenInsert::removeDeadCode(MachineDomTreeNode *N) { return Changed; } - bool HexagonGenInsert::runOnMachineFunction(MachineFunction &MF) { if (skipFunction(*MF.getFunction())) return false; @@ -1586,12 +1586,10 @@ bool HexagonGenInsert::runOnMachineFunction(MachineFunction &MF) { return true; } - FunctionPass *llvm::createHexagonGenInsert() { return new HexagonGenInsert(); } - //===----------------------------------------------------------------------===// // Public Constructor Functions //===----------------------------------------------------------------------===// |

