brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.3 KiB · d96fade Raw
219 lines · cpp
1//===----- HexagonMCShuffler.cpp - MC bundle shuffling --------------------===//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 implements the shuffling of insns inside a bundle according to the10// packet formation rules of the Hexagon ISA.11//12//===----------------------------------------------------------------------===//13 14#include "MCTargetDesc/HexagonMCShuffler.h"15#include "MCTargetDesc/HexagonMCInstrInfo.h"16#include "MCTargetDesc/HexagonShuffler.h"17#include "llvm/MC/MCInst.h"18#include "llvm/MC/MCInstrDesc.h"19#include "llvm/MC/MCInstrInfo.h"20#include "llvm/Support/CommandLine.h"21#include "llvm/Support/Debug.h"22#include "llvm/Support/raw_ostream.h"23#include <cassert>24 25#define DEBUG_TYPE "hexagon-shuffle"26 27using namespace llvm;28 29static cl::opt<bool>30    DisableShuffle("disable-hexagon-shuffle", cl::Hidden, cl::init(false),31                   cl::desc("Disable Hexagon instruction shuffling"));32 33void HexagonMCShuffler::init(MCInst &MCB) {34  if (HexagonMCInstrInfo::isBundle(MCB)) {35    MCInst const *Extender = nullptr;36    // Copy the bundle for the shuffling.37    for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {38      MCInst &MI = *const_cast<MCInst *>(I.getInst());39      LLVM_DEBUG(dbgs() << "Shuffling: " << MCII.getName(MI.getOpcode())40                        << '\n');41      assert(!HexagonMCInstrInfo::getDesc(MCII, MI).isPseudo());42 43      if (!HexagonMCInstrInfo::isImmext(MI)) {44        append(MI, Extender, HexagonMCInstrInfo::getUnits(MCII, STI, MI));45        Extender = nullptr;46      } else47        Extender = &MI;48    }49  }50 51  Loc = MCB.getLoc();52  BundleFlags = MCB.getOperand(0).getImm();53}54 55void HexagonMCShuffler::init(MCInst &MCB, MCInst const &AddMI,56                             bool bInsertAtFront) {57  if (HexagonMCInstrInfo::isBundle(MCB)) {58    if (bInsertAtFront)59      append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, AddMI));60    MCInst const *Extender = nullptr;61    // Copy the bundle for the shuffling.62    for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {63      assert(!HexagonMCInstrInfo::getDesc(MCII, *I.getInst()).isPseudo());64      MCInst &MI = *const_cast<MCInst *>(I.getInst());65      if (!HexagonMCInstrInfo::isImmext(MI)) {66        append(MI, Extender, HexagonMCInstrInfo::getUnits(MCII, STI, MI));67        Extender = nullptr;68      } else69        Extender = &MI;70    }71    if (!bInsertAtFront)72      append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, AddMI));73  }74 75  Loc = MCB.getLoc();76  BundleFlags = MCB.getOperand(0).getImm();77}78 79void HexagonMCShuffler::copyTo(MCInst &MCB) {80  MCB.clear();81  MCB.addOperand(MCOperand::createImm(BundleFlags));82  MCB.setLoc(Loc);83  // Copy the results into the bundle.84  for (auto &I : *this) {85    MCInst const &MI = I.getDesc();86    MCInst const *Extender = I.getExtender();87    if (Extender)88      MCB.addOperand(MCOperand::createInst(Extender));89    MCB.addOperand(MCOperand::createInst(&MI));90  }91}92 93bool HexagonMCShuffler::reshuffleTo(MCInst &MCB) {94  if (shuffle()) {95    // Copy the results into the bundle.96    copyTo(MCB);97    return true;98  }99  LLVM_DEBUG(MCB.dump());100  return false;101}102 103bool llvm::HexagonMCShuffle(MCContext &Context, bool ReportErrors,104                            MCInstrInfo const &MCII, MCSubtargetInfo const &STI,105                            MCInst &MCB) {106  HexagonMCShuffler MCS(Context, ReportErrors, MCII, STI, MCB);107 108  if (DisableShuffle)109    // Ignore if user chose so.110    return false;111 112  if (!HexagonMCInstrInfo::bundleSize(MCB)) {113    // There once was a bundle:114    //    BUNDLE implicit-def %d2, implicit-def %r4, implicit-def %r5,115    //    implicit-def %d7, ...116    //      * %d2 = IMPLICIT_DEF; flags:117    //      * %d7 = IMPLICIT_DEF; flags:118    // After the IMPLICIT_DEFs were removed by the asm printer, the bundle119    // became empty.120    LLVM_DEBUG(dbgs() << "Skipping empty bundle");121    return false;122  } else if (!HexagonMCInstrInfo::isBundle(MCB)) {123    LLVM_DEBUG(dbgs() << "Skipping stand-alone insn");124    return false;125  }126 127  return MCS.reshuffleTo(MCB);128}129 130bool llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,131                            MCSubtargetInfo const &STI, MCInst &MCB,132                            SmallVector<DuplexCandidate, 8> possibleDuplexes) {133 134  if (DisableShuffle || possibleDuplexes.size() == 0)135    return false;136 137  if (!HexagonMCInstrInfo::bundleSize(MCB)) {138    // There once was a bundle:139    //    BUNDLE implicit-def %d2, implicit-def %r4, implicit-def %r5,140    //    implicit-def %d7, ...141    //      * %d2 = IMPLICIT_DEF; flags:142    //      * %d7 = IMPLICIT_DEF; flags:143    // After the IMPLICIT_DEFs were removed by the asm printer, the bundle144    // became empty.145    LLVM_DEBUG(dbgs() << "Skipping empty bundle");146    return false;147  } else if (!HexagonMCInstrInfo::isBundle(MCB)) {148    LLVM_DEBUG(dbgs() << "Skipping stand-alone insn");149    return false;150  }151 152  bool doneShuffling = false;153  while (possibleDuplexes.size() > 0 && (!doneShuffling)) {154    // case of Duplex Found155    DuplexCandidate duplexToTry = possibleDuplexes.pop_back_val();156    MCInst Attempt(MCB);157    HexagonMCInstrInfo::replaceDuplex(Context, Attempt, duplexToTry);158    HexagonMCShuffler MCS(Context, false, MCII, STI, Attempt); // copy packet to the shuffler159    if (MCS.size() == 1) {                     // case of one duplex160      // copy the created duplex in the shuffler to the bundle161      MCS.copyTo(MCB);162      return false;163    }164    // try shuffle with this duplex165    doneShuffling = MCS.reshuffleTo(MCB);166 167    if (doneShuffling)168      break;169  }170 171  if (!doneShuffling) {172    HexagonMCShuffler MCS(Context, false, MCII, STI, MCB);173    doneShuffling = MCS.reshuffleTo(MCB); // shuffle174  }175 176  return doneShuffling;177}178 179bool llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,180                            MCSubtargetInfo const &STI, MCInst &MCB,181                            MCInst const &AddMI, int fixupCount) {182  if (!HexagonMCInstrInfo::isBundle(MCB))183    return false;184 185  // if fixups present, make sure we don't insert too many nops that would186  // later prevent an extender from being inserted.187  unsigned int bundleSize = HexagonMCInstrInfo::bundleSize(MCB);188  if (bundleSize >= HEXAGON_PACKET_SIZE)189    return false;190  bool bhasDuplex = HexagonMCInstrInfo::hasDuplex(MCII, MCB);191  if (fixupCount >= 2) {192    if (bhasDuplex) {193      if (bundleSize >= HEXAGON_PACKET_SIZE - 1) {194        return false;195      }196    } else {197      return false;198    }199  } else {200    if (bundleSize == HEXAGON_PACKET_SIZE - 1 && fixupCount)201      return false;202  }203 204  if (DisableShuffle)205    return false;206 207  // mgl: temporary code (shuffler doesn't take into account the fact that208  // a duplex takes up two slots.  for example, 3 nops can be put into a packet209  // containing a duplex oversubscribing slots by 1).210  unsigned maxBundleSize = (HexagonMCInstrInfo::hasImmExt(MCB))211                               ? HEXAGON_PACKET_SIZE212                               : HEXAGON_PACKET_SIZE - 1;213  if (bhasDuplex && bundleSize >= maxBundleSize)214    return false;215 216  HexagonMCShuffler MCS(Context, false, MCII, STI, MCB, AddMI, false);217  return MCS.reshuffleTo(MCB);218}219