brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.0 KiB · bcd51fc Raw
210 lines · cpp
1//===----- HexagonLoopAlign.cpp - Generate loop alignment directives  -----===//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// Inspect a basic block and if its single basic block loop with a small9// number of instructions, set the prefLoopAlignment to 32 bytes (5).10//===----------------------------------------------------------------------===//11 12#include "Hexagon.h"13#include "HexagonTargetMachine.h"14#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"15#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"16#include "llvm/Support/Debug.h"17 18#define DEBUG_TYPE "hexagon-loop-align"19 20using namespace llvm;21 22static cl::opt<bool>23    DisableLoopAlign("disable-hexagon-loop-align", cl::Hidden,24                     cl::desc("Disable Hexagon loop alignment pass"));25 26static cl::opt<uint32_t> HVXLoopAlignLimitUB(27    "hexagon-hvx-loop-align-limit-ub", cl::Hidden, cl::init(16),28    cl::desc("Set hexagon hvx loop upper bound align limit"));29 30static cl::opt<uint32_t> TinyLoopAlignLimitUB(31    "hexagon-tiny-loop-align-limit-ub", cl::Hidden, cl::init(16),32    cl::desc("Set hexagon tiny-core loop upper bound align limit"));33 34static cl::opt<uint32_t>35    LoopAlignLimitUB("hexagon-loop-align-limit-ub", cl::Hidden, cl::init(8),36                     cl::desc("Set hexagon loop upper bound align limit"));37 38static cl::opt<uint32_t>39    LoopAlignLimitLB("hexagon-loop-align-limit-lb", cl::Hidden, cl::init(4),40                     cl::desc("Set hexagon loop lower bound align limit"));41 42static cl::opt<uint32_t>43    LoopBndlAlignLimit("hexagon-loop-bundle-align-limit", cl::Hidden,44                       cl::init(4),45                       cl::desc("Set hexagon loop align bundle limit"));46 47static cl::opt<uint32_t> TinyLoopBndlAlignLimit(48    "hexagon-tiny-loop-bundle-align-limit", cl::Hidden, cl::init(8),49    cl::desc("Set hexagon tiny-core loop align bundle limit"));50 51static cl::opt<uint32_t>52    LoopEdgeThreshold("hexagon-loop-edge-threshold", cl::Hidden, cl::init(7500),53                      cl::desc("Set hexagon loop align edge threshold"));54 55namespace {56 57class HexagonLoopAlign : public MachineFunctionPass {58  const HexagonSubtarget *HST = nullptr;59  const TargetMachine *HTM = nullptr;60  const HexagonInstrInfo *HII = nullptr;61 62public:63  static char ID;64  HexagonLoopAlign() : MachineFunctionPass(ID) {}65  bool shouldBalignLoop(MachineBasicBlock &BB, bool AboveThres);66  bool isSingleLoop(MachineBasicBlock &MBB);67  bool attemptToBalignSmallLoop(MachineFunction &MF, MachineBasicBlock &MBB);68 69  void getAnalysisUsage(AnalysisUsage &AU) const override {70    AU.addRequired<MachineBranchProbabilityInfoWrapperPass>();71    AU.addRequired<MachineBlockFrequencyInfoWrapperPass>();72    MachineFunctionPass::getAnalysisUsage(AU);73  }74 75  StringRef getPassName() const override { return "Hexagon LoopAlign pass"; }76  bool runOnMachineFunction(MachineFunction &MF) override;77};78 79char HexagonLoopAlign::ID = 0;80 81bool HexagonLoopAlign::shouldBalignLoop(MachineBasicBlock &BB,82                                        bool AboveThres) {83  bool isVec = false;84  unsigned InstCnt = 0;85  unsigned BndlCnt = 0;86 87  for (MachineBasicBlock::instr_iterator II = BB.instr_begin(),88                                         IE = BB.instr_end();89       II != IE; ++II) {90 91    // End if the instruction is endloop.92    if (HII->isEndLoopN(II->getOpcode()))93      break;94    // Count the number of bundles.95    if (II->isBundle()) {96      BndlCnt++;97      continue;98    }99    // Skip over debug instructions.100    if (II->isDebugInstr())101      continue;102    // Check if there are any HVX instructions in loop.103    isVec |= HII->isHVXVec(*II);104    // Count the number of instructions.105    InstCnt++;106  }107 108  LLVM_DEBUG({109    dbgs() << "Bundle Count : " << BndlCnt << "\n";110    dbgs() << "Instruction Count : " << InstCnt << "\n";111  });112 113  unsigned LimitUB = 0;114  unsigned LimitBndl = LoopBndlAlignLimit;115  // The conditions in the order of priority.116  if (HST->isTinyCore()) {117    LimitUB = TinyLoopAlignLimitUB;118    LimitBndl = TinyLoopBndlAlignLimit;119  } else if (isVec)120    LimitUB = HVXLoopAlignLimitUB;121  else if (AboveThres)122    LimitUB = LoopAlignLimitUB;123 124  // if the upper bound is not set to a value, implies we didn't meet125  // the criteria.126  if (LimitUB == 0)127    return false;128 129  return InstCnt >= LoopAlignLimitLB && InstCnt <= LimitUB &&130         BndlCnt <= LimitBndl;131}132 133bool HexagonLoopAlign::isSingleLoop(MachineBasicBlock &MBB) {134  int Succs = MBB.succ_size();135  return (MBB.isSuccessor(&MBB) && (Succs == 2));136}137 138bool HexagonLoopAlign::attemptToBalignSmallLoop(MachineFunction &MF,139                                                MachineBasicBlock &MBB) {140  if (!isSingleLoop(MBB))141    return false;142 143  const MachineBranchProbabilityInfo *MBPI =144      &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();145  const MachineBlockFrequencyInfo *MBFI =146      &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();147 148  // Compute frequency of back edge,149  BlockFrequency BlockFreq = MBFI->getBlockFreq(&MBB);150  BranchProbability BrProb = MBPI->getEdgeProbability(&MBB, &MBB);151  BlockFrequency EdgeFreq = BlockFreq * BrProb;152  LLVM_DEBUG({153    dbgs() << "Loop Align Pass:\n";154    dbgs() << "\tedge with freq(" << EdgeFreq.getFrequency() << ")\n";155  });156 157  bool AboveThres = EdgeFreq.getFrequency() > LoopEdgeThreshold;158  if (shouldBalignLoop(MBB, AboveThres)) {159    // We found a loop, change its alignment to be 32 (5).160    MBB.setAlignment(llvm::Align(1 << 5));161    return true;162  }163  return false;164}165 166// Inspect each basic block, and if its a single BB loop, see if it167// meets the criteria for increasing alignment to 32.168 169bool HexagonLoopAlign::runOnMachineFunction(MachineFunction &MF) {170 171  HST = &MF.getSubtarget<HexagonSubtarget>();172  HII = HST->getInstrInfo();173  HTM = &MF.getTarget();174 175  if (skipFunction(MF.getFunction()))176    return false;177  if (DisableLoopAlign)178    return false;179 180  // This optimization is performed at181  // i) -O2 and above, and  when the loop has a HVX instruction.182  // ii) -O3183  if (HST->useHVXOps()) {184    if (HTM->getOptLevel() < CodeGenOptLevel::Default)185      return false;186  } else {187    if (HTM->getOptLevel() < CodeGenOptLevel::Aggressive)188      return false;189  }190 191  bool Changed = false;192  for (MachineFunction::iterator MBBi = MF.begin(), MBBe = MF.end();193       MBBi != MBBe; ++MBBi) {194    MachineBasicBlock &MBB = *MBBi;195    Changed |= attemptToBalignSmallLoop(MF, MBB);196  }197  return Changed;198}199 200} // namespace201 202INITIALIZE_PASS(HexagonLoopAlign, "hexagon-loop-align",203                "Hexagon LoopAlign pass", false, false)204 205//===----------------------------------------------------------------------===//206//                         Public Constructor Functions207//===----------------------------------------------------------------------===//208 209FunctionPass *llvm::createHexagonLoopAlign() { return new HexagonLoopAlign(); }210