|
| 1 | +/*========================== begin_copyright_notice ============================ |
| 2 | +
|
| 3 | +Copyright (C) 2025 Intel Corporation |
| 4 | +
|
| 5 | +SPDX-License-Identifier: MIT |
| 6 | +
|
| 7 | +============================= end_copyright_notice ===========================*/ |
| 8 | + |
| 9 | +#include "Compiler/CISACodeGen/DropTargetBBs.hpp" |
| 10 | + |
| 11 | +#include "common/LLVMWarningsPush.hpp" |
| 12 | +#include <llvm/ADT/STLExtras.h> |
| 13 | +#include <llvm/IR/Function.h> |
| 14 | +#include <llvm/IR/Constants.h> |
| 15 | +#include <llvm/IR/Instructions.h> |
| 16 | +#include "common/LLVMWarningsPop.hpp" |
| 17 | + |
| 18 | +#include "Compiler/IGCPassSupport.h" |
| 19 | +#include "common/igc_regkeys.hpp" |
| 20 | + |
| 21 | +#include <fstream> |
| 22 | +#include <string> |
| 23 | +#include <optional> |
| 24 | +#include <filesystem> |
| 25 | + |
| 26 | +using namespace llvm; |
| 27 | +using namespace IGC; |
| 28 | + |
| 29 | +#define PASS_FLAG "igc-drop-target-bbs" |
| 30 | +#define PASS_DESCRIPTION "Drop target basic blocks" |
| 31 | +#define PASS_CFG_ONLY false |
| 32 | +#define PASS_ANALYSIS false |
| 33 | +IGC_INITIALIZE_PASS_BEGIN(DropTargetBBs, PASS_FLAG, PASS_DESCRIPTION, PASS_CFG_ONLY, PASS_ANALYSIS) |
| 34 | +IGC_INITIALIZE_PASS_END(DropTargetBBs, PASS_FLAG, PASS_DESCRIPTION, PASS_CFG_ONLY, PASS_ANALYSIS) |
| 35 | + |
| 36 | +#define DROP_BB_DEBUG(msg) \ |
| 37 | + do { \ |
| 38 | + if (VerboseLog) { \ |
| 39 | + llvm::errs() << msg << "\n"; \ |
| 40 | + } \ |
| 41 | + } while (0) |
| 42 | + |
| 43 | +char IGC::DropTargetBBs::ID = 0; |
| 44 | + |
| 45 | +DropTargetBBs::DropTargetBBs() : FunctionPass(ID), VerboseLog(IGC_GET_FLAG_VALUE(VerboseDropTargetBBs)) { |
| 46 | + initializeDropTargetBBsPass(*PassRegistry::getPassRegistry()); |
| 47 | +} |
| 48 | + |
| 49 | +void DropTargetBBs::getAnalysisUsage(llvm::AnalysisUsage &AU) const {} |
| 50 | + |
| 51 | +static std::optional<int> getBBIndexByName(Function &F, const std::string &BBName) { |
| 52 | + int bbIndex = 0; |
| 53 | + for (auto &BB : F) { |
| 54 | + if (BB.hasName() && BB.getName() == BBName) { |
| 55 | + return bbIndex; |
| 56 | + } |
| 57 | + bbIndex++; |
| 58 | + } |
| 59 | + return std::nullopt; |
| 60 | +} |
| 61 | + |
| 62 | +static std::optional<SmallVector<std::string, 8>> getBBNamesToDrop(const Function &F, const char *DropBBListBasePath) { |
| 63 | + SmallVector<std::string, 8> BBsToDrop; |
| 64 | + std::filesystem::path DropBBListPath = std::filesystem::path(DropBBListBasePath) / (F.getName().str() + ".txt"); |
| 65 | + { |
| 66 | + std::ifstream DropBBFile(DropBBListPath); |
| 67 | + if (!DropBBFile.is_open()) { |
| 68 | + return std::nullopt; |
| 69 | + } |
| 70 | + |
| 71 | + std::string line; |
| 72 | + while (std::getline(DropBBFile, line)) { |
| 73 | + if (line.empty()) { |
| 74 | + continue; |
| 75 | + } |
| 76 | + |
| 77 | + if (line.back() == '\r') { |
| 78 | + line.pop_back(); |
| 79 | + } |
| 80 | + |
| 81 | + BBsToDrop.push_back(line); |
| 82 | + } |
| 83 | + DropBBFile.close(); |
| 84 | + } |
| 85 | + return BBsToDrop; |
| 86 | +} |
| 87 | + |
| 88 | +bool DropTargetBBs::runOnFunction(Function &F) { |
| 89 | + if (F.isDeclaration()) { |
| 90 | + return false; |
| 91 | + } |
| 92 | + |
| 93 | + auto BBsToDropOptional = getBBNamesToDrop(F, IGC_GET_REGKEYSTRING(DropTargetBBListPath)); |
| 94 | + if (!BBsToDropOptional.has_value()) { |
| 95 | + return false; |
| 96 | + } |
| 97 | + |
| 98 | + const auto &BBsToDrop = BBsToDropOptional.value(); |
| 99 | + SmallVector<std::uint32_t, 8> BBIndexesToDrop; |
| 100 | + for (const auto &BBName : BBsToDrop) { |
| 101 | + auto BBIndex = getBBIndexByName(F, BBName); |
| 102 | + if (BBIndex.has_value()) { |
| 103 | + BBIndexesToDrop.push_back(BBIndex.value()); |
| 104 | + } |
| 105 | + } |
| 106 | + |
| 107 | + if (BBIndexesToDrop.empty()) { |
| 108 | + return false; |
| 109 | + } |
| 110 | + |
| 111 | + DROP_BB_DEBUG("DropTargetBBss: Examining function: " << F.getName()); |
| 112 | + DROP_BB_DEBUG("DropTargetBBss: BB num: " << F.size()); |
| 113 | + |
| 114 | + for (const auto &BBIndex : BBIndexesToDrop) { |
| 115 | + if (BBIndex >= F.size()) { |
| 116 | + continue; |
| 117 | + } |
| 118 | + auto BI = F.begin(); |
| 119 | + std::advance(BI, BBIndex); |
| 120 | + BasicBlock *BB = &*BI; |
| 121 | + DROP_BB_DEBUG("DropTargetBBs: Dropping BB index: " << BBIndex << " Name: " << BB->getName()); |
| 122 | + |
| 123 | + while (!BB->use_empty()) { |
| 124 | + auto *User = *BB->user_begin(); |
| 125 | + if (auto *PHI = dyn_cast<PHINode>(User)) { |
| 126 | + PHI->removeIncomingValue(BB, true); |
| 127 | + } else if (auto *Br = dyn_cast<BranchInst>(User)) { |
| 128 | + BasicBlock *NextBB = BB->getNextNode(); |
| 129 | + if (NextBB) { |
| 130 | + Br->setSuccessor(Br->getSuccessor(0) == BB ? 0 : 1, NextBB); |
| 131 | + } else { |
| 132 | + Br->eraseFromParent(); |
| 133 | + } |
| 134 | + } else if (auto *SI = dyn_cast<SwitchInst>(User)) { |
| 135 | + if (auto *CI = SI->findCaseDest(BB)) { |
| 136 | + SI->removeCase(SI->findCaseValue(CI)); |
| 137 | + } |
| 138 | + } else { |
| 139 | + User->replaceUsesOfWith(BB, PoisonValue::get(BB->getType())); |
| 140 | + } |
| 141 | + } |
| 142 | + |
| 143 | + for (Instruction &I : *BB) { |
| 144 | + if (!I.use_empty()) { |
| 145 | + I.replaceAllUsesWith(PoisonValue::get(I.getType())); |
| 146 | + } |
| 147 | + } |
| 148 | + |
| 149 | + BB->eraseFromParent(); |
| 150 | + } |
| 151 | + |
| 152 | + return true; |
| 153 | +} |
0 commit comments