4810 lines · cpp
1//===- HexagonInstrInfo.cpp - Hexagon Instruction Information -------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains the Hexagon implementation of the TargetInstrInfo class.10//11//===----------------------------------------------------------------------===//12 13#include "HexagonInstrInfo.h"14#include "HexagonFrameLowering.h"15#include "HexagonHazardRecognizer.h"16#include "HexagonRegisterInfo.h"17#include "HexagonSubtarget.h"18#include "llvm/ADT/ArrayRef.h"19#include "llvm/ADT/SmallPtrSet.h"20#include "llvm/ADT/SmallVector.h"21#include "llvm/ADT/StringExtras.h"22#include "llvm/ADT/StringRef.h"23#include "llvm/CodeGen/DFAPacketizer.h"24#include "llvm/CodeGen/LiveIntervals.h"25#include "llvm/CodeGen/LivePhysRegs.h"26#include "llvm/CodeGen/MachineBasicBlock.h"27#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"28#include "llvm/CodeGen/MachineFrameInfo.h"29#include "llvm/CodeGen/MachineFunction.h"30#include "llvm/CodeGen/MachineInstr.h"31#include "llvm/CodeGen/MachineInstrBuilder.h"32#include "llvm/CodeGen/MachineInstrBundle.h"33#include "llvm/CodeGen/MachineMemOperand.h"34#include "llvm/CodeGen/MachineOperand.h"35#include "llvm/CodeGen/MachineRegisterInfo.h"36#include "llvm/CodeGen/ScheduleDAG.h"37#include "llvm/CodeGen/TargetInstrInfo.h"38#include "llvm/CodeGen/TargetOpcodes.h"39#include "llvm/CodeGen/TargetRegisterInfo.h"40#include "llvm/CodeGen/TargetSubtargetInfo.h"41#include "llvm/CodeGenTypes/MachineValueType.h"42#include "llvm/IR/DebugLoc.h"43#include "llvm/IR/GlobalVariable.h"44#include "llvm/MC/MCAsmInfo.h"45#include "llvm/MC/MCInstBuilder.h"46#include "llvm/MC/MCInstrDesc.h"47#include "llvm/MC/MCInstrItineraries.h"48#include "llvm/Support/BranchProbability.h"49#include "llvm/Support/CommandLine.h"50#include "llvm/Support/Debug.h"51#include "llvm/Support/ErrorHandling.h"52#include "llvm/Support/MathExtras.h"53#include "llvm/Support/raw_ostream.h"54#include "llvm/Target/TargetMachine.h"55#include <cassert>56#include <cctype>57#include <cstdint>58#include <cstring>59#include <iterator>60#include <optional>61#include <string>62#include <utility>63 64using namespace llvm;65 66#define DEBUG_TYPE "hexagon-instrinfo"67 68#define GET_INSTRINFO_CTOR_DTOR69#define GET_INSTRMAP_INFO70#include "HexagonDepTimingClasses.h"71#include "HexagonGenDFAPacketizer.inc"72#include "HexagonGenInstrInfo.inc"73 74cl::opt<bool> ScheduleInlineAsm("hexagon-sched-inline-asm", cl::Hidden,75 cl::init(false), cl::desc("Do not consider inline-asm a scheduling/"76 "packetization boundary."));77 78static cl::opt<bool> EnableBranchPrediction("hexagon-enable-branch-prediction",79 cl::Hidden, cl::init(true), cl::desc("Enable branch prediction"));80 81static cl::opt<bool> DisableNVSchedule(82 "disable-hexagon-nv-schedule", cl::Hidden,83 cl::desc("Disable schedule adjustment for new value stores."));84 85static cl::opt<bool> EnableTimingClassLatency(86 "enable-timing-class-latency", cl::Hidden, cl::init(false),87 cl::desc("Enable timing class latency"));88 89static cl::opt<bool> EnableALUForwarding(90 "enable-alu-forwarding", cl::Hidden, cl::init(true),91 cl::desc("Enable vec alu forwarding"));92 93static cl::opt<bool> EnableACCForwarding(94 "enable-acc-forwarding", cl::Hidden, cl::init(true),95 cl::desc("Enable vec acc forwarding"));96 97static cl::opt<bool> BranchRelaxAsmLarge("branch-relax-asm-large",98 cl::init(true), cl::Hidden,99 cl::desc("branch relax asm"));100 101static cl::opt<bool>102 UseDFAHazardRec("dfa-hazard-rec", cl::init(true), cl::Hidden,103 cl::desc("Use the DFA based hazard recognizer."));104 105/// Constants for Hexagon instructions.106const int Hexagon_MEMW_OFFSET_MAX = 4095;107const int Hexagon_MEMW_OFFSET_MIN = -4096;108const int Hexagon_MEMD_OFFSET_MAX = 8191;109const int Hexagon_MEMD_OFFSET_MIN = -8192;110const int Hexagon_MEMH_OFFSET_MAX = 2047;111const int Hexagon_MEMH_OFFSET_MIN = -2048;112const int Hexagon_MEMB_OFFSET_MAX = 1023;113const int Hexagon_MEMB_OFFSET_MIN = -1024;114const int Hexagon_ADDI_OFFSET_MAX = 32767;115const int Hexagon_ADDI_OFFSET_MIN = -32768;116 117// Pin the vtable to this file.118void HexagonInstrInfo::anchor() {}119 120HexagonInstrInfo::HexagonInstrInfo(const HexagonSubtarget &ST)121 : HexagonGenInstrInfo(ST, RegInfo, Hexagon::ADJCALLSTACKDOWN,122 Hexagon::ADJCALLSTACKUP),123 RegInfo(ST.getHwMode()), Subtarget(ST) {}124 125namespace llvm {126namespace HexagonFUnits {127 bool isSlot0Only(unsigned units);128}129}130 131static bool isIntRegForSubInst(Register Reg) {132 return (Reg >= Hexagon::R0 && Reg <= Hexagon::R7) ||133 (Reg >= Hexagon::R16 && Reg <= Hexagon::R23);134}135 136static bool isDblRegForSubInst(Register Reg, const HexagonRegisterInfo &HRI) {137 return isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::isub_lo)) &&138 isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::isub_hi));139}140 141/// Calculate number of instructions excluding the debug instructions.142static unsigned nonDbgMICount(MachineBasicBlock::const_instr_iterator MIB,143 MachineBasicBlock::const_instr_iterator MIE) {144 unsigned Count = 0;145 for (; MIB != MIE; ++MIB) {146 if (!MIB->isDebugInstr())147 ++Count;148 }149 return Count;150}151 152// Check if the A2_tfrsi instruction is cheap or not. If the operand has153// to be constant-extendend it is not cheap since it occupies two slots154// in a packet.155bool HexagonInstrInfo::isAsCheapAsAMove(const MachineInstr &MI) const {156 // Enable the following steps only at Os/Oz157 if (!(MI.getMF()->getFunction().hasOptSize()))158 return MI.isAsCheapAsAMove();159 160 if (MI.getOpcode() == Hexagon::A2_tfrsi) {161 auto Op = MI.getOperand(1);162 // If the instruction has a global address as operand, it is not cheap163 // since the operand will be constant extended.164 if (Op.isGlobal())165 return false;166 // If the instruction has an operand of size > 16bits, its will be167 // const-extended and hence, it is not cheap.168 if (Op.isImm()) {169 int64_t Imm = Op.getImm();170 if (!isInt<16>(Imm))171 return false;172 }173 }174 return MI.isAsCheapAsAMove();175}176 177// Do not sink floating point instructions that updates USR register.178// Example:179// feclearexcept180// F2_conv_w2sf181// fetestexcept182// MachineSink sinks F2_conv_w2sf and we are not able to catch exceptions.183// TODO: On some of these floating point instructions, USR is marked as Use.184// In reality, these instructions also Def the USR. If USR is marked as Def,185// some of the assumptions in assembler packetization are broken.186bool HexagonInstrInfo::shouldSink(const MachineInstr &MI) const {187 // Assumption: A floating point instruction that reads the USR will write188 // the USR as well.189 if (isFloat(MI) && MI.hasRegisterImplicitUseOperand(Hexagon::USR))190 return false;191 return true;192}193 194/// Find the hardware loop instruction used to set-up the specified loop.195/// On Hexagon, we have two instructions used to set-up the hardware loop196/// (LOOP0, LOOP1) with corresponding endloop (ENDLOOP0, ENDLOOP1) instructions197/// to indicate the end of a loop.198MachineInstr *HexagonInstrInfo::findLoopInstr(MachineBasicBlock *BB,199 unsigned EndLoopOp, MachineBasicBlock *TargetBB,200 SmallPtrSet<MachineBasicBlock *, 8> &Visited) const {201 unsigned LOOPi;202 unsigned LOOPr;203 if (EndLoopOp == Hexagon::ENDLOOP0) {204 LOOPi = Hexagon::J2_loop0i;205 LOOPr = Hexagon::J2_loop0r;206 } else { // EndLoopOp == Hexagon::EndLOOP1207 LOOPi = Hexagon::J2_loop1i;208 LOOPr = Hexagon::J2_loop1r;209 }210 211 // The loop set-up instruction will be in a predecessor block212 for (MachineBasicBlock *PB : BB->predecessors()) {213 // If this has been visited, already skip it.214 if (!Visited.insert(PB).second)215 continue;216 if (PB == BB)217 continue;218 for (MachineInstr &I : llvm::reverse(PB->instrs())) {219 unsigned Opc = I.getOpcode();220 if (Opc == LOOPi || Opc == LOOPr)221 return &I;222 // We've reached a different loop, which means the loop01 has been223 // removed.224 if (Opc == EndLoopOp && I.getOperand(0).getMBB() != TargetBB)225 return nullptr;226 }227 // Check the predecessors for the LOOP instruction.228 if (MachineInstr *Loop = findLoopInstr(PB, EndLoopOp, TargetBB, Visited))229 return Loop;230 }231 return nullptr;232}233 234/// Gather register def/uses from MI.235/// This treats possible (predicated) defs as actually happening ones236/// (conservatively).237static inline void parseOperands(const MachineInstr &MI,238 SmallVectorImpl<Register> &Defs, SmallVectorImpl<Register> &Uses) {239 Defs.clear();240 Uses.clear();241 242 for (const MachineOperand &MO : MI.operands()) {243 if (!MO.isReg())244 continue;245 246 Register Reg = MO.getReg();247 if (!Reg)248 continue;249 250 if (MO.isUse())251 Uses.push_back(MO.getReg());252 253 if (MO.isDef())254 Defs.push_back(MO.getReg());255 }256}257 258// Position dependent, so check twice for swap.259static bool isDuplexPairMatch(unsigned Ga, unsigned Gb) {260 switch (Ga) {261 case HexagonII::HSIG_None:262 default:263 return false;264 case HexagonII::HSIG_L1:265 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_A);266 case HexagonII::HSIG_L2:267 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||268 Gb == HexagonII::HSIG_A);269 case HexagonII::HSIG_S1:270 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||271 Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_A);272 case HexagonII::HSIG_S2:273 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||274 Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_S2 ||275 Gb == HexagonII::HSIG_A);276 case HexagonII::HSIG_A:277 return (Gb == HexagonII::HSIG_A);278 case HexagonII::HSIG_Compound:279 return (Gb == HexagonII::HSIG_Compound);280 }281 return false;282}283 284/// isLoadFromStackSlot - If the specified machine instruction is a direct285/// load from a stack slot, return the virtual or physical register number of286/// the destination along with the FrameIndex of the loaded stack slot. If287/// not, return 0. This predicate must return 0 if the instruction has288/// any side effects other than loading from the stack slot.289Register HexagonInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,290 int &FrameIndex) const {291 switch (MI.getOpcode()) {292 default:293 break;294 case Hexagon::L2_loadri_io:295 case Hexagon::L2_loadrd_io:296 case Hexagon::V6_vL32b_ai:297 case Hexagon::V6_vL32b_nt_ai:298 case Hexagon::V6_vL32Ub_ai:299 case Hexagon::LDriw_pred:300 case Hexagon::LDriw_ctr:301 case Hexagon::PS_vloadrq_ai:302 case Hexagon::PS_vloadrw_ai:303 case Hexagon::PS_vloadrw_nt_ai: {304 const MachineOperand OpFI = MI.getOperand(1);305 if (!OpFI.isFI())306 return 0;307 const MachineOperand OpOff = MI.getOperand(2);308 if (!OpOff.isImm() || OpOff.getImm() != 0)309 return 0;310 FrameIndex = OpFI.getIndex();311 return MI.getOperand(0).getReg();312 }313 314 case Hexagon::L2_ploadrit_io:315 case Hexagon::L2_ploadrif_io:316 case Hexagon::L2_ploadrdt_io:317 case Hexagon::L2_ploadrdf_io: {318 const MachineOperand OpFI = MI.getOperand(2);319 if (!OpFI.isFI())320 return 0;321 const MachineOperand OpOff = MI.getOperand(3);322 if (!OpOff.isImm() || OpOff.getImm() != 0)323 return 0;324 FrameIndex = OpFI.getIndex();325 return MI.getOperand(0).getReg();326 }327 }328 329 return 0;330}331 332/// isStoreToStackSlot - If the specified machine instruction is a direct333/// store to a stack slot, return the virtual or physical register number of334/// the source reg along with the FrameIndex of the loaded stack slot. If335/// not, return 0. This predicate must return 0 if the instruction has336/// any side effects other than storing to the stack slot.337Register HexagonInstrInfo::isStoreToStackSlot(const MachineInstr &MI,338 int &FrameIndex) const {339 switch (MI.getOpcode()) {340 default:341 break;342 case Hexagon::S2_storerb_io:343 case Hexagon::S2_storerh_io:344 case Hexagon::S2_storeri_io:345 case Hexagon::S2_storerd_io:346 case Hexagon::V6_vS32b_ai:347 case Hexagon::V6_vS32Ub_ai:348 case Hexagon::STriw_pred:349 case Hexagon::STriw_ctr:350 case Hexagon::PS_vstorerq_ai:351 case Hexagon::PS_vstorerw_ai: {352 const MachineOperand &OpFI = MI.getOperand(0);353 if (!OpFI.isFI())354 return 0;355 const MachineOperand &OpOff = MI.getOperand(1);356 if (!OpOff.isImm() || OpOff.getImm() != 0)357 return 0;358 FrameIndex = OpFI.getIndex();359 return MI.getOperand(2).getReg();360 }361 362 case Hexagon::S2_pstorerbt_io:363 case Hexagon::S2_pstorerbf_io:364 case Hexagon::S2_pstorerht_io:365 case Hexagon::S2_pstorerhf_io:366 case Hexagon::S2_pstorerit_io:367 case Hexagon::S2_pstorerif_io:368 case Hexagon::S2_pstorerdt_io:369 case Hexagon::S2_pstorerdf_io: {370 const MachineOperand &OpFI = MI.getOperand(1);371 if (!OpFI.isFI())372 return 0;373 const MachineOperand &OpOff = MI.getOperand(2);374 if (!OpOff.isImm() || OpOff.getImm() != 0)375 return 0;376 FrameIndex = OpFI.getIndex();377 return MI.getOperand(3).getReg();378 }379 }380 381 return 0;382}383 384/// This function checks if the instruction or bundle of instructions385/// has load from stack slot and returns frameindex and machine memory386/// operand of that instruction if true.387bool HexagonInstrInfo::hasLoadFromStackSlot(388 const MachineInstr &MI,389 SmallVectorImpl<const MachineMemOperand *> &Accesses) const {390 if (MI.isBundle()) {391 const MachineBasicBlock *MBB = MI.getParent();392 MachineBasicBlock::const_instr_iterator MII = MI.getIterator();393 for (++MII; MII != MBB->instr_end() && MII->isInsideBundle(); ++MII)394 if (TargetInstrInfo::hasLoadFromStackSlot(*MII, Accesses))395 return true;396 return false;397 }398 399 return TargetInstrInfo::hasLoadFromStackSlot(MI, Accesses);400}401 402/// This function checks if the instruction or bundle of instructions403/// has store to stack slot and returns frameindex and machine memory404/// operand of that instruction if true.405bool HexagonInstrInfo::hasStoreToStackSlot(406 const MachineInstr &MI,407 SmallVectorImpl<const MachineMemOperand *> &Accesses) const {408 if (MI.isBundle()) {409 const MachineBasicBlock *MBB = MI.getParent();410 MachineBasicBlock::const_instr_iterator MII = MI.getIterator();411 for (++MII; MII != MBB->instr_end() && MII->isInsideBundle(); ++MII)412 if (TargetInstrInfo::hasStoreToStackSlot(*MII, Accesses))413 return true;414 return false;415 }416 417 return TargetInstrInfo::hasStoreToStackSlot(MI, Accesses);418}419 420/// This function can analyze one/two way branching only and should (mostly) be421/// called by target independent side.422/// First entry is always the opcode of the branching instruction, except when423/// the Cond vector is supposed to be empty, e.g., when analyzeBranch fails, a424/// BB with only unconditional jump. Subsequent entries depend upon the opcode,425/// e.g. Jump_c p will have426/// Cond[0] = Jump_c427/// Cond[1] = p428/// HW-loop ENDLOOP:429/// Cond[0] = ENDLOOP430/// Cond[1] = MBB431/// New value jump:432/// Cond[0] = Hexagon::CMPEQri_f_Jumpnv_t_V4 -- specific opcode433/// Cond[1] = R434/// Cond[2] = Imm435bool HexagonInstrInfo::analyzeBranch(MachineBasicBlock &MBB,436 MachineBasicBlock *&TBB,437 MachineBasicBlock *&FBB,438 SmallVectorImpl<MachineOperand> &Cond,439 bool AllowModify) const {440 TBB = nullptr;441 FBB = nullptr;442 Cond.clear();443 444 // If the block has no terminators, it just falls into the block after it.445 MachineBasicBlock::instr_iterator I = MBB.instr_end();446 if (I == MBB.instr_begin())447 return false;448 449 // A basic block may looks like this:450 //451 // [ insn452 // EH_LABEL453 // insn454 // insn455 // insn456 // EH_LABEL457 // insn ]458 //459 // It has two succs but does not have a terminator460 // Don't know how to handle it.461 do {462 --I;463 if (I->isEHLabel())464 // Don't analyze EH branches.465 return true;466 } while (I != MBB.instr_begin());467 468 I = MBB.instr_end();469 --I;470 471 while (I->isDebugInstr()) {472 if (I == MBB.instr_begin())473 return false;474 --I;475 }476 477 bool JumpToBlock = I->getOpcode() == Hexagon::J2_jump &&478 I->getOperand(0).isMBB();479 // Delete the J2_jump if it's equivalent to a fall-through.480 if (AllowModify && JumpToBlock &&481 MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {482 LLVM_DEBUG(dbgs() << "\nErasing the jump to successor block\n";);483 I->eraseFromParent();484 I = MBB.instr_end();485 if (I == MBB.instr_begin())486 return false;487 --I;488 }489 if (!isUnpredicatedTerminator(*I))490 return false;491 492 // Get the last instruction in the block.493 MachineInstr *LastInst = &*I;494 MachineInstr *SecondLastInst = nullptr;495 // Find one more terminator if present.496 while (true) {497 if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {498 if (!SecondLastInst)499 SecondLastInst = &*I;500 else501 // This is a third branch.502 return true;503 }504 if (I == MBB.instr_begin())505 break;506 --I;507 }508 509 int LastOpcode = LastInst->getOpcode();510 int SecLastOpcode = SecondLastInst ? SecondLastInst->getOpcode() : 0;511 // If the branch target is not a basic block, it could be a tail call.512 // (It is, if the target is a function.)513 if (LastOpcode == Hexagon::J2_jump && !LastInst->getOperand(0).isMBB())514 return true;515 if (SecLastOpcode == Hexagon::J2_jump &&516 !SecondLastInst->getOperand(0).isMBB())517 return true;518 519 bool LastOpcodeHasJMP_c = PredOpcodeHasJMP_c(LastOpcode);520 bool LastOpcodeHasNVJump = isNewValueJump(*LastInst);521 522 if (LastOpcodeHasJMP_c && !LastInst->getOperand(1).isMBB())523 return true;524 525 // If there is only one terminator instruction, process it.526 if (LastInst && !SecondLastInst) {527 if (LastOpcode == Hexagon::J2_jump) {528 TBB = LastInst->getOperand(0).getMBB();529 return false;530 }531 if (isEndLoopN(LastOpcode)) {532 TBB = LastInst->getOperand(0).getMBB();533 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));534 Cond.push_back(LastInst->getOperand(0));535 return false;536 }537 if (LastOpcodeHasJMP_c) {538 TBB = LastInst->getOperand(1).getMBB();539 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));540 Cond.push_back(LastInst->getOperand(0));541 return false;542 }543 // Only supporting rr/ri versions of new-value jumps.544 if (LastOpcodeHasNVJump && (LastInst->getNumExplicitOperands() == 3)) {545 TBB = LastInst->getOperand(2).getMBB();546 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));547 Cond.push_back(LastInst->getOperand(0));548 Cond.push_back(LastInst->getOperand(1));549 return false;550 }551 LLVM_DEBUG(dbgs() << "\nCant analyze " << printMBBReference(MBB)552 << " with one jump\n";);553 // Otherwise, don't know what this is.554 return true;555 }556 557 bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode);558 bool SecLastOpcodeHasNVJump = isNewValueJump(*SecondLastInst);559 if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::J2_jump)) {560 if (!SecondLastInst->getOperand(1).isMBB())561 return true;562 TBB = SecondLastInst->getOperand(1).getMBB();563 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));564 Cond.push_back(SecondLastInst->getOperand(0));565 FBB = LastInst->getOperand(0).getMBB();566 return false;567 }568 569 // Only supporting rr/ri versions of new-value jumps.570 if (SecLastOpcodeHasNVJump &&571 (SecondLastInst->getNumExplicitOperands() == 3) &&572 (LastOpcode == Hexagon::J2_jump)) {573 TBB = SecondLastInst->getOperand(2).getMBB();574 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));575 Cond.push_back(SecondLastInst->getOperand(0));576 Cond.push_back(SecondLastInst->getOperand(1));577 FBB = LastInst->getOperand(0).getMBB();578 return false;579 }580 581 // If the block ends with two Hexagon:JMPs, handle it. The second one is not582 // executed, so remove it.583 if (SecLastOpcode == Hexagon::J2_jump && LastOpcode == Hexagon::J2_jump) {584 TBB = SecondLastInst->getOperand(0).getMBB();585 I = LastInst->getIterator();586 if (AllowModify)587 I->eraseFromParent();588 return false;589 }590 591 // If the block ends with an ENDLOOP, and J2_jump, handle it.592 if (isEndLoopN(SecLastOpcode) && LastOpcode == Hexagon::J2_jump) {593 TBB = SecondLastInst->getOperand(0).getMBB();594 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));595 Cond.push_back(SecondLastInst->getOperand(0));596 FBB = LastInst->getOperand(0).getMBB();597 return false;598 }599 LLVM_DEBUG(dbgs() << "\nCant analyze " << printMBBReference(MBB)600 << " with two jumps";);601 // Otherwise, can't handle this.602 return true;603}604 605unsigned HexagonInstrInfo::removeBranch(MachineBasicBlock &MBB,606 int *BytesRemoved) const {607 assert(!BytesRemoved && "code size not handled");608 609 LLVM_DEBUG(dbgs() << "\nRemoving branches out of " << printMBBReference(MBB));610 MachineBasicBlock::iterator I = MBB.end();611 unsigned Count = 0;612 while (I != MBB.begin()) {613 --I;614 if (I->isDebugInstr())615 continue;616 // Only removing branches from end of MBB.617 if (!I->isBranch())618 return Count;619 if (Count && (I->getOpcode() == Hexagon::J2_jump))620 llvm_unreachable("Malformed basic block: unconditional branch not last");621 MBB.erase(&MBB.back());622 I = MBB.end();623 ++Count;624 }625 return Count;626}627 628unsigned HexagonInstrInfo::insertBranch(MachineBasicBlock &MBB,629 MachineBasicBlock *TBB,630 MachineBasicBlock *FBB,631 ArrayRef<MachineOperand> Cond,632 const DebugLoc &DL,633 int *BytesAdded) const {634 unsigned BOpc = Hexagon::J2_jump;635 unsigned BccOpc = Hexagon::J2_jumpt;636 assert(validateBranchCond(Cond) && "Invalid branching condition");637 assert(TBB && "insertBranch must not be told to insert a fallthrough");638 assert(!BytesAdded && "code size not handled");639 640 // Check if reverseBranchCondition has asked to reverse this branch641 // If we want to reverse the branch an odd number of times, we want642 // J2_jumpf.643 if (!Cond.empty() && Cond[0].isImm())644 BccOpc = Cond[0].getImm();645 646 if (!FBB) {647 if (Cond.empty()) {648 // Due to a bug in TailMerging/CFG Optimization, we need to add a649 // special case handling of a predicated jump followed by an650 // unconditional jump. If not, Tail Merging and CFG Optimization go651 // into an infinite loop.652 MachineBasicBlock *NewTBB, *NewFBB;653 SmallVector<MachineOperand, 4> Cond;654 auto Term = MBB.getFirstTerminator();655 if (Term != MBB.end() && isPredicated(*Term) &&656 !analyzeBranch(MBB, NewTBB, NewFBB, Cond, false) &&657 MachineFunction::iterator(NewTBB) == ++MBB.getIterator()) {658 reverseBranchCondition(Cond);659 removeBranch(MBB);660 return insertBranch(MBB, TBB, nullptr, Cond, DL);661 }662 BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB);663 } else if (isEndLoopN(Cond[0].getImm())) {664 int EndLoopOp = Cond[0].getImm();665 assert(Cond[1].isMBB());666 // Since we're adding an ENDLOOP, there better be a LOOP instruction.667 // Check for it, and change the BB target if needed.668 SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;669 MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),670 VisitedBBs);671 assert(Loop != nullptr && "Inserting an ENDLOOP without a LOOP");672 Loop->getOperand(0).setMBB(TBB);673 // Add the ENDLOOP after the finding the LOOP0.674 BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);675 } else if (isNewValueJump(Cond[0].getImm())) {676 assert((Cond.size() == 3) && "Only supporting rr/ri version of nvjump");677 // New value jump678 // (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset)679 // (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset)680 unsigned Flags1 = getUndefRegState(Cond[1].isUndef());681 LLVM_DEBUG(dbgs() << "\nInserting NVJump for "682 << printMBBReference(MBB););683 if (Cond[2].isReg()) {684 unsigned Flags2 = getUndefRegState(Cond[2].isUndef());685 BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[1].getReg(), Flags1).686 addReg(Cond[2].getReg(), Flags2).addMBB(TBB);687 } else if(Cond[2].isImm()) {688 BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[1].getReg(), Flags1).689 addImm(Cond[2].getImm()).addMBB(TBB);690 } else691 llvm_unreachable("Invalid condition for branching");692 } else {693 assert((Cond.size() == 2) && "Malformed cond vector");694 const MachineOperand &RO = Cond[1];695 unsigned Flags = getUndefRegState(RO.isUndef());696 BuildMI(&MBB, DL, get(BccOpc)).addReg(RO.getReg(), Flags).addMBB(TBB);697 }698 return 1;699 }700 assert((!Cond.empty()) &&701 "Cond. cannot be empty when multiple branchings are required");702 assert((!isNewValueJump(Cond[0].getImm())) &&703 "NV-jump cannot be inserted with another branch");704 // Special case for hardware loops. The condition is a basic block.705 if (isEndLoopN(Cond[0].getImm())) {706 int EndLoopOp = Cond[0].getImm();707 assert(Cond[1].isMBB());708 // Since we're adding an ENDLOOP, there better be a LOOP instruction.709 // Check for it, and change the BB target if needed.710 SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;711 MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),712 VisitedBBs);713 assert(Loop != nullptr && "Inserting an ENDLOOP without a LOOP");714 Loop->getOperand(0).setMBB(TBB);715 // Add the ENDLOOP after the finding the LOOP0.716 BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);717 } else {718 const MachineOperand &RO = Cond[1];719 unsigned Flags = getUndefRegState(RO.isUndef());720 BuildMI(&MBB, DL, get(BccOpc)).addReg(RO.getReg(), Flags).addMBB(TBB);721 }722 BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB);723 724 return 2;725}726 727namespace {728class HexagonPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {729 MachineInstr *Loop, *EndLoop;730 MachineFunction *MF;731 const HexagonInstrInfo *TII;732 int64_t TripCount;733 Register LoopCount;734 DebugLoc DL;735 736public:737 HexagonPipelinerLoopInfo(MachineInstr *Loop, MachineInstr *EndLoop)738 : Loop(Loop), EndLoop(EndLoop), MF(Loop->getParent()->getParent()),739 TII(MF->getSubtarget<HexagonSubtarget>().getInstrInfo()),740 DL(Loop->getDebugLoc()) {741 // Inspect the Loop instruction up-front, as it may be deleted when we call742 // createTripCountGreaterCondition.743 TripCount = Loop->getOpcode() == Hexagon::J2_loop0r744 ? -1745 : Loop->getOperand(1).getImm();746 if (TripCount == -1)747 LoopCount = Loop->getOperand(1).getReg();748 }749 750 bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {751 // Only ignore the terminator.752 return MI == EndLoop;753 }754 755 std::optional<bool> createTripCountGreaterCondition(756 int TC, MachineBasicBlock &MBB,757 SmallVectorImpl<MachineOperand> &Cond) override {758 if (TripCount == -1) {759 // Check if we're done with the loop.760 Register Done = TII->createVR(MF, MVT::i1);761 MachineInstr *NewCmp = BuildMI(&MBB, DL,762 TII->get(Hexagon::C2_cmpgtui), Done)763 .addReg(LoopCount)764 .addImm(TC);765 Cond.push_back(MachineOperand::CreateImm(Hexagon::J2_jumpf));766 Cond.push_back(NewCmp->getOperand(0));767 return {};768 }769 770 return TripCount > TC;771 }772 773 void setPreheader(MachineBasicBlock *NewPreheader) override {774 NewPreheader->splice(NewPreheader->getFirstTerminator(), Loop->getParent(),775 Loop);776 }777 778 void adjustTripCount(int TripCountAdjust) override {779 // If the loop trip count is a compile-time value, then just change the780 // value.781 if (Loop->getOpcode() == Hexagon::J2_loop0i ||782 Loop->getOpcode() == Hexagon::J2_loop1i) {783 int64_t TripCount = Loop->getOperand(1).getImm() + TripCountAdjust;784 assert(TripCount > 0 && "Can't create an empty or negative loop!");785 Loop->getOperand(1).setImm(TripCount);786 return;787 }788 789 // The loop trip count is a run-time value. We generate code to subtract790 // one from the trip count, and update the loop instruction.791 Register LoopCount = Loop->getOperand(1).getReg();792 Register NewLoopCount = TII->createVR(MF, MVT::i32);793 BuildMI(*Loop->getParent(), Loop, Loop->getDebugLoc(),794 TII->get(Hexagon::A2_addi), NewLoopCount)795 .addReg(LoopCount)796 .addImm(TripCountAdjust);797 Loop->getOperand(1).setReg(NewLoopCount);798 }799 800 void disposed(LiveIntervals *LIS) override {801 if (LIS)802 LIS->RemoveMachineInstrFromMaps(*Loop);803 Loop->eraseFromParent();804 }805};806} // namespace807 808std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>809HexagonInstrInfo::analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const {810 // We really "analyze" only hardware loops right now.811 MachineBasicBlock::iterator I = LoopBB->getFirstTerminator();812 813 if (I != LoopBB->end() && isEndLoopN(I->getOpcode())) {814 SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;815 MachineInstr *LoopInst = findLoopInstr(816 LoopBB, I->getOpcode(), I->getOperand(0).getMBB(), VisitedBBs);817 if (LoopInst)818 return std::make_unique<HexagonPipelinerLoopInfo>(LoopInst, &*I);819 }820 return nullptr;821}822 823bool HexagonInstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB,824 unsigned NumCycles, unsigned ExtraPredCycles,825 BranchProbability Probability) const {826 return nonDbgBBSize(&MBB) <= 3;827}828 829bool HexagonInstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB,830 unsigned NumTCycles, unsigned ExtraTCycles, MachineBasicBlock &FMBB,831 unsigned NumFCycles, unsigned ExtraFCycles, BranchProbability Probability)832 const {833 return nonDbgBBSize(&TMBB) <= 3 && nonDbgBBSize(&FMBB) <= 3;834}835 836bool HexagonInstrInfo::isProfitableToDupForIfCvt(MachineBasicBlock &MBB,837 unsigned NumInstrs, BranchProbability Probability) const {838 return NumInstrs <= 4;839}840 841static void getLiveInRegsAt(LivePhysRegs &Regs, const MachineInstr &MI) {842 SmallVector<std::pair<MCPhysReg, const MachineOperand*>,2> Clobbers;843 const MachineBasicBlock &B = *MI.getParent();844 Regs.addLiveIns(B);845 auto E = MachineBasicBlock::const_iterator(MI.getIterator());846 for (auto I = B.begin(); I != E; ++I) {847 Clobbers.clear();848 Regs.stepForward(*I, Clobbers);849 }850}851 852static void getLiveOutRegsAt(LivePhysRegs &Regs, const MachineInstr &MI) {853 const MachineBasicBlock &B = *MI.getParent();854 Regs.addLiveOuts(B);855 auto E = ++MachineBasicBlock::const_iterator(MI.getIterator()).getReverse();856 for (auto I = B.rbegin(); I != E; ++I)857 Regs.stepBackward(*I);858}859 860void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB,861 MachineBasicBlock::iterator I,862 const DebugLoc &DL, Register DestReg,863 Register SrcReg, bool KillSrc,864 bool RenamableDest,865 bool RenamableSrc) const {866 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();867 unsigned KillFlag = getKillRegState(KillSrc);868 869 if (Hexagon::IntRegsRegClass.contains(SrcReg, DestReg)) {870 BuildMI(MBB, I, DL, get(Hexagon::A2_tfr), DestReg)871 .addReg(SrcReg, KillFlag);872 return;873 }874 if (Hexagon::DoubleRegsRegClass.contains(SrcReg, DestReg)) {875 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrp), DestReg)876 .addReg(SrcReg, KillFlag);877 return;878 }879 if (Hexagon::PredRegsRegClass.contains(SrcReg, DestReg)) {880 // Map Pd = Ps to Pd = or(Ps, Ps).881 BuildMI(MBB, I, DL, get(Hexagon::C2_or), DestReg)882 .addReg(SrcReg).addReg(SrcReg, KillFlag);883 return;884 }885 if (Hexagon::CtrRegsRegClass.contains(DestReg) &&886 Hexagon::IntRegsRegClass.contains(SrcReg)) {887 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrrcr), DestReg)888 .addReg(SrcReg, KillFlag);889 return;890 }891 if (Hexagon::IntRegsRegClass.contains(DestReg) &&892 Hexagon::CtrRegsRegClass.contains(SrcReg)) {893 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrcrr), DestReg)894 .addReg(SrcReg, KillFlag);895 return;896 }897 if (Hexagon::ModRegsRegClass.contains(DestReg) &&898 Hexagon::IntRegsRegClass.contains(SrcReg)) {899 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrrcr), DestReg)900 .addReg(SrcReg, KillFlag);901 return;902 }903 if (Hexagon::PredRegsRegClass.contains(SrcReg) &&904 Hexagon::IntRegsRegClass.contains(DestReg)) {905 BuildMI(MBB, I, DL, get(Hexagon::C2_tfrpr), DestReg)906 .addReg(SrcReg, KillFlag);907 return;908 }909 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&910 Hexagon::PredRegsRegClass.contains(DestReg)) {911 BuildMI(MBB, I, DL, get(Hexagon::C2_tfrrp), DestReg)912 .addReg(SrcReg, KillFlag);913 return;914 }915 if (Hexagon::PredRegsRegClass.contains(SrcReg) &&916 Hexagon::IntRegsRegClass.contains(DestReg)) {917 BuildMI(MBB, I, DL, get(Hexagon::C2_tfrpr), DestReg)918 .addReg(SrcReg, KillFlag);919 return;920 }921 if (Hexagon::HvxVRRegClass.contains(SrcReg, DestReg)) {922 BuildMI(MBB, I, DL, get(Hexagon::V6_vassign), DestReg).923 addReg(SrcReg, KillFlag);924 return;925 }926 if (Hexagon::HvxWRRegClass.contains(SrcReg, DestReg)) {927 LivePhysRegs LiveAtMI(HRI);928 getLiveInRegsAt(LiveAtMI, *I);929 Register SrcLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);930 Register SrcHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);931 unsigned UndefLo = getUndefRegState(!LiveAtMI.contains(SrcLo));932 unsigned UndefHi = getUndefRegState(!LiveAtMI.contains(SrcHi));933 BuildMI(MBB, I, DL, get(Hexagon::V6_vcombine), DestReg)934 .addReg(SrcHi, KillFlag | UndefHi)935 .addReg(SrcLo, KillFlag | UndefLo);936 return;937 }938 if (Hexagon::HvxQRRegClass.contains(SrcReg, DestReg)) {939 BuildMI(MBB, I, DL, get(Hexagon::V6_pred_and), DestReg)940 .addReg(SrcReg)941 .addReg(SrcReg, KillFlag);942 return;943 }944 if (Hexagon::HvxQRRegClass.contains(SrcReg) &&945 Hexagon::HvxVRRegClass.contains(DestReg)) {946 llvm_unreachable("Unimplemented pred to vec");947 return;948 }949 if (Hexagon::HvxQRRegClass.contains(DestReg) &&950 Hexagon::HvxVRRegClass.contains(SrcReg)) {951 llvm_unreachable("Unimplemented vec to pred");952 return;953 }954 955#ifndef NDEBUG956 // Show the invalid registers to ease debugging.957 dbgs() << "Invalid registers for copy in " << printMBBReference(MBB) << ": "958 << printReg(DestReg, &HRI) << " = " << printReg(SrcReg, &HRI) << '\n';959#endif960 llvm_unreachable("Unimplemented");961}962 963void HexagonInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,964 MachineBasicBlock::iterator I,965 Register SrcReg, bool isKill, int FI,966 const TargetRegisterClass *RC,967 Register VReg,968 MachineInstr::MIFlag Flags) const {969 DebugLoc DL = MBB.findDebugLoc(I);970 MachineFunction &MF = *MBB.getParent();971 MachineFrameInfo &MFI = MF.getFrameInfo();972 unsigned KillFlag = getKillRegState(isKill);973 974 MachineMemOperand *MMO = MF.getMachineMemOperand(975 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,976 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));977 978 if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {979 BuildMI(MBB, I, DL, get(Hexagon::S2_storeri_io))980 .addFrameIndex(FI).addImm(0)981 .addReg(SrcReg, KillFlag).addMemOperand(MMO);982 } else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {983 BuildMI(MBB, I, DL, get(Hexagon::S2_storerd_io))984 .addFrameIndex(FI).addImm(0)985 .addReg(SrcReg, KillFlag).addMemOperand(MMO);986 } else if (Hexagon::PredRegsRegClass.hasSubClassEq(RC)) {987 BuildMI(MBB, I, DL, get(Hexagon::STriw_pred))988 .addFrameIndex(FI).addImm(0)989 .addReg(SrcReg, KillFlag).addMemOperand(MMO);990 } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {991 BuildMI(MBB, I, DL, get(Hexagon::STriw_ctr))992 .addFrameIndex(FI).addImm(0)993 .addReg(SrcReg, KillFlag).addMemOperand(MMO);994 } else if (Hexagon::HvxQRRegClass.hasSubClassEq(RC)) {995 BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerq_ai))996 .addFrameIndex(FI).addImm(0)997 .addReg(SrcReg, KillFlag).addMemOperand(MMO);998 } else if (Hexagon::HvxVRRegClass.hasSubClassEq(RC)) {999 BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerv_ai))1000 .addFrameIndex(FI).addImm(0)1001 .addReg(SrcReg, KillFlag).addMemOperand(MMO);1002 } else if (Hexagon::HvxWRRegClass.hasSubClassEq(RC)) {1003 BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerw_ai))1004 .addFrameIndex(FI).addImm(0)1005 .addReg(SrcReg, KillFlag).addMemOperand(MMO);1006 } else {1007 llvm_unreachable("Unimplemented");1008 }1009}1010 1011void HexagonInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,1012 MachineBasicBlock::iterator I,1013 Register DestReg, int FI,1014 const TargetRegisterClass *RC,1015 Register VReg,1016 MachineInstr::MIFlag Flags) const {1017 DebugLoc DL = MBB.findDebugLoc(I);1018 MachineFunction &MF = *MBB.getParent();1019 MachineFrameInfo &MFI = MF.getFrameInfo();1020 1021 MachineMemOperand *MMO = MF.getMachineMemOperand(1022 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,1023 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));1024 1025 if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {1026 BuildMI(MBB, I, DL, get(Hexagon::L2_loadri_io), DestReg)1027 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);1028 } else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {1029 BuildMI(MBB, I, DL, get(Hexagon::L2_loadrd_io), DestReg)1030 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);1031 } else if (Hexagon::PredRegsRegClass.hasSubClassEq(RC)) {1032 BuildMI(MBB, I, DL, get(Hexagon::LDriw_pred), DestReg)1033 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);1034 } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {1035 BuildMI(MBB, I, DL, get(Hexagon::LDriw_ctr), DestReg)1036 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);1037 } else if (Hexagon::HvxQRRegClass.hasSubClassEq(RC)) {1038 BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrq_ai), DestReg)1039 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);1040 } else if (Hexagon::HvxVRRegClass.hasSubClassEq(RC)) {1041 BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrv_ai), DestReg)1042 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);1043 } else if (Hexagon::HvxWRRegClass.hasSubClassEq(RC)) {1044 BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrw_ai), DestReg)1045 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);1046 } else {1047 llvm_unreachable("Can't store this register to stack slot");1048 }1049}1050 1051/// expandPostRAPseudo - This function is called for all pseudo instructions1052/// that remain after register allocation. Many pseudo instructions are1053/// created to help register allocation. This is the place to convert them1054/// into real instructions. The target can edit MI in place, or it can insert1055/// new instructions and erase MI. The function should return true if1056/// anything was changed.1057bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {1058 MachineBasicBlock &MBB = *MI.getParent();1059 MachineFunction &MF = *MBB.getParent();1060 MachineRegisterInfo &MRI = MF.getRegInfo();1061 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();1062 LivePhysRegs LiveIn(HRI), LiveOut(HRI);1063 DebugLoc DL = MI.getDebugLoc();1064 unsigned Opc = MI.getOpcode();1065 1066 auto RealCirc = [&](unsigned Opc, bool HasImm, unsigned MxOp) {1067 Register Mx = MI.getOperand(MxOp).getReg();1068 Register CSx = (Mx == Hexagon::M0 ? Hexagon::CS0 : Hexagon::CS1);1069 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrrcr), CSx)1070 .add(MI.getOperand((HasImm ? 5 : 4)));1071 auto MIB = BuildMI(MBB, MI, DL, get(Opc)).add(MI.getOperand(0))1072 .add(MI.getOperand(1)).add(MI.getOperand(2)).add(MI.getOperand(3));1073 if (HasImm)1074 MIB.add(MI.getOperand(4));1075 MIB.addReg(CSx, RegState::Implicit);1076 MBB.erase(MI);1077 return true;1078 };1079 1080 auto UseAligned = [&](const MachineInstr &MI, Align NeedAlign) {1081 if (MI.memoperands().empty())1082 return false;1083 return all_of(MI.memoperands(), [NeedAlign](const MachineMemOperand *MMO) {1084 return MMO->getAlign() >= NeedAlign;1085 });1086 };1087 1088 switch (Opc) {1089 case Hexagon::PS_call_instrprof_custom: {1090 auto Op0 = MI.getOperand(0);1091 assert(Op0.isGlobal() &&1092 "First operand must be a global containing handler name.");1093 const GlobalValue *NameVar = Op0.getGlobal();1094 const GlobalVariable *GV = dyn_cast<GlobalVariable>(NameVar);1095 auto *Arr = cast<ConstantDataArray>(GV->getInitializer());1096 StringRef NameStr = Arr->isCString() ? Arr->getAsCString() : Arr->getAsString();1097 1098 MachineOperand &Op1 = MI.getOperand(1);1099 // Set R0 with the imm value to be passed to the custom profiling handler.1100 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrsi), Hexagon::R0)1101 .addImm(Op1.getImm());1102 // The call to the custom handler is being treated as a special one as the1103 // callee is responsible for saving and restoring all the registers1104 // (including caller saved registers) it needs to modify. This is1105 // done to reduce the impact of instrumentation on the code being1106 // instrumented/profiled.1107 // NOTE: R14, R15 and R28 are reserved for PLT handling. These registers1108 // are in the Def list of the Hexagon::PS_call_instrprof_custom and1109 // therefore will be handled appropriately duing register allocation.1110 1111 // TODO: It may be a good idea to add a separate pseudo instruction for1112 // static relocation which doesn't need to reserve r14, r15 and r28.1113 1114 auto MIB = BuildMI(MBB, MI, DL, get(Hexagon::J2_call))1115 .addUse(Hexagon::R0, RegState::Implicit|RegState::InternalRead)1116 .addDef(Hexagon::R29, RegState::ImplicitDefine)1117 .addDef(Hexagon::R30, RegState::ImplicitDefine)1118 .addDef(Hexagon::R14, RegState::ImplicitDefine)1119 .addDef(Hexagon::R15, RegState::ImplicitDefine)1120 .addDef(Hexagon::R28, RegState::ImplicitDefine);1121 const char *cstr = MF.createExternalSymbolName(NameStr);1122 MIB.addExternalSymbol(cstr);1123 MBB.erase(MI);1124 return true;1125 }1126 case TargetOpcode::COPY: {1127 MachineOperand &MD = MI.getOperand(0);1128 MachineOperand &MS = MI.getOperand(1);1129 MachineBasicBlock::iterator MBBI = MI.getIterator();1130 if (MD.getReg() != MS.getReg() && !MS.isUndef()) {1131 copyPhysReg(MBB, MI, DL, MD.getReg(), MS.getReg(), MS.isKill());1132 std::prev(MBBI)->copyImplicitOps(*MBB.getParent(), MI);1133 }1134 MBB.erase(MBBI);1135 return true;1136 }1137 case Hexagon::PS_aligna:1138 BuildMI(MBB, MI, DL, get(Hexagon::A2_andir), MI.getOperand(0).getReg())1139 .addReg(HRI.getFrameRegister())1140 .addImm(-MI.getOperand(1).getImm());1141 MBB.erase(MI);1142 return true;1143 case Hexagon::V6_vassignp: {1144 Register SrcReg = MI.getOperand(1).getReg();1145 Register DstReg = MI.getOperand(0).getReg();1146 Register SrcLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);1147 Register SrcHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);1148 getLiveInRegsAt(LiveIn, MI);1149 unsigned UndefLo = getUndefRegState(!LiveIn.contains(SrcLo));1150 unsigned UndefHi = getUndefRegState(!LiveIn.contains(SrcHi));1151 unsigned Kill = getKillRegState(MI.getOperand(1).isKill());1152 BuildMI(MBB, MI, DL, get(Hexagon::V6_vcombine), DstReg)1153 .addReg(SrcHi, UndefHi)1154 .addReg(SrcLo, Kill | UndefLo);1155 MBB.erase(MI);1156 return true;1157 }1158 case Hexagon::V6_lo: {1159 Register SrcReg = MI.getOperand(1).getReg();1160 Register DstReg = MI.getOperand(0).getReg();1161 Register SrcSubLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);1162 copyPhysReg(MBB, MI, DL, DstReg, SrcSubLo, MI.getOperand(1).isKill());1163 MBB.erase(MI);1164 MRI.clearKillFlags(SrcSubLo);1165 return true;1166 }1167 case Hexagon::V6_hi: {1168 Register SrcReg = MI.getOperand(1).getReg();1169 Register DstReg = MI.getOperand(0).getReg();1170 Register SrcSubHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);1171 copyPhysReg(MBB, MI, DL, DstReg, SrcSubHi, MI.getOperand(1).isKill());1172 MBB.erase(MI);1173 MRI.clearKillFlags(SrcSubHi);1174 return true;1175 }1176 case Hexagon::PS_vloadrv_ai: {1177 Register DstReg = MI.getOperand(0).getReg();1178 const MachineOperand &BaseOp = MI.getOperand(1);1179 assert(BaseOp.getSubReg() == 0);1180 int Offset = MI.getOperand(2).getImm();1181 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);1182 unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vL32b_ai1183 : Hexagon::V6_vL32Ub_ai;1184 BuildMI(MBB, MI, DL, get(NewOpc), DstReg)1185 .addReg(BaseOp.getReg(), getRegState(BaseOp))1186 .addImm(Offset)1187 .cloneMemRefs(MI);1188 MBB.erase(MI);1189 return true;1190 }1191 case Hexagon::PS_vloadrw_ai: {1192 Register DstReg = MI.getOperand(0).getReg();1193 const MachineOperand &BaseOp = MI.getOperand(1);1194 assert(BaseOp.getSubReg() == 0);1195 int Offset = MI.getOperand(2).getImm();1196 unsigned VecOffset = HRI.getSpillSize(Hexagon::HvxVRRegClass);1197 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);1198 unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vL32b_ai1199 : Hexagon::V6_vL32Ub_ai;1200 BuildMI(MBB, MI, DL, get(NewOpc),1201 HRI.getSubReg(DstReg, Hexagon::vsub_lo))1202 .addReg(BaseOp.getReg(), getRegState(BaseOp) & ~RegState::Kill)1203 .addImm(Offset)1204 .cloneMemRefs(MI);1205 BuildMI(MBB, MI, DL, get(NewOpc),1206 HRI.getSubReg(DstReg, Hexagon::vsub_hi))1207 .addReg(BaseOp.getReg(), getRegState(BaseOp))1208 .addImm(Offset + VecOffset)1209 .cloneMemRefs(MI);1210 MBB.erase(MI);1211 return true;1212 }1213 case Hexagon::PS_vstorerv_ai: {1214 const MachineOperand &SrcOp = MI.getOperand(2);1215 assert(SrcOp.getSubReg() == 0);1216 const MachineOperand &BaseOp = MI.getOperand(0);1217 assert(BaseOp.getSubReg() == 0);1218 int Offset = MI.getOperand(1).getImm();1219 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);1220 unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vS32b_ai1221 : Hexagon::V6_vS32Ub_ai;1222 BuildMI(MBB, MI, DL, get(NewOpc))1223 .addReg(BaseOp.getReg(), getRegState(BaseOp))1224 .addImm(Offset)1225 .addReg(SrcOp.getReg(), getRegState(SrcOp))1226 .cloneMemRefs(MI);1227 MBB.erase(MI);1228 return true;1229 }1230 case Hexagon::PS_vstorerw_ai: {1231 Register SrcReg = MI.getOperand(2).getReg();1232 const MachineOperand &BaseOp = MI.getOperand(0);1233 assert(BaseOp.getSubReg() == 0);1234 int Offset = MI.getOperand(1).getImm();1235 unsigned VecOffset = HRI.getSpillSize(Hexagon::HvxVRRegClass);1236 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);1237 unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vS32b_ai1238 : Hexagon::V6_vS32Ub_ai;1239 BuildMI(MBB, MI, DL, get(NewOpc))1240 .addReg(BaseOp.getReg(), getRegState(BaseOp) & ~RegState::Kill)1241 .addImm(Offset)1242 .addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_lo))1243 .cloneMemRefs(MI);1244 BuildMI(MBB, MI, DL, get(NewOpc))1245 .addReg(BaseOp.getReg(), getRegState(BaseOp))1246 .addImm(Offset + VecOffset)1247 .addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_hi))1248 .cloneMemRefs(MI);1249 MBB.erase(MI);1250 return true;1251 }1252 case Hexagon::PS_true: {1253 Register Reg = MI.getOperand(0).getReg();1254 BuildMI(MBB, MI, DL, get(Hexagon::C2_orn), Reg)1255 .addReg(Reg, RegState::Undef)1256 .addReg(Reg, RegState::Undef);1257 MBB.erase(MI);1258 return true;1259 }1260 case Hexagon::PS_false: {1261 Register Reg = MI.getOperand(0).getReg();1262 BuildMI(MBB, MI, DL, get(Hexagon::C2_andn), Reg)1263 .addReg(Reg, RegState::Undef)1264 .addReg(Reg, RegState::Undef);1265 MBB.erase(MI);1266 return true;1267 }1268 case Hexagon::PS_qtrue: {1269 BuildMI(MBB, MI, DL, get(Hexagon::V6_veqw), MI.getOperand(0).getReg())1270 .addReg(Hexagon::V0, RegState::Undef)1271 .addReg(Hexagon::V0, RegState::Undef);1272 MBB.erase(MI);1273 return true;1274 }1275 case Hexagon::PS_qfalse: {1276 BuildMI(MBB, MI, DL, get(Hexagon::V6_vgtw), MI.getOperand(0).getReg())1277 .addReg(Hexagon::V0, RegState::Undef)1278 .addReg(Hexagon::V0, RegState::Undef);1279 MBB.erase(MI);1280 return true;1281 }1282 case Hexagon::PS_vdd0: {1283 Register Vd = MI.getOperand(0).getReg();1284 BuildMI(MBB, MI, DL, get(Hexagon::V6_vsubw_dv), Vd)1285 .addReg(Vd, RegState::Undef)1286 .addReg(Vd, RegState::Undef);1287 MBB.erase(MI);1288 return true;1289 }1290 case Hexagon::PS_vmulw: {1291 // Expand a 64-bit vector multiply into 2 32-bit scalar multiplies.1292 Register DstReg = MI.getOperand(0).getReg();1293 Register Src1Reg = MI.getOperand(1).getReg();1294 Register Src2Reg = MI.getOperand(2).getReg();1295 Register Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::isub_hi);1296 Register Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::isub_lo);1297 Register Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::isub_hi);1298 Register Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::isub_lo);1299 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_mpyi),1300 HRI.getSubReg(DstReg, Hexagon::isub_hi))1301 .addReg(Src1SubHi)1302 .addReg(Src2SubHi);1303 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_mpyi),1304 HRI.getSubReg(DstReg, Hexagon::isub_lo))1305 .addReg(Src1SubLo)1306 .addReg(Src2SubLo);1307 MBB.erase(MI);1308 MRI.clearKillFlags(Src1SubHi);1309 MRI.clearKillFlags(Src1SubLo);1310 MRI.clearKillFlags(Src2SubHi);1311 MRI.clearKillFlags(Src2SubLo);1312 return true;1313 }1314 case Hexagon::PS_vmulw_acc: {1315 // Expand 64-bit vector multiply with addition into 2 scalar multiplies.1316 Register DstReg = MI.getOperand(0).getReg();1317 Register Src1Reg = MI.getOperand(1).getReg();1318 Register Src2Reg = MI.getOperand(2).getReg();1319 Register Src3Reg = MI.getOperand(3).getReg();1320 Register Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::isub_hi);1321 Register Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::isub_lo);1322 Register Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::isub_hi);1323 Register Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::isub_lo);1324 Register Src3SubHi = HRI.getSubReg(Src3Reg, Hexagon::isub_hi);1325 Register Src3SubLo = HRI.getSubReg(Src3Reg, Hexagon::isub_lo);1326 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_maci),1327 HRI.getSubReg(DstReg, Hexagon::isub_hi))1328 .addReg(Src1SubHi)1329 .addReg(Src2SubHi)1330 .addReg(Src3SubHi);1331 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_maci),1332 HRI.getSubReg(DstReg, Hexagon::isub_lo))1333 .addReg(Src1SubLo)1334 .addReg(Src2SubLo)1335 .addReg(Src3SubLo);1336 MBB.erase(MI);1337 MRI.clearKillFlags(Src1SubHi);1338 MRI.clearKillFlags(Src1SubLo);1339 MRI.clearKillFlags(Src2SubHi);1340 MRI.clearKillFlags(Src2SubLo);1341 MRI.clearKillFlags(Src3SubHi);1342 MRI.clearKillFlags(Src3SubLo);1343 return true;1344 }1345 case Hexagon::PS_pselect: {1346 const MachineOperand &Op0 = MI.getOperand(0);1347 const MachineOperand &Op1 = MI.getOperand(1);1348 const MachineOperand &Op2 = MI.getOperand(2);1349 const MachineOperand &Op3 = MI.getOperand(3);1350 Register Rd = Op0.getReg();1351 Register Pu = Op1.getReg();1352 Register Rs = Op2.getReg();1353 Register Rt = Op3.getReg();1354 DebugLoc DL = MI.getDebugLoc();1355 unsigned K1 = getKillRegState(Op1.isKill());1356 unsigned K2 = getKillRegState(Op2.isKill());1357 unsigned K3 = getKillRegState(Op3.isKill());1358 if (Rd != Rs)1359 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrpt), Rd)1360 .addReg(Pu, (Rd == Rt) ? K1 : 0)1361 .addReg(Rs, K2);1362 if (Rd != Rt)1363 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrpf), Rd)1364 .addReg(Pu, K1)1365 .addReg(Rt, K3);1366 MBB.erase(MI);1367 return true;1368 }1369 case Hexagon::PS_vselect: {1370 const MachineOperand &Op0 = MI.getOperand(0);1371 const MachineOperand &Op1 = MI.getOperand(1);1372 const MachineOperand &Op2 = MI.getOperand(2);1373 const MachineOperand &Op3 = MI.getOperand(3);1374 getLiveOutRegsAt(LiveOut, MI);1375 bool IsDestLive = !LiveOut.available(MRI, Op0.getReg());1376 Register PReg = Op1.getReg();1377 assert(Op1.getSubReg() == 0);1378 unsigned PState = getRegState(Op1);1379 1380 if (Op0.getReg() != Op2.getReg()) {1381 unsigned S = Op0.getReg() != Op3.getReg() ? PState & ~RegState::Kill1382 : PState;1383 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vcmov))1384 .add(Op0)1385 .addReg(PReg, S)1386 .add(Op2);1387 if (IsDestLive)1388 T.addReg(Op0.getReg(), RegState::Implicit);1389 IsDestLive = true;1390 }1391 if (Op0.getReg() != Op3.getReg()) {1392 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vncmov))1393 .add(Op0)1394 .addReg(PReg, PState)1395 .add(Op3);1396 if (IsDestLive)1397 T.addReg(Op0.getReg(), RegState::Implicit);1398 }1399 MBB.erase(MI);1400 return true;1401 }1402 case Hexagon::PS_wselect: {1403 MachineOperand &Op0 = MI.getOperand(0);1404 MachineOperand &Op1 = MI.getOperand(1);1405 MachineOperand &Op2 = MI.getOperand(2);1406 MachineOperand &Op3 = MI.getOperand(3);1407 getLiveOutRegsAt(LiveOut, MI);1408 bool IsDestLive = !LiveOut.available(MRI, Op0.getReg());1409 Register PReg = Op1.getReg();1410 assert(Op1.getSubReg() == 0);1411 unsigned PState = getRegState(Op1);1412 1413 if (Op0.getReg() != Op2.getReg()) {1414 unsigned S = Op0.getReg() != Op3.getReg() ? PState & ~RegState::Kill1415 : PState;1416 Register SrcLo = HRI.getSubReg(Op2.getReg(), Hexagon::vsub_lo);1417 Register SrcHi = HRI.getSubReg(Op2.getReg(), Hexagon::vsub_hi);1418 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vccombine))1419 .add(Op0)1420 .addReg(PReg, S)1421 .addReg(SrcHi)1422 .addReg(SrcLo);1423 if (IsDestLive)1424 T.addReg(Op0.getReg(), RegState::Implicit);1425 IsDestLive = true;1426 }1427 if (Op0.getReg() != Op3.getReg()) {1428 Register SrcLo = HRI.getSubReg(Op3.getReg(), Hexagon::vsub_lo);1429 Register SrcHi = HRI.getSubReg(Op3.getReg(), Hexagon::vsub_hi);1430 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vnccombine))1431 .add(Op0)1432 .addReg(PReg, PState)1433 .addReg(SrcHi)1434 .addReg(SrcLo);1435 if (IsDestLive)1436 T.addReg(Op0.getReg(), RegState::Implicit);1437 }1438 MBB.erase(MI);1439 return true;1440 }1441 1442 case Hexagon::PS_crash: {1443 // Generate a misaligned load that is guaranteed to cause a crash.1444 class CrashPseudoSourceValue : public PseudoSourceValue {1445 public:1446 CrashPseudoSourceValue(const TargetMachine &TM)1447 : PseudoSourceValue(TargetCustom, TM) {}1448 1449 bool isConstant(const MachineFrameInfo *) const override {1450 return false;1451 }1452 bool isAliased(const MachineFrameInfo *) const override {1453 return false;1454 }1455 bool mayAlias(const MachineFrameInfo *) const override {1456 return false;1457 }1458 void printCustom(raw_ostream &OS) const override {1459 OS << "MisalignedCrash";1460 }1461 };1462 1463 static const CrashPseudoSourceValue CrashPSV(MF.getTarget());1464 MachineMemOperand *MMO = MF.getMachineMemOperand(1465 MachinePointerInfo(&CrashPSV),1466 MachineMemOperand::MOLoad | MachineMemOperand::MOVolatile, 8,1467 Align(1));1468 BuildMI(MBB, MI, DL, get(Hexagon::PS_loadrdabs), Hexagon::D13)1469 .addImm(0xBADC0FEE) // Misaligned load.1470 .addMemOperand(MMO);1471 MBB.erase(MI);1472 return true;1473 }1474 1475 case Hexagon::PS_tailcall_i:1476 MI.setDesc(get(Hexagon::J2_jump));1477 return true;1478 case Hexagon::PS_tailcall_r:1479 case Hexagon::PS_jmpret:1480 MI.setDesc(get(Hexagon::J2_jumpr));1481 return true;1482 case Hexagon::PS_jmprett:1483 MI.setDesc(get(Hexagon::J2_jumprt));1484 return true;1485 case Hexagon::PS_jmpretf:1486 MI.setDesc(get(Hexagon::J2_jumprf));1487 return true;1488 case Hexagon::PS_jmprettnewpt:1489 MI.setDesc(get(Hexagon::J2_jumprtnewpt));1490 return true;1491 case Hexagon::PS_jmpretfnewpt:1492 MI.setDesc(get(Hexagon::J2_jumprfnewpt));1493 return true;1494 case Hexagon::PS_jmprettnew:1495 MI.setDesc(get(Hexagon::J2_jumprtnew));1496 return true;1497 case Hexagon::PS_jmpretfnew:1498 MI.setDesc(get(Hexagon::J2_jumprfnew));1499 return true;1500 1501 case Hexagon::PS_loadrub_pci:1502 return RealCirc(Hexagon::L2_loadrub_pci, /*HasImm*/true, /*MxOp*/4);1503 case Hexagon::PS_loadrb_pci:1504 return RealCirc(Hexagon::L2_loadrb_pci, /*HasImm*/true, /*MxOp*/4);1505 case Hexagon::PS_loadruh_pci:1506 return RealCirc(Hexagon::L2_loadruh_pci, /*HasImm*/true, /*MxOp*/4);1507 case Hexagon::PS_loadrh_pci:1508 return RealCirc(Hexagon::L2_loadrh_pci, /*HasImm*/true, /*MxOp*/4);1509 case Hexagon::PS_loadri_pci:1510 return RealCirc(Hexagon::L2_loadri_pci, /*HasImm*/true, /*MxOp*/4);1511 case Hexagon::PS_loadrd_pci:1512 return RealCirc(Hexagon::L2_loadrd_pci, /*HasImm*/true, /*MxOp*/4);1513 case Hexagon::PS_loadrub_pcr:1514 return RealCirc(Hexagon::L2_loadrub_pcr, /*HasImm*/false, /*MxOp*/3);1515 case Hexagon::PS_loadrb_pcr:1516 return RealCirc(Hexagon::L2_loadrb_pcr, /*HasImm*/false, /*MxOp*/3);1517 case Hexagon::PS_loadruh_pcr:1518 return RealCirc(Hexagon::L2_loadruh_pcr, /*HasImm*/false, /*MxOp*/3);1519 case Hexagon::PS_loadrh_pcr:1520 return RealCirc(Hexagon::L2_loadrh_pcr, /*HasImm*/false, /*MxOp*/3);1521 case Hexagon::PS_loadri_pcr:1522 return RealCirc(Hexagon::L2_loadri_pcr, /*HasImm*/false, /*MxOp*/3);1523 case Hexagon::PS_loadrd_pcr:1524 return RealCirc(Hexagon::L2_loadrd_pcr, /*HasImm*/false, /*MxOp*/3);1525 case Hexagon::PS_storerb_pci:1526 return RealCirc(Hexagon::S2_storerb_pci, /*HasImm*/true, /*MxOp*/3);1527 case Hexagon::PS_storerh_pci:1528 return RealCirc(Hexagon::S2_storerh_pci, /*HasImm*/true, /*MxOp*/3);1529 case Hexagon::PS_storerf_pci:1530 return RealCirc(Hexagon::S2_storerf_pci, /*HasImm*/true, /*MxOp*/3);1531 case Hexagon::PS_storeri_pci:1532 return RealCirc(Hexagon::S2_storeri_pci, /*HasImm*/true, /*MxOp*/3);1533 case Hexagon::PS_storerd_pci:1534 return RealCirc(Hexagon::S2_storerd_pci, /*HasImm*/true, /*MxOp*/3);1535 case Hexagon::PS_storerb_pcr:1536 return RealCirc(Hexagon::S2_storerb_pcr, /*HasImm*/false, /*MxOp*/2);1537 case Hexagon::PS_storerh_pcr:1538 return RealCirc(Hexagon::S2_storerh_pcr, /*HasImm*/false, /*MxOp*/2);1539 case Hexagon::PS_storerf_pcr:1540 return RealCirc(Hexagon::S2_storerf_pcr, /*HasImm*/false, /*MxOp*/2);1541 case Hexagon::PS_storeri_pcr:1542 return RealCirc(Hexagon::S2_storeri_pcr, /*HasImm*/false, /*MxOp*/2);1543 case Hexagon::PS_storerd_pcr:1544 return RealCirc(Hexagon::S2_storerd_pcr, /*HasImm*/false, /*MxOp*/2);1545 }1546 1547 return false;1548}1549 1550MachineBasicBlock::instr_iterator1551HexagonInstrInfo::expandVGatherPseudo(MachineInstr &MI) const {1552 MachineBasicBlock &MBB = *MI.getParent();1553 const DebugLoc &DL = MI.getDebugLoc();1554 unsigned Opc = MI.getOpcode();1555 MachineBasicBlock::iterator First;1556 1557 switch (Opc) {1558 case Hexagon::V6_vgather_vscatter_mh_pseudo:1559 // This is mainly a place holder. It will be extended.1560 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermh))1561 .add(MI.getOperand(2))1562 .add(MI.getOperand(3))1563 .add(MI.getOperand(4));1564 BuildMI(MBB, MI, DL, get(Hexagon::V6_vscattermh))1565 .add(MI.getOperand(2))1566 .add(MI.getOperand(3))1567 .add(MI.getOperand(4))1568 .addReg(Hexagon::VTMP);1569 MBB.erase(MI);1570 return First.getInstrIterator();1571 case Hexagon::V6_vgathermh_pseudo:1572 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermh))1573 .add(MI.getOperand(2))1574 .add(MI.getOperand(3))1575 .add(MI.getOperand(4));1576 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))1577 .add(MI.getOperand(0))1578 .addImm(MI.getOperand(1).getImm())1579 .addReg(Hexagon::VTMP);1580 MBB.erase(MI);1581 return First.getInstrIterator();1582 1583 case Hexagon::V6_vgathermw_pseudo:1584 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermw))1585 .add(MI.getOperand(2))1586 .add(MI.getOperand(3))1587 .add(MI.getOperand(4));1588 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))1589 .add(MI.getOperand(0))1590 .addImm(MI.getOperand(1).getImm())1591 .addReg(Hexagon::VTMP);1592 MBB.erase(MI);1593 return First.getInstrIterator();1594 1595 case Hexagon::V6_vgathermhw_pseudo:1596 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhw))1597 .add(MI.getOperand(2))1598 .add(MI.getOperand(3))1599 .add(MI.getOperand(4));1600 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))1601 .add(MI.getOperand(0))1602 .addImm(MI.getOperand(1).getImm())1603 .addReg(Hexagon::VTMP);1604 MBB.erase(MI);1605 return First.getInstrIterator();1606 1607 case Hexagon::V6_vgathermhq_pseudo:1608 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhq))1609 .add(MI.getOperand(2))1610 .add(MI.getOperand(3))1611 .add(MI.getOperand(4))1612 .add(MI.getOperand(5));1613 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))1614 .add(MI.getOperand(0))1615 .addImm(MI.getOperand(1).getImm())1616 .addReg(Hexagon::VTMP);1617 MBB.erase(MI);1618 return First.getInstrIterator();1619 1620 case Hexagon::V6_vgathermwq_pseudo:1621 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermwq))1622 .add(MI.getOperand(2))1623 .add(MI.getOperand(3))1624 .add(MI.getOperand(4))1625 .add(MI.getOperand(5));1626 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))1627 .add(MI.getOperand(0))1628 .addImm(MI.getOperand(1).getImm())1629 .addReg(Hexagon::VTMP);1630 MBB.erase(MI);1631 return First.getInstrIterator();1632 1633 case Hexagon::V6_vgathermhwq_pseudo:1634 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhwq))1635 .add(MI.getOperand(2))1636 .add(MI.getOperand(3))1637 .add(MI.getOperand(4))1638 .add(MI.getOperand(5));1639 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))1640 .add(MI.getOperand(0))1641 .addImm(MI.getOperand(1).getImm())1642 .addReg(Hexagon::VTMP);1643 MBB.erase(MI);1644 return First.getInstrIterator();1645 }1646 1647 return MI.getIterator();1648}1649 1650// We indicate that we want to reverse the branch by1651// inserting the reversed branching opcode.1652bool HexagonInstrInfo::reverseBranchCondition(1653 SmallVectorImpl<MachineOperand> &Cond) const {1654 if (Cond.empty())1655 return true;1656 assert(Cond[0].isImm() && "First entry in the cond vector not imm-val");1657 unsigned opcode = Cond[0].getImm();1658 //unsigned temp;1659 assert(get(opcode).isBranch() && "Should be a branching condition.");1660 if (isEndLoopN(opcode))1661 return true;1662 unsigned NewOpcode = getInvertedPredicatedOpcode(opcode);1663 Cond[0].setImm(NewOpcode);1664 return false;1665}1666 1667void HexagonInstrInfo::insertNoop(MachineBasicBlock &MBB,1668 MachineBasicBlock::iterator MI) const {1669 DebugLoc DL;1670 BuildMI(MBB, MI, DL, get(Hexagon::A2_nop));1671}1672 1673bool HexagonInstrInfo::isPostIncrement(const MachineInstr &MI) const {1674 return getAddrMode(MI) == HexagonII::PostInc;1675}1676 1677// Returns true if an instruction is predicated irrespective of the predicate1678// sense. For example, all of the following will return true.1679// if (p0) R1 = add(R2, R3)1680// if (!p0) R1 = add(R2, R3)1681// if (p0.new) R1 = add(R2, R3)1682// if (!p0.new) R1 = add(R2, R3)1683// Note: New-value stores are not included here as in the current1684// implementation, we don't need to check their predicate sense.1685bool HexagonInstrInfo::isPredicated(const MachineInstr &MI) const {1686 const uint64_t F = MI.getDesc().TSFlags;1687 return (F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask;1688}1689 1690bool HexagonInstrInfo::PredicateInstruction(1691 MachineInstr &MI, ArrayRef<MachineOperand> Cond) const {1692 if (Cond.empty() || isNewValueJump(Cond[0].getImm()) ||1693 isEndLoopN(Cond[0].getImm())) {1694 LLVM_DEBUG(dbgs() << "\nCannot predicate:"; MI.dump(););1695 return false;1696 }1697 int Opc = MI.getOpcode();1698 assert (isPredicable(MI) && "Expected predicable instruction");1699 bool invertJump = predOpcodeHasNot(Cond);1700 1701 // We have to predicate MI "in place", i.e. after this function returns,1702 // MI will need to be transformed into a predicated form. To avoid com-1703 // plicated manipulations with the operands (handling tied operands,1704 // etc.), build a new temporary instruction, then overwrite MI with it.1705 1706 MachineBasicBlock &B = *MI.getParent();1707 DebugLoc DL = MI.getDebugLoc();1708 unsigned PredOpc = getCondOpcode(Opc, invertJump);1709 MachineInstrBuilder T = BuildMI(B, MI, DL, get(PredOpc));1710 unsigned NOp = 0, NumOps = MI.getNumOperands();1711 while (NOp < NumOps) {1712 MachineOperand &Op = MI.getOperand(NOp);1713 if (!Op.isReg() || !Op.isDef() || Op.isImplicit())1714 break;1715 T.add(Op);1716 NOp++;1717 }1718 1719 Register PredReg;1720 unsigned PredRegPos, PredRegFlags;1721 bool GotPredReg = getPredReg(Cond, PredReg, PredRegPos, PredRegFlags);1722 (void)GotPredReg;1723 assert(GotPredReg);1724 T.addReg(PredReg, PredRegFlags);1725 while (NOp < NumOps)1726 T.add(MI.getOperand(NOp++));1727 1728 MI.setDesc(get(PredOpc));1729 while (unsigned n = MI.getNumOperands())1730 MI.removeOperand(n-1);1731 for (unsigned i = 0, n = T->getNumOperands(); i < n; ++i)1732 MI.addOperand(T->getOperand(i));1733 1734 MachineBasicBlock::instr_iterator TI = T->getIterator();1735 B.erase(TI);1736 1737 MachineRegisterInfo &MRI = B.getParent()->getRegInfo();1738 MRI.clearKillFlags(PredReg);1739 return true;1740}1741 1742bool HexagonInstrInfo::SubsumesPredicate(ArrayRef<MachineOperand> Pred1,1743 ArrayRef<MachineOperand> Pred2) const {1744 // TODO: Fix this1745 return false;1746}1747 1748bool HexagonInstrInfo::ClobbersPredicate(MachineInstr &MI,1749 std::vector<MachineOperand> &Pred,1750 bool SkipDead) const {1751 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();1752 1753 for (const MachineOperand &MO : MI.operands()) {1754 if (MO.isReg()) {1755 if (!MO.isDef())1756 continue;1757 const TargetRegisterClass* RC = HRI.getMinimalPhysRegClass(MO.getReg());1758 if (RC == &Hexagon::PredRegsRegClass) {1759 Pred.push_back(MO);1760 return true;1761 }1762 continue;1763 } else if (MO.isRegMask()) {1764 for (Register PR : Hexagon::PredRegsRegClass) {1765 if (!MI.modifiesRegister(PR, &HRI))1766 continue;1767 Pred.push_back(MO);1768 return true;1769 }1770 }1771 }1772 return false;1773}1774 1775bool HexagonInstrInfo::isPredicable(const MachineInstr &MI) const {1776 if (!MI.getDesc().isPredicable())1777 return false;1778 1779 if (MI.isCall() || isTailCall(MI)) {1780 if (!Subtarget.usePredicatedCalls())1781 return false;1782 }1783 1784 // HVX loads are not predicable on v60, but are on v62.1785 if (!Subtarget.hasV62Ops()) {1786 switch (MI.getOpcode()) {1787 case Hexagon::V6_vL32b_ai:1788 case Hexagon::V6_vL32b_pi:1789 case Hexagon::V6_vL32b_ppu:1790 case Hexagon::V6_vL32b_cur_ai:1791 case Hexagon::V6_vL32b_cur_pi:1792 case Hexagon::V6_vL32b_cur_ppu:1793 case Hexagon::V6_vL32b_nt_ai:1794 case Hexagon::V6_vL32b_nt_pi:1795 case Hexagon::V6_vL32b_nt_ppu:1796 case Hexagon::V6_vL32b_tmp_ai:1797 case Hexagon::V6_vL32b_tmp_pi:1798 case Hexagon::V6_vL32b_tmp_ppu:1799 case Hexagon::V6_vL32b_nt_cur_ai:1800 case Hexagon::V6_vL32b_nt_cur_pi:1801 case Hexagon::V6_vL32b_nt_cur_ppu:1802 case Hexagon::V6_vL32b_nt_tmp_ai:1803 case Hexagon::V6_vL32b_nt_tmp_pi:1804 case Hexagon::V6_vL32b_nt_tmp_ppu:1805 return false;1806 }1807 }1808 return true;1809}1810 1811bool HexagonInstrInfo::isSchedulingBoundary(const MachineInstr &MI,1812 const MachineBasicBlock *MBB,1813 const MachineFunction &MF) const {1814 // Debug info is never a scheduling boundary. It's necessary to be explicit1815 // due to the special treatment of IT instructions below, otherwise a1816 // dbg_value followed by an IT will result in the IT instruction being1817 // considered a scheduling hazard, which is wrong. It should be the actual1818 // instruction preceding the dbg_value instruction(s), just like it is1819 // when debug info is not present.1820 if (MI.isDebugInstr())1821 return false;1822 1823 // Throwing call is a boundary.1824 if (MI.isCall()) {1825 // Don't mess around with no return calls.1826 if (doesNotReturn(MI))1827 return true;1828 // If any of the block's successors is a landing pad, this could be a1829 // throwing call.1830 for (auto *I : MBB->successors())1831 if (I->isEHPad())1832 return true;1833 }1834 1835 // Terminators and labels can't be scheduled around.1836 if (MI.getDesc().isTerminator() || MI.isPosition())1837 return true;1838 1839 // INLINEASM_BR can jump to another block1840 if (MI.getOpcode() == TargetOpcode::INLINEASM_BR)1841 return true;1842 1843 if (MI.isInlineAsm() && !ScheduleInlineAsm)1844 return true;1845 1846 return false;1847}1848 1849/// Measure the specified inline asm to determine an approximation of its1850/// length.1851/// Comments (which run till the next SeparatorString or newline) do not1852/// count as an instruction.1853/// Any other non-whitespace text is considered an instruction, with1854/// multiple instructions separated by SeparatorString or newlines.1855/// Variable-length instructions are not handled here; this function1856/// may be overloaded in the target code to do that.1857/// Hexagon counts the number of ##'s and adjust for that many1858/// constant exenders.1859unsigned HexagonInstrInfo::getInlineAsmLength(const char *Str,1860 const MCAsmInfo &MAI,1861 const TargetSubtargetInfo *STI) const {1862 StringRef AStr(Str);1863 // Count the number of instructions in the asm.1864 bool atInsnStart = true;1865 unsigned Length = 0;1866 const unsigned MaxInstLength = MAI.getMaxInstLength(STI);1867 for (; *Str; ++Str) {1868 if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),1869 strlen(MAI.getSeparatorString())) == 0)1870 atInsnStart = true;1871 if (atInsnStart && !isSpace(static_cast<unsigned char>(*Str))) {1872 Length += MaxInstLength;1873 atInsnStart = false;1874 }1875 if (atInsnStart && strncmp(Str, MAI.getCommentString().data(),1876 MAI.getCommentString().size()) == 0)1877 atInsnStart = false;1878 }1879 1880 // Add to size number of constant extenders seen * 4.1881 StringRef Occ("##");1882 Length += AStr.count(Occ)*4;1883 return Length;1884}1885 1886ScheduleHazardRecognizer*1887HexagonInstrInfo::CreateTargetPostRAHazardRecognizer(1888 const InstrItineraryData *II, const ScheduleDAG *DAG) const {1889 if (UseDFAHazardRec)1890 return new HexagonHazardRecognizer(II, this, Subtarget);1891 return TargetInstrInfo::CreateTargetPostRAHazardRecognizer(II, DAG);1892}1893 1894/// For a comparison instruction, return the source registers in1895/// \p SrcReg and \p SrcReg2 if having two register operands, and the value it1896/// compares against in CmpValue. Return true if the comparison instruction1897/// can be analyzed.1898bool HexagonInstrInfo::analyzeCompare(const MachineInstr &MI, Register &SrcReg,1899 Register &SrcReg2, int64_t &Mask,1900 int64_t &Value) const {1901 unsigned Opc = MI.getOpcode();1902 1903 // Set mask and the first source register.1904 switch (Opc) {1905 case Hexagon::C2_cmpeq:1906 case Hexagon::C2_cmpeqp:1907 case Hexagon::C2_cmpgt:1908 case Hexagon::C2_cmpgtp:1909 case Hexagon::C2_cmpgtu:1910 case Hexagon::C2_cmpgtup:1911 case Hexagon::C4_cmpneq:1912 case Hexagon::C4_cmplte:1913 case Hexagon::C4_cmplteu:1914 case Hexagon::C2_cmpeqi:1915 case Hexagon::C2_cmpgti:1916 case Hexagon::C2_cmpgtui:1917 case Hexagon::C4_cmpneqi:1918 case Hexagon::C4_cmplteui:1919 case Hexagon::C4_cmpltei:1920 SrcReg = MI.getOperand(1).getReg();1921 Mask = ~0;1922 break;1923 case Hexagon::A4_cmpbeq:1924 case Hexagon::A4_cmpbgt:1925 case Hexagon::A4_cmpbgtu:1926 case Hexagon::A4_cmpbeqi:1927 case Hexagon::A4_cmpbgti:1928 case Hexagon::A4_cmpbgtui:1929 SrcReg = MI.getOperand(1).getReg();1930 Mask = 0xFF;1931 break;1932 case Hexagon::A4_cmpheq:1933 case Hexagon::A4_cmphgt:1934 case Hexagon::A4_cmphgtu:1935 case Hexagon::A4_cmpheqi:1936 case Hexagon::A4_cmphgti:1937 case Hexagon::A4_cmphgtui:1938 SrcReg = MI.getOperand(1).getReg();1939 Mask = 0xFFFF;1940 break;1941 }1942 1943 // Set the value/second source register.1944 switch (Opc) {1945 case Hexagon::C2_cmpeq:1946 case Hexagon::C2_cmpeqp:1947 case Hexagon::C2_cmpgt:1948 case Hexagon::C2_cmpgtp:1949 case Hexagon::C2_cmpgtu:1950 case Hexagon::C2_cmpgtup:1951 case Hexagon::A4_cmpbeq:1952 case Hexagon::A4_cmpbgt:1953 case Hexagon::A4_cmpbgtu:1954 case Hexagon::A4_cmpheq:1955 case Hexagon::A4_cmphgt:1956 case Hexagon::A4_cmphgtu:1957 case Hexagon::C4_cmpneq:1958 case Hexagon::C4_cmplte:1959 case Hexagon::C4_cmplteu:1960 SrcReg2 = MI.getOperand(2).getReg();1961 Value = 0;1962 return true;1963 1964 case Hexagon::C2_cmpeqi:1965 case Hexagon::C2_cmpgtui:1966 case Hexagon::C2_cmpgti:1967 case Hexagon::C4_cmpneqi:1968 case Hexagon::C4_cmplteui:1969 case Hexagon::C4_cmpltei:1970 case Hexagon::A4_cmpbeqi:1971 case Hexagon::A4_cmpbgti:1972 case Hexagon::A4_cmpbgtui:1973 case Hexagon::A4_cmpheqi:1974 case Hexagon::A4_cmphgti:1975 case Hexagon::A4_cmphgtui: {1976 SrcReg2 = 0;1977 const MachineOperand &Op2 = MI.getOperand(2);1978 if (!Op2.isImm())1979 return false;1980 Value = MI.getOperand(2).getImm();1981 return true;1982 }1983 }1984 1985 return false;1986}1987 1988unsigned HexagonInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,1989 const MachineInstr &MI,1990 unsigned *PredCost) const {1991 return getInstrTimingClassLatency(ItinData, MI);1992}1993 1994DFAPacketizer *HexagonInstrInfo::CreateTargetScheduleState(1995 const TargetSubtargetInfo &STI) const {1996 const InstrItineraryData *II = STI.getInstrItineraryData();1997 return static_cast<const HexagonSubtarget&>(STI).createDFAPacketizer(II);1998}1999 2000// Inspired by this pair:2001// %r13 = L2_loadri_io %r29, 136; mem:LD4[FixedStack0]2002// S2_storeri_io %r29, 132, killed %r1; flags: mem:ST4[FixedStack1]2003// Currently AA considers the addresses in these instructions to be aliasing.2004bool HexagonInstrInfo::areMemAccessesTriviallyDisjoint(2005 const MachineInstr &MIa, const MachineInstr &MIb) const {2006 if (MIa.hasUnmodeledSideEffects() || MIb.hasUnmodeledSideEffects() ||2007 MIa.hasOrderedMemoryRef() || MIb.hasOrderedMemoryRef())2008 return false;2009 2010 // Instructions that are pure loads, not loads and stores like memops are not2011 // dependent.2012 if (MIa.mayLoad() && !isMemOp(MIa) && MIb.mayLoad() && !isMemOp(MIb))2013 return true;2014 2015 // Get the base register in MIa.2016 unsigned BasePosA, OffsetPosA;2017 if (!getBaseAndOffsetPosition(MIa, BasePosA, OffsetPosA))2018 return false;2019 const MachineOperand &BaseA = MIa.getOperand(BasePosA);2020 Register BaseRegA = BaseA.getReg();2021 unsigned BaseSubA = BaseA.getSubReg();2022 2023 // Get the base register in MIb.2024 unsigned BasePosB, OffsetPosB;2025 if (!getBaseAndOffsetPosition(MIb, BasePosB, OffsetPosB))2026 return false;2027 const MachineOperand &BaseB = MIb.getOperand(BasePosB);2028 Register BaseRegB = BaseB.getReg();2029 unsigned BaseSubB = BaseB.getSubReg();2030 2031 if (BaseRegA != BaseRegB || BaseSubA != BaseSubB)2032 return false;2033 2034 // Get the access sizes.2035 unsigned SizeA = getMemAccessSize(MIa);2036 unsigned SizeB = getMemAccessSize(MIb);2037 2038 // Get the offsets. Handle immediates only for now.2039 const MachineOperand &OffA = MIa.getOperand(OffsetPosA);2040 const MachineOperand &OffB = MIb.getOperand(OffsetPosB);2041 if (!MIa.getOperand(OffsetPosA).isImm() ||2042 !MIb.getOperand(OffsetPosB).isImm())2043 return false;2044 int OffsetA = isPostIncrement(MIa) ? 0 : OffA.getImm();2045 int OffsetB = isPostIncrement(MIb) ? 0 : OffB.getImm();2046 2047 // This is a mem access with the same base register and known offsets from it.2048 // Reason about it.2049 if (OffsetA > OffsetB) {2050 uint64_t OffDiff = (uint64_t)((int64_t)OffsetA - (int64_t)OffsetB);2051 return SizeB <= OffDiff;2052 }2053 if (OffsetA < OffsetB) {2054 uint64_t OffDiff = (uint64_t)((int64_t)OffsetB - (int64_t)OffsetA);2055 return SizeA <= OffDiff;2056 }2057 2058 return false;2059}2060 2061/// If the instruction is an increment of a constant value, return the amount.2062bool HexagonInstrInfo::getIncrementValue(const MachineInstr &MI,2063 int &Value) const {2064 if (isPostIncrement(MI)) {2065 unsigned BasePos = 0, OffsetPos = 0;2066 if (!getBaseAndOffsetPosition(MI, BasePos, OffsetPos))2067 return false;2068 const MachineOperand &OffsetOp = MI.getOperand(OffsetPos);2069 if (OffsetOp.isImm()) {2070 Value = OffsetOp.getImm();2071 return true;2072 }2073 } else if (MI.getOpcode() == Hexagon::A2_addi) {2074 const MachineOperand &AddOp = MI.getOperand(2);2075 if (AddOp.isImm()) {2076 Value = AddOp.getImm();2077 return true;2078 }2079 }2080 2081 return false;2082}2083 2084std::pair<unsigned, unsigned>2085HexagonInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {2086 return std::make_pair(TF & ~HexagonII::MO_Bitmasks,2087 TF & HexagonII::MO_Bitmasks);2088}2089 2090ArrayRef<std::pair<unsigned, const char*>>2091HexagonInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {2092 using namespace HexagonII;2093 2094 static const std::pair<unsigned, const char*> Flags[] = {2095 {MO_PCREL, "hexagon-pcrel"},2096 {MO_GOT, "hexagon-got"},2097 {MO_LO16, "hexagon-lo16"},2098 {MO_HI16, "hexagon-hi16"},2099 {MO_GPREL, "hexagon-gprel"},2100 {MO_GDGOT, "hexagon-gdgot"},2101 {MO_GDPLT, "hexagon-gdplt"},2102 {MO_IE, "hexagon-ie"},2103 {MO_IEGOT, "hexagon-iegot"},2104 {MO_TPREL, "hexagon-tprel"}2105 };2106 return ArrayRef(Flags);2107}2108 2109ArrayRef<std::pair<unsigned, const char*>>2110HexagonInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {2111 using namespace HexagonII;2112 2113 static const std::pair<unsigned, const char*> Flags[] = {2114 {HMOTF_ConstExtended, "hexagon-ext"}2115 };2116 return ArrayRef(Flags);2117}2118 2119Register HexagonInstrInfo::createVR(MachineFunction *MF, MVT VT) const {2120 MachineRegisterInfo &MRI = MF->getRegInfo();2121 const TargetRegisterClass *TRC;2122 if (VT == MVT::i1) {2123 TRC = &Hexagon::PredRegsRegClass;2124 } else if (VT == MVT::i32 || VT == MVT::f32) {2125 TRC = &Hexagon::IntRegsRegClass;2126 } else if (VT == MVT::i64 || VT == MVT::f64) {2127 TRC = &Hexagon::DoubleRegsRegClass;2128 } else {2129 llvm_unreachable("Cannot handle this register class");2130 }2131 2132 Register NewReg = MRI.createVirtualRegister(TRC);2133 return NewReg;2134}2135 2136bool HexagonInstrInfo::isAbsoluteSet(const MachineInstr &MI) const {2137 return (getAddrMode(MI) == HexagonII::AbsoluteSet);2138}2139 2140bool HexagonInstrInfo::isAccumulator(const MachineInstr &MI) const {2141 const uint64_t F = MI.getDesc().TSFlags;2142 return((F >> HexagonII::AccumulatorPos) & HexagonII::AccumulatorMask);2143}2144 2145bool HexagonInstrInfo::isBaseImmOffset(const MachineInstr &MI) const {2146 return getAddrMode(MI) == HexagonII::BaseImmOffset;2147}2148 2149bool HexagonInstrInfo::isComplex(const MachineInstr &MI) const {2150 return !isTC1(MI) && !isTC2Early(MI) && !MI.getDesc().mayLoad() &&2151 !MI.getDesc().mayStore() &&2152 MI.getDesc().getOpcode() != Hexagon::S2_allocframe &&2153 MI.getDesc().getOpcode() != Hexagon::L2_deallocframe &&2154 !isMemOp(MI) && !MI.isBranch() && !MI.isReturn() && !MI.isCall();2155}2156 2157// Return true if the instruction is a compound branch instruction.2158bool HexagonInstrInfo::isCompoundBranchInstr(const MachineInstr &MI) const {2159 return getType(MI) == HexagonII::TypeCJ && MI.isBranch();2160}2161 2162// TODO: In order to have isExtendable for fpimm/f32Ext, we need to handle2163// isFPImm and later getFPImm as well.2164bool HexagonInstrInfo::isConstExtended(const MachineInstr &MI) const {2165 const uint64_t F = MI.getDesc().TSFlags;2166 unsigned isExtended = (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;2167 if (isExtended) // Instruction must be extended.2168 return true;2169 2170 unsigned isExtendable =2171 (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask;2172 if (!isExtendable)2173 return false;2174 2175 if (MI.isCall())2176 return false;2177 2178 short ExtOpNum = getCExtOpNum(MI);2179 const MachineOperand &MO = MI.getOperand(ExtOpNum);2180 // Use MO operand flags to determine if MO2181 // has the HMOTF_ConstExtended flag set.2182 if (MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended)2183 return true;2184 // If this is a Machine BB address we are talking about, and it is2185 // not marked as extended, say so.2186 if (MO.isMBB())2187 return false;2188 2189 // We could be using an instruction with an extendable immediate and shoehorn2190 // a global address into it. If it is a global address it will be constant2191 // extended. We do this for COMBINE.2192 if (MO.isGlobal() || MO.isSymbol() || MO.isBlockAddress() ||2193 MO.isJTI() || MO.isCPI() || MO.isFPImm())2194 return true;2195 2196 // If the extendable operand is not 'Immediate' type, the instruction should2197 // have 'isExtended' flag set.2198 assert(MO.isImm() && "Extendable operand must be Immediate type");2199 2200 int64_t Value = MO.getImm();2201 if ((F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask) {2202 int32_t SValue = Value;2203 int32_t MinValue = getMinValue(MI);2204 int32_t MaxValue = getMaxValue(MI);2205 return SValue < MinValue || SValue > MaxValue;2206 }2207 uint32_t UValue = Value;2208 uint32_t MinValue = getMinValue(MI);2209 uint32_t MaxValue = getMaxValue(MI);2210 return UValue < MinValue || UValue > MaxValue;2211}2212 2213bool HexagonInstrInfo::isDeallocRet(const MachineInstr &MI) const {2214 switch (MI.getOpcode()) {2215 case Hexagon::L4_return:2216 case Hexagon::L4_return_t:2217 case Hexagon::L4_return_f:2218 case Hexagon::L4_return_tnew_pnt:2219 case Hexagon::L4_return_fnew_pnt:2220 case Hexagon::L4_return_tnew_pt:2221 case Hexagon::L4_return_fnew_pt:2222 return true;2223 }2224 return false;2225}2226 2227// Return true when ConsMI uses a register defined by ProdMI.2228bool HexagonInstrInfo::isDependent(const MachineInstr &ProdMI,2229 const MachineInstr &ConsMI) const {2230 if (!ProdMI.getDesc().getNumDefs())2231 return false;2232 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();2233 2234 SmallVector<Register, 4> DefsA;2235 SmallVector<Register, 4> DefsB;2236 SmallVector<Register, 8> UsesA;2237 SmallVector<Register, 8> UsesB;2238 2239 parseOperands(ProdMI, DefsA, UsesA);2240 parseOperands(ConsMI, DefsB, UsesB);2241 2242 for (auto &RegA : DefsA)2243 for (auto &RegB : UsesB) {2244 // True data dependency.2245 if (RegA == RegB)2246 return true;2247 2248 if (RegA.isPhysical() && llvm::is_contained(HRI.subregs(RegA), RegB))2249 return true;2250 2251 if (RegB.isPhysical() && llvm::is_contained(HRI.subregs(RegB), RegA))2252 return true;2253 }2254 2255 return false;2256}2257 2258// Returns true if the instruction is already a .cur.2259bool HexagonInstrInfo::isDotCurInst(const MachineInstr &MI) const {2260 switch (MI.getOpcode()) {2261 case Hexagon::V6_vL32b_cur_pi:2262 case Hexagon::V6_vL32b_cur_ai:2263 return true;2264 }2265 return false;2266}2267 2268// Returns true, if any one of the operands is a dot new2269// insn, whether it is predicated dot new or register dot new.2270bool HexagonInstrInfo::isDotNewInst(const MachineInstr &MI) const {2271 if (isNewValueInst(MI) || (isPredicated(MI) && isPredicatedNew(MI)))2272 return true;2273 2274 return false;2275}2276 2277/// Symmetrical. See if these two instructions are fit for duplex pair.2278bool HexagonInstrInfo::isDuplexPair(const MachineInstr &MIa,2279 const MachineInstr &MIb) const {2280 HexagonII::SubInstructionGroup MIaG = getDuplexCandidateGroup(MIa);2281 HexagonII::SubInstructionGroup MIbG = getDuplexCandidateGroup(MIb);2282 return (isDuplexPairMatch(MIaG, MIbG) || isDuplexPairMatch(MIbG, MIaG));2283}2284 2285bool HexagonInstrInfo::isEndLoopN(unsigned Opcode) const {2286 return (Opcode == Hexagon::ENDLOOP0 ||2287 Opcode == Hexagon::ENDLOOP1);2288}2289 2290bool HexagonInstrInfo::isExpr(unsigned OpType) const {2291 switch(OpType) {2292 case MachineOperand::MO_MachineBasicBlock:2293 case MachineOperand::MO_GlobalAddress:2294 case MachineOperand::MO_ExternalSymbol:2295 case MachineOperand::MO_JumpTableIndex:2296 case MachineOperand::MO_ConstantPoolIndex:2297 case MachineOperand::MO_BlockAddress:2298 return true;2299 default:2300 return false;2301 }2302}2303 2304bool HexagonInstrInfo::isExtendable(const MachineInstr &MI) const {2305 const MCInstrDesc &MID = MI.getDesc();2306 const uint64_t F = MID.TSFlags;2307 if ((F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask)2308 return true;2309 2310 // TODO: This is largely obsolete now. Will need to be removed2311 // in consecutive patches.2312 switch (MI.getOpcode()) {2313 // PS_fi and PS_fia remain special cases.2314 case Hexagon::PS_fi:2315 case Hexagon::PS_fia:2316 return true;2317 default:2318 return false;2319 }2320 return false;2321}2322 2323// This returns true in two cases:2324// - The OP code itself indicates that this is an extended instruction.2325// - One of MOs has been marked with HMOTF_ConstExtended flag.2326bool HexagonInstrInfo::isExtended(const MachineInstr &MI) const {2327 // First check if this is permanently extended op code.2328 const uint64_t F = MI.getDesc().TSFlags;2329 if ((F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask)2330 return true;2331 // Use MO operand flags to determine if one of MI's operands2332 // has HMOTF_ConstExtended flag set.2333 for (const MachineOperand &MO : MI.operands())2334 if (MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended)2335 return true;2336 return false;2337}2338 2339bool HexagonInstrInfo::isFloat(const MachineInstr &MI) const {2340 unsigned Opcode = MI.getOpcode();2341 const uint64_t F = get(Opcode).TSFlags;2342 return (F >> HexagonII::FPPos) & HexagonII::FPMask;2343}2344 2345// No V60 HVX VMEM with A_INDIRECT.2346bool HexagonInstrInfo::isHVXMemWithAIndirect(const MachineInstr &I,2347 const MachineInstr &J) const {2348 if (!isHVXVec(I))2349 return false;2350 if (!I.mayLoad() && !I.mayStore())2351 return false;2352 return J.isIndirectBranch() || isIndirectCall(J) || isIndirectL4Return(J);2353}2354 2355bool HexagonInstrInfo::isIndirectCall(const MachineInstr &MI) const {2356 switch (MI.getOpcode()) {2357 case Hexagon::J2_callr:2358 case Hexagon::J2_callrf:2359 case Hexagon::J2_callrt:2360 case Hexagon::PS_call_nr:2361 return true;2362 }2363 return false;2364}2365 2366bool HexagonInstrInfo::isIndirectL4Return(const MachineInstr &MI) const {2367 switch (MI.getOpcode()) {2368 case Hexagon::L4_return:2369 case Hexagon::L4_return_t:2370 case Hexagon::L4_return_f:2371 case Hexagon::L4_return_fnew_pnt:2372 case Hexagon::L4_return_fnew_pt:2373 case Hexagon::L4_return_tnew_pnt:2374 case Hexagon::L4_return_tnew_pt:2375 return true;2376 }2377 return false;2378}2379 2380bool HexagonInstrInfo::isJumpR(const MachineInstr &MI) const {2381 switch (MI.getOpcode()) {2382 case Hexagon::J2_jumpr:2383 case Hexagon::J2_jumprt:2384 case Hexagon::J2_jumprf:2385 case Hexagon::J2_jumprtnewpt:2386 case Hexagon::J2_jumprfnewpt:2387 case Hexagon::J2_jumprtnew:2388 case Hexagon::J2_jumprfnew:2389 return true;2390 }2391 return false;2392}2393 2394// Return true if a given MI can accommodate given offset.2395// Use abs estimate as oppose to the exact number.2396// TODO: This will need to be changed to use MC level2397// definition of instruction extendable field size.2398bool HexagonInstrInfo::isJumpWithinBranchRange(const MachineInstr &MI,2399 unsigned offset) const {2400 // This selection of jump instructions matches to that what2401 // analyzeBranch can parse, plus NVJ.2402 if (isNewValueJump(MI)) // r9:22403 return isInt<11>(offset);2404 2405 switch (MI.getOpcode()) {2406 // Still missing Jump to address condition on register value.2407 default:2408 return false;2409 case Hexagon::J2_jump: // bits<24> dst; // r22:22410 case Hexagon::J2_call:2411 case Hexagon::PS_call_nr:2412 return isInt<24>(offset);2413 case Hexagon::J2_jumpt: //bits<17> dst; // r15:22414 case Hexagon::J2_jumpf:2415 case Hexagon::J2_jumptnew:2416 case Hexagon::J2_jumptnewpt:2417 case Hexagon::J2_jumpfnew:2418 case Hexagon::J2_jumpfnewpt:2419 case Hexagon::J2_callt:2420 case Hexagon::J2_callf:2421 return isInt<17>(offset);2422 case Hexagon::J2_loop0i:2423 case Hexagon::J2_loop0iext:2424 case Hexagon::J2_loop0r:2425 case Hexagon::J2_loop0rext:2426 case Hexagon::J2_loop1i:2427 case Hexagon::J2_loop1iext:2428 case Hexagon::J2_loop1r:2429 case Hexagon::J2_loop1rext:2430 return isInt<9>(offset);2431 // TODO: Add all the compound branches here. Can we do this in Relation model?2432 case Hexagon::J4_cmpeqi_tp0_jump_nt:2433 case Hexagon::J4_cmpeqi_tp1_jump_nt:2434 case Hexagon::J4_cmpeqn1_tp0_jump_nt:2435 case Hexagon::J4_cmpeqn1_tp1_jump_nt:2436 return isInt<11>(offset);2437 }2438}2439 2440bool HexagonInstrInfo::isLateSourceInstr(const MachineInstr &MI) const {2441 // Instructions with iclass A_CVI_VX and attribute A_CVI_LATE uses a multiply2442 // resource, but all operands can be received late like an ALU instruction.2443 return getType(MI) == HexagonII::TypeCVI_VX_LATE;2444}2445 2446bool HexagonInstrInfo::isLoopN(const MachineInstr &MI) const {2447 unsigned Opcode = MI.getOpcode();2448 return Opcode == Hexagon::J2_loop0i ||2449 Opcode == Hexagon::J2_loop0r ||2450 Opcode == Hexagon::J2_loop0iext ||2451 Opcode == Hexagon::J2_loop0rext ||2452 Opcode == Hexagon::J2_loop1i ||2453 Opcode == Hexagon::J2_loop1r ||2454 Opcode == Hexagon::J2_loop1iext ||2455 Opcode == Hexagon::J2_loop1rext;2456}2457 2458bool HexagonInstrInfo::isMemOp(const MachineInstr &MI) const {2459 switch (MI.getOpcode()) {2460 default: return false;2461 case Hexagon::L4_iadd_memopw_io:2462 case Hexagon::L4_isub_memopw_io:2463 case Hexagon::L4_add_memopw_io:2464 case Hexagon::L4_sub_memopw_io:2465 case Hexagon::L4_and_memopw_io:2466 case Hexagon::L4_or_memopw_io:2467 case Hexagon::L4_iadd_memoph_io:2468 case Hexagon::L4_isub_memoph_io:2469 case Hexagon::L4_add_memoph_io:2470 case Hexagon::L4_sub_memoph_io:2471 case Hexagon::L4_and_memoph_io:2472 case Hexagon::L4_or_memoph_io:2473 case Hexagon::L4_iadd_memopb_io:2474 case Hexagon::L4_isub_memopb_io:2475 case Hexagon::L4_add_memopb_io:2476 case Hexagon::L4_sub_memopb_io:2477 case Hexagon::L4_and_memopb_io:2478 case Hexagon::L4_or_memopb_io:2479 case Hexagon::L4_ior_memopb_io:2480 case Hexagon::L4_ior_memoph_io:2481 case Hexagon::L4_ior_memopw_io:2482 case Hexagon::L4_iand_memopb_io:2483 case Hexagon::L4_iand_memoph_io:2484 case Hexagon::L4_iand_memopw_io:2485 return true;2486 }2487 return false;2488}2489 2490bool HexagonInstrInfo::isNewValue(const MachineInstr &MI) const {2491 const uint64_t F = MI.getDesc().TSFlags;2492 return (F >> HexagonII::NewValuePos) & HexagonII::NewValueMask;2493}2494 2495bool HexagonInstrInfo::isNewValue(unsigned Opcode) const {2496 const uint64_t F = get(Opcode).TSFlags;2497 return (F >> HexagonII::NewValuePos) & HexagonII::NewValueMask;2498}2499 2500bool HexagonInstrInfo::isNewValueInst(const MachineInstr &MI) const {2501 return isNewValueJump(MI) || isNewValueStore(MI);2502}2503 2504bool HexagonInstrInfo::isNewValueJump(const MachineInstr &MI) const {2505 return isNewValue(MI) && MI.isBranch();2506}2507 2508bool HexagonInstrInfo::isNewValueJump(unsigned Opcode) const {2509 return isNewValue(Opcode) && get(Opcode).isBranch() && isPredicated(Opcode);2510}2511 2512bool HexagonInstrInfo::isNewValueStore(const MachineInstr &MI) const {2513 const uint64_t F = MI.getDesc().TSFlags;2514 return (F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask;2515}2516 2517bool HexagonInstrInfo::isNewValueStore(unsigned Opcode) const {2518 const uint64_t F = get(Opcode).TSFlags;2519 return (F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask;2520}2521 2522// Returns true if a particular operand is extendable for an instruction.2523bool HexagonInstrInfo::isOperandExtended(const MachineInstr &MI,2524 unsigned OperandNum) const {2525 const uint64_t F = MI.getDesc().TSFlags;2526 return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask)2527 == OperandNum;2528}2529 2530bool HexagonInstrInfo::isPredicatedNew(const MachineInstr &MI) const {2531 const uint64_t F = MI.getDesc().TSFlags;2532 assert(isPredicated(MI));2533 return (F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask;2534}2535 2536bool HexagonInstrInfo::isPredicatedNew(unsigned Opcode) const {2537 const uint64_t F = get(Opcode).TSFlags;2538 assert(isPredicated(Opcode));2539 return (F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask;2540}2541 2542bool HexagonInstrInfo::isPredicatedTrue(const MachineInstr &MI) const {2543 const uint64_t F = MI.getDesc().TSFlags;2544 return !((F >> HexagonII::PredicatedFalsePos) &2545 HexagonII::PredicatedFalseMask);2546}2547 2548bool HexagonInstrInfo::isPredicatedTrue(unsigned Opcode) const {2549 const uint64_t F = get(Opcode).TSFlags;2550 // Make sure that the instruction is predicated.2551 assert((F>> HexagonII::PredicatedPos) & HexagonII::PredicatedMask);2552 return !((F >> HexagonII::PredicatedFalsePos) &2553 HexagonII::PredicatedFalseMask);2554}2555 2556bool HexagonInstrInfo::isPredicated(unsigned Opcode) const {2557 const uint64_t F = get(Opcode).TSFlags;2558 return (F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask;2559}2560 2561bool HexagonInstrInfo::isPredicateLate(unsigned Opcode) const {2562 const uint64_t F = get(Opcode).TSFlags;2563 return (F >> HexagonII::PredicateLatePos) & HexagonII::PredicateLateMask;2564}2565 2566bool HexagonInstrInfo::isPredictedTaken(unsigned Opcode) const {2567 const uint64_t F = get(Opcode).TSFlags;2568 assert(get(Opcode).isBranch() &&2569 (isPredicatedNew(Opcode) || isNewValue(Opcode)));2570 return (F >> HexagonII::TakenPos) & HexagonII::TakenMask;2571}2572 2573bool HexagonInstrInfo::isSaveCalleeSavedRegsCall(const MachineInstr &MI) const {2574 return MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4 ||2575 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT ||2576 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_PIC ||2577 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC;2578}2579 2580bool HexagonInstrInfo::isSignExtendingLoad(const MachineInstr &MI) const {2581 switch (MI.getOpcode()) {2582 // Byte2583 case Hexagon::L2_loadrb_io:2584 case Hexagon::L4_loadrb_ur:2585 case Hexagon::L4_loadrb_ap:2586 case Hexagon::L2_loadrb_pr:2587 case Hexagon::L2_loadrb_pbr:2588 case Hexagon::L2_loadrb_pi:2589 case Hexagon::L2_loadrb_pci:2590 case Hexagon::L2_loadrb_pcr:2591 case Hexagon::L2_loadbsw2_io:2592 case Hexagon::L4_loadbsw2_ur:2593 case Hexagon::L4_loadbsw2_ap:2594 case Hexagon::L2_loadbsw2_pr:2595 case Hexagon::L2_loadbsw2_pbr:2596 case Hexagon::L2_loadbsw2_pi:2597 case Hexagon::L2_loadbsw2_pci:2598 case Hexagon::L2_loadbsw2_pcr:2599 case Hexagon::L2_loadbsw4_io:2600 case Hexagon::L4_loadbsw4_ur:2601 case Hexagon::L4_loadbsw4_ap:2602 case Hexagon::L2_loadbsw4_pr:2603 case Hexagon::L2_loadbsw4_pbr:2604 case Hexagon::L2_loadbsw4_pi:2605 case Hexagon::L2_loadbsw4_pci:2606 case Hexagon::L2_loadbsw4_pcr:2607 case Hexagon::L4_loadrb_rr:2608 case Hexagon::L2_ploadrbt_io:2609 case Hexagon::L2_ploadrbt_pi:2610 case Hexagon::L2_ploadrbf_io:2611 case Hexagon::L2_ploadrbf_pi:2612 case Hexagon::L2_ploadrbtnew_io:2613 case Hexagon::L2_ploadrbfnew_io:2614 case Hexagon::L4_ploadrbt_rr:2615 case Hexagon::L4_ploadrbf_rr:2616 case Hexagon::L4_ploadrbtnew_rr:2617 case Hexagon::L4_ploadrbfnew_rr:2618 case Hexagon::L2_ploadrbtnew_pi:2619 case Hexagon::L2_ploadrbfnew_pi:2620 case Hexagon::L4_ploadrbt_abs:2621 case Hexagon::L4_ploadrbf_abs:2622 case Hexagon::L4_ploadrbtnew_abs:2623 case Hexagon::L4_ploadrbfnew_abs:2624 case Hexagon::L2_loadrbgp:2625 // Half2626 case Hexagon::L2_loadrh_io:2627 case Hexagon::L4_loadrh_ur:2628 case Hexagon::L4_loadrh_ap:2629 case Hexagon::L2_loadrh_pr:2630 case Hexagon::L2_loadrh_pbr:2631 case Hexagon::L2_loadrh_pi:2632 case Hexagon::L2_loadrh_pci:2633 case Hexagon::L2_loadrh_pcr:2634 case Hexagon::L4_loadrh_rr:2635 case Hexagon::L2_ploadrht_io:2636 case Hexagon::L2_ploadrht_pi:2637 case Hexagon::L2_ploadrhf_io:2638 case Hexagon::L2_ploadrhf_pi:2639 case Hexagon::L2_ploadrhtnew_io:2640 case Hexagon::L2_ploadrhfnew_io:2641 case Hexagon::L4_ploadrht_rr:2642 case Hexagon::L4_ploadrhf_rr:2643 case Hexagon::L4_ploadrhtnew_rr:2644 case Hexagon::L4_ploadrhfnew_rr:2645 case Hexagon::L2_ploadrhtnew_pi:2646 case Hexagon::L2_ploadrhfnew_pi:2647 case Hexagon::L4_ploadrht_abs:2648 case Hexagon::L4_ploadrhf_abs:2649 case Hexagon::L4_ploadrhtnew_abs:2650 case Hexagon::L4_ploadrhfnew_abs:2651 case Hexagon::L2_loadrhgp:2652 return true;2653 default:2654 return false;2655 }2656}2657 2658bool HexagonInstrInfo::isSolo(const MachineInstr &MI) const {2659 const uint64_t F = MI.getDesc().TSFlags;2660 return (F >> HexagonII::SoloPos) & HexagonII::SoloMask;2661}2662 2663bool HexagonInstrInfo::isSpillPredRegOp(const MachineInstr &MI) const {2664 switch (MI.getOpcode()) {2665 case Hexagon::STriw_pred:2666 case Hexagon::LDriw_pred:2667 return true;2668 default:2669 return false;2670 }2671}2672 2673bool HexagonInstrInfo::isTailCall(const MachineInstr &MI) const {2674 if (!MI.isBranch())2675 return false;2676 2677 for (auto &Op : MI.operands())2678 if (Op.isGlobal() || Op.isSymbol())2679 return true;2680 return false;2681}2682 2683// Returns true when SU has a timing class TC1.2684bool HexagonInstrInfo::isTC1(const MachineInstr &MI) const {2685 unsigned SchedClass = MI.getDesc().getSchedClass();2686 return is_TC1(SchedClass);2687}2688 2689bool HexagonInstrInfo::isTC2(const MachineInstr &MI) const {2690 unsigned SchedClass = MI.getDesc().getSchedClass();2691 return is_TC2(SchedClass);2692}2693 2694bool HexagonInstrInfo::isTC2Early(const MachineInstr &MI) const {2695 unsigned SchedClass = MI.getDesc().getSchedClass();2696 return is_TC2early(SchedClass);2697}2698 2699bool HexagonInstrInfo::isTC4x(const MachineInstr &MI) const {2700 unsigned SchedClass = MI.getDesc().getSchedClass();2701 return is_TC4x(SchedClass);2702}2703 2704// Schedule this ASAP.2705bool HexagonInstrInfo::isToBeScheduledASAP(const MachineInstr &MI1,2706 const MachineInstr &MI2) const {2707 if (mayBeCurLoad(MI1)) {2708 // if (result of SU is used in Next) return true;2709 Register DstReg = MI1.getOperand(0).getReg();2710 int N = MI2.getNumOperands();2711 for (int I = 0; I < N; I++)2712 if (MI2.getOperand(I).isReg() && DstReg == MI2.getOperand(I).getReg())2713 return true;2714 }2715 if (mayBeNewStore(MI2))2716 if (MI2.getOpcode() == Hexagon::V6_vS32b_pi)2717 if (MI1.getOperand(0).isReg() && MI2.getOperand(3).isReg() &&2718 MI1.getOperand(0).getReg() == MI2.getOperand(3).getReg())2719 return true;2720 return false;2721}2722 2723bool HexagonInstrInfo::isHVXVec(const MachineInstr &MI) const {2724 const uint64_t V = getType(MI);2725 return HexagonII::TypeCVI_FIRST <= V && V <= HexagonII::TypeCVI_LAST;2726}2727 2728// Check if the Offset is a valid auto-inc imm by Load/Store Type.2729bool HexagonInstrInfo::isValidAutoIncImm(const EVT VT, int Offset) const {2730 int Size = VT.getSizeInBits() / 8;2731 if (Offset % Size != 0)2732 return false;2733 int Count = Offset / Size;2734 2735 switch (VT.getSimpleVT().SimpleTy) {2736 // For scalars the auto-inc is s42737 case MVT::i8:2738 case MVT::i16:2739 case MVT::i32:2740 case MVT::i64:2741 case MVT::f32:2742 case MVT::f64:2743 case MVT::v2i16:2744 case MVT::v2i32:2745 case MVT::v4i8:2746 case MVT::v4i16:2747 case MVT::v8i8:2748 return isInt<4>(Count);2749 // For HVX vectors the auto-inc is s32750 case MVT::v64i8:2751 case MVT::v32i16:2752 case MVT::v16i32:2753 case MVT::v8i64:2754 case MVT::v128i8:2755 case MVT::v64i16:2756 case MVT::v32i32:2757 case MVT::v16i64:2758 return isInt<3>(Count);2759 default:2760 break;2761 }2762 2763 llvm_unreachable("Not an valid type!");2764}2765 2766bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset,2767 const TargetRegisterInfo *TRI, bool Extend) const {2768 // This function is to check whether the "Offset" is in the correct range of2769 // the given "Opcode". If "Offset" is not in the correct range, "A2_addi" is2770 // inserted to calculate the final address. Due to this reason, the function2771 // assumes that the "Offset" has correct alignment.2772 // We used to assert if the offset was not properly aligned, however,2773 // there are cases where a misaligned pointer recast can cause this2774 // problem, and we need to allow for it. The front end warns of such2775 // misaligns with respect to load size.2776 switch (Opcode) {2777 case Hexagon::PS_vstorerq_ai:2778 case Hexagon::PS_vstorerv_ai:2779 case Hexagon::PS_vstorerw_ai:2780 case Hexagon::PS_vstorerw_nt_ai:2781 case Hexagon::PS_vloadrq_ai:2782 case Hexagon::PS_vloadrv_ai:2783 case Hexagon::PS_vloadrw_ai:2784 case Hexagon::PS_vloadrw_nt_ai:2785 case Hexagon::V6_vL32b_ai:2786 case Hexagon::V6_vS32b_ai:2787 case Hexagon::V6_vS32b_pred_ai:2788 case Hexagon::V6_vS32b_npred_ai:2789 case Hexagon::V6_vS32b_qpred_ai:2790 case Hexagon::V6_vS32b_nqpred_ai:2791 case Hexagon::V6_vS32b_new_ai:2792 case Hexagon::V6_vS32b_new_pred_ai:2793 case Hexagon::V6_vS32b_new_npred_ai:2794 case Hexagon::V6_vS32b_nt_pred_ai:2795 case Hexagon::V6_vS32b_nt_npred_ai:2796 case Hexagon::V6_vS32b_nt_new_ai:2797 case Hexagon::V6_vS32b_nt_new_pred_ai:2798 case Hexagon::V6_vS32b_nt_new_npred_ai:2799 case Hexagon::V6_vS32b_nt_qpred_ai:2800 case Hexagon::V6_vS32b_nt_nqpred_ai:2801 case Hexagon::V6_vL32b_nt_ai:2802 case Hexagon::V6_vS32b_nt_ai:2803 case Hexagon::V6_vL32Ub_ai:2804 case Hexagon::V6_vS32Ub_ai:2805 case Hexagon::V6_vL32b_cur_ai:2806 case Hexagon::V6_vL32b_tmp_ai:2807 case Hexagon::V6_vL32b_pred_ai:2808 case Hexagon::V6_vL32b_npred_ai:2809 case Hexagon::V6_vL32b_cur_pred_ai:2810 case Hexagon::V6_vL32b_cur_npred_ai:2811 case Hexagon::V6_vL32b_tmp_pred_ai:2812 case Hexagon::V6_vL32b_tmp_npred_ai:2813 case Hexagon::V6_vL32b_nt_cur_ai:2814 case Hexagon::V6_vL32b_nt_tmp_ai:2815 case Hexagon::V6_vL32b_nt_pred_ai:2816 case Hexagon::V6_vL32b_nt_npred_ai:2817 case Hexagon::V6_vL32b_nt_cur_pred_ai:2818 case Hexagon::V6_vL32b_nt_cur_npred_ai:2819 case Hexagon::V6_vL32b_nt_tmp_pred_ai:2820 case Hexagon::V6_vL32b_nt_tmp_npred_ai:2821 case Hexagon::V6_vS32Ub_npred_ai:2822 case Hexagon::V6_vgathermh_pseudo:2823 case Hexagon::V6_vgather_vscatter_mh_pseudo:2824 case Hexagon::V6_vgathermw_pseudo:2825 case Hexagon::V6_vgathermhw_pseudo:2826 case Hexagon::V6_vgathermhq_pseudo:2827 case Hexagon::V6_vgathermwq_pseudo:2828 case Hexagon::V6_vgathermhwq_pseudo: {2829 unsigned VectorSize = TRI->getSpillSize(Hexagon::HvxVRRegClass);2830 assert(isPowerOf2_32(VectorSize));2831 if (Offset & (VectorSize-1))2832 return false;2833 return isInt<4>(Offset >> Log2_32(VectorSize));2834 }2835 2836 case Hexagon::J2_loop0i:2837 case Hexagon::J2_loop1i:2838 return isUInt<10>(Offset);2839 2840 case Hexagon::S4_storeirb_io:2841 case Hexagon::S4_storeirbt_io:2842 case Hexagon::S4_storeirbf_io:2843 return isUInt<6>(Offset);2844 2845 case Hexagon::S4_storeirh_io:2846 case Hexagon::S4_storeirht_io:2847 case Hexagon::S4_storeirhf_io:2848 return isShiftedUInt<6,1>(Offset);2849 2850 case Hexagon::S4_storeiri_io:2851 case Hexagon::S4_storeirit_io:2852 case Hexagon::S4_storeirif_io:2853 return isShiftedUInt<6,2>(Offset);2854 // Handle these two compare instructions that are not extendable.2855 case Hexagon::A4_cmpbeqi:2856 return isUInt<8>(Offset);2857 case Hexagon::A4_cmpbgti:2858 return isInt<8>(Offset);2859 }2860 2861 if (Extend)2862 return true;2863 2864 switch (Opcode) {2865 case Hexagon::L2_loadri_io:2866 case Hexagon::S2_storeri_io:2867 return (Offset >= Hexagon_MEMW_OFFSET_MIN) &&2868 (Offset <= Hexagon_MEMW_OFFSET_MAX);2869 2870 case Hexagon::L2_loadrd_io:2871 case Hexagon::S2_storerd_io:2872 return (Offset >= Hexagon_MEMD_OFFSET_MIN) &&2873 (Offset <= Hexagon_MEMD_OFFSET_MAX);2874 2875 case Hexagon::L2_loadrh_io:2876 case Hexagon::L2_loadruh_io:2877 case Hexagon::S2_storerh_io:2878 case Hexagon::S2_storerf_io:2879 return (Offset >= Hexagon_MEMH_OFFSET_MIN) &&2880 (Offset <= Hexagon_MEMH_OFFSET_MAX);2881 2882 case Hexagon::L2_loadrb_io:2883 case Hexagon::L2_loadrub_io:2884 case Hexagon::S2_storerb_io:2885 return (Offset >= Hexagon_MEMB_OFFSET_MIN) &&2886 (Offset <= Hexagon_MEMB_OFFSET_MAX);2887 2888 case Hexagon::A2_addi:2889 return (Offset >= Hexagon_ADDI_OFFSET_MIN) &&2890 (Offset <= Hexagon_ADDI_OFFSET_MAX);2891 2892 case Hexagon::L4_iadd_memopw_io:2893 case Hexagon::L4_isub_memopw_io:2894 case Hexagon::L4_add_memopw_io:2895 case Hexagon::L4_sub_memopw_io:2896 case Hexagon::L4_iand_memopw_io:2897 case Hexagon::L4_ior_memopw_io:2898 case Hexagon::L4_and_memopw_io:2899 case Hexagon::L4_or_memopw_io:2900 return (0 <= Offset && Offset <= 255);2901 2902 case Hexagon::L4_iadd_memoph_io:2903 case Hexagon::L4_isub_memoph_io:2904 case Hexagon::L4_add_memoph_io:2905 case Hexagon::L4_sub_memoph_io:2906 case Hexagon::L4_iand_memoph_io:2907 case Hexagon::L4_ior_memoph_io:2908 case Hexagon::L4_and_memoph_io:2909 case Hexagon::L4_or_memoph_io:2910 return (0 <= Offset && Offset <= 127);2911 2912 case Hexagon::L4_iadd_memopb_io:2913 case Hexagon::L4_isub_memopb_io:2914 case Hexagon::L4_add_memopb_io:2915 case Hexagon::L4_sub_memopb_io:2916 case Hexagon::L4_iand_memopb_io:2917 case Hexagon::L4_ior_memopb_io:2918 case Hexagon::L4_and_memopb_io:2919 case Hexagon::L4_or_memopb_io:2920 return (0 <= Offset && Offset <= 63);2921 2922 // LDriw_xxx and STriw_xxx are pseudo operations, so it has to take offset of2923 // any size. Later pass knows how to handle it.2924 case Hexagon::STriw_pred:2925 case Hexagon::LDriw_pred:2926 case Hexagon::STriw_ctr:2927 case Hexagon::LDriw_ctr:2928 return true;2929 2930 case Hexagon::PS_fi:2931 case Hexagon::PS_fia:2932 case Hexagon::INLINEASM:2933 return true;2934 2935 case Hexagon::L2_ploadrbt_io:2936 case Hexagon::L2_ploadrbf_io:2937 case Hexagon::L2_ploadrubt_io:2938 case Hexagon::L2_ploadrubf_io:2939 case Hexagon::S2_pstorerbt_io:2940 case Hexagon::S2_pstorerbf_io:2941 return isUInt<6>(Offset);2942 2943 case Hexagon::L2_ploadrht_io:2944 case Hexagon::L2_ploadrhf_io:2945 case Hexagon::L2_ploadruht_io:2946 case Hexagon::L2_ploadruhf_io:2947 case Hexagon::S2_pstorerht_io:2948 case Hexagon::S2_pstorerhf_io:2949 return isShiftedUInt<6,1>(Offset);2950 2951 case Hexagon::L2_ploadrit_io:2952 case Hexagon::L2_ploadrif_io:2953 case Hexagon::S2_pstorerit_io:2954 case Hexagon::S2_pstorerif_io:2955 return isShiftedUInt<6,2>(Offset);2956 2957 case Hexagon::L2_ploadrdt_io:2958 case Hexagon::L2_ploadrdf_io:2959 case Hexagon::S2_pstorerdt_io:2960 case Hexagon::S2_pstorerdf_io:2961 return isShiftedUInt<6,3>(Offset);2962 2963 case Hexagon::L2_loadbsw2_io:2964 case Hexagon::L2_loadbzw2_io:2965 return isShiftedInt<11,1>(Offset);2966 2967 case Hexagon::L2_loadbsw4_io:2968 case Hexagon::L2_loadbzw4_io:2969 return isShiftedInt<11,2>(Offset);2970 } // switch2971 2972 dbgs() << "Failed Opcode is : " << Opcode << " (" << getName(Opcode)2973 << ")\n";2974 llvm_unreachable("No offset range is defined for this opcode. "2975 "Please define it in the above switch statement!");2976}2977 2978bool HexagonInstrInfo::isVecAcc(const MachineInstr &MI) const {2979 return isHVXVec(MI) && isAccumulator(MI);2980}2981 2982bool HexagonInstrInfo::isVecALU(const MachineInstr &MI) const {2983 const uint64_t F = get(MI.getOpcode()).TSFlags;2984 const uint64_t V = ((F >> HexagonII::TypePos) & HexagonII::TypeMask);2985 return2986 V == HexagonII::TypeCVI_VA ||2987 V == HexagonII::TypeCVI_VA_DV;2988}2989 2990bool HexagonInstrInfo::isVecUsableNextPacket(const MachineInstr &ProdMI,2991 const MachineInstr &ConsMI) const {2992 if (EnableACCForwarding && isVecAcc(ProdMI) && isVecAcc(ConsMI))2993 return true;2994 2995 if (EnableALUForwarding && (isVecALU(ConsMI) || isLateSourceInstr(ConsMI)))2996 return true;2997 2998 if (mayBeNewStore(ConsMI))2999 return true;3000 3001 return false;3002}3003 3004bool HexagonInstrInfo::isZeroExtendingLoad(const MachineInstr &MI) const {3005 switch (MI.getOpcode()) {3006 // Byte3007 case Hexagon::L2_loadrub_io:3008 case Hexagon::L4_loadrub_ur:3009 case Hexagon::L4_loadrub_ap:3010 case Hexagon::L2_loadrub_pr:3011 case Hexagon::L2_loadrub_pbr:3012 case Hexagon::L2_loadrub_pi:3013 case Hexagon::L2_loadrub_pci:3014 case Hexagon::L2_loadrub_pcr:3015 case Hexagon::L2_loadbzw2_io:3016 case Hexagon::L4_loadbzw2_ur:3017 case Hexagon::L4_loadbzw2_ap:3018 case Hexagon::L2_loadbzw2_pr:3019 case Hexagon::L2_loadbzw2_pbr:3020 case Hexagon::L2_loadbzw2_pi:3021 case Hexagon::L2_loadbzw2_pci:3022 case Hexagon::L2_loadbzw2_pcr:3023 case Hexagon::L2_loadbzw4_io:3024 case Hexagon::L4_loadbzw4_ur:3025 case Hexagon::L4_loadbzw4_ap:3026 case Hexagon::L2_loadbzw4_pr:3027 case Hexagon::L2_loadbzw4_pbr:3028 case Hexagon::L2_loadbzw4_pi:3029 case Hexagon::L2_loadbzw4_pci:3030 case Hexagon::L2_loadbzw4_pcr:3031 case Hexagon::L4_loadrub_rr:3032 case Hexagon::L2_ploadrubt_io:3033 case Hexagon::L2_ploadrubt_pi:3034 case Hexagon::L2_ploadrubf_io:3035 case Hexagon::L2_ploadrubf_pi:3036 case Hexagon::L2_ploadrubtnew_io:3037 case Hexagon::L2_ploadrubfnew_io:3038 case Hexagon::L4_ploadrubt_rr:3039 case Hexagon::L4_ploadrubf_rr:3040 case Hexagon::L4_ploadrubtnew_rr:3041 case Hexagon::L4_ploadrubfnew_rr:3042 case Hexagon::L2_ploadrubtnew_pi:3043 case Hexagon::L2_ploadrubfnew_pi:3044 case Hexagon::L4_ploadrubt_abs:3045 case Hexagon::L4_ploadrubf_abs:3046 case Hexagon::L4_ploadrubtnew_abs:3047 case Hexagon::L4_ploadrubfnew_abs:3048 case Hexagon::L2_loadrubgp:3049 // Half3050 case Hexagon::L2_loadruh_io:3051 case Hexagon::L4_loadruh_ur:3052 case Hexagon::L4_loadruh_ap:3053 case Hexagon::L2_loadruh_pr:3054 case Hexagon::L2_loadruh_pbr:3055 case Hexagon::L2_loadruh_pi:3056 case Hexagon::L2_loadruh_pci:3057 case Hexagon::L2_loadruh_pcr:3058 case Hexagon::L4_loadruh_rr:3059 case Hexagon::L2_ploadruht_io:3060 case Hexagon::L2_ploadruht_pi:3061 case Hexagon::L2_ploadruhf_io:3062 case Hexagon::L2_ploadruhf_pi:3063 case Hexagon::L2_ploadruhtnew_io:3064 case Hexagon::L2_ploadruhfnew_io:3065 case Hexagon::L4_ploadruht_rr:3066 case Hexagon::L4_ploadruhf_rr:3067 case Hexagon::L4_ploadruhtnew_rr:3068 case Hexagon::L4_ploadruhfnew_rr:3069 case Hexagon::L2_ploadruhtnew_pi:3070 case Hexagon::L2_ploadruhfnew_pi:3071 case Hexagon::L4_ploadruht_abs:3072 case Hexagon::L4_ploadruhf_abs:3073 case Hexagon::L4_ploadruhtnew_abs:3074 case Hexagon::L4_ploadruhfnew_abs:3075 case Hexagon::L2_loadruhgp:3076 return true;3077 default:3078 return false;3079 }3080}3081 3082// Add latency to instruction.3083bool HexagonInstrInfo::addLatencyToSchedule(const MachineInstr &MI1,3084 const MachineInstr &MI2) const {3085 if (isHVXVec(MI1) && isHVXVec(MI2))3086 if (!isVecUsableNextPacket(MI1, MI2))3087 return true;3088 return false;3089}3090 3091/// Get the base register and byte offset of a load/store instr.3092bool HexagonInstrInfo::getMemOperandsWithOffsetWidth(3093 const MachineInstr &LdSt, SmallVectorImpl<const MachineOperand *> &BaseOps,3094 int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,3095 const TargetRegisterInfo *TRI) const {3096 OffsetIsScalable = false;3097 const MachineOperand *BaseOp = getBaseAndOffset(LdSt, Offset, Width);3098 if (!BaseOp || !BaseOp->isReg())3099 return false;3100 BaseOps.push_back(BaseOp);3101 return true;3102}3103 3104/// Can these instructions execute at the same time in a bundle.3105bool HexagonInstrInfo::canExecuteInBundle(const MachineInstr &First,3106 const MachineInstr &Second) const {3107 if (Second.mayStore() && First.getOpcode() == Hexagon::S2_allocframe) {3108 const MachineOperand &Op = Second.getOperand(0);3109 if (Op.isReg() && Op.isUse() && Op.getReg() == Hexagon::R29)3110 return true;3111 }3112 if (DisableNVSchedule)3113 return false;3114 if (mayBeNewStore(Second)) {3115 // Make sure the definition of the first instruction is the value being3116 // stored.3117 const MachineOperand &Stored =3118 Second.getOperand(Second.getNumOperands() - 1);3119 if (!Stored.isReg())3120 return false;3121 for (unsigned i = 0, e = First.getNumOperands(); i < e; ++i) {3122 const MachineOperand &Op = First.getOperand(i);3123 if (Op.isReg() && Op.isDef() && Op.getReg() == Stored.getReg())3124 return true;3125 }3126 }3127 return false;3128}3129 3130bool HexagonInstrInfo::doesNotReturn(const MachineInstr &CallMI) const {3131 unsigned Opc = CallMI.getOpcode();3132 return Opc == Hexagon::PS_call_nr || Opc == Hexagon::PS_callr_nr;3133}3134 3135bool HexagonInstrInfo::hasEHLabel(const MachineBasicBlock *B) const {3136 for (auto &I : *B)3137 if (I.isEHLabel())3138 return true;3139 return false;3140}3141 3142// Returns true if an instruction can be converted into a non-extended3143// equivalent instruction.3144bool HexagonInstrInfo::hasNonExtEquivalent(const MachineInstr &MI) const {3145 short NonExtOpcode;3146 // Check if the instruction has a register form that uses register in place3147 // of the extended operand, if so return that as the non-extended form.3148 if (Hexagon::getRegForm(MI.getOpcode()) >= 0)3149 return true;3150 3151 if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) {3152 // Check addressing mode and retrieve non-ext equivalent instruction.3153 3154 switch (getAddrMode(MI)) {3155 case HexagonII::Absolute:3156 // Load/store with absolute addressing mode can be converted into3157 // base+offset mode.3158 NonExtOpcode = Hexagon::changeAddrMode_abs_io(MI.getOpcode());3159 break;3160 case HexagonII::BaseImmOffset:3161 // Load/store with base+offset addressing mode can be converted into3162 // base+register offset addressing mode. However left shift operand should3163 // be set to 0.3164 NonExtOpcode = Hexagon::changeAddrMode_io_rr(MI.getOpcode());3165 break;3166 case HexagonII::BaseLongOffset:3167 NonExtOpcode = Hexagon::changeAddrMode_ur_rr(MI.getOpcode());3168 break;3169 default:3170 return false;3171 }3172 if (NonExtOpcode < 0)3173 return false;3174 return true;3175 }3176 return false;3177}3178 3179bool HexagonInstrInfo::hasPseudoInstrPair(const MachineInstr &MI) const {3180 return Hexagon::getRealHWInstr(MI.getOpcode(),3181 Hexagon::InstrType_Pseudo) >= 0;3182}3183 3184bool HexagonInstrInfo::hasUncondBranch(const MachineBasicBlock *B)3185 const {3186 MachineBasicBlock::const_iterator I = B->getFirstTerminator(), E = B->end();3187 while (I != E) {3188 if (I->isBarrier())3189 return true;3190 ++I;3191 }3192 return false;3193}3194 3195// Returns true, if a LD insn can be promoted to a cur load.3196bool HexagonInstrInfo::mayBeCurLoad(const MachineInstr &MI) const {3197 const uint64_t F = MI.getDesc().TSFlags;3198 return ((F >> HexagonII::mayCVLoadPos) & HexagonII::mayCVLoadMask) &&3199 Subtarget.hasV60Ops();3200}3201 3202// Returns true, if a ST insn can be promoted to a new-value store.3203bool HexagonInstrInfo::mayBeNewStore(const MachineInstr &MI) const {3204 if (MI.mayStore() && !Subtarget.useNewValueStores())3205 return false;3206 3207 const uint64_t F = MI.getDesc().TSFlags;3208 return (F >> HexagonII::mayNVStorePos) & HexagonII::mayNVStoreMask;3209}3210 3211bool HexagonInstrInfo::producesStall(const MachineInstr &ProdMI,3212 const MachineInstr &ConsMI) const {3213 // There is no stall when ProdMI is not a V60 vector.3214 if (!isHVXVec(ProdMI))3215 return false;3216 3217 // There is no stall when ProdMI and ConsMI are not dependent.3218 if (!isDependent(ProdMI, ConsMI))3219 return false;3220 3221 // When Forward Scheduling is enabled, there is no stall if ProdMI and ConsMI3222 // are scheduled in consecutive packets.3223 if (isVecUsableNextPacket(ProdMI, ConsMI))3224 return false;3225 3226 return true;3227}3228 3229bool HexagonInstrInfo::producesStall(const MachineInstr &MI,3230 MachineBasicBlock::const_instr_iterator BII) const {3231 // There is no stall when I is not a V60 vector.3232 if (!isHVXVec(MI))3233 return false;3234 3235 MachineBasicBlock::const_instr_iterator MII = BII;3236 MachineBasicBlock::const_instr_iterator MIE = MII->getParent()->instr_end();3237 3238 if (!MII->isBundle())3239 return producesStall(*MII, MI);3240 3241 for (++MII; MII != MIE && MII->isInsideBundle(); ++MII) {3242 const MachineInstr &J = *MII;3243 if (producesStall(J, MI))3244 return true;3245 }3246 return false;3247}3248 3249bool HexagonInstrInfo::predCanBeUsedAsDotNew(const MachineInstr &MI,3250 Register PredReg) const {3251 for (const MachineOperand &MO : MI.operands()) {3252 // Predicate register must be explicitly defined.3253 if (MO.isRegMask() && MO.clobbersPhysReg(PredReg))3254 return false;3255 if (MO.isReg() && MO.isDef() && MO.isImplicit() && (MO.getReg() == PredReg))3256 return false;3257 }3258 3259 // Instruction that produce late predicate cannot be used as sources of3260 // dot-new.3261 switch (MI.getOpcode()) {3262 case Hexagon::A4_addp_c:3263 case Hexagon::A4_subp_c:3264 case Hexagon::A4_tlbmatch:3265 case Hexagon::A5_ACS:3266 case Hexagon::F2_sfinvsqrta:3267 case Hexagon::F2_sfrecipa:3268 case Hexagon::J2_endloop0:3269 case Hexagon::J2_endloop01:3270 case Hexagon::J2_ploop1si:3271 case Hexagon::J2_ploop1sr:3272 case Hexagon::J2_ploop2si:3273 case Hexagon::J2_ploop2sr:3274 case Hexagon::J2_ploop3si:3275 case Hexagon::J2_ploop3sr:3276 case Hexagon::S2_cabacdecbin:3277 case Hexagon::S2_storew_locked:3278 case Hexagon::S4_stored_locked:3279 return false;3280 }3281 return true;3282}3283 3284bool HexagonInstrInfo::PredOpcodeHasJMP_c(unsigned Opcode) const {3285 return Opcode == Hexagon::J2_jumpt ||3286 Opcode == Hexagon::J2_jumptpt ||3287 Opcode == Hexagon::J2_jumpf ||3288 Opcode == Hexagon::J2_jumpfpt ||3289 Opcode == Hexagon::J2_jumptnew ||3290 Opcode == Hexagon::J2_jumpfnew ||3291 Opcode == Hexagon::J2_jumptnewpt ||3292 Opcode == Hexagon::J2_jumpfnewpt;3293}3294 3295bool HexagonInstrInfo::predOpcodeHasNot(ArrayRef<MachineOperand> Cond) const {3296 if (Cond.empty() || !isPredicated(Cond[0].getImm()))3297 return false;3298 return !isPredicatedTrue(Cond[0].getImm());3299}3300 3301unsigned HexagonInstrInfo::getAddrMode(const MachineInstr &MI) const {3302 const uint64_t F = MI.getDesc().TSFlags;3303 return (F >> HexagonII::AddrModePos) & HexagonII::AddrModeMask;3304}3305 3306// Returns the base register in a memory access (load/store). The offset is3307// returned in Offset and the access size is returned in AccessSize.3308// If the base operand has a subregister or the offset field does not contain3309// an immediate value, return nullptr.3310MachineOperand *3311HexagonInstrInfo::getBaseAndOffset(const MachineInstr &MI, int64_t &Offset,3312 LocationSize &AccessSize) const {3313 // Return if it is not a base+offset type instruction or a MemOp.3314 if (getAddrMode(MI) != HexagonII::BaseImmOffset &&3315 getAddrMode(MI) != HexagonII::BaseLongOffset && !isMemOp(MI) &&3316 !isPostIncrement(MI))3317 return nullptr;3318 3319 AccessSize = LocationSize::precise(getMemAccessSize(MI));3320 3321 unsigned BasePos = 0, OffsetPos = 0;3322 if (!getBaseAndOffsetPosition(MI, BasePos, OffsetPos))3323 return nullptr;3324 3325 // Post increment updates its EA after the mem access,3326 // so we need to treat its offset as zero.3327 if (isPostIncrement(MI)) {3328 Offset = 0;3329 } else {3330 const MachineOperand &OffsetOp = MI.getOperand(OffsetPos);3331 if (!OffsetOp.isImm())3332 return nullptr;3333 Offset = OffsetOp.getImm();3334 }3335 3336 const MachineOperand &BaseOp = MI.getOperand(BasePos);3337 if (BaseOp.getSubReg() != 0)3338 return nullptr;3339 return &const_cast<MachineOperand&>(BaseOp);3340}3341 3342/// Return the position of the base and offset operands for this instruction.3343bool HexagonInstrInfo::getBaseAndOffsetPosition(const MachineInstr &MI,3344 unsigned &BasePos, unsigned &OffsetPos) const {3345 if (!isAddrModeWithOffset(MI) && !isPostIncrement(MI))3346 return false;3347 3348 // Deal with memops first.3349 if (isMemOp(MI)) {3350 BasePos = 0;3351 OffsetPos = 1;3352 } else if (MI.mayStore()) {3353 BasePos = 0;3354 OffsetPos = 1;3355 } else if (MI.mayLoad()) {3356 BasePos = 1;3357 OffsetPos = 2;3358 } else3359 return false;3360 3361 if (isPredicated(MI)) {3362 BasePos++;3363 OffsetPos++;3364 }3365 if (isPostIncrement(MI)) {3366 BasePos++;3367 OffsetPos++;3368 }3369 3370 if (!MI.getOperand(BasePos).isReg() || !MI.getOperand(OffsetPos).isImm())3371 return false;3372 3373 return true;3374}3375 3376// Inserts branching instructions in reverse order of their occurrence.3377// e.g. jump_t t1 (i1)3378// jump t2 (i2)3379// Jumpers = {i2, i1}3380SmallVector<MachineInstr*, 2> HexagonInstrInfo::getBranchingInstrs(3381 MachineBasicBlock& MBB) const {3382 SmallVector<MachineInstr*, 2> Jumpers;3383 // If the block has no terminators, it just falls into the block after it.3384 MachineBasicBlock::instr_iterator I = MBB.instr_end();3385 if (I == MBB.instr_begin())3386 return Jumpers;3387 3388 // A basic block may looks like this:3389 //3390 // [ insn3391 // EH_LABEL3392 // insn3393 // insn3394 // insn3395 // EH_LABEL3396 // insn ]3397 //3398 // It has two succs but does not have a terminator3399 // Don't know how to handle it.3400 do {3401 --I;3402 if (I->isEHLabel())3403 return Jumpers;3404 } while (I != MBB.instr_begin());3405 3406 I = MBB.instr_end();3407 --I;3408 3409 while (I->isDebugInstr()) {3410 if (I == MBB.instr_begin())3411 return Jumpers;3412 --I;3413 }3414 if (!isUnpredicatedTerminator(*I))3415 return Jumpers;3416 3417 // Get the last instruction in the block.3418 MachineInstr *LastInst = &*I;3419 Jumpers.push_back(LastInst);3420 MachineInstr *SecondLastInst = nullptr;3421 // Find one more terminator if present.3422 do {3423 if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {3424 if (!SecondLastInst) {3425 SecondLastInst = &*I;3426 Jumpers.push_back(SecondLastInst);3427 } else // This is a third branch.3428 return Jumpers;3429 }3430 if (I == MBB.instr_begin())3431 break;3432 --I;3433 } while (true);3434 return Jumpers;3435}3436 3437// Returns Operand Index for the constant extended instruction.3438unsigned HexagonInstrInfo::getCExtOpNum(const MachineInstr &MI) const {3439 const uint64_t F = MI.getDesc().TSFlags;3440 return (F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask;3441}3442 3443// See if instruction could potentially be a duplex candidate.3444// If so, return its group. Zero otherwise.3445HexagonII::CompoundGroup HexagonInstrInfo::getCompoundCandidateGroup(3446 const MachineInstr &MI) const {3447 Register DstReg, SrcReg, Src1Reg, Src2Reg;3448 3449 switch (MI.getOpcode()) {3450 default:3451 return HexagonII::HCG_None;3452 //3453 // Compound pairs.3454 // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"3455 // "Rd16=#U6 ; jump #r9:2"3456 // "Rd16=Rs16 ; jump #r9:2"3457 //3458 case Hexagon::C2_cmpeq:3459 case Hexagon::C2_cmpgt:3460 case Hexagon::C2_cmpgtu:3461 DstReg = MI.getOperand(0).getReg();3462 Src1Reg = MI.getOperand(1).getReg();3463 Src2Reg = MI.getOperand(2).getReg();3464 if (Hexagon::PredRegsRegClass.contains(DstReg) &&3465 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&3466 isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg))3467 return HexagonII::HCG_A;3468 break;3469 case Hexagon::C2_cmpeqi:3470 case Hexagon::C2_cmpgti:3471 case Hexagon::C2_cmpgtui:3472 // P0 = cmp.eq(Rs,#u2)3473 DstReg = MI.getOperand(0).getReg();3474 SrcReg = MI.getOperand(1).getReg();3475 if (Hexagon::PredRegsRegClass.contains(DstReg) &&3476 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&3477 isIntRegForSubInst(SrcReg) && MI.getOperand(2).isImm() &&3478 ((isUInt<5>(MI.getOperand(2).getImm())) ||3479 (MI.getOperand(2).getImm() == -1)))3480 return HexagonII::HCG_A;3481 break;3482 case Hexagon::A2_tfr:3483 // Rd = Rs3484 DstReg = MI.getOperand(0).getReg();3485 SrcReg = MI.getOperand(1).getReg();3486 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))3487 return HexagonII::HCG_A;3488 break;3489 case Hexagon::A2_tfrsi:3490 // Rd = #u63491 // Do not test for #u6 size since the const is getting extended3492 // regardless and compound could be formed.3493 DstReg = MI.getOperand(0).getReg();3494 if (isIntRegForSubInst(DstReg))3495 return HexagonII::HCG_A;3496 break;3497 case Hexagon::S2_tstbit_i:3498 DstReg = MI.getOperand(0).getReg();3499 Src1Reg = MI.getOperand(1).getReg();3500 if (Hexagon::PredRegsRegClass.contains(DstReg) &&3501 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&3502 MI.getOperand(2).isImm() &&3503 isIntRegForSubInst(Src1Reg) && (MI.getOperand(2).getImm() == 0))3504 return HexagonII::HCG_A;3505 break;3506 // The fact that .new form is used pretty much guarantees3507 // that predicate register will match. Nevertheless,3508 // there could be some false positives without additional3509 // checking.3510 case Hexagon::J2_jumptnew:3511 case Hexagon::J2_jumpfnew:3512 case Hexagon::J2_jumptnewpt:3513 case Hexagon::J2_jumpfnewpt:3514 Src1Reg = MI.getOperand(0).getReg();3515 if (Hexagon::PredRegsRegClass.contains(Src1Reg) &&3516 (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg))3517 return HexagonII::HCG_B;3518 break;3519 // Transfer and jump:3520 // Rd=#U6 ; jump #r9:23521 // Rd=Rs ; jump #r9:23522 // Do not test for jump range here.3523 case Hexagon::J2_jump:3524 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:3525 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:3526 return HexagonII::HCG_C;3527 }3528 3529 return HexagonII::HCG_None;3530}3531 3532// Returns -1 when there is no opcode found.3533unsigned HexagonInstrInfo::getCompoundOpcode(const MachineInstr &GA,3534 const MachineInstr &GB) const {3535 assert(getCompoundCandidateGroup(GA) == HexagonII::HCG_A);3536 assert(getCompoundCandidateGroup(GB) == HexagonII::HCG_B);3537 if ((GA.getOpcode() != Hexagon::C2_cmpeqi) ||3538 (GB.getOpcode() != Hexagon::J2_jumptnew))3539 return -1u;3540 Register DestReg = GA.getOperand(0).getReg();3541 if (!GB.readsRegister(DestReg, /*TRI=*/nullptr))3542 return -1u;3543 if (DestReg != Hexagon::P0 && DestReg != Hexagon::P1)3544 return -1u;3545 // The value compared against must be either u5 or -1.3546 const MachineOperand &CmpOp = GA.getOperand(2);3547 if (!CmpOp.isImm())3548 return -1u;3549 int V = CmpOp.getImm();3550 if (V == -1)3551 return DestReg == Hexagon::P0 ? Hexagon::J4_cmpeqn1_tp0_jump_nt3552 : Hexagon::J4_cmpeqn1_tp1_jump_nt;3553 if (!isUInt<5>(V))3554 return -1u;3555 return DestReg == Hexagon::P0 ? Hexagon::J4_cmpeqi_tp0_jump_nt3556 : Hexagon::J4_cmpeqi_tp1_jump_nt;3557}3558 3559// Returns -1 if there is no opcode found.3560int HexagonInstrInfo::getDuplexOpcode(const MachineInstr &MI,3561 bool ForBigCore) const {3562 // Static table to switch the opcodes across Tiny Core and Big Core.3563 // dup_ opcodes are Big core opcodes.3564 // NOTE: There are special instructions that need to handled later.3565 // L4_return* instructions, they will only occupy SLOT0 (on big core too).3566 // PS_jmpret - This pseudo translates to J2_jumpr which occupies only SLOT2.3567 // The compiler need to base the root instruction to L6_return_map_to_raw3568 // which can go any slot.3569 static const std::map<unsigned, unsigned> DupMap = {3570 {Hexagon::A2_add, Hexagon::dup_A2_add},3571 {Hexagon::A2_addi, Hexagon::dup_A2_addi},3572 {Hexagon::A2_andir, Hexagon::dup_A2_andir},3573 {Hexagon::A2_combineii, Hexagon::dup_A2_combineii},3574 {Hexagon::A2_sxtb, Hexagon::dup_A2_sxtb},3575 {Hexagon::A2_sxth, Hexagon::dup_A2_sxth},3576 {Hexagon::A2_tfr, Hexagon::dup_A2_tfr},3577 {Hexagon::A2_tfrsi, Hexagon::dup_A2_tfrsi},3578 {Hexagon::A2_zxtb, Hexagon::dup_A2_zxtb},3579 {Hexagon::A2_zxth, Hexagon::dup_A2_zxth},3580 {Hexagon::A4_combineii, Hexagon::dup_A4_combineii},3581 {Hexagon::A4_combineir, Hexagon::dup_A4_combineir},3582 {Hexagon::A4_combineri, Hexagon::dup_A4_combineri},3583 {Hexagon::C2_cmoveif, Hexagon::dup_C2_cmoveif},3584 {Hexagon::C2_cmoveit, Hexagon::dup_C2_cmoveit},3585 {Hexagon::C2_cmovenewif, Hexagon::dup_C2_cmovenewif},3586 {Hexagon::C2_cmovenewit, Hexagon::dup_C2_cmovenewit},3587 {Hexagon::C2_cmpeqi, Hexagon::dup_C2_cmpeqi},3588 {Hexagon::L2_deallocframe, Hexagon::dup_L2_deallocframe},3589 {Hexagon::L2_loadrb_io, Hexagon::dup_L2_loadrb_io},3590 {Hexagon::L2_loadrd_io, Hexagon::dup_L2_loadrd_io},3591 {Hexagon::L2_loadrh_io, Hexagon::dup_L2_loadrh_io},3592 {Hexagon::L2_loadri_io, Hexagon::dup_L2_loadri_io},3593 {Hexagon::L2_loadrub_io, Hexagon::dup_L2_loadrub_io},3594 {Hexagon::L2_loadruh_io, Hexagon::dup_L2_loadruh_io},3595 {Hexagon::S2_allocframe, Hexagon::dup_S2_allocframe},3596 {Hexagon::S2_storerb_io, Hexagon::dup_S2_storerb_io},3597 {Hexagon::S2_storerd_io, Hexagon::dup_S2_storerd_io},3598 {Hexagon::S2_storerh_io, Hexagon::dup_S2_storerh_io},3599 {Hexagon::S2_storeri_io, Hexagon::dup_S2_storeri_io},3600 {Hexagon::S4_storeirb_io, Hexagon::dup_S4_storeirb_io},3601 {Hexagon::S4_storeiri_io, Hexagon::dup_S4_storeiri_io},3602 };3603 unsigned OpNum = MI.getOpcode();3604 // Conversion to Big core.3605 if (ForBigCore) {3606 auto Iter = DupMap.find(OpNum);3607 if (Iter != DupMap.end())3608 return Iter->second;3609 } else { // Conversion to Tiny core.3610 for (const auto &Iter : DupMap)3611 if (Iter.second == OpNum)3612 return Iter.first;3613 }3614 return -1;3615}3616 3617int HexagonInstrInfo::getCondOpcode(int Opc, bool invertPredicate) const {3618 enum Hexagon::PredSense inPredSense;3619 inPredSense = invertPredicate ? Hexagon::PredSense_false :3620 Hexagon::PredSense_true;3621 int CondOpcode = Hexagon::getPredOpcode(Opc, inPredSense);3622 if (CondOpcode >= 0) // Valid Conditional opcode/instruction3623 return CondOpcode;3624 3625 llvm_unreachable("Unexpected predicable instruction");3626}3627 3628// Return the cur value instruction for a given store.3629int HexagonInstrInfo::getDotCurOp(const MachineInstr &MI) const {3630 switch (MI.getOpcode()) {3631 default: llvm_unreachable("Unknown .cur type");3632 case Hexagon::V6_vL32b_pi:3633 return Hexagon::V6_vL32b_cur_pi;3634 case Hexagon::V6_vL32b_ai:3635 return Hexagon::V6_vL32b_cur_ai;3636 case Hexagon::V6_vL32b_nt_pi:3637 return Hexagon::V6_vL32b_nt_cur_pi;3638 case Hexagon::V6_vL32b_nt_ai:3639 return Hexagon::V6_vL32b_nt_cur_ai;3640 case Hexagon::V6_vL32b_ppu:3641 return Hexagon::V6_vL32b_cur_ppu;3642 case Hexagon::V6_vL32b_nt_ppu:3643 return Hexagon::V6_vL32b_nt_cur_ppu;3644 }3645 return 0;3646}3647 3648// Return the regular version of the .cur instruction.3649int HexagonInstrInfo::getNonDotCurOp(const MachineInstr &MI) const {3650 switch (MI.getOpcode()) {3651 default: llvm_unreachable("Unknown .cur type");3652 case Hexagon::V6_vL32b_cur_pi:3653 return Hexagon::V6_vL32b_pi;3654 case Hexagon::V6_vL32b_cur_ai:3655 return Hexagon::V6_vL32b_ai;3656 case Hexagon::V6_vL32b_nt_cur_pi:3657 return Hexagon::V6_vL32b_nt_pi;3658 case Hexagon::V6_vL32b_nt_cur_ai:3659 return Hexagon::V6_vL32b_nt_ai;3660 case Hexagon::V6_vL32b_cur_ppu:3661 return Hexagon::V6_vL32b_ppu;3662 case Hexagon::V6_vL32b_nt_cur_ppu:3663 return Hexagon::V6_vL32b_nt_ppu;3664 }3665 return 0;3666}3667 3668// The diagram below shows the steps involved in the conversion of a predicated3669// store instruction to its .new predicated new-value form.3670//3671// Note: It doesn't include conditional new-value stores as they can't be3672// converted to .new predicate.3673//3674// p.new NV store [ if(p0.new)memw(R0+#0)=R2.new ]3675// ^ ^3676// / \ (not OK. it will cause new-value store to be3677// / X conditional on p0.new while R2 producer is3678// / \ on p0)3679// / \.3680// p.new store p.old NV store3681// [if(p0.new)memw(R0+#0)=R2] [if(p0)memw(R0+#0)=R2.new]3682// ^ ^3683// \ /3684// \ /3685// \ /3686// p.old store3687// [if (p0)memw(R0+#0)=R2]3688//3689// The following set of instructions further explains the scenario where3690// conditional new-value store becomes invalid when promoted to .new predicate3691// form.3692//3693// { 1) if (p0) r0 = add(r1, r2)3694// 2) p0 = cmp.eq(r3, #0) }3695//3696// 3) if (p0) memb(r1+#0) = r0 --> this instruction can't be grouped with3697// the first two instructions because in instr 1, r0 is conditional on old value3698// of p0 but its use in instr 3 is conditional on p0 modified by instr 2 which3699// is not valid for new-value stores.3700// Predicated new value stores (i.e. if (p0) memw(..)=r0.new) are excluded3701// from the "Conditional Store" list. Because a predicated new value store3702// would NOT be promoted to a double dot new store. See diagram below:3703// This function returns yes for those stores that are predicated but not3704// yet promoted to predicate dot new instructions.3705//3706// +---------------------+3707// /-----| if (p0) memw(..)=r0 |---------\~3708// || +---------------------+ ||3709// promote || /\ /\ || promote3710// || /||\ /||\ ||3711// \||/ demote || \||/3712// \/ || || \/3713// +-------------------------+ || +-------------------------+3714// | if (p0.new) memw(..)=r0 | || | if (p0) memw(..)=r0.new |3715// +-------------------------+ || +-------------------------+3716// || || ||3717// || demote \||/3718// promote || \/ NOT possible3719// || || /\~3720// \||/ || /||\~3721// \/ || ||3722// +-----------------------------+3723// | if (p0.new) memw(..)=r0.new |3724// +-----------------------------+3725// Double Dot New Store3726//3727// Returns the most basic instruction for the .new predicated instructions and3728// new-value stores.3729// For example, all of the following instructions will be converted back to the3730// same instruction:3731// 1) if (p0.new) memw(R0+#0) = R1.new --->3732// 2) if (p0) memw(R0+#0)= R1.new -------> if (p0) memw(R0+#0) = R13733// 3) if (p0.new) memw(R0+#0) = R1 --->3734//3735// To understand the translation of instruction 1 to its original form, consider3736// a packet with 3 instructions.3737// { p0 = cmp.eq(R0,R1)3738// if (p0.new) R2 = add(R3, R4)3739// R5 = add (R3, R1)3740// }3741// if (p0) memw(R5+#0) = R2 <--- trying to include it in the previous packet3742//3743// This instruction can be part of the previous packet only if both p0 and R23744// are promoted to .new values. This promotion happens in steps, first3745// predicate register is promoted to .new and in the next iteration R2 is3746// promoted. Therefore, in case of dependence check failure (due to R5) during3747// next iteration, it should be converted back to its most basic form.3748 3749// Return the new value instruction for a given store.3750int HexagonInstrInfo::getDotNewOp(const MachineInstr &MI) const {3751 int NVOpcode = Hexagon::getNewValueOpcode(MI.getOpcode());3752 if (NVOpcode >= 0) // Valid new-value store instruction.3753 return NVOpcode;3754 3755 switch (MI.getOpcode()) {3756 default:3757 report_fatal_error(Twine("Unknown .new type: ") +3758 std::to_string(MI.getOpcode()));3759 case Hexagon::S4_storerb_ur:3760 return Hexagon::S4_storerbnew_ur;3761 3762 case Hexagon::S2_storerb_pci:3763 return Hexagon::S2_storerb_pci;3764 3765 case Hexagon::S2_storeri_pci:3766 return Hexagon::S2_storeri_pci;3767 3768 case Hexagon::S2_storerh_pci:3769 return Hexagon::S2_storerh_pci;3770 3771 case Hexagon::S2_storerd_pci:3772 return Hexagon::S2_storerd_pci;3773 3774 case Hexagon::S2_storerf_pci:3775 return Hexagon::S2_storerf_pci;3776 3777 case Hexagon::V6_vS32b_ai:3778 return Hexagon::V6_vS32b_new_ai;3779 3780 case Hexagon::V6_vS32b_pi:3781 return Hexagon::V6_vS32b_new_pi;3782 }3783 return 0;3784}3785 3786// Returns the opcode to use when converting MI, which is a conditional jump,3787// into a conditional instruction which uses the .new value of the predicate.3788// We also use branch probabilities to add a hint to the jump.3789// If MBPI is null, all edges will be treated as equally likely for the3790// purposes of establishing a predication hint.3791int HexagonInstrInfo::getDotNewPredJumpOp(const MachineInstr &MI,3792 const MachineBranchProbabilityInfo *MBPI) const {3793 // We assume that block can have at most two successors.3794 const MachineBasicBlock *Src = MI.getParent();3795 const MachineOperand &BrTarget = MI.getOperand(1);3796 bool Taken = false;3797 const BranchProbability OneHalf(1, 2);3798 3799 auto getEdgeProbability = [MBPI] (const MachineBasicBlock *Src,3800 const MachineBasicBlock *Dst) {3801 if (MBPI)3802 return MBPI->getEdgeProbability(Src, Dst);3803 return BranchProbability(1, Src->succ_size());3804 };3805 3806 if (BrTarget.isMBB()) {3807 const MachineBasicBlock *Dst = BrTarget.getMBB();3808 Taken = getEdgeProbability(Src, Dst) >= OneHalf;3809 } else {3810 // The branch target is not a basic block (most likely a function).3811 // Since BPI only gives probabilities for targets that are basic blocks,3812 // try to identify another target of this branch (potentially a fall-3813 // -through) and check the probability of that target.3814 //3815 // The only handled branch combinations are:3816 // - one conditional branch,3817 // - one conditional branch followed by one unconditional branch.3818 // Otherwise, assume not-taken.3819 assert(MI.isConditionalBranch());3820 const MachineBasicBlock &B = *MI.getParent();3821 bool SawCond = false, Bad = false;3822 for (const MachineInstr &I : B) {3823 if (!I.isBranch())3824 continue;3825 if (I.isConditionalBranch()) {3826 SawCond = true;3827 if (&I != &MI) {3828 Bad = true;3829 break;3830 }3831 }3832 if (I.isUnconditionalBranch() && !SawCond) {3833 Bad = true;3834 break;3835 }3836 }3837 if (!Bad) {3838 MachineBasicBlock::const_instr_iterator It(MI);3839 MachineBasicBlock::const_instr_iterator NextIt = std::next(It);3840 if (NextIt == B.instr_end()) {3841 // If this branch is the last, look for the fall-through block.3842 for (const MachineBasicBlock *SB : B.successors()) {3843 if (!B.isLayoutSuccessor(SB))3844 continue;3845 Taken = getEdgeProbability(Src, SB) < OneHalf;3846 break;3847 }3848 } else {3849 assert(NextIt->isUnconditionalBranch());3850 // Find the first MBB operand and assume it's the target.3851 const MachineBasicBlock *BT = nullptr;3852 for (const MachineOperand &Op : NextIt->operands()) {3853 if (!Op.isMBB())3854 continue;3855 BT = Op.getMBB();3856 break;3857 }3858 Taken = BT && getEdgeProbability(Src, BT) < OneHalf;3859 }3860 } // if (!Bad)3861 }3862 3863 // The Taken flag should be set to something reasonable by this point.3864 3865 switch (MI.getOpcode()) {3866 case Hexagon::J2_jumpt:3867 return Taken ? Hexagon::J2_jumptnewpt : Hexagon::J2_jumptnew;3868 case Hexagon::J2_jumpf:3869 return Taken ? Hexagon::J2_jumpfnewpt : Hexagon::J2_jumpfnew;3870 3871 default:3872 llvm_unreachable("Unexpected jump instruction.");3873 }3874}3875 3876// Return .new predicate version for an instruction.3877int HexagonInstrInfo::getDotNewPredOp(const MachineInstr &MI,3878 const MachineBranchProbabilityInfo *MBPI) const {3879 switch (MI.getOpcode()) {3880 // Conditional Jumps3881 case Hexagon::J2_jumpt:3882 case Hexagon::J2_jumpf:3883 return getDotNewPredJumpOp(MI, MBPI);3884 }3885 3886 int NewOpcode = Hexagon::getPredNewOpcode(MI.getOpcode());3887 if (NewOpcode >= 0)3888 return NewOpcode;3889 return 0;3890}3891 3892int HexagonInstrInfo::getDotOldOp(const MachineInstr &MI) const {3893 int NewOp = MI.getOpcode();3894 if (isPredicated(NewOp) && isPredicatedNew(NewOp)) { // Get predicate old form3895 NewOp = Hexagon::getPredOldOpcode(NewOp);3896 // All Hexagon architectures have prediction bits on dot-new branches,3897 // but only Hexagon V60+ has prediction bits on dot-old ones. Make sure3898 // to pick the right opcode when converting back to dot-old.3899 if (!Subtarget.hasFeature(Hexagon::ArchV60)) {3900 switch (NewOp) {3901 case Hexagon::J2_jumptpt:3902 NewOp = Hexagon::J2_jumpt;3903 break;3904 case Hexagon::J2_jumpfpt:3905 NewOp = Hexagon::J2_jumpf;3906 break;3907 case Hexagon::J2_jumprtpt:3908 NewOp = Hexagon::J2_jumprt;3909 break;3910 case Hexagon::J2_jumprfpt:3911 NewOp = Hexagon::J2_jumprf;3912 break;3913 }3914 }3915 assert(NewOp >= 0 &&3916 "Couldn't change predicate new instruction to its old form.");3917 }3918 3919 if (isNewValueStore(NewOp)) { // Convert into non-new-value format3920 NewOp = Hexagon::getNonNVStore(NewOp);3921 assert(NewOp >= 0 && "Couldn't change new-value store to its old form.");3922 }3923 3924 if (Subtarget.hasV60Ops())3925 return NewOp;3926 3927 // Subtargets prior to V60 didn't support 'taken' forms of predicated jumps.3928 switch (NewOp) {3929 case Hexagon::J2_jumpfpt:3930 return Hexagon::J2_jumpf;3931 case Hexagon::J2_jumptpt:3932 return Hexagon::J2_jumpt;3933 case Hexagon::J2_jumprfpt:3934 return Hexagon::J2_jumprf;3935 case Hexagon::J2_jumprtpt:3936 return Hexagon::J2_jumprt;3937 }3938 return NewOp;3939}3940 3941// See if instruction could potentially be a duplex candidate.3942// If so, return its group. Zero otherwise.3943HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup(3944 const MachineInstr &MI) const {3945 Register DstReg, SrcReg, Src1Reg, Src2Reg;3946 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();3947 3948 switch (MI.getOpcode()) {3949 default:3950 return HexagonII::HSIG_None;3951 //3952 // Group L1:3953 //3954 // Rd = memw(Rs+#u4:2)3955 // Rd = memub(Rs+#u4:0)3956 case Hexagon::L2_loadri_io:3957 case Hexagon::dup_L2_loadri_io:3958 DstReg = MI.getOperand(0).getReg();3959 SrcReg = MI.getOperand(1).getReg();3960 // Special case this one from Group L2.3961 // Rd = memw(r29+#u5:2)3962 if (isIntRegForSubInst(DstReg)) {3963 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&3964 HRI.getStackRegister() == SrcReg &&3965 MI.getOperand(2).isImm() &&3966 isShiftedUInt<5,2>(MI.getOperand(2).getImm()))3967 return HexagonII::HSIG_L2;3968 // Rd = memw(Rs+#u4:2)3969 if (isIntRegForSubInst(SrcReg) &&3970 (MI.getOperand(2).isImm() &&3971 isShiftedUInt<4,2>(MI.getOperand(2).getImm())))3972 return HexagonII::HSIG_L1;3973 }3974 break;3975 case Hexagon::L2_loadrub_io:3976 case Hexagon::dup_L2_loadrub_io:3977 // Rd = memub(Rs+#u4:0)3978 DstReg = MI.getOperand(0).getReg();3979 SrcReg = MI.getOperand(1).getReg();3980 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&3981 MI.getOperand(2).isImm() && isUInt<4>(MI.getOperand(2).getImm()))3982 return HexagonII::HSIG_L1;3983 break;3984 //3985 // Group L2:3986 //3987 // Rd = memh/memuh(Rs+#u3:1)3988 // Rd = memb(Rs+#u3:0)3989 // Rd = memw(r29+#u5:2) - Handled above.3990 // Rdd = memd(r29+#u5:3)3991 // deallocframe3992 // [if ([!]p0[.new])] dealloc_return3993 // [if ([!]p0[.new])] jumpr r313994 case Hexagon::L2_loadrh_io:3995 case Hexagon::L2_loadruh_io:3996 case Hexagon::dup_L2_loadrh_io:3997 case Hexagon::dup_L2_loadruh_io:3998 // Rd = memh/memuh(Rs+#u3:1)3999 DstReg = MI.getOperand(0).getReg();4000 SrcReg = MI.getOperand(1).getReg();4001 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&4002 MI.getOperand(2).isImm() &&4003 isShiftedUInt<3,1>(MI.getOperand(2).getImm()))4004 return HexagonII::HSIG_L2;4005 break;4006 case Hexagon::L2_loadrb_io:4007 case Hexagon::dup_L2_loadrb_io:4008 // Rd = memb(Rs+#u3:0)4009 DstReg = MI.getOperand(0).getReg();4010 SrcReg = MI.getOperand(1).getReg();4011 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&4012 MI.getOperand(2).isImm() &&4013 isUInt<3>(MI.getOperand(2).getImm()))4014 return HexagonII::HSIG_L2;4015 break;4016 case Hexagon::L2_loadrd_io:4017 case Hexagon::dup_L2_loadrd_io:4018 // Rdd = memd(r29+#u5:3)4019 DstReg = MI.getOperand(0).getReg();4020 SrcReg = MI.getOperand(1).getReg();4021 if (isDblRegForSubInst(DstReg, HRI) &&4022 Hexagon::IntRegsRegClass.contains(SrcReg) &&4023 HRI.getStackRegister() == SrcReg &&4024 MI.getOperand(2).isImm() &&4025 isShiftedUInt<5,3>(MI.getOperand(2).getImm()))4026 return HexagonII::HSIG_L2;4027 break;4028 // dealloc_return is not documented in Hexagon Manual, but marked4029 // with A_SUBINSN attribute in iset_v4classic.py.4030 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:4031 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:4032 case Hexagon::L4_return:4033 case Hexagon::L2_deallocframe:4034 case Hexagon::dup_L2_deallocframe:4035 return HexagonII::HSIG_L2;4036 case Hexagon::EH_RETURN_JMPR:4037 case Hexagon::PS_jmpret:4038 case Hexagon::SL2_jumpr31:4039 // jumpr r314040 // Actual form JMPR implicit-def %pc, implicit %r31, implicit internal %r04041 DstReg = MI.getOperand(0).getReg();4042 if (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg))4043 return HexagonII::HSIG_L2;4044 break;4045 case Hexagon::PS_jmprett:4046 case Hexagon::PS_jmpretf:4047 case Hexagon::PS_jmprettnewpt:4048 case Hexagon::PS_jmpretfnewpt:4049 case Hexagon::PS_jmprettnew:4050 case Hexagon::PS_jmpretfnew:4051 case Hexagon::SL2_jumpr31_t:4052 case Hexagon::SL2_jumpr31_f:4053 case Hexagon::SL2_jumpr31_tnew:4054 case Hexagon::SL2_jumpr31_fnew:4055 DstReg = MI.getOperand(1).getReg();4056 SrcReg = MI.getOperand(0).getReg();4057 // [if ([!]p0[.new])] jumpr r314058 if ((Hexagon::PredRegsRegClass.contains(SrcReg) &&4059 (Hexagon::P0 == SrcReg)) &&4060 (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg)))4061 return HexagonII::HSIG_L2;4062 break;4063 case Hexagon::L4_return_t:4064 case Hexagon::L4_return_f:4065 case Hexagon::L4_return_tnew_pnt:4066 case Hexagon::L4_return_fnew_pnt:4067 case Hexagon::L4_return_tnew_pt:4068 case Hexagon::L4_return_fnew_pt:4069 // [if ([!]p0[.new])] dealloc_return4070 SrcReg = MI.getOperand(0).getReg();4071 if (Hexagon::PredRegsRegClass.contains(SrcReg) && (Hexagon::P0 == SrcReg))4072 return HexagonII::HSIG_L2;4073 break;4074 //4075 // Group S1:4076 //4077 // memw(Rs+#u4:2) = Rt4078 // memb(Rs+#u4:0) = Rt4079 case Hexagon::S2_storeri_io:4080 case Hexagon::dup_S2_storeri_io:4081 // Special case this one from Group S2.4082 // memw(r29+#u5:2) = Rt4083 Src1Reg = MI.getOperand(0).getReg();4084 Src2Reg = MI.getOperand(2).getReg();4085 if (Hexagon::IntRegsRegClass.contains(Src1Reg) &&4086 isIntRegForSubInst(Src2Reg) &&4087 HRI.getStackRegister() == Src1Reg && MI.getOperand(1).isImm() &&4088 isShiftedUInt<5,2>(MI.getOperand(1).getImm()))4089 return HexagonII::HSIG_S2;4090 // memw(Rs+#u4:2) = Rt4091 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&4092 MI.getOperand(1).isImm() &&4093 isShiftedUInt<4,2>(MI.getOperand(1).getImm()))4094 return HexagonII::HSIG_S1;4095 break;4096 case Hexagon::S2_storerb_io:4097 case Hexagon::dup_S2_storerb_io:4098 // memb(Rs+#u4:0) = Rt4099 Src1Reg = MI.getOperand(0).getReg();4100 Src2Reg = MI.getOperand(2).getReg();4101 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&4102 MI.getOperand(1).isImm() && isUInt<4>(MI.getOperand(1).getImm()))4103 return HexagonII::HSIG_S1;4104 break;4105 //4106 // Group S2:4107 //4108 // memh(Rs+#u3:1) = Rt4109 // memw(r29+#u5:2) = Rt4110 // memd(r29+#s6:3) = Rtt4111 // memw(Rs+#u4:2) = #U14112 // memb(Rs+#u4) = #U14113 // allocframe(#u5:3)4114 case Hexagon::S2_storerh_io:4115 case Hexagon::dup_S2_storerh_io:4116 // memh(Rs+#u3:1) = Rt4117 Src1Reg = MI.getOperand(0).getReg();4118 Src2Reg = MI.getOperand(2).getReg();4119 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&4120 MI.getOperand(1).isImm() &&4121 isShiftedUInt<3,1>(MI.getOperand(1).getImm()))4122 return HexagonII::HSIG_S1;4123 break;4124 case Hexagon::S2_storerd_io:4125 case Hexagon::dup_S2_storerd_io:4126 // memd(r29+#s6:3) = Rtt4127 Src1Reg = MI.getOperand(0).getReg();4128 Src2Reg = MI.getOperand(2).getReg();4129 if (isDblRegForSubInst(Src2Reg, HRI) &&4130 Hexagon::IntRegsRegClass.contains(Src1Reg) &&4131 HRI.getStackRegister() == Src1Reg && MI.getOperand(1).isImm() &&4132 isShiftedInt<6,3>(MI.getOperand(1).getImm()))4133 return HexagonII::HSIG_S2;4134 break;4135 case Hexagon::S4_storeiri_io:4136 case Hexagon::dup_S4_storeiri_io:4137 // memw(Rs+#u4:2) = #U14138 Src1Reg = MI.getOperand(0).getReg();4139 if (isIntRegForSubInst(Src1Reg) && MI.getOperand(1).isImm() &&4140 isShiftedUInt<4,2>(MI.getOperand(1).getImm()) &&4141 MI.getOperand(2).isImm() && isUInt<1>(MI.getOperand(2).getImm()))4142 return HexagonII::HSIG_S2;4143 break;4144 case Hexagon::S4_storeirb_io:4145 case Hexagon::dup_S4_storeirb_io:4146 // memb(Rs+#u4) = #U14147 Src1Reg = MI.getOperand(0).getReg();4148 if (isIntRegForSubInst(Src1Reg) &&4149 MI.getOperand(1).isImm() && isUInt<4>(MI.getOperand(1).getImm()) &&4150 MI.getOperand(2).isImm() && isUInt<1>(MI.getOperand(2).getImm()))4151 return HexagonII::HSIG_S2;4152 break;4153 case Hexagon::S2_allocframe:4154 case Hexagon::dup_S2_allocframe:4155 if (MI.getOperand(2).isImm() &&4156 isShiftedUInt<5,3>(MI.getOperand(2).getImm()))4157 return HexagonII::HSIG_S1;4158 break;4159 //4160 // Group A:4161 //4162 // Rx = add(Rx,#s7)4163 // Rd = Rs4164 // Rd = #u64165 // Rd = #-14166 // if ([!]P0[.new]) Rd = #04167 // Rd = add(r29,#u6:2)4168 // Rx = add(Rx,Rs)4169 // P0 = cmp.eq(Rs,#u2)4170 // Rdd = combine(#0,Rs)4171 // Rdd = combine(Rs,#0)4172 // Rdd = combine(#u2,#U2)4173 // Rd = add(Rs,#1)4174 // Rd = add(Rs,#-1)4175 // Rd = sxth/sxtb/zxtb/zxth(Rs)4176 // Rd = and(Rs,#1)4177 case Hexagon::A2_addi:4178 case Hexagon::dup_A2_addi:4179 DstReg = MI.getOperand(0).getReg();4180 SrcReg = MI.getOperand(1).getReg();4181 if (isIntRegForSubInst(DstReg)) {4182 // Rd = add(r29,#u6:2)4183 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&4184 HRI.getStackRegister() == SrcReg && MI.getOperand(2).isImm() &&4185 isShiftedUInt<6,2>(MI.getOperand(2).getImm()))4186 return HexagonII::HSIG_A;4187 // Rx = add(Rx,#s7)4188 if ((DstReg == SrcReg) && MI.getOperand(2).isImm() &&4189 isInt<7>(MI.getOperand(2).getImm()))4190 return HexagonII::HSIG_A;4191 // Rd = add(Rs,#1)4192 // Rd = add(Rs,#-1)4193 if (isIntRegForSubInst(SrcReg) && MI.getOperand(2).isImm() &&4194 ((MI.getOperand(2).getImm() == 1) ||4195 (MI.getOperand(2).getImm() == -1)))4196 return HexagonII::HSIG_A;4197 }4198 break;4199 case Hexagon::A2_add:4200 case Hexagon::dup_A2_add:4201 // Rx = add(Rx,Rs)4202 DstReg = MI.getOperand(0).getReg();4203 Src1Reg = MI.getOperand(1).getReg();4204 Src2Reg = MI.getOperand(2).getReg();4205 if (isIntRegForSubInst(DstReg) && (DstReg == Src1Reg) &&4206 isIntRegForSubInst(Src2Reg))4207 return HexagonII::HSIG_A;4208 break;4209 case Hexagon::A2_andir:4210 case Hexagon::dup_A2_andir:4211 // Same as zxtb.4212 // Rd16=and(Rs16,#255)4213 // Rd16=and(Rs16,#1)4214 DstReg = MI.getOperand(0).getReg();4215 SrcReg = MI.getOperand(1).getReg();4216 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&4217 MI.getOperand(2).isImm() &&4218 ((MI.getOperand(2).getImm() == 1) ||4219 (MI.getOperand(2).getImm() == 255)))4220 return HexagonII::HSIG_A;4221 break;4222 case Hexagon::A2_tfr:4223 case Hexagon::dup_A2_tfr:4224 // Rd = Rs4225 DstReg = MI.getOperand(0).getReg();4226 SrcReg = MI.getOperand(1).getReg();4227 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))4228 return HexagonII::HSIG_A;4229 break;4230 case Hexagon::A2_tfrsi:4231 case Hexagon::dup_A2_tfrsi:4232 // Rd = #u64233 // Do not test for #u6 size since the const is getting extended4234 // regardless and compound could be formed.4235 // Rd = #-14236 DstReg = MI.getOperand(0).getReg();4237 if (isIntRegForSubInst(DstReg))4238 return HexagonII::HSIG_A;4239 break;4240 case Hexagon::C2_cmoveit:4241 case Hexagon::C2_cmovenewit:4242 case Hexagon::C2_cmoveif:4243 case Hexagon::C2_cmovenewif:4244 case Hexagon::dup_C2_cmoveit:4245 case Hexagon::dup_C2_cmovenewit:4246 case Hexagon::dup_C2_cmoveif:4247 case Hexagon::dup_C2_cmovenewif:4248 // if ([!]P0[.new]) Rd = #04249 // Actual form:4250 // %r16 = C2_cmovenewit internal %p0, 0, implicit undef %r16;4251 DstReg = MI.getOperand(0).getReg();4252 SrcReg = MI.getOperand(1).getReg();4253 if (isIntRegForSubInst(DstReg) &&4254 Hexagon::PredRegsRegClass.contains(SrcReg) && Hexagon::P0 == SrcReg &&4255 MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0)4256 return HexagonII::HSIG_A;4257 break;4258 case Hexagon::C2_cmpeqi:4259 case Hexagon::dup_C2_cmpeqi:4260 // P0 = cmp.eq(Rs,#u2)4261 DstReg = MI.getOperand(0).getReg();4262 SrcReg = MI.getOperand(1).getReg();4263 if (Hexagon::PredRegsRegClass.contains(DstReg) &&4264 Hexagon::P0 == DstReg && isIntRegForSubInst(SrcReg) &&4265 MI.getOperand(2).isImm() && isUInt<2>(MI.getOperand(2).getImm()))4266 return HexagonII::HSIG_A;4267 break;4268 case Hexagon::A2_combineii:4269 case Hexagon::A4_combineii:4270 case Hexagon::dup_A2_combineii:4271 case Hexagon::dup_A4_combineii:4272 // Rdd = combine(#u2,#U2)4273 DstReg = MI.getOperand(0).getReg();4274 if (isDblRegForSubInst(DstReg, HRI) &&4275 ((MI.getOperand(1).isImm() && isUInt<2>(MI.getOperand(1).getImm())) ||4276 (MI.getOperand(1).isGlobal() &&4277 isUInt<2>(MI.getOperand(1).getOffset()))) &&4278 ((MI.getOperand(2).isImm() && isUInt<2>(MI.getOperand(2).getImm())) ||4279 (MI.getOperand(2).isGlobal() &&4280 isUInt<2>(MI.getOperand(2).getOffset()))))4281 return HexagonII::HSIG_A;4282 break;4283 case Hexagon::A4_combineri:4284 case Hexagon::dup_A4_combineri:4285 // Rdd = combine(Rs,#0)4286 // Rdd = combine(Rs,#0)4287 DstReg = MI.getOperand(0).getReg();4288 SrcReg = MI.getOperand(1).getReg();4289 if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&4290 ((MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0) ||4291 (MI.getOperand(2).isGlobal() && MI.getOperand(2).getOffset() == 0)))4292 return HexagonII::HSIG_A;4293 break;4294 case Hexagon::A4_combineir:4295 case Hexagon::dup_A4_combineir:4296 // Rdd = combine(#0,Rs)4297 DstReg = MI.getOperand(0).getReg();4298 SrcReg = MI.getOperand(2).getReg();4299 if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&4300 ((MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) ||4301 (MI.getOperand(1).isGlobal() && MI.getOperand(1).getOffset() == 0)))4302 return HexagonII::HSIG_A;4303 break;4304 case Hexagon::A2_sxtb:4305 case Hexagon::A2_sxth:4306 case Hexagon::A2_zxtb:4307 case Hexagon::A2_zxth:4308 case Hexagon::dup_A2_sxtb:4309 case Hexagon::dup_A2_sxth:4310 case Hexagon::dup_A2_zxtb:4311 case Hexagon::dup_A2_zxth:4312 // Rd = sxth/sxtb/zxtb/zxth(Rs)4313 DstReg = MI.getOperand(0).getReg();4314 SrcReg = MI.getOperand(1).getReg();4315 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))4316 return HexagonII::HSIG_A;4317 break;4318 }4319 4320 return HexagonII::HSIG_None;4321}4322 4323short HexagonInstrInfo::getEquivalentHWInstr(const MachineInstr &MI) const {4324 return Hexagon::getRealHWInstr(MI.getOpcode(), Hexagon::InstrType_Real);4325}4326 4327unsigned HexagonInstrInfo::getInstrTimingClassLatency(4328 const InstrItineraryData *ItinData, const MachineInstr &MI) const {4329 // Default to one cycle for no itinerary. However, an "empty" itinerary may4330 // still have a MinLatency property, which getStageLatency checks.4331 if (!ItinData)4332 return getInstrLatency(ItinData, MI);4333 4334 if (MI.isTransient())4335 return 0;4336 return ItinData->getStageLatency(MI.getDesc().getSchedClass());4337}4338 4339/// getOperandLatency - Compute and return the use operand latency of a given4340/// pair of def and use.4341/// In most cases, the static scheduling itinerary was enough to determine the4342/// operand latency. But it may not be possible for instructions with variable4343/// number of defs / uses.4344///4345/// This is a raw interface to the itinerary that may be directly overridden by4346/// a target. Use computeOperandLatency to get the best estimate of latency.4347std::optional<unsigned> HexagonInstrInfo::getOperandLatency(4348 const InstrItineraryData *ItinData, const MachineInstr &DefMI,4349 unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const {4350 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();4351 4352 // Get DefIdx and UseIdx for super registers.4353 const MachineOperand &DefMO = DefMI.getOperand(DefIdx);4354 4355 if (DefMO.isReg() && DefMO.getReg().isPhysical()) {4356 if (DefMO.isImplicit()) {4357 for (MCPhysReg SR : HRI.superregs(DefMO.getReg())) {4358 int Idx = DefMI.findRegisterDefOperandIdx(SR, &HRI, false, false);4359 if (Idx != -1) {4360 DefIdx = Idx;4361 break;4362 }4363 }4364 }4365 4366 const MachineOperand &UseMO = UseMI.getOperand(UseIdx);4367 if (UseMO.isImplicit()) {4368 for (MCPhysReg SR : HRI.superregs(UseMO.getReg())) {4369 int Idx = UseMI.findRegisterUseOperandIdx(SR, &HRI, false);4370 if (Idx != -1) {4371 UseIdx = Idx;4372 break;4373 }4374 }4375 }4376 }4377 4378 std::optional<unsigned> Latency = TargetInstrInfo::getOperandLatency(4379 ItinData, DefMI, DefIdx, UseMI, UseIdx);4380 if (Latency == 0)4381 // We should never have 0 cycle latency between two instructions unless4382 // they can be packetized together. However, this decision can't be made4383 // here.4384 Latency = 1;4385 return Latency;4386}4387 4388// inverts the predication logic.4389// p -> NotP4390// NotP -> P4391bool HexagonInstrInfo::getInvertedPredSense(4392 SmallVectorImpl<MachineOperand> &Cond) const {4393 if (Cond.empty())4394 return false;4395 unsigned Opc = getInvertedPredicatedOpcode(Cond[0].getImm());4396 Cond[0].setImm(Opc);4397 return true;4398}4399 4400unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const {4401 int InvPredOpcode;4402 InvPredOpcode = isPredicatedTrue(Opc) ? Hexagon::getFalsePredOpcode(Opc)4403 : Hexagon::getTruePredOpcode(Opc);4404 if (InvPredOpcode >= 0) // Valid instruction with the inverted predicate.4405 return InvPredOpcode;4406 4407 llvm_unreachable("Unexpected predicated instruction");4408}4409 4410// Returns the max value that doesn't need to be extended.4411int HexagonInstrInfo::getMaxValue(const MachineInstr &MI) const {4412 const uint64_t F = MI.getDesc().TSFlags;4413 unsigned isSigned = (F >> HexagonII::ExtentSignedPos)4414 & HexagonII::ExtentSignedMask;4415 unsigned bits = (F >> HexagonII::ExtentBitsPos)4416 & HexagonII::ExtentBitsMask;4417 4418 if (isSigned) // if value is signed4419 return ~(-1U << (bits - 1));4420 else4421 return ~(-1U << bits);4422}4423 4424 4425bool HexagonInstrInfo::isAddrModeWithOffset(const MachineInstr &MI) const {4426 switch (MI.getOpcode()) {4427 case Hexagon::L2_loadrbgp:4428 case Hexagon::L2_loadrdgp:4429 case Hexagon::L2_loadrhgp:4430 case Hexagon::L2_loadrigp:4431 case Hexagon::L2_loadrubgp:4432 case Hexagon::L2_loadruhgp:4433 case Hexagon::S2_storerbgp:4434 case Hexagon::S2_storerbnewgp:4435 case Hexagon::S2_storerhgp:4436 case Hexagon::S2_storerhnewgp:4437 case Hexagon::S2_storerigp:4438 case Hexagon::S2_storerinewgp:4439 case Hexagon::S2_storerdgp:4440 case Hexagon::S2_storerfgp:4441 return true;4442 }4443 const uint64_t F = MI.getDesc().TSFlags;4444 unsigned addrMode =4445 ((F >> HexagonII::AddrModePos) & HexagonII::AddrModeMask);4446 // Disallow any base+offset instruction. The assembler does not yet reorder4447 // based up any zero offset instruction.4448 return (addrMode == HexagonII::BaseRegOffset ||4449 addrMode == HexagonII::BaseImmOffset ||4450 addrMode == HexagonII::BaseLongOffset);4451}4452 4453bool HexagonInstrInfo::isPureSlot0(const MachineInstr &MI) const {4454 // Workaround for the Global Scheduler. Sometimes, it creates4455 // A4_ext as a Pseudo instruction and calls this function to see if4456 // it can be added to an existing bundle. Since the instruction doesn't4457 // belong to any BB yet, we can't use getUnits API.4458 if (MI.getOpcode() == Hexagon::A4_ext)4459 return false;4460 4461 unsigned FuncUnits = getUnits(MI);4462 return HexagonFUnits::isSlot0Only(FuncUnits);4463}4464 4465bool HexagonInstrInfo::isRestrictNoSlot1Store(const MachineInstr &MI) const {4466 const uint64_t F = MI.getDesc().TSFlags;4467 return ((F >> HexagonII::RestrictNoSlot1StorePos) &4468 HexagonII::RestrictNoSlot1StoreMask);4469}4470 4471void HexagonInstrInfo::changeDuplexOpcode(MachineBasicBlock::instr_iterator MII,4472 bool ToBigInstrs) const {4473 int Opcode = -1;4474 if (ToBigInstrs) { // To BigCore Instr.4475 // Check if the instruction can form a Duplex.4476 if (getDuplexCandidateGroup(*MII))4477 // Get the opcode marked "dup_*" tag.4478 Opcode = getDuplexOpcode(*MII, ToBigInstrs);4479 } else // To TinyCore Instr.4480 Opcode = getDuplexOpcode(*MII, ToBigInstrs);4481 4482 // Change the opcode of the instruction.4483 if (Opcode >= 0)4484 MII->setDesc(get(Opcode));4485}4486 4487// This function is used to translate instructions to facilitate generating4488// Duplexes on TinyCore.4489void HexagonInstrInfo::translateInstrsForDup(MachineFunction &MF,4490 bool ToBigInstrs) const {4491 for (auto &MB : MF)4492 for (MachineBasicBlock::instr_iterator Instr = MB.instr_begin(),4493 End = MB.instr_end();4494 Instr != End; ++Instr)4495 changeDuplexOpcode(Instr, ToBigInstrs);4496}4497 4498// This is a specialized form of above function.4499void HexagonInstrInfo::translateInstrsForDup(4500 MachineBasicBlock::instr_iterator MII, bool ToBigInstrs) const {4501 MachineBasicBlock *MBB = MII->getParent();4502 while ((MII != MBB->instr_end()) && MII->isInsideBundle()) {4503 changeDuplexOpcode(MII, ToBigInstrs);4504 ++MII;4505 }4506}4507 4508unsigned HexagonInstrInfo::getMemAccessSize(const MachineInstr &MI) const {4509 using namespace HexagonII;4510 4511 const uint64_t F = MI.getDesc().TSFlags;4512 unsigned S = (F >> MemAccessSizePos) & MemAccesSizeMask;4513 unsigned Size = getMemAccessSizeInBytes(MemAccessSize(S));4514 if (Size != 0)4515 return Size;4516 // Y2_dcfetchbo is special4517 if (MI.getOpcode() == Hexagon::Y2_dcfetchbo)4518 return HexagonII::DoubleWordAccess;4519 4520 // Handle vector access sizes.4521 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();4522 switch (S) {4523 case HexagonII::HVXVectorAccess:4524 return HRI.getSpillSize(Hexagon::HvxVRRegClass);4525 default:4526 llvm_unreachable("Unexpected instruction");4527 }4528}4529 4530// Returns the min value that doesn't need to be extended.4531int HexagonInstrInfo::getMinValue(const MachineInstr &MI) const {4532 const uint64_t F = MI.getDesc().TSFlags;4533 unsigned isSigned = (F >> HexagonII::ExtentSignedPos)4534 & HexagonII::ExtentSignedMask;4535 unsigned bits = (F >> HexagonII::ExtentBitsPos)4536 & HexagonII::ExtentBitsMask;4537 4538 if (isSigned) // if value is signed4539 return -1U << (bits - 1);4540 else4541 return 0;4542}4543 4544// Returns opcode of the non-extended equivalent instruction.4545short HexagonInstrInfo::getNonExtOpcode(const MachineInstr &MI) const {4546 // Check if the instruction has a register form that uses register in place4547 // of the extended operand, if so return that as the non-extended form.4548 short NonExtOpcode = Hexagon::getRegForm(MI.getOpcode());4549 if (NonExtOpcode >= 0)4550 return NonExtOpcode;4551 4552 if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) {4553 // Check addressing mode and retrieve non-ext equivalent instruction.4554 switch (getAddrMode(MI)) {4555 case HexagonII::Absolute:4556 return Hexagon::changeAddrMode_abs_io(MI.getOpcode());4557 case HexagonII::BaseImmOffset:4558 return Hexagon::changeAddrMode_io_rr(MI.getOpcode());4559 case HexagonII::BaseLongOffset:4560 return Hexagon::changeAddrMode_ur_rr(MI.getOpcode());4561 4562 default:4563 return -1;4564 }4565 }4566 return -1;4567}4568 4569bool HexagonInstrInfo::getPredReg(ArrayRef<MachineOperand> Cond,4570 Register &PredReg, unsigned &PredRegPos, unsigned &PredRegFlags) const {4571 if (Cond.empty())4572 return false;4573 assert(Cond.size() == 2);4574 if (isNewValueJump(Cond[0].getImm()) || Cond[1].isMBB()) {4575 LLVM_DEBUG(dbgs() << "No predregs for new-value jumps/endloop");4576 return false;4577 }4578 PredReg = Cond[1].getReg();4579 PredRegPos = 1;4580 // See IfConversion.cpp why we add RegState::Implicit | RegState::Undef4581 PredRegFlags = 0;4582 if (Cond[1].isImplicit())4583 PredRegFlags = RegState::Implicit;4584 if (Cond[1].isUndef())4585 PredRegFlags |= RegState::Undef;4586 return true;4587}4588 4589short HexagonInstrInfo::getPseudoInstrPair(const MachineInstr &MI) const {4590 return Hexagon::getRealHWInstr(MI.getOpcode(), Hexagon::InstrType_Pseudo);4591}4592 4593short HexagonInstrInfo::getRegForm(const MachineInstr &MI) const {4594 return Hexagon::getRegForm(MI.getOpcode());4595}4596 4597// Return the number of bytes required to encode the instruction.4598// Hexagon instructions are fixed length, 4 bytes, unless they4599// use a constant extender, which requires another 4 bytes.4600// For debug instructions and prolog labels, return 0.4601unsigned HexagonInstrInfo::getSize(const MachineInstr &MI) const {4602 if (MI.isDebugInstr() || MI.isPosition())4603 return 0;4604 4605 unsigned Size = MI.getDesc().getSize();4606 if (!Size)4607 // Assume the default insn size in case it cannot be determined4608 // for whatever reason.4609 Size = HEXAGON_INSTR_SIZE;4610 4611 if (isConstExtended(MI) || isExtended(MI))4612 Size += HEXAGON_INSTR_SIZE;4613 4614 // Try and compute number of instructions in asm.4615 if (BranchRelaxAsmLarge && MI.getOpcode() == Hexagon::INLINEASM) {4616 const MachineBasicBlock &MBB = *MI.getParent();4617 const MachineFunction *MF = MBB.getParent();4618 const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo();4619 4620 // Count the number of register definitions to find the asm string.4621 unsigned NumDefs = 0;4622 for (; MI.getOperand(NumDefs).isReg() && MI.getOperand(NumDefs).isDef();4623 ++NumDefs)4624 assert(NumDefs != MI.getNumOperands()-2 && "No asm string?");4625 4626 assert(MI.getOperand(NumDefs).isSymbol() && "No asm string?");4627 // Disassemble the AsmStr and approximate number of instructions.4628 const char *AsmStr = MI.getOperand(NumDefs).getSymbolName();4629 Size = getInlineAsmLength(AsmStr, *MAI);4630 }4631 4632 return Size;4633}4634 4635uint64_t HexagonInstrInfo::getType(const MachineInstr &MI) const {4636 const uint64_t F = MI.getDesc().TSFlags;4637 return (F >> HexagonII::TypePos) & HexagonII::TypeMask;4638}4639 4640InstrStage::FuncUnits HexagonInstrInfo::getUnits(const MachineInstr &MI) const {4641 const InstrItineraryData &II = *Subtarget.getInstrItineraryData();4642 const InstrStage &IS = *II.beginStage(MI.getDesc().getSchedClass());4643 4644 return IS.getUnits();4645}4646 4647// Calculate size of the basic block without debug instructions.4648unsigned HexagonInstrInfo::nonDbgBBSize(const MachineBasicBlock *BB) const {4649 return nonDbgMICount(BB->instr_begin(), BB->instr_end());4650}4651 4652unsigned HexagonInstrInfo::nonDbgBundleSize(4653 MachineBasicBlock::const_iterator BundleHead) const {4654 assert(BundleHead->isBundle() && "Not a bundle header");4655 auto MII = BundleHead.getInstrIterator();4656 // Skip the bundle header.4657 return nonDbgMICount(++MII, getBundleEnd(BundleHead.getInstrIterator()));4658}4659 4660/// immediateExtend - Changes the instruction in place to one using an immediate4661/// extender.4662void HexagonInstrInfo::immediateExtend(MachineInstr &MI) const {4663 assert((isExtendable(MI)||isConstExtended(MI)) &&4664 "Instruction must be extendable");4665 // Find which operand is extendable.4666 short ExtOpNum = getCExtOpNum(MI);4667 MachineOperand &MO = MI.getOperand(ExtOpNum);4668 // This needs to be something we understand.4669 assert((MO.isMBB() || MO.isImm()) &&4670 "Branch with unknown extendable field type");4671 // Mark given operand as extended.4672 MO.addTargetFlag(HexagonII::HMOTF_ConstExtended);4673}4674 4675bool HexagonInstrInfo::invertAndChangeJumpTarget(4676 MachineInstr &MI, MachineBasicBlock *NewTarget) const {4677 LLVM_DEBUG(dbgs() << "\n[invertAndChangeJumpTarget] to "4678 << printMBBReference(*NewTarget);4679 MI.dump(););4680 assert(MI.isBranch());4681 unsigned NewOpcode = getInvertedPredicatedOpcode(MI.getOpcode());4682 int TargetPos = MI.getNumOperands() - 1;4683 // In general branch target is the last operand,4684 // but some implicit defs added at the end might change it.4685 while ((TargetPos > -1) && !MI.getOperand(TargetPos).isMBB())4686 --TargetPos;4687 assert((TargetPos >= 0) && MI.getOperand(TargetPos).isMBB());4688 MI.getOperand(TargetPos).setMBB(NewTarget);4689 if (EnableBranchPrediction && isPredicatedNew(MI)) {4690 NewOpcode = reversePrediction(NewOpcode);4691 }4692 MI.setDesc(get(NewOpcode));4693 return true;4694}4695 4696void HexagonInstrInfo::genAllInsnTimingClasses(MachineFunction &MF) const {4697 /* +++ The code below is used to generate complete set of Hexagon Insn +++ */4698 MachineFunction::iterator A = MF.begin();4699 MachineBasicBlock &B = *A;4700 MachineBasicBlock::iterator I = B.begin();4701 DebugLoc DL = I->getDebugLoc();4702 MachineInstr *NewMI;4703 4704 for (unsigned insn = TargetOpcode::GENERIC_OP_END+1;4705 insn < Hexagon::INSTRUCTION_LIST_END; ++insn) {4706 NewMI = BuildMI(B, I, DL, get(insn));4707 LLVM_DEBUG(dbgs() << "\n"4708 << getName(NewMI->getOpcode())4709 << " Class: " << NewMI->getDesc().getSchedClass());4710 NewMI->eraseFromParent();4711 }4712 /* --- The code above is used to generate complete set of Hexagon Insn --- */4713}4714 4715// inverts the predication logic.4716// p -> NotP4717// NotP -> P4718bool HexagonInstrInfo::reversePredSense(MachineInstr &MI) const {4719 LLVM_DEBUG(dbgs() << "\nTrying to reverse pred. sense of:"; MI.dump());4720 MI.setDesc(get(getInvertedPredicatedOpcode(MI.getOpcode())));4721 return true;4722}4723 4724// Reverse the branch prediction.4725unsigned HexagonInstrInfo::reversePrediction(unsigned Opcode) const {4726 int PredRevOpcode = -1;4727 if (isPredictedTaken(Opcode))4728 PredRevOpcode = Hexagon::notTakenBranchPrediction(Opcode);4729 else4730 PredRevOpcode = Hexagon::takenBranchPrediction(Opcode);4731 assert(PredRevOpcode > 0);4732 return PredRevOpcode;4733}4734 4735// TODO: Add more rigorous validation.4736bool HexagonInstrInfo::validateBranchCond(const ArrayRef<MachineOperand> &Cond)4737 const {4738 return Cond.empty() || (Cond[0].isImm() && (Cond.size() != 1));4739}4740 4741void HexagonInstrInfo::4742setBundleNoShuf(MachineBasicBlock::instr_iterator MIB) const {4743 assert(MIB->isBundle());4744 MachineOperand &Operand = MIB->getOperand(0);4745 if (Operand.isImm())4746 Operand.setImm(Operand.getImm() | memShufDisabledMask);4747 else4748 MIB->addOperand(MachineOperand::CreateImm(memShufDisabledMask));4749}4750 4751bool HexagonInstrInfo::getBundleNoShuf(const MachineInstr &MIB) const {4752 assert(MIB.isBundle());4753 const MachineOperand &Operand = MIB.getOperand(0);4754 return (Operand.isImm() && (Operand.getImm() & memShufDisabledMask) != 0);4755}4756 4757bool HexagonInstrInfo::isQFPMul(const MachineInstr *MI) const {4758 return (MI->getOpcode() == Hexagon::V6_vmpy_qf16_hf ||4759 MI->getOpcode() == Hexagon::V6_vmpy_qf16_mix_hf ||4760 MI->getOpcode() == Hexagon::V6_vmpy_qf32_hf ||4761 MI->getOpcode() == Hexagon::V6_vmpy_qf32_mix_hf ||4762 MI->getOpcode() == Hexagon::V6_vmpy_qf32_sf ||4763 MI->getOpcode() == Hexagon::V6_vmpy_qf16_mix_hf ||4764 MI->getOpcode() == Hexagon::V6_vmpy_qf16 ||4765 MI->getOpcode() == Hexagon::V6_vmpy_qf32_mix_hf ||4766 MI->getOpcode() == Hexagon::V6_vmpy_qf32_qf16 ||4767 MI->getOpcode() == Hexagon::V6_vmpy_qf32);4768}4769 4770// Addressing mode relations.4771short HexagonInstrInfo::changeAddrMode_abs_io(short Opc) const {4772 return Opc >= 0 ? Hexagon::changeAddrMode_abs_io(Opc) : Opc;4773}4774 4775short HexagonInstrInfo::changeAddrMode_io_abs(short Opc) const {4776 return Opc >= 0 ? Hexagon::changeAddrMode_io_abs(Opc) : Opc;4777}4778 4779short HexagonInstrInfo::changeAddrMode_io_pi(short Opc) const {4780 return Opc >= 0 ? Hexagon::changeAddrMode_io_pi(Opc) : Opc;4781}4782 4783short HexagonInstrInfo::changeAddrMode_io_rr(short Opc) const {4784 return Opc >= 0 ? Hexagon::changeAddrMode_io_rr(Opc) : Opc;4785}4786 4787short HexagonInstrInfo::changeAddrMode_pi_io(short Opc) const {4788 return Opc >= 0 ? Hexagon::changeAddrMode_pi_io(Opc) : Opc;4789}4790 4791short HexagonInstrInfo::changeAddrMode_rr_io(short Opc) const {4792 return Opc >= 0 ? Hexagon::changeAddrMode_rr_io(Opc) : Opc;4793}4794 4795short HexagonInstrInfo::changeAddrMode_rr_ur(short Opc) const {4796 return Opc >= 0 ? Hexagon::changeAddrMode_rr_ur(Opc) : Opc;4797}4798 4799short HexagonInstrInfo::changeAddrMode_ur_rr(short Opc) const {4800 return Opc >= 0 ? Hexagon::changeAddrMode_ur_rr(Opc) : Opc;4801}4802 4803MCInst HexagonInstrInfo::getNop() const {4804 static const MCInst Nop = MCInstBuilder(Hexagon::A2_nop);4805 4806 return MCInstBuilder(Hexagon::BUNDLE)4807 .addImm(0)4808 .addInst(&Nop);4809}4810