19efc761dSJorge Gorbe Moya //===- Region.cpp ---------------------------------------------------------===// 29efc761dSJorge Gorbe Moya // 39efc761dSJorge Gorbe Moya // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 49efc761dSJorge Gorbe Moya // See https://llvm.org/LICENSE.txt for license information. 59efc761dSJorge Gorbe Moya // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 69efc761dSJorge Gorbe Moya // 79efc761dSJorge Gorbe Moya //===----------------------------------------------------------------------===// 89efc761dSJorge Gorbe Moya 99efc761dSJorge Gorbe Moya #include "llvm/SandboxIR/Region.h" 10e22b07e7Svporpo #include "llvm/SandboxIR/Function.h" 119efc761dSJorge Gorbe Moya 129efc761dSJorge Gorbe Moya namespace llvm::sandboxir { 139efc761dSJorge Gorbe Moya 14*4b209c5dSvporpo InstructionCost ScoreBoard::getCost(Instruction *I) const { 15*4b209c5dSvporpo auto *LLVMI = cast<llvm::Instruction>(I->Val); 16*4b209c5dSvporpo SmallVector<const llvm::Value *> Operands(LLVMI->operands()); 17*4b209c5dSvporpo return TTI.getInstructionCost(LLVMI, Operands, CostKind); 18*4b209c5dSvporpo } 19*4b209c5dSvporpo 20*4b209c5dSvporpo void ScoreBoard::remove(Instruction *I) { 21*4b209c5dSvporpo auto Cost = getCost(I); 22*4b209c5dSvporpo if (Rgn.contains(I)) 23*4b209c5dSvporpo // If `I` is one the newly added ones, then we should adjust `AfterCost` 24*4b209c5dSvporpo AfterCost -= Cost; 25*4b209c5dSvporpo else 26*4b209c5dSvporpo // If `I` is one of the original instructions (outside the region) then it 27*4b209c5dSvporpo // is part of the original code, so adjust `BeforeCost`. 28*4b209c5dSvporpo BeforeCost += Cost; 29*4b209c5dSvporpo } 30*4b209c5dSvporpo 31*4b209c5dSvporpo #ifndef NDEBUG 32*4b209c5dSvporpo void ScoreBoard::dump() const { dump(dbgs()); } 33*4b209c5dSvporpo #endif 34*4b209c5dSvporpo 35*4b209c5dSvporpo Region::Region(Context &Ctx, TargetTransformInfo &TTI) 36*4b209c5dSvporpo : Ctx(Ctx), Scoreboard(*this, TTI) { 379efc761dSJorge Gorbe Moya LLVMContext &LLVMCtx = Ctx.LLVMCtx; 389efc761dSJorge Gorbe Moya auto *RegionStrMD = MDString::get(LLVMCtx, RegionStr); 399efc761dSJorge Gorbe Moya RegionMDN = MDNode::getDistinct(LLVMCtx, {RegionStrMD}); 40b22c3c1eSJorge Gorbe Moya 41b22c3c1eSJorge Gorbe Moya CreateInstCB = Ctx.registerCreateInstrCallback( 42b22c3c1eSJorge Gorbe Moya [this](Instruction *NewInst) { add(NewInst); }); 43b22c3c1eSJorge Gorbe Moya EraseInstCB = Ctx.registerEraseInstrCallback( 44b22c3c1eSJorge Gorbe Moya [this](Instruction *ErasedInst) { remove(ErasedInst); }); 459efc761dSJorge Gorbe Moya } 469efc761dSJorge Gorbe Moya 47b22c3c1eSJorge Gorbe Moya Region::~Region() { 48b22c3c1eSJorge Gorbe Moya Ctx.unregisterCreateInstrCallback(CreateInstCB); 49b22c3c1eSJorge Gorbe Moya Ctx.unregisterEraseInstrCallback(EraseInstCB); 50b22c3c1eSJorge Gorbe Moya } 519efc761dSJorge Gorbe Moya 529efc761dSJorge Gorbe Moya void Region::add(Instruction *I) { 539efc761dSJorge Gorbe Moya Insts.insert(I); 549efc761dSJorge Gorbe Moya // TODO: Consider tagging instructions lazily. 559efc761dSJorge Gorbe Moya cast<llvm::Instruction>(I->Val)->setMetadata(MDKind, RegionMDN); 56*4b209c5dSvporpo // Keep track of the instruction cost. 57*4b209c5dSvporpo Scoreboard.add(I); 589efc761dSJorge Gorbe Moya } 599efc761dSJorge Gorbe Moya 609efc761dSJorge Gorbe Moya void Region::remove(Instruction *I) { 61*4b209c5dSvporpo // Keep track of the instruction cost. This need to be done *before* we remove 62*4b209c5dSvporpo // `I` from the region. 63*4b209c5dSvporpo Scoreboard.remove(I); 64*4b209c5dSvporpo 659efc761dSJorge Gorbe Moya Insts.remove(I); 669efc761dSJorge Gorbe Moya cast<llvm::Instruction>(I->Val)->setMetadata(MDKind, nullptr); 679efc761dSJorge Gorbe Moya } 689efc761dSJorge Gorbe Moya 699efc761dSJorge Gorbe Moya #ifndef NDEBUG 709efc761dSJorge Gorbe Moya bool Region::operator==(const Region &Other) const { 719efc761dSJorge Gorbe Moya if (Insts.size() != Other.Insts.size()) 729efc761dSJorge Gorbe Moya return false; 739efc761dSJorge Gorbe Moya if (!std::is_permutation(Insts.begin(), Insts.end(), Other.Insts.begin())) 749efc761dSJorge Gorbe Moya return false; 759efc761dSJorge Gorbe Moya return true; 769efc761dSJorge Gorbe Moya } 779efc761dSJorge Gorbe Moya 789efc761dSJorge Gorbe Moya void Region::dump(raw_ostream &OS) const { 799efc761dSJorge Gorbe Moya for (auto *I : Insts) 809efc761dSJorge Gorbe Moya OS << *I << "\n"; 819efc761dSJorge Gorbe Moya } 829efc761dSJorge Gorbe Moya 839efc761dSJorge Gorbe Moya void Region::dump() const { 849efc761dSJorge Gorbe Moya dump(dbgs()); 859efc761dSJorge Gorbe Moya dbgs() << "\n"; 869efc761dSJorge Gorbe Moya } 879efc761dSJorge Gorbe Moya #endif // NDEBUG 889efc761dSJorge Gorbe Moya 89*4b209c5dSvporpo SmallVector<std::unique_ptr<Region>> 90*4b209c5dSvporpo Region::createRegionsFromMD(Function &F, TargetTransformInfo &TTI) { 919efc761dSJorge Gorbe Moya SmallVector<std::unique_ptr<Region>> Regions; 929efc761dSJorge Gorbe Moya DenseMap<MDNode *, Region *> MDNToRegion; 939efc761dSJorge Gorbe Moya auto &Ctx = F.getContext(); 949efc761dSJorge Gorbe Moya for (BasicBlock &BB : F) { 959efc761dSJorge Gorbe Moya for (Instruction &Inst : BB) { 969efc761dSJorge Gorbe Moya if (auto *MDN = cast<llvm::Instruction>(Inst.Val)->getMetadata(MDKind)) { 979efc761dSJorge Gorbe Moya Region *R = nullptr; 989efc761dSJorge Gorbe Moya auto It = MDNToRegion.find(MDN); 999efc761dSJorge Gorbe Moya if (It == MDNToRegion.end()) { 100*4b209c5dSvporpo Regions.push_back(std::make_unique<Region>(Ctx, TTI)); 1019efc761dSJorge Gorbe Moya R = Regions.back().get(); 1029efc761dSJorge Gorbe Moya MDNToRegion[MDN] = R; 1039efc761dSJorge Gorbe Moya } else { 1049efc761dSJorge Gorbe Moya R = It->second; 1059efc761dSJorge Gorbe Moya } 1069efc761dSJorge Gorbe Moya R->add(&Inst); 1079efc761dSJorge Gorbe Moya } 1089efc761dSJorge Gorbe Moya } 1099efc761dSJorge Gorbe Moya } 1109efc761dSJorge Gorbe Moya return Regions; 1119efc761dSJorge Gorbe Moya } 1129efc761dSJorge Gorbe Moya 1139efc761dSJorge Gorbe Moya } // namespace llvm::sandboxir 114