Skip to content

Commit 2dbf124

Browse files
committed
Apply review comment to llvmIRToStableString + fix LLVMBasedICFGExportTest
1 parent f72108e commit 2dbf124

3 files changed

Lines changed: 48 additions & 16 deletions

File tree

include/phasar/Utils/LLVMShorthands.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ bool matchesSignature(const llvm::Function *F, const llvm::FunctionType *FType,
5252
bool matchesSignature(const llvm::FunctionType *FType1,
5353
const llvm::FunctionType *FType2);
5454

55+
/// We need to be able to remove a Module->ModuleSlotTracker mapping, because
56+
/// inside the same process the LLVM allocator may choose the same address for a
57+
/// new llvm::Module as for a previously deleted Module.
58+
/// Looking up the ModuleSlotTracker for the new module (that has the same
59+
/// address as the old module) will give the ModuleSlotTracker for the old
60+
/// module that is invalid for the new one. This is common behavior in the
61+
/// unittests and leads to several <badref> prints.
62+
void clearModuleSlotTrackerFor(const llvm::Module *M);
63+
5564
/**
5665
* @brief Returns a string representation of a LLVM Value.
5766
*/

lib/Utils/LLVMShorthands.cpp

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,12 @@ bool matchesSignature(const llvm::FunctionType *FType1,
142142
return false;
143143
}
144144

145+
static llvm::SmallDenseMap<const llvm::Module *,
146+
std::unique_ptr<llvm::ModuleSlotTracker>, 2>
147+
ModuleToSlotTracker;
148+
145149
static llvm::ModuleSlotTracker &getModuleSlotTrackerFor(const llvm::Value *V) {
146-
static llvm::SmallDenseMap<const llvm::Module *,
147-
std::unique_ptr<llvm::ModuleSlotTracker>, 2>
148-
ModuleToSlotTracker;
150+
149151
const auto *M = getModuleFromVal(V);
150152

151153
auto &Ret = ModuleToSlotTracker[M];
@@ -156,6 +158,10 @@ static llvm::ModuleSlotTracker &getModuleSlotTrackerFor(const llvm::Value *V) {
156158
return *Ret;
157159
}
158160

161+
void clearModuleSlotTrackerFor(const llvm::Module *M) {
162+
ModuleToSlotTracker.erase(M);
163+
}
164+
159165
std::string llvmIRToString(const llvm::Value *V) {
160166
std::string IRBuffer;
161167
llvm::raw_string_ostream RSO(IRBuffer);
@@ -172,17 +178,17 @@ std::string llvmIRToStableString(const llvm::Value *V) {
172178
V->print(RSO, getModuleSlotTrackerFor(V));
173179
RSO.flush();
174180

175-
if (auto Meta = IRBuffer.find_first_of("!#"); Meta != std::string::npos) {
176-
IRBuffer.erase(Meta);
181+
auto IRBufferRef = llvm::StringRef(IRBuffer).ltrim();
177182

178-
boost::trim_right(IRBuffer);
179-
assert(!IRBuffer.empty());
180-
if (IRBuffer.back() == ',') {
181-
IRBuffer.pop_back();
182-
}
183+
if (auto Meta = IRBufferRef.find_first_of("!#");
184+
Meta != llvm::StringRef::npos) {
185+
IRBufferRef = IRBufferRef.slice(0, Meta).rtrim();
186+
187+
assert(!IRBufferRef.empty());
188+
IRBufferRef.consume_back(",");
183189
}
184190

185-
boost::trim_left(IRBuffer);
191+
IRBuffer = IRBufferRef.str();
186192

187193
IRBuffer.append(" | ID: ");
188194
IRBuffer.append(getMetaDataID(V));

unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGExportTest.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,14 @@ class LLVMBasedICFGExportTest : public ::testing::Test {
4848
LLVMTypeHierarchy TH(IRDB);
4949
LLVMBasedICFG ICFG(IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH);
5050

51-
return asSrcCode ? ICFG.exportICFGAsSourceCodeJson()
52-
: ICFG.exportICFGAsJson();
51+
std::cerr << "ModuleRef: " << IRDB.getWPAModule() << "\n";
52+
53+
auto Ret =
54+
asSrcCode ? ICFG.exportICFGAsSourceCodeJson() : ICFG.exportICFGAsJson();
55+
56+
clearModuleSlotTrackerFor(IRDB.getWPAModule());
57+
58+
return Ret;
5359
}
5460

5561
nlohmann::json exportCFGFor(const std::string &testFile,
@@ -62,8 +68,14 @@ class LLVMBasedICFGExportTest : public ::testing::Test {
6268
assert(F != nullptr && "Invalid function");
6369
// ASSERT_NE(nullptr, F);
6470

65-
return asSrcCode ? CFG.exportCFGAsSourceCodeJson(F)
66-
: CFG.exportCFGAsJson(F);
71+
std::cerr << "ModuleRef: " << IRDB.getWPAModule() << "\n";
72+
73+
auto Ret =
74+
asSrcCode ? CFG.exportCFGAsSourceCodeJson(F) : CFG.exportCFGAsJson(F);
75+
76+
clearModuleSlotTrackerFor(IRDB.getWPAModule());
77+
78+
return Ret;
6779
}
6880

6981
MapTy getAllRetSites(const LLVMBasedICFG &ICFG) {
@@ -95,7 +107,8 @@ class LLVMBasedICFGExportTest : public ::testing::Test {
95107
[&](auto &&Elem) {
96108
return Elem == nlohmann::json{{"from", From}, {"to", To}};
97109
}))
98-
<< "No edge from " << From << " to " << To;
110+
<< "No edge from " << From << " to " << To << " in "
111+
<< ExportedICFG.dump(4);
99112
};
100113

101114
auto print = [WithDebugOutput](auto &&...Args) {
@@ -173,7 +186,11 @@ class LLVMBasedICFGExportTest : public ::testing::Test {
173186
LLVMTypeHierarchy TH(IRDB);
174187
LLVMBasedICFG ICFG(IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH);
175188

189+
std::cerr << "ModuleRef: " << IRDB.getWPAModule() << "\n";
190+
176191
verifyIRJson(ICFG.exportICFGAsJson(), ICFG, WithDebugOutput);
192+
193+
clearModuleSlotTrackerFor(IRDB.getWPAModule());
177194
}
178195
};
179196

0 commit comments

Comments
 (0)