LLVM 22.0.0git
Region.cpp
Go to the documentation of this file.
1//===- Region.cpp ---------------------------------------------------------===//
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-exception
6//
7//===----------------------------------------------------------------------===//
8
11
12namespace llvm::sandboxir {
13
14InstructionCost ScoreBoard::getCost(Instruction *I) const {
15 auto *LLVMI = cast<llvm::Instruction>(I->Val);
16 SmallVector<const llvm::Value *> Operands(LLVMI->operands());
17 return TTI.getInstructionCost(LLVMI, Operands, CostKind);
18}
19
21 auto Cost = getCost(I);
22 if (Rgn.contains(I))
23 // If `I` is one the newly added ones, then we should adjust `AfterCost`
24 AfterCost -= Cost;
25 else
26 // If `I` is one of the original instructions (outside the region) then it
27 // is part of the original code, so adjust `BeforeCost`.
28 BeforeCost += Cost;
29}
30
31#ifndef NDEBUG
32void ScoreBoard::dump() const { dump(dbgs()); }
33#endif
34
36 : Ctx(Ctx), Scoreboard(*this, TTI) {
37 LLVMContext &LLVMCtx = Ctx.LLVMCtx;
38 auto *RegionStrMD = MDString::get(LLVMCtx, RegionStr);
39 RegionMDN = MDNode::getDistinct(LLVMCtx, {RegionStrMD});
40
41 CreateInstCB = Ctx.registerCreateInstrCallback(
42 [this](Instruction *NewInst) { add(NewInst); });
43 EraseInstCB = Ctx.registerEraseInstrCallback([this](Instruction *ErasedInst) {
44 remove(ErasedInst);
45 removeFromAux(ErasedInst);
46 });
47}
48
50 Ctx.unregisterCreateInstrCallback(CreateInstCB);
51 Ctx.unregisterEraseInstrCallback(EraseInstCB);
52}
53
54void Region::addImpl(Instruction *I, bool IgnoreCost) {
55 Insts.insert(I);
56 // TODO: Consider tagging instructions lazily.
57 cast<llvm::Instruction>(I->Val)->setMetadata(MDKind, RegionMDN);
58 if (!IgnoreCost)
59 // Keep track of the instruction cost.
60 Scoreboard.add(I);
61}
62
63void Region::setAux(ArrayRef<Instruction *> Aux) {
64 this->Aux = SmallVector<Instruction *>(Aux);
65 auto &LLVMCtx = Ctx.LLVMCtx;
66 for (auto [Idx, I] : enumerate(Aux)) {
67 llvm::ConstantInt *IdxC =
68 llvm::ConstantInt::get(llvm::Type::getInt32Ty(LLVMCtx), Idx, false);
69 assert(cast<llvm::Instruction>(I->Val)->getMetadata(AuxMDKind) == nullptr &&
70 "Instruction already in Aux!");
71 cast<llvm::Instruction>(I->Val)->setMetadata(
72 AuxMDKind, MDNode::get(LLVMCtx, ConstantAsMetadata::get(IdxC)));
73 // Aux instrs should always be in a region.
74 addImpl(I, /*DontTrackCost=*/true);
75 }
76}
77
78void Region::setAux(unsigned Idx, Instruction *I) {
79 assert((Idx >= Aux.size() || Aux[Idx] == nullptr) &&
80 "There is already an Instruction at Idx in Aux!");
81 unsigned ExpectedSz = Idx + 1;
82 if (Aux.size() < ExpectedSz) {
83 auto SzBefore = Aux.size();
84 Aux.resize(ExpectedSz);
85 // Initialize the gap with nullptr.
86 for (unsigned Idx = SzBefore; Idx + 1 < ExpectedSz; ++Idx)
87 Aux[Idx] = nullptr;
88 }
89 Aux[Idx] = I;
90 // Aux instrs should always be in a region.
91 addImpl(I, /*DontTrackCost=*/true);
92}
93
94void Region::dropAuxMetadata(Instruction *I) {
95 auto *LLVMI = cast<llvm::Instruction>(I->Val);
96 LLVMI->setMetadata(AuxMDKind, nullptr);
97}
98
99void Region::removeFromAux(Instruction *I) {
100 auto It = find(Aux, I);
101 if (It == Aux.end())
102 return;
103 dropAuxMetadata(I);
104 Aux.erase(It);
105}
106
108 for (unsigned Idx : seq<unsigned>(0, Aux.size()))
109 dropAuxMetadata(Aux[Idx]);
110 Aux.clear();
111}
112
113void Region::remove(Instruction *I) {
114 // Keep track of the instruction cost. This need to be done *before* we remove
115 // `I` from the region.
116 Scoreboard.remove(I);
117
118 Insts.remove(I);
119 cast<llvm::Instruction>(I->Val)->setMetadata(MDKind, nullptr);
120}
121
122#ifndef NDEBUG
123bool Region::operator==(const Region &Other) const {
124 if (Insts.size() != Other.Insts.size())
125 return false;
126 if (!std::is_permutation(Insts.begin(), Insts.end(), Other.Insts.begin()))
127 return false;
128 return true;
129}
130
132 for (auto *I : Insts)
133 OS << *I << "\n";
134 if (!Aux.empty()) {
135 OS << "\nAux:\n";
136 for (auto *I : Aux) {
137 if (I == nullptr)
138 OS << "NULL\n";
139 else
140 OS << *I << "\n";
141 }
142 }
143}
144
145void Region::dump() const {
146 dump(dbgs());
147 dbgs() << "\n";
148}
149#endif // NDEBUG
150
155 auto &Ctx = F.getContext();
156 for (BasicBlock &BB : F) {
157 for (Instruction &Inst : BB) {
158 auto *LLVMI = cast<llvm::Instruction>(Inst.Val);
159 Region *R = nullptr;
160 if (auto *MDN = LLVMI->getMetadata(MDKind)) {
161 auto [It, Inserted] = MDNToRegion.try_emplace(MDN);
162 if (Inserted) {
163 Regions.push_back(std::make_unique<Region>(Ctx, TTI));
164 R = Regions.back().get();
165 It->second = R;
166 } else {
167 R = It->second;
168 }
169 R->addImpl(&Inst, /*IgnoreCost=*/true);
170 }
171 if (auto *AuxMDN = LLVMI->getMetadata(AuxMDKind)) {
172 llvm::Constant *IdxC =
173 dyn_cast<ConstantAsMetadata>(AuxMDN->getOperand(0))->getValue();
174 auto Idx = cast<llvm::ConstantInt>(IdxC)->getSExtValue();
175 if (R == nullptr) {
176 errs() << "No region specified for Aux: '" << *LLVMI << "'\n";
177 exit(1);
178 }
179 R->setAux(Idx, &Inst);
180 }
181 }
182 }
183#ifndef NDEBUG
184 // Check that there are no gaps in the Aux vector.
185 for (auto &RPtr : Regions)
186 for (auto *I : RPtr->getAux())
187 assert(I != nullptr && "Gap in Aux!");
188#endif
189 return Regions;
190}
191
192} // namespace llvm::sandboxir
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
mir Rename Register Operands
raw_pwrite_stream & OS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
static ConstantAsMetadata * get(Constant *C)
Definition: Metadata.h:535
This is the shared class of boolean and integer constants.
Definition: Constants.h:87
This is an important base class in LLVM.
Definition: Constant.h:43
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition: DenseMap.h:245
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
static MDTuple * getDistinct(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1573
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1565
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
Definition: Metadata.cpp:607
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
LLVM_ABI InstructionCost getInstructionCost(const User *U, ArrayRef< const Value * > Operands, TargetCostKind CostKind) const
Estimate the cost of a given IR user when lowered.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
Contains a list of sandboxir::Instruction's.
Definition: BasicBlock.h:68
LLVM_ABI CallbackID registerCreateInstrCallback(CreateInstrCallback CB)
Register a callback that gets called right after a SandboxIR instruction is created.
Definition: Context.cpp:742
LLVM_ABI void unregisterCreateInstrCallback(CallbackID ID)
Definition: Context.cpp:749
LLVM_ABI void unregisterEraseInstrCallback(CallbackID ID)
Definition: Context.cpp:735
LLVMContext & LLVMCtx
Definition: Context.h:70
LLVM_ABI CallbackID registerEraseInstrCallback(EraseInstrCallback CB)
Register a callback that gets called when a SandboxIR instruction is about to be removed from its par...
Definition: Context.cpp:728
A sandboxir::User with operands, opcode and linked with previous/next instructions in an instruction ...
Definition: Instruction.h:43
The main job of the Region is to point to new instructions generated by vectorization passes.
Definition: Region.h:96
void dump() const
Definition: Region.cpp:145
bool contains(Instruction *I) const
Returns true if I is in the Region.
Definition: Region.h:150
bool operator==(const Region &Other) const
This is an expensive check, meant for testing.
Definition: Region.cpp:123
LLVM_ABI Region(Context &Ctx, TargetTransformInfo &TTI)
Definition: Region.cpp:35
static LLVM_ABI SmallVector< std::unique_ptr< Region > > createRegionsFromMD(Function &F, TargetTransformInfo &TTI)
Definition: Region.cpp:152
LLVM_ABI void clearAux()
Clears all auxiliary data.
Definition: Region.cpp:107
LLVM_ABI ~Region()
Definition: Region.cpp:49
LLVM_ABI void remove(Instruction *I)
Mark I as a deleted instruction from the region.
Definition: Region.cpp:20
LLVM_DUMP_METHOD void dump() const
Definition: Region.cpp:32
void add(Instruction *I)
Mark I as a newly added instruction to the region.
Definition: Region.h:42
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1770
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition: STLExtras.h:2491
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Other
Any other memory.
InstructionCost Cost