1 //===------ VirtualInstruction.cpp ------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // Tools for determining which instructions are within a statement and the
10 // nature of their operands.
12 //===----------------------------------------------------------------------===//
14 #include "polly/Support/VirtualInstruction.h"
16 using namespace polly
;
19 VirtualUse
VirtualUse::create(Scop
*S
, const Use
&U
, LoopInfo
*LI
,
21 auto *UserBB
= getUseBlock(U
);
22 Loop
*UserScope
= LI
->getLoopFor(UserBB
);
23 Instruction
*UI
= dyn_cast
<Instruction
>(U
.getUser());
24 ScopStmt
*UserStmt
= S
->getStmtFor(UI
);
26 // Uses by PHI nodes are always reading values written by other statements,
27 // except it is within a region statement.
28 if (PHINode
*PHI
= dyn_cast
<PHINode
>(UI
)) {
29 // Handle PHI in exit block.
30 if (S
->getRegion().getExit() == PHI
->getParent())
31 return VirtualUse(UserStmt
, U
.get(), Inter
, nullptr, nullptr);
33 if (UserStmt
->getEntryBlock() != PHI
->getParent())
34 return VirtualUse(UserStmt
, U
.get(), Intra
, nullptr, nullptr);
36 // The MemoryAccess is expected to be set if @p Virtual is true.
37 MemoryAccess
*IncomingMA
= nullptr;
39 if (const ScopArrayInfo
*SAI
=
40 S
->getScopArrayInfoOrNull(PHI
, MemoryKind::PHI
)) {
41 IncomingMA
= S
->getPHIRead(SAI
);
42 assert(IncomingMA
->getStatement() == UserStmt
);
46 return VirtualUse(UserStmt
, U
.get(), Inter
, nullptr, IncomingMA
);
49 return create(S
, UserStmt
, UserScope
, U
.get(), Virtual
);
52 VirtualUse
VirtualUse::create(Scop
*S
, ScopStmt
*UserStmt
, Loop
*UserScope
,
53 Value
*Val
, bool Virtual
) {
54 assert(!isa
<StoreInst
>(Val
) && "a StoreInst cannot be used");
56 if (isa
<BasicBlock
>(Val
))
57 return VirtualUse(UserStmt
, Val
, Block
, nullptr, nullptr);
59 if (isa
<llvm::Constant
>(Val
) || isa
<MetadataAsValue
>(Val
) ||
61 return VirtualUse(UserStmt
, Val
, Constant
, nullptr, nullptr);
63 // Is the value synthesizable? If the user has been pruned
64 // (UserStmt == nullptr), it is either not used anywhere or is synthesizable.
65 // We assume synthesizable which practically should have the same effect.
66 auto *SE
= S
->getSE();
67 if (SE
->isSCEVable(Val
->getType())) {
68 auto *ScevExpr
= SE
->getSCEVAtScope(Val
, UserScope
);
69 if (!UserStmt
|| canSynthesize(Val
, *UserStmt
->getParent(), SE
, UserScope
))
70 return VirtualUse(UserStmt
, Val
, Synthesizable
, ScevExpr
, nullptr);
73 // FIXME: Inconsistency between lookupInvariantEquivClass and
74 // getRequiredInvariantLoads. Querying one of them should be enough.
75 auto &RIL
= S
->getRequiredInvariantLoads();
76 if (S
->lookupInvariantEquivClass(Val
) || RIL
.count(dyn_cast
<LoadInst
>(Val
)))
77 return VirtualUse(UserStmt
, Val
, Hoisted
, nullptr, nullptr);
79 // ReadOnly uses may have MemoryAccesses that we want to associate with the
80 // use. This is why we look for a MemoryAccess here already.
81 MemoryAccess
*InputMA
= nullptr;
82 if (UserStmt
&& Virtual
)
83 InputMA
= UserStmt
->lookupValueReadOf(Val
);
85 // Uses are read-only if they have been defined before the SCoP, i.e., they
86 // cannot be written to inside the SCoP. Arguments are defined before any
87 // instructions, hence also before the SCoP. If the user has been pruned
88 // (UserStmt == nullptr) and is not SCEVable, assume it is read-only as it is
89 // neither an intra- nor an inter-use.
90 if (!UserStmt
|| isa
<Argument
>(Val
))
91 return VirtualUse(UserStmt
, Val
, ReadOnly
, nullptr, InputMA
);
93 auto Inst
= cast
<Instruction
>(Val
);
94 if (!S
->contains(Inst
))
95 return VirtualUse(UserStmt
, Val
, ReadOnly
, nullptr, InputMA
);
97 // A use is inter-statement if either it is defined in another statement, or
98 // there is a MemoryAccess that reads its value that has been written by
100 if (InputMA
|| (!Virtual
&& UserStmt
!= S
->getStmtFor(Inst
)))
101 return VirtualUse(UserStmt
, Val
, Inter
, nullptr, InputMA
);
103 return VirtualUse(UserStmt
, Val
, Intra
, nullptr, nullptr);
106 void VirtualUse::print(raw_ostream
&OS
, bool Reproducible
) const {
107 OS
<< "User: [" << User
->getBaseName() << "] ";
109 case VirtualUse::Constant
:
110 OS
<< "Constant Op:";
112 case VirtualUse::Block
:
113 OS
<< "BasicBlock Op:";
115 case VirtualUse::Synthesizable
:
116 OS
<< "Synthesizable Op:";
118 case VirtualUse::Hoisted
:
119 OS
<< "Hoisted load Op:";
121 case VirtualUse::ReadOnly
:
122 OS
<< "Read-Only Op:";
124 case VirtualUse::Intra
:
127 case VirtualUse::Inter
:
135 OS
<< '"' << Val
->getName() << '"';
137 Val
->print(OS
, true);
143 if (InputMA
&& !Reproducible
)
144 OS
<< ' ' << InputMA
;
147 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
148 LLVM_DUMP_METHOD
void VirtualUse::dump() const {
149 print(errs(), false);
154 void VirtualInstruction::print(raw_ostream
&OS
, bool Reproducible
) const {
155 if (!Stmt
|| !Inst
) {
156 OS
<< "[null VirtualInstruction]";
160 OS
<< "[" << Stmt
->getBaseName() << "]";
161 Inst
->print(OS
, !Reproducible
);
164 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
165 LLVM_DUMP_METHOD
void VirtualInstruction::dump() const {
166 print(errs(), false);
171 /// Return true if @p Inst cannot be removed, even if it is nowhere referenced.
172 static bool isRoot(const Instruction
*Inst
) {
173 // The store is handled by its MemoryAccess. The load must be reached from the
174 // roots in order to be marked as used.
175 if (isa
<LoadInst
>(Inst
) || isa
<StoreInst
>(Inst
))
178 // Terminator instructions (in region statements) are required for control
180 if (Inst
->isTerminator())
183 // Writes to memory must be honored.
184 if (Inst
->mayWriteToMemory())
190 /// Return true for MemoryAccesses that cannot be removed because it represents
191 /// an llvm::Value that is used after the SCoP.
192 static bool isEscaping(MemoryAccess
*MA
) {
193 assert(MA
->isOriginalValueKind());
194 Scop
*S
= MA
->getStatement()->getParent();
195 return S
->isEscaping(cast
<Instruction
>(MA
->getAccessValue()));
198 /// Add non-removable virtual instructions in @p Stmt to @p RootInsts.
200 addInstructionRoots(ScopStmt
*Stmt
,
201 SmallVectorImpl
<VirtualInstruction
> &RootInsts
) {
202 if (!Stmt
->isBlockStmt()) {
203 // In region statements the terminator statement and all statements that
204 // are not in the entry block cannot be eliminated and consequently must
206 RootInsts
.emplace_back(Stmt
,
207 Stmt
->getRegion()->getEntry()->getTerminator());
208 for (BasicBlock
*BB
: Stmt
->getRegion()->blocks())
209 if (Stmt
->getRegion()->getEntry() != BB
)
210 for (Instruction
&Inst
: *BB
)
211 RootInsts
.emplace_back(Stmt
, &Inst
);
215 for (Instruction
*Inst
: Stmt
->getInstructions())
217 RootInsts
.emplace_back(Stmt
, Inst
);
220 /// Add non-removable memory accesses in @p Stmt to @p RootInsts.
222 /// @param Local If true, all writes are assumed to escape. markAndSweep
223 /// algorithms can use this to be applicable to a single ScopStmt only without
224 /// the risk of removing definitions required by other statements.
225 /// If false, only writes for SCoP-escaping values are roots. This
226 /// is global mode, where such writes must be marked by theirs uses
227 /// in order to be reachable.
228 static void addAccessRoots(ScopStmt
*Stmt
,
229 SmallVectorImpl
<MemoryAccess
*> &RootAccs
,
231 for (auto *MA
: *Stmt
) {
235 // Writes to arrays are always used.
236 if (MA
->isLatestArrayKind())
237 RootAccs
.push_back(MA
);
239 // Values are roots if they are escaping.
240 else if (MA
->isLatestValueKind()) {
241 if (Local
|| isEscaping(MA
))
242 RootAccs
.push_back(MA
);
245 // Exit phis are, by definition, escaping.
246 else if (MA
->isLatestExitPHIKind())
247 RootAccs
.push_back(MA
);
249 // phi writes are only roots if we are not visiting the statement
250 // containing the PHINode.
251 else if (Local
&& MA
->isLatestPHIKind())
252 RootAccs
.push_back(MA
);
256 /// Determine all instruction and access roots.
257 static void addRoots(ScopStmt
*Stmt
,
258 SmallVectorImpl
<VirtualInstruction
> &RootInsts
,
259 SmallVectorImpl
<MemoryAccess
*> &RootAccs
, bool Local
) {
260 addInstructionRoots(Stmt
, RootInsts
);
261 addAccessRoots(Stmt
, RootAccs
, Local
);
264 /// Mark accesses and instructions as used if they are reachable from a root,
265 /// walking the operand trees.
267 /// @param S The SCoP to walk.
268 /// @param LI The LoopInfo Analysis.
269 /// @param RootInsts List of root instructions.
270 /// @param RootAccs List of root accesses.
271 /// @param UsesInsts[out] Receives all reachable instructions, including the
273 /// @param UsedAccs[out] Receives all reachable accesses, including the roots.
274 /// @param OnlyLocal If non-nullptr, restricts walking to a single
276 static void walkReachable(Scop
*S
, LoopInfo
*LI
,
277 ArrayRef
<VirtualInstruction
> RootInsts
,
278 ArrayRef
<MemoryAccess
*> RootAccs
,
279 DenseSet
<VirtualInstruction
> &UsedInsts
,
280 DenseSet
<MemoryAccess
*> &UsedAccs
,
281 ScopStmt
*OnlyLocal
= nullptr) {
285 SmallVector
<VirtualInstruction
, 32> WorklistInsts
;
286 SmallVector
<MemoryAccess
*, 32> WorklistAccs
;
288 WorklistInsts
.append(RootInsts
.begin(), RootInsts
.end());
289 WorklistAccs
.append(RootAccs
.begin(), RootAccs
.end());
291 auto AddToWorklist
= [&](VirtualUse VUse
) {
292 switch (VUse
.getKind()) {
293 case VirtualUse::Block
:
294 case VirtualUse::Constant
:
295 case VirtualUse::Synthesizable
:
296 case VirtualUse::Hoisted
:
298 case VirtualUse::ReadOnly
:
299 // Read-only scalars only have MemoryAccesses if ModelReadOnlyScalars is
301 if (!VUse
.getMemoryAccess())
304 case VirtualUse::Inter
:
305 assert(VUse
.getMemoryAccess());
306 WorklistAccs
.push_back(VUse
.getMemoryAccess());
308 case VirtualUse::Intra
:
309 WorklistInsts
.emplace_back(VUse
.getUser(),
310 cast
<Instruction
>(VUse
.getValue()));
316 // We have two worklists to process: Only when the MemoryAccess worklist is
317 // empty, we process the instruction worklist.
319 while (!WorklistAccs
.empty()) {
320 auto *Acc
= WorklistAccs
.pop_back_val();
322 ScopStmt
*Stmt
= Acc
->getStatement();
323 if (OnlyLocal
&& Stmt
!= OnlyLocal
)
326 auto Inserted
= UsedAccs
.insert(Acc
);
327 if (!Inserted
.second
)
331 const ScopArrayInfo
*SAI
= Acc
->getScopArrayInfo();
333 if (Acc
->isLatestValueKind()) {
334 MemoryAccess
*DefAcc
= S
->getValueDef(SAI
);
336 // Accesses to read-only values do not have a definition.
338 WorklistAccs
.push_back(S
->getValueDef(SAI
));
341 if (Acc
->isLatestAnyPHIKind()) {
342 auto IncomingMAs
= S
->getPHIIncomings(SAI
);
343 WorklistAccs
.append(IncomingMAs
.begin(), IncomingMAs
.end());
347 if (Acc
->isWrite()) {
348 if (Acc
->isOriginalValueKind() ||
349 (Acc
->isOriginalArrayKind() && Acc
->getAccessValue())) {
350 Loop
*Scope
= Stmt
->getSurroundingLoop();
352 VirtualUse::create(S
, Stmt
, Scope
, Acc
->getAccessValue(), true);
356 if (Acc
->isOriginalAnyPHIKind()) {
357 for (auto Incoming
: Acc
->getIncoming()) {
358 VirtualUse VUse
= VirtualUse::create(
359 S
, Stmt
, LI
->getLoopFor(Incoming
.first
), Incoming
.second
, true);
364 if (Acc
->isOriginalArrayKind())
365 WorklistInsts
.emplace_back(Stmt
, Acc
->getAccessInstruction());
369 // If both worklists are empty, stop walking.
370 if (WorklistInsts
.empty())
373 VirtualInstruction VInst
= WorklistInsts
.pop_back_val();
374 ScopStmt
*Stmt
= VInst
.getStmt();
375 Instruction
*Inst
= VInst
.getInstruction();
377 // Do not process statements other than the local.
378 if (OnlyLocal
&& Stmt
!= OnlyLocal
)
381 auto InsertResult
= UsedInsts
.insert(VInst
);
382 if (!InsertResult
.second
)
385 // Add all operands to the worklists.
386 PHINode
*PHI
= dyn_cast
<PHINode
>(Inst
);
387 if (PHI
&& PHI
->getParent() == Stmt
->getEntryBlock()) {
388 if (MemoryAccess
*PHIRead
= Stmt
->lookupPHIReadOf(PHI
))
389 WorklistAccs
.push_back(PHIRead
);
391 for (VirtualUse VUse
: VInst
.operands())
395 // If there is an array access, also add its MemoryAccesses to the worklist.
396 const MemoryAccessList
*Accs
= Stmt
->lookupArrayAccessesFor(Inst
);
400 for (MemoryAccess
*Acc
: *Accs
)
401 WorklistAccs
.push_back(Acc
);
405 void polly::markReachable(Scop
*S
, LoopInfo
*LI
,
406 DenseSet
<VirtualInstruction
> &UsedInsts
,
407 DenseSet
<MemoryAccess
*> &UsedAccs
,
408 ScopStmt
*OnlyLocal
) {
409 SmallVector
<VirtualInstruction
, 32> RootInsts
;
410 SmallVector
<MemoryAccess
*, 32> RootAccs
;
413 addRoots(OnlyLocal
, RootInsts
, RootAccs
, true);
415 for (auto &Stmt
: *S
)
416 addRoots(&Stmt
, RootInsts
, RootAccs
, false);
419 walkReachable(S
, LI
, RootInsts
, RootAccs
, UsedInsts
, UsedAccs
, OnlyLocal
);