summaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/LoopInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/LoopInfo.cpp')
-rw-r--r--llvm/lib/Analysis/LoopInfo.cpp32
1 files changed, 26 insertions, 6 deletions
diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp
index b5af210f1b92..a85869b16333 100644
--- a/llvm/lib/Analysis/LoopInfo.cpp
+++ b/llvm/lib/Analysis/LoopInfo.cpp
@@ -34,6 +34,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PrintPasses.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -431,6 +432,10 @@ static bool isBlockInLCSSAForm(const Loop &L, const BasicBlock &BB,
for (const Use &U : I.uses()) {
const Instruction *UI = cast<Instruction>(U.getUser());
const BasicBlock *UserBB = UI->getParent();
+
+ // For practical purposes, we consider that the use in a PHI
+ // occurs in the respective predecessor block. For more info,
+ // see the `phi` doc in LangRef and the LCSSA doc.
if (const PHINode *P = dyn_cast<PHINode>(UI))
UserBB = P->getIncomingBlock(U);
@@ -535,6 +540,22 @@ void Loop::setLoopAlreadyUnrolled() {
setLoopID(NewLoopID);
}
+void Loop::setLoopMustProgress() {
+ LLVMContext &Context = getHeader()->getContext();
+
+ MDNode *MustProgress = findOptionMDForLoop(this, "llvm.loop.mustprogress");
+
+ if (MustProgress)
+ return;
+
+ MDNode *MustProgressMD =
+ MDNode::get(Context, MDString::get(Context, "llvm.loop.mustprogress"));
+ MDNode *LoopID = getLoopID();
+ MDNode *NewLoopID =
+ makePostTransformationMetadata(Context, LoopID, {}, {MustProgressMD});
+ setLoopID(NewLoopID);
+}
+
bool Loop::isAnnotatedParallel() const {
MDNode *DesiredLoopIdMetadata = getLoopID();
@@ -546,7 +567,7 @@ bool Loop::isAnnotatedParallel() const {
SmallPtrSet<MDNode *, 4>
ParallelAccessGroups; // For scalable 'contains' check.
if (ParallelAccesses) {
- for (const MDOperand &MD : drop_begin(ParallelAccesses->operands(), 1)) {
+ for (const MDOperand &MD : drop_begin(ParallelAccesses->operands())) {
MDNode *AccGroup = cast<MDNode>(MD.get());
assert(isValidAsAccessGroup(AccGroup) &&
"List item must be an access group");
@@ -764,7 +785,7 @@ void UnloopUpdater::removeBlocksFromAncestors() {
/// Update the parent loop for all subloops directly nested within unloop.
void UnloopUpdater::updateSubloopParents() {
- while (!Unloop.empty()) {
+ while (!Unloop.isInnermost()) {
Loop *Subloop = *std::prev(Unloop.end());
Unloop.removeChildLoop(std::prev(Unloop.end()));
@@ -862,7 +883,7 @@ void LoopInfo::erase(Loop *Unloop) {
auto InvalidateOnExit = make_scope_exit([&]() { destroy(Unloop); });
// First handle the special case of no parent loop to simplify the algorithm.
- if (!Unloop->getParentLoop()) {
+ if (Unloop->isOutermost()) {
// Since BBLoop had no parent, Unloop blocks are no longer in a loop.
for (Loop::block_iterator I = Unloop->block_begin(),
E = Unloop->block_end();
@@ -887,7 +908,7 @@ void LoopInfo::erase(Loop *Unloop) {
}
// Move all of the subloops to the top-level.
- while (!Unloop->empty())
+ while (!Unloop->isInnermost())
addTopLevelLoop(Unloop->removeChildLoop(std::prev(Unloop->end())));
return;
@@ -1017,8 +1038,7 @@ MDNode *llvm::makePostTransformationMetadata(LLVMContext &Context,
SmallVector<Metadata *, 4> MDs;
// Reserve first location for self reference to the LoopID metadata node.
- TempMDTuple TempNode = MDNode::getTemporary(Context, None);
- MDs.push_back(TempNode.get());
+ MDs.push_back(nullptr);
// Remove metadata for the transformation that has been applied or that became
// outdated.