Skip to content

Commit 2873cfd

Browse files
aengelkeslinder1
authored andcommitted
[IR] Don't verify module flags on every access (llvm#102153)
8b4306c introduced validity checks for every module flag access, because the auto-upgrader uses named metadata before verifying the module. This causes overhead for all other accesses, and the check is, in fact, only need at that single place. Change the upgrader to be careful when accessing module flags before the module is verified and remove the checks on all other occasions. There are two tangential optimizations included: first, when querying a specific flag, don't enumerate all other flags into a vector as well. Second, don't use a Twine for getNamedMetadata(), which has materialization overhead -- all call sites use simple strings that can be implicitly converted to a StringRef. (cherry picked from commit b7cd564) To minimize the diff I just copied the "checked" version of getDebugMetadataVersionFromModule that was inlined into UpgradeDebugInfo in the upstream patch. One could also delay the checks that rely on the version in the Verifier until after we've already verified the module flags metadata, but that seemed needlessly complicated. Change-Id: Id98ec158770d5b3e839e3de1c558f507c28cc82c
1 parent 7fd2163 commit 2873cfd

File tree

4 files changed

+49
-44
lines changed

4 files changed

+49
-44
lines changed

llvm/include/llvm/IR/Module.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,6 @@ class LLVM_EXTERNAL_VISIBILITY Module {
158158
/// converted result in MFB.
159159
static bool isValidModFlagBehavior(Metadata *MD, ModFlagBehavior &MFB);
160160

161-
/// Check if the given module flag metadata represents a valid module flag,
162-
/// and store the flag behavior, the key string and the value metadata.
163-
static bool isValidModuleFlag(const MDNode &ModFlag, ModFlagBehavior &MFB,
164-
MDString *&Key, Metadata *&Val);
165-
166161
struct ModuleFlagEntry {
167162
ModFlagBehavior Behavior;
168163
MDString *Key;
@@ -505,7 +500,7 @@ class LLVM_EXTERNAL_VISIBILITY Module {
505500

506501
/// Return the first NamedMDNode in the module with the specified name. This
507502
/// method returns null if a NamedMDNode with the specified name is not found.
508-
NamedMDNode *getNamedMetadata(const Twine &Name) const;
503+
NamedMDNode *getNamedMetadata(StringRef Name) const;
509504

510505
/// Return the named MDNode in the module with the specified name. This method
511506
/// returns a new NamedMDNode if a NamedMDNode with the specified name is not

llvm/lib/IR/AutoUpgrade.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4900,7 +4900,25 @@ bool llvm::UpgradeDebugInfo(Module &M) {
49004900
if (DisableAutoUpgradeDebugInfo)
49014901
return false;
49024902

4903-
unsigned Version = getDebugMetadataVersionFromModule(M);
4903+
// We need to get metadata before the module is verified (i.e., getModuleFlag
4904+
// makes assumptions that we haven't verified yet). Carefully extract the flag
4905+
// from the metadata.
4906+
unsigned Version = 0;
4907+
if (NamedMDNode *ModFlags = M.getModuleFlagsMetadata()) {
4908+
auto OpIt = find_if(ModFlags->operands(), [](const MDNode *Flag) {
4909+
if (Flag->getNumOperands() < 3)
4910+
return false;
4911+
if (MDString *K = dyn_cast_or_null<MDString>(Flag->getOperand(1)))
4912+
return K->getString() == "Debug Info Version";
4913+
return false;
4914+
});
4915+
if (OpIt != ModFlags->op_end()) {
4916+
const MDOperand &ValOp = (*OpIt)->getOperand(2);
4917+
if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(ValOp))
4918+
Version = CI->getZExtValue();
4919+
}
4920+
}
4921+
49044922
bool VersionSupported = Version == DEBUG_METADATA_VERSION ||
49054923
Version == DEBUG_METADATA_VERSION_HETEROGENEOUS_DWARF;
49064924
if (VersionSupported) {

llvm/lib/IR/Module.cpp

Lines changed: 15 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -259,10 +259,8 @@ GlobalIFunc *Module::getNamedIFunc(StringRef Name) const {
259259
/// getNamedMetadata - Return the first NamedMDNode in the module with the
260260
/// specified name. This method returns null if a NamedMDNode with the
261261
/// specified name is not found.
262-
NamedMDNode *Module::getNamedMetadata(const Twine &Name) const {
263-
SmallString<256> NameData;
264-
StringRef NameRef = Name.toStringRef(NameData);
265-
return NamedMDSymTab.lookup(NameRef);
262+
NamedMDNode *Module::getNamedMetadata(StringRef Name) const {
263+
return NamedMDSymTab.lookup(Name);
266264
}
267265

268266
/// getOrInsertNamedMetadata - Return the first named MDNode in the module
@@ -300,46 +298,31 @@ bool Module::isValidModFlagBehavior(Metadata *MD, ModFlagBehavior &MFB) {
300298
return false;
301299
}
302300

303-
bool Module::isValidModuleFlag(const MDNode &ModFlag, ModFlagBehavior &MFB,
304-
MDString *&Key, Metadata *&Val) {
305-
if (ModFlag.getNumOperands() < 3)
306-
return false;
307-
if (!isValidModFlagBehavior(ModFlag.getOperand(0), MFB))
308-
return false;
309-
MDString *K = dyn_cast_or_null<MDString>(ModFlag.getOperand(1));
310-
if (!K)
311-
return false;
312-
Key = K;
313-
Val = ModFlag.getOperand(2);
314-
return true;
315-
}
316-
317301
/// getModuleFlagsMetadata - Returns the module flags in the provided vector.
318302
void Module::
319303
getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const {
320304
const NamedMDNode *ModFlags = getModuleFlagsMetadata();
321305
if (!ModFlags) return;
322306

323307
for (const MDNode *Flag : ModFlags->operands()) {
324-
ModFlagBehavior MFB;
325-
MDString *Key = nullptr;
326-
Metadata *Val = nullptr;
327-
if (isValidModuleFlag(*Flag, MFB, Key, Val)) {
328-
// Check the operands of the MDNode before accessing the operands.
329-
// The verifier will actually catch these failures.
330-
Flags.push_back(ModuleFlagEntry(MFB, Key, Val));
331-
}
308+
// The verifier will catch errors, so no need to check them here.
309+
auto *MFBConstant = mdconst::extract<ConstantInt>(Flag->getOperand(0));
310+
auto MFB = static_cast<ModFlagBehavior>(MFBConstant->getLimitedValue());
311+
MDString *Key = cast<MDString>(Flag->getOperand(1));
312+
Metadata *Val = Flag->getOperand(2);
313+
Flags.push_back(ModuleFlagEntry(MFB, Key, Val));
332314
}
333315
}
334316

335317
/// Return the corresponding value if Key appears in module flags, otherwise
336318
/// return null.
337319
Metadata *Module::getModuleFlag(StringRef Key) const {
338-
SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
339-
getModuleFlagsMetadata(ModuleFlags);
340-
for (const ModuleFlagEntry &MFE : ModuleFlags) {
341-
if (Key == MFE.Key->getString())
342-
return MFE.Val;
320+
const NamedMDNode *ModFlags = getModuleFlagsMetadata();
321+
if (!ModFlags)
322+
return nullptr;
323+
for (const MDNode *Flag : ModFlags->operands()) {
324+
if (Key == cast<MDString>(Flag->getOperand(1))->getString())
325+
return Flag->getOperand(2);
343326
}
344327
return nullptr;
345328
}
@@ -387,10 +370,7 @@ void Module::setModuleFlag(ModFlagBehavior Behavior, StringRef Key,
387370
NamedMDNode *ModFlags = getOrInsertModuleFlagsMetadata();
388371
// Replace the flag if it already exists.
389372
for (MDNode *Flag : ModFlags->operands()) {
390-
ModFlagBehavior MFB;
391-
MDString *K = nullptr;
392-
Metadata *V = nullptr;
393-
if (isValidModuleFlag(*Flag, MFB, K, V) && K->getString() == Key) {
373+
if (cast<MDString>(Flag->getOperand(1))->getString() == Key) {
394374
Flag->replaceOperandWith(2, Val);
395375
return;
396376
}

llvm/lib/IR/Verifier.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,8 +402,20 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
402402
: VerifierSupport(OS, M), LandingPadResultTy(nullptr),
403403
SawFrameEscape(false), TBAAVerifyHelper(this) {
404404
TreatBrokenDebugInfoAsError = ShouldTreatBrokenDebugInfoAsError;
405-
if (unsigned V = getDebugMetadataVersionFromModule(M))
406-
DebugInfoVersion = V;
405+
if (NamedMDNode *ModFlags = M.getModuleFlagsMetadata()) {
406+
auto OpIt = find_if(ModFlags->operands(), [](const MDNode *Flag) {
407+
if (Flag->getNumOperands() < 3)
408+
return false;
409+
if (MDString *K = dyn_cast_or_null<MDString>(Flag->getOperand(1)))
410+
return K->getString() == "Debug Info Version";
411+
return false;
412+
});
413+
if (OpIt != ModFlags->op_end()) {
414+
const MDOperand &ValOp = (*OpIt)->getOperand(2);
415+
if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(ValOp))
416+
DebugInfoVersion = CI->getZExtValue();
417+
}
418+
}
407419
}
408420

409421
bool hasBrokenDebugInfo() const { return BrokenDebugInfo; }

0 commit comments

Comments
 (0)