Skip to content

Commit 2d2635d

Browse files
author
Aleksandr Popov
committed
[NFC] Extract LoopStructure from IRCE
Preparatory patch for extracting LoopConstrainer to a separate file to reuse it outside IRCE.
1 parent fc98921 commit 2d2635d

File tree

5 files changed

+508
-474
lines changed

5 files changed

+508
-474
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
//===- LoopConstrainer.h ----------------------------------------*- C++ -*-===//
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+
9+
#ifndef LLVM_TRANSFORMS_UTILS_LOOP_CONSTRAINER_H
10+
#define LLVM_TRANSFORMS_UTILS_LOOP_CONSTRAINER_H
11+
12+
#include "llvm/Support/Casting.h"
13+
#include <optional>
14+
15+
namespace llvm {
16+
17+
class BasicBlock;
18+
class BranchInst;
19+
class IntegerType;
20+
class Loop;
21+
class ScalarEvolution;
22+
class Value;
23+
24+
// Keeps track of the structure of a loop. This is similar to llvm::Loop,
25+
// except that it is more lightweight and can track the state of a loop through
26+
// changing and potentially invalid IR. This structure also formalizes the
27+
// kinds of loops we can deal with -- ones that have a single latch that is also
28+
// an exiting block *and* have a canonical induction variable.
29+
struct LoopStructure {
30+
const char *Tag = "";
31+
32+
BasicBlock *Header = nullptr;
33+
BasicBlock *Latch = nullptr;
34+
35+
// `Latch's terminator instruction is `LatchBr', and it's `LatchBrExitIdx'th
36+
// successor is `LatchExit', the exit block of the loop.
37+
BranchInst *LatchBr = nullptr;
38+
BasicBlock *LatchExit = nullptr;
39+
unsigned LatchBrExitIdx = std::numeric_limits<unsigned>::max();
40+
41+
// The loop represented by this instance of LoopStructure is semantically
42+
// equivalent to:
43+
//
44+
// intN_ty inc = IndVarIncreasing ? 1 : -1;
45+
// pred_ty predicate = IndVarIncreasing ? ICMP_SLT : ICMP_SGT;
46+
//
47+
// for (intN_ty iv = IndVarStart; predicate(iv, LoopExitAt); iv = IndVarBase)
48+
// ... body ...
49+
50+
Value *IndVarBase = nullptr;
51+
Value *IndVarStart = nullptr;
52+
Value *IndVarStep = nullptr;
53+
Value *LoopExitAt = nullptr;
54+
bool IndVarIncreasing = false;
55+
bool IsSignedPredicate = true;
56+
IntegerType *ExitCountTy = nullptr;
57+
58+
LoopStructure() = default;
59+
60+
template <typename M> LoopStructure map(M Map) const {
61+
LoopStructure Result;
62+
Result.Tag = Tag;
63+
Result.Header = cast<BasicBlock>(Map(Header));
64+
Result.Latch = cast<BasicBlock>(Map(Latch));
65+
Result.LatchBr = cast<BranchInst>(Map(LatchBr));
66+
Result.LatchExit = cast<BasicBlock>(Map(LatchExit));
67+
Result.LatchBrExitIdx = LatchBrExitIdx;
68+
Result.IndVarBase = Map(IndVarBase);
69+
Result.IndVarStart = Map(IndVarStart);
70+
Result.IndVarStep = Map(IndVarStep);
71+
Result.LoopExitAt = Map(LoopExitAt);
72+
Result.IndVarIncreasing = IndVarIncreasing;
73+
Result.IsSignedPredicate = IsSignedPredicate;
74+
Result.ExitCountTy = ExitCountTy;
75+
return Result;
76+
}
77+
78+
static std::optional<LoopStructure>
79+
parseLoopStructure(ScalarEvolution &, Loop &, bool, const char *&);
80+
};
81+
} // namespace llvm
82+
83+
#endif // LLVM_TRANSFORMS_UTILS_LOOP_CONSTRAINER_H

0 commit comments

Comments
 (0)