LLVM 23.0.0git
LVRange.cpp
Go to the documentation of this file.
1//===-- LVRange.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//
9// This implements the LVRange class.
10//
11//===----------------------------------------------------------------------===//
12
17
18using namespace llvm;
19using namespace llvm::logicalview;
20
21#define DEBUG_TYPE "Range"
22
24 RangesTree.clear();
25
26 LLVM_DEBUG({ dbgs() << "\nRanges Tree entries:\n"; });
27
28 // Traverse the ranges and store them into the interval tree.
29 for (LVRangeEntry &RangeEntry : RangeEntries) {
31 LVScope *Scope = RangeEntry.scope();
32 dbgs() << "Scope: " << format_decimal(Scope->getLevel(), 5) << " "
33 << "Range: [" << hexValue(RangeEntry.lower()) << ":"
34 << hexValue(RangeEntry.upper()) << "]\n";
35 });
36
37 RangesTree.insert(RangeEntry.lower(), RangeEntry.upper(),
38 RangeEntry.scope());
39 }
40
41 // Create the interval tree.
42 RangesTree.create();
43
45 dbgs() << "\nRanges Tree:\n";
46 RangesTree.print(dbgs());
47 });
48}
49
50// Add the pair in an ascending order, with the smallest ranges at the
51// start; in that way, enclosing scopes ranges are at the end of the
52// list; we assume that low <= high.
54 LVAddress UpperAddress) {
55 // We assume the low <= high.
56 if (LowerAddress > UpperAddress)
57 std::swap(LowerAddress, UpperAddress);
58
59 // Record the lowest and highest seen addresses.
60 if (LowerAddress < Lower)
61 Lower = LowerAddress;
62 if (UpperAddress > Upper)
63 Upper = UpperAddress;
64
65 // Just add the scope and range pair, in no particular order.
66 RangeEntries.emplace_back(LowerAddress, UpperAddress, Scope);
67}
68
70 assert(Scope && "Scope must not be nullptr");
71 // Traverse the ranges and update the ranges set only if the ranges
72 // values are not already recorded.
73 if (const LVLocations *Locations = Scope->getRanges())
74 for (const LVLocation *Location : *Locations) {
75 LVAddress LowPC = Location->getLowerAddress();
76 LVAddress HighPC = Location->getUpperAddress();
77 if (!hasEntry(LowPC, HighPC))
78 // Add the pair of addresses.
79 addEntry(Scope, LowPC, HighPC);
80 }
81}
82
83// Get the scope associated with the input address.
85 LLVM_DEBUG({ dbgs() << formatv("Searching: {0:x8}\nFound: ", Address); });
86
87 LVScope *Target = nullptr;
88 LVLevel TargetLevel = 0;
89 LVLevel Level = 0;
90 LVScope *Scope = nullptr;
91 for (LVRangesTree::find_iterator Iter = RangesTree.find(Address),
92 End = RangesTree.find_end();
93 Iter != End; ++Iter) {
95 dbgs() << formatv("[{0:x8},{1:x8}] ", Iter->left(), Iter->right());
96 });
97 Scope = Iter->value();
98 Level = Scope->getLevel();
99 if (Level > TargetLevel) {
100 TargetLevel = Level;
101 Target = Scope;
102 }
103 }
104
105 LLVM_DEBUG({ dbgs() << (Scope ? "\n" : "None\n"); });
106
107 return Target;
108}
109
110// Find the associated Scope for the given ranges values.
112 LVAddress UpperAddress) const {
113 for (const LVRangeEntry &RangeEntry : RangeEntries)
114 if (LowerAddress >= RangeEntry.lower() && UpperAddress < RangeEntry.upper())
115 return RangeEntry.scope();
116 return nullptr;
117}
118
119// True if the range addresses contain the pair [LowerAddress, UpperAddress].
120bool LVRange::hasEntry(LVAddress LowerAddress, LVAddress UpperAddress) const {
121 for (const LVRangeEntry &RangeEntry : RangeEntries)
122 if (LowerAddress == RangeEntry.lower() &&
123 UpperAddress == RangeEntry.upper())
124 return true;
125 return false;
126}
127
128// Sort the range elements for the whole Compile Unit.
130 auto CompareRangeEntry = [](const LVRangeEntry &lhs,
131 const LVRangeEntry &rhs) -> bool {
132 if (lhs.lower() < rhs.lower())
133 return true;
134
135 // If the lower address is the same, use the upper address value in
136 // order to put first the smallest interval.
137 if (lhs.lower() == rhs.lower())
138 return lhs.upper() < rhs.upper();
139
140 return false;
141 };
142
143 // Sort the ranges using low address and range size.
144 llvm::stable_sort(RangeEntries, CompareRangeEntry);
145}
146
147void LVRange::print(raw_ostream &OS, bool Full) const {
148 size_t Indentation = 0;
149 for (const LVRangeEntry &RangeEntry : RangeEntries) {
150 LVScope *Scope = RangeEntry.scope();
151 Scope->printAttributes(OS, Full);
152 Indentation = options().indentationSize();
153 if (Indentation)
154 OS << " ";
155 OS << formatv("[{0:x8},{1:x8}] ", RangeEntry.lower(), RangeEntry.upper())
156 << formattedKind(Scope->kind()) << " " << formattedName(Scope->getName())
157 << "\n";
158 }
159 printExtra(OS, Full);
160}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_DEBUG(...)
Definition Debug.h:114
Target - Wrapper for Target specific information.
size_t indentationSize() const
Definition LVOptions.h:313
RangeType lower() const
Definition LVRange.h:38
RangeType upper() const
Definition LVRange.h:39
LVScope * getEntry(LVAddress Address) const
Definition LVRange.cpp:84
bool hasEntry(LVAddress Low, LVAddress High) const
Definition LVRange.cpp:120
void printExtra(raw_ostream &OS, bool Full=true) const override
Definition LVRange.h:89
void print(raw_ostream &OS, bool Full=true) const override
Definition LVRange.cpp:147
void addEntry(LVScope *Scope, LVAddress LowerAddress, LVAddress UpperAddress)
Definition LVRange.cpp:53
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
FormattedNumber hexValue(uint64_t N, unsigned Width=HEX_WIDTH, bool Upper=false)
Definition LVSupport.h:123
uint16_t LVLevel
Definition LVObject.h:38
std::string formattedKind(StringRef Kind)
Definition LVSupport.h:236
std::string formattedName(StringRef Name)
Definition LVSupport.h:240
uint64_t LVAddress
Definition LVObject.h:36
LVOptions & options()
Definition LVOptions.h:448
SmallVector< LVLocation *, 8 > LVLocations
Definition LVObject.h:78
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
Definition STLExtras.h:2116
FormattedNumber format_decimal(int64_t N, unsigned Width)
format_decimal - Output N as a right justified, fixed-width decimal.
Definition Format.h:216
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:872