HexagonVectorPrint.cpp revision 327952
1105197Ssam//===- HexagonVectorPrint.cpp - Generate vector printing instructions -----===// 2105197Ssam// 3105197Ssam// The LLVM Compiler Infrastructure 4139823Simp// 5105197Ssam// This file is distributed under the University of Illinois Open Source 6105197Ssam// License. See LICENSE.TXT for details. 7105197Ssam// 8105197Ssam//===----------------------------------------------------------------------===// 9105197Ssam// 10105197Ssam// This pass adds the capability to generate pseudo vector/predicate register 11105197Ssam// printing instructions. These pseudo instructions should be used with the 12105197Ssam// simulator, NEVER on hardware. 13105197Ssam// 14105197Ssam//===----------------------------------------------------------------------===// 15105197Ssam 16105197Ssam#include "HexagonInstrInfo.h" 17105197Ssam#include "HexagonSubtarget.h" 18105197Ssam#include "llvm/ADT/StringRef.h" 19105197Ssam#include "llvm/CodeGen/MachineBasicBlock.h" 20105197Ssam#include "llvm/CodeGen/MachineFunction.h" 21105197Ssam#include "llvm/CodeGen/MachineFunctionPass.h" 22105197Ssam#include "llvm/CodeGen/MachineInstr.h" 23105197Ssam#include "llvm/CodeGen/MachineInstrBuilder.h" 24105197Ssam#include "llvm/CodeGen/MachineOperand.h" 25105197Ssam#include "llvm/CodeGen/TargetOpcodes.h" 26105197Ssam#include "llvm/IR/DebugLoc.h" 27105197Ssam#include "llvm/IR/InlineAsm.h" 28105197Ssam#include "llvm/Pass.h" 29105197Ssam#include "llvm/Support/CommandLine.h" 30105197Ssam#include "llvm/Support/Debug.h" 31105197Ssam#include "llvm/Support/ErrorHandling.h" 32105197Ssam#include "llvm/Support/raw_ostream.h" 33105197Ssam#include <string> 34105197Ssam#include <vector> 35105197Ssam 36105197Ssamusing namespace llvm; 37105197Ssam 38105197Ssam#define DEBUG_TYPE "hexagon-vector-print" 39105197Ssam 40105197Ssamstatic cl::opt<bool> TraceHexVectorStoresOnly("trace-hex-vector-stores-only", 41105197Ssam cl::Hidden, cl::ZeroOrMore, cl::init(false), 42105197Ssam cl::desc("Enables tracing of vector stores")); 43105197Ssam 44105197Ssamnamespace llvm { 45119643Ssam 46119643SsamFunctionPass *createHexagonVectorPrint(); 47105197Ssamvoid initializeHexagonVectorPrintPass(PassRegistry&); 48105197Ssam 49105197Ssam} // end namespace llvm 50105197Ssam 51105197Ssamnamespace { 52105197Ssam 53105197Ssamclass HexagonVectorPrint : public MachineFunctionPass { 54105197Ssam const HexagonSubtarget *QST = nullptr; 55105197Ssam const HexagonInstrInfo *QII = nullptr; 56105197Ssam const HexagonRegisterInfo *QRI = nullptr; 57158767Spjd 58105197Ssampublic: 59183550Szec static char ID; 60105197Ssam 61105197Ssam HexagonVectorPrint() : MachineFunctionPass(ID) { 62105197Ssam initializeHexagonVectorPrintPass(*PassRegistry::getPassRegistry()); 63105197Ssam } 64105197Ssam 65105197Ssam StringRef getPassName() const override { return "Hexagon VectorPrint pass"; } 66105197Ssam 67105197Ssam bool runOnMachineFunction(MachineFunction &Fn) override; 68105197Ssam}; 69105197Ssam 70105197Ssam} // end anonymous namespace 71105197Ssam 72105197Ssamchar HexagonVectorPrint::ID = 0; 73105197Ssam 74105197Ssamstatic bool isVecReg(unsigned Reg) { 75105197Ssam return (Reg >= Hexagon::V0 && Reg <= Hexagon::V31) 76105197Ssam || (Reg >= Hexagon::W0 && Reg <= Hexagon::W15) 77105197Ssam || (Reg >= Hexagon::Q0 && Reg <= Hexagon::Q3); 78185571Sbz} 79105197Ssam 80105197Ssamstatic std::string getStringReg(unsigned R) { 81105197Ssam if (R >= Hexagon::V0 && R <= Hexagon::V31) { 82185571Sbz static const char* S[] = { "20", "21", "22", "23", "24", "25", "26", "27", 83105197Ssam "28", "29", "2a", "2b", "2c", "2d", "2e", "2f", 84105197Ssam "30", "31", "32", "33", "34", "35", "36", "37", 85105197Ssam "38", "39", "3a", "3b", "3c", "3d", "3e", "3f"}; 86105197Ssam return S[R-Hexagon::V0]; 87105197Ssam } 88105197Ssam if (R >= Hexagon::Q0 && R <= Hexagon::Q3) { 89105197Ssam static const char* S[] = { "00", "01", "02", "03"}; 90105197Ssam return S[R-Hexagon::Q0]; 91105197Ssam 92105197Ssam } 93105197Ssam llvm_unreachable("valid vreg"); 94105197Ssam} 95105197Ssam 96105197Ssamstatic void addAsmInstr(MachineBasicBlock *MBB, unsigned Reg, 97105197Ssam MachineBasicBlock::instr_iterator I, 98105197Ssam const DebugLoc &DL, const HexagonInstrInfo *QII, 99105197Ssam MachineFunction &Fn) { 100105197Ssam std::string VDescStr = ".long 0x1dffe0" + getStringReg(Reg); 101105197Ssam const char *cstr = Fn.createExternalSymbolName(VDescStr); 102181803Sbz unsigned ExtraInfo = InlineAsm::Extra_HasSideEffects; 103105197Ssam BuildMI(*MBB, I, DL, QII->get(TargetOpcode::INLINEASM)) 104105197Ssam .addExternalSymbol(cstr) 105105197Ssam .addImm(ExtraInfo); 106105197Ssam} 107105197Ssam 108105197Ssamstatic bool getInstrVecReg(const MachineInstr &MI, unsigned &Reg) { 109105197Ssam if (MI.getNumOperands() < 1) return false; 110105197Ssam // Vec load or compute. 111105197Ssam if (MI.getOperand(0).isReg() && MI.getOperand(0).isDef()) { 112105197Ssam Reg = MI.getOperand(0).getReg(); 113105197Ssam if (isVecReg(Reg)) 114105197Ssam return !TraceHexVectorStoresOnly; 115105197Ssam } 116105197Ssam // Vec store. 117105197Ssam if (MI.mayStore() && MI.getNumOperands() >= 3 && MI.getOperand(2).isReg()) { 118185088Szec Reg = MI.getOperand(2).getReg(); 119185088Szec if (isVecReg(Reg)) 120185088Szec return true; 121185088Szec } 122185088Szec // Vec store post increment. 123185088Szec if (MI.mayStore() && MI.getNumOperands() >= 4 && MI.getOperand(3).isReg()) { 124185088Szec Reg = MI.getOperand(3).getReg(); 125185088Szec if (isVecReg(Reg)) 126185088Szec return true; 127185088Szec } 128185088Szec return false; 129105197Ssam} 130185088Szec 131105197Ssambool HexagonVectorPrint::runOnMachineFunction(MachineFunction &Fn) { 132185088Szec bool Changed = false; 133185088Szec QST = &Fn.getSubtarget<HexagonSubtarget>(); 134185088Szec QRI = QST->getRegisterInfo(); 135185088Szec QII = QST->getInstrInfo(); 136105197Ssam std::vector<MachineInstr *> VecPrintList; 137185088Szec for (auto &MBB : Fn) 138185088Szec for (auto &MI : MBB) { 139185088Szec if (MI.isBundle()) { 140185088Szec MachineBasicBlock::instr_iterator MII = MI.getIterator(); 141185088Szec for (++MII; MII != MBB.instr_end() && MII->isInsideBundle(); ++MII) { 142185088Szec if (MII->getNumOperands() < 1) 143119643Ssam continue; 144120585Ssam unsigned Reg = 0; 145120585Ssam if (getInstrVecReg(*MII, Reg)) { 146120585Ssam VecPrintList.push_back((&*MII)); 147120585Ssam DEBUG(dbgs() << "Found vector reg inside bundle \n"; MII->dump()); 148120585Ssam } 149120585Ssam } 150120585Ssam } else { 151120585Ssam unsigned Reg = 0; 152119643Ssam if (getInstrVecReg(MI, Reg)) { 153120585Ssam VecPrintList.push_back(&MI); 154120585Ssam DEBUG(dbgs() << "Found vector reg \n"; MI.dump()); 155120585Ssam } 156120585Ssam } 157120585Ssam } 158120585Ssam 159120585Ssam Changed = !VecPrintList.empty(); 160120585Ssam if (!Changed) 161119643Ssam return Changed; 162119643Ssam 163120585Ssam for (auto *I : VecPrintList) { 164120585Ssam DebugLoc DL = I->getDebugLoc(); 165120585Ssam MachineBasicBlock *MBB = I->getParent(); 166120585Ssam DEBUG(dbgs() << "Evaluating V MI\n"; I->dump()); 167120585Ssam unsigned Reg = 0; 168120585Ssam if (!getInstrVecReg(*I, Reg)) 169120585Ssam llvm_unreachable("Need a vector reg"); 170119643Ssam MachineBasicBlock::instr_iterator MII = I->getIterator(); 171120585Ssam if (I->isInsideBundle()) { 172120585Ssam DEBUG(dbgs() << "add to end of bundle\n"; I->dump()); 173120585Ssam while (MBB->instr_end() != MII && MII->isInsideBundle()) 174120585Ssam MII++; 175120585Ssam } else { 176120585Ssam DEBUG(dbgs() << "add after instruction\n"; I->dump()); 177120585Ssam MII++; 178119643Ssam } 179120585Ssam if (MBB->instr_end() == MII) 180120585Ssam continue; 181120585Ssam 182120585Ssam if (Reg >= Hexagon::V0 && Reg <= Hexagon::V31) { 183120585Ssam DEBUG(dbgs() << "adding dump for V" << Reg-Hexagon::V0 << '\n'); 184120585Ssam addAsmInstr(MBB, Reg, MII, DL, QII, Fn); 185120585Ssam } else if (Reg >= Hexagon::W0 && Reg <= Hexagon::W15) { 186105197Ssam DEBUG(dbgs() << "adding dump for W" << Reg-Hexagon::W0 << '\n'); 187105197Ssam addAsmInstr(MBB, Hexagon::V0 + (Reg - Hexagon::W0) * 2 + 1, 188128856Ssam MII, DL, QII, Fn); 189105197Ssam addAsmInstr(MBB, Hexagon::V0 + (Reg - Hexagon::W0) * 2, 190105197Ssam MII, DL, QII, Fn); 191128856Ssam } else if (Reg >= Hexagon::Q0 && Reg <= Hexagon::Q3) { 192128856Ssam DEBUG(dbgs() << "adding dump for Q" << Reg-Hexagon::Q0 << '\n'); 193128856Ssam addAsmInstr(MBB, Reg, MII, DL, QII, Fn); 194185348Szec } else 195105197Ssam llvm_unreachable("Bad Vector reg"); 196105197Ssam } 197105197Ssam return Changed; 198185348Szec} 199105197Ssam 200105197Ssam//===----------------------------------------------------------------------===// 201105197Ssam// Public Constructor Functions 202105197Ssam//===----------------------------------------------------------------------===// 203105197SsamINITIALIZE_PASS(HexagonVectorPrint, "hexagon-vector-print", 204105197Ssam "Hexagon VectorPrint pass", false, false) 205105197Ssam 206105197SsamFunctionPass *llvm::createHexagonVectorPrint() { 207105197Ssam return new HexagonVectorPrint(); 208105197Ssam} 209105197Ssam