xref: /llvm-project/llvm/tools/llvm-reduce/deltas/ReduceDIMetadata.cpp (revision c2e62c745996cbd4e19ac1ffcafc849960377b57)
12c799b77SMatthew Voss //===- ReduceDIMetadata.cpp - Specialized Delta pass for DebugInfo --------===//
22c799b77SMatthew Voss //
32c799b77SMatthew Voss // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42c799b77SMatthew Voss // See https://llvm.org/LICENSE.txt for license information.
52c799b77SMatthew Voss // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62c799b77SMatthew Voss //
72c799b77SMatthew Voss //===----------------------------------------------------------------------===//
82c799b77SMatthew Voss //
92c799b77SMatthew Voss // This file implements two functions used by the Generic Delta Debugging
102c799b77SMatthew Voss // Algorithm, which are used to reduce DebugInfo metadata nodes.
112c799b77SMatthew Voss //
122c799b77SMatthew Voss //===----------------------------------------------------------------------===//
132c799b77SMatthew Voss 
142c799b77SMatthew Voss #include "ReduceDIMetadata.h"
152c799b77SMatthew Voss #include "Delta.h"
162c799b77SMatthew Voss #include "llvm/ADT/Sequence.h"
17333ffafbSMatt Arsenault #include "llvm/ADT/SetVector.h"
182c799b77SMatthew Voss #include "llvm/ADT/SmallVector.h"
192c799b77SMatthew Voss #include "llvm/IR/DebugInfoMetadata.h"
202c799b77SMatthew Voss #include "llvm/IR/InstIterator.h"
212c799b77SMatthew Voss #include <tuple>
222c799b77SMatthew Voss #include <vector>
232c799b77SMatthew Voss 
242c799b77SMatthew Voss using namespace llvm;
252c799b77SMatthew Voss 
262c799b77SMatthew Voss using MDNodeList = SmallVector<MDNode *>;
272c799b77SMatthew Voss 
identifyUninterestingMDNodes(Oracle & O,MDNodeList & MDs)282c799b77SMatthew Voss void identifyUninterestingMDNodes(Oracle &O, MDNodeList &MDs) {
29fe50eac8SMatthew Voss   SetVector<std::tuple<MDNode *, size_t, MDNode *>> Tuples;
302c799b77SMatthew Voss   std::vector<MDNode *> ToLook;
31fe50eac8SMatthew Voss   SetVector<MDNode *> Visited;
322c799b77SMatthew Voss 
332c799b77SMatthew Voss   // Start by looking at the attachments we collected
342c799b77SMatthew Voss   for (const auto &NMD : MDs)
35fe50eac8SMatthew Voss     if (NMD)
362c799b77SMatthew Voss       ToLook.push_back(NMD);
372c799b77SMatthew Voss 
382c799b77SMatthew Voss   while (!ToLook.empty()) {
392c799b77SMatthew Voss     MDNode *MD = ToLook.back();
402c799b77SMatthew Voss     ToLook.pop_back();
412c799b77SMatthew Voss 
422c799b77SMatthew Voss     if (Visited.count(MD))
432c799b77SMatthew Voss       continue;
442c799b77SMatthew Voss 
452c799b77SMatthew Voss     // Determine if the current MDNode is DebugInfo
462c799b77SMatthew Voss     if (DINode *DIM = dyn_cast_or_null<DINode>(MD)) {
472c799b77SMatthew Voss       // Scan operands and record attached tuples
482c799b77SMatthew Voss       for (size_t I = 0; I < DIM->getNumOperands(); ++I)
492c799b77SMatthew Voss         if (MDTuple *MDT = dyn_cast_or_null<MDTuple>(DIM->getOperand(I)))
502c799b77SMatthew Voss           if (!Visited.count(MDT) && MDT->getNumOperands())
512c799b77SMatthew Voss             Tuples.insert({DIM, I, MDT});
522c799b77SMatthew Voss     }
532c799b77SMatthew Voss 
542c799b77SMatthew Voss     // Add all of the operands of the current node to the loop's todo list.
552c799b77SMatthew Voss     for (Metadata *Op : MD->operands())
562c799b77SMatthew Voss       if (MDNode *OMD = dyn_cast_or_null<MDNode>(Op))
572c799b77SMatthew Voss         ToLook.push_back(OMD);
582c799b77SMatthew Voss 
592c799b77SMatthew Voss     Visited.insert(MD);
602c799b77SMatthew Voss   }
612c799b77SMatthew Voss 
622c799b77SMatthew Voss   for (auto &T : Tuples) {
632c799b77SMatthew Voss     auto [DbgNode, OpIdx, Tup] = T;
642c799b77SMatthew Voss     // Remove the operands of the tuple that are not in the desired chunks.
652c799b77SMatthew Voss     SmallVector<Metadata *, 16> TN;
662c799b77SMatthew Voss     for (size_t I = 0; I < Tup->getNumOperands(); ++I) {
672c799b77SMatthew Voss       // Ignore any operands that are not DebugInfo metadata nodes.
68*c2e62c74SOrlando Cazalet-Hyams       if (Metadata *Op = Tup->getOperand(I).get()) {
69*c2e62c74SOrlando Cazalet-Hyams         if (isa<DINode>(Op) || isa<DIGlobalVariableExpression>(Op))
702c799b77SMatthew Voss           // Don't add uninteresting operands to the tuple.
712c799b77SMatthew Voss           if (!O.shouldKeep())
722c799b77SMatthew Voss             continue;
73*c2e62c74SOrlando Cazalet-Hyams         TN.push_back(Op);
74*c2e62c74SOrlando Cazalet-Hyams       }
752c799b77SMatthew Voss     }
762c799b77SMatthew Voss     if (TN.size() != Tup->getNumOperands())
772c799b77SMatthew Voss       DbgNode->replaceOperandWith(OpIdx, DbgNode->get(DbgNode->getContext(), TN));
782c799b77SMatthew Voss   }
792c799b77SMatthew Voss }
802c799b77SMatthew Voss 
extractDIMetadataFromModule(Oracle & O,ReducerWorkItem & WorkItem)8123cc36e4SMatt Arsenault static void extractDIMetadataFromModule(Oracle &O, ReducerWorkItem &WorkItem) {
8223cc36e4SMatt Arsenault   Module &Program = WorkItem.getModule();
8323cc36e4SMatt Arsenault 
842c799b77SMatthew Voss   MDNodeList MDs;
852c799b77SMatthew Voss   // Collect all !dbg metadata attachments.
862c799b77SMatthew Voss   for (const auto &DC : Program.debug_compile_units())
872c799b77SMatthew Voss     if (DC)
882c799b77SMatthew Voss       MDs.push_back(DC);
892c799b77SMatthew Voss   for (GlobalVariable &GV : Program.globals())
902c799b77SMatthew Voss     GV.getMetadata(llvm::LLVMContext::MD_dbg, MDs);
912c799b77SMatthew Voss   for (Function &F : Program.functions()) {
922c799b77SMatthew Voss     F.getMetadata(llvm::LLVMContext::MD_dbg, MDs);
932c799b77SMatthew Voss     for (Instruction &I : instructions(F))
942c799b77SMatthew Voss       if (auto *DI = I.getMetadata(llvm::LLVMContext::MD_dbg))
952c799b77SMatthew Voss         MDs.push_back(DI);
962c799b77SMatthew Voss   }
972c799b77SMatthew Voss   identifyUninterestingMDNodes(O, MDs);
982c799b77SMatthew Voss }
992c799b77SMatthew Voss 
reduceDIMetadataDeltaPass(TestRunner & Test)1002c799b77SMatthew Voss void llvm::reduceDIMetadataDeltaPass(TestRunner &Test) {
1012592ccdeSArthur Eubanks   runDeltaPass(Test, extractDIMetadataFromModule, "Reducing DIMetadata");
1022c799b77SMatthew Voss }
103